Mercurial > hg > orthanc
comparison OrthancServer/Internals/DicomImageDecoder.cpp @ 853:839be3022203 jpeg
DicomImageInformation
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 06 Jun 2014 11:45:16 +0200 |
parents | 5944b8b80842 |
children | ff530685e46a |
comparison
equal
deleted
inserted
replaced
852:5944b8b80842 | 853:839be3022203 |
---|---|
97 { | 97 { |
98 class DicomImageDecoder::ImageSource | 98 class DicomImageDecoder::ImageSource |
99 { | 99 { |
100 private: | 100 private: |
101 std::string psmct_; | 101 std::string psmct_; |
102 std::auto_ptr<DicomIntegerPixelAccessor> accessor_; | 102 std::auto_ptr<DicomIntegerPixelAccessor> slowAccessor_; |
103 | 103 std::auto_ptr<ImageAccessor> fastAccessor_; |
104 | |
104 public: | 105 public: |
105 void Setup(DcmDataset& dataset, | 106 void Setup(DcmDataset& dataset, |
106 unsigned int frame) | 107 unsigned int frame) |
107 { | 108 { |
109 psmct_.clear(); | |
110 slowAccessor_.reset(NULL); | |
111 fastAccessor_.reset(NULL); | |
112 | |
108 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data | 113 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data |
109 | 114 |
110 DicomMap m; | 115 DicomMap m; |
111 FromDcmtkBridge::Convert(m, dataset); | 116 FromDcmtkBridge::Convert(m, dataset); |
112 | 117 |
119 e != NULL) | 124 e != NULL) |
120 { | 125 { |
121 Uint8* pixData = NULL; | 126 Uint8* pixData = NULL; |
122 if (e->getUint8Array(pixData) == EC_Normal) | 127 if (e->getUint8Array(pixData) == EC_Normal) |
123 { | 128 { |
124 accessor_.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); | 129 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); |
125 } | 130 } |
126 } | 131 } |
127 else if (DicomImageDecoder::DecodePsmctRle1(psmct_, dataset)) | 132 else if (DicomImageDecoder::DecodePsmctRle1(psmct_, dataset)) |
128 { | 133 { |
129 LOG(INFO) << "The PMSCT_RLE1 decoding has succeeded"; | 134 LOG(INFO) << "The PMSCT_RLE1 decoding has succeeded"; |
131 if (psmct_.size() > 0) | 136 if (psmct_.size() > 0) |
132 { | 137 { |
133 pixData = reinterpret_cast<Uint8*>(&psmct_[0]); | 138 pixData = reinterpret_cast<Uint8*>(&psmct_[0]); |
134 } | 139 } |
135 | 140 |
136 accessor_.reset(new DicomIntegerPixelAccessor(m, pixData, psmct_.size())); | 141 slowAccessor_.reset(new DicomIntegerPixelAccessor(m, pixData, psmct_.size())); |
137 } | 142 } |
138 | 143 |
139 if (accessor_.get() == NULL) | 144 if (slowAccessor_.get() == NULL) |
140 { | 145 { |
141 throw OrthancException(ErrorCode_BadFileFormat); | 146 throw OrthancException(ErrorCode_BadFileFormat); |
142 } | 147 } |
143 | 148 |
144 accessor_->SetCurrentFrame(frame); | 149 slowAccessor_->SetCurrentFrame(frame); |
150 | |
151 | |
152 /** | |
153 * If possible, create a fast ImageAccessor to the image buffer. | |
154 **/ | |
155 | |
156 | |
157 } | |
158 | |
159 unsigned int GetWidth() const | |
160 { | |
161 assert(slowAccessor_.get() != NULL); | |
162 return slowAccessor_->GetInformation().GetWidth(); | |
163 } | |
164 | |
165 unsigned int GetHeight() const | |
166 { | |
167 assert(slowAccessor_.get() != NULL); | |
168 return slowAccessor_->GetInformation().GetHeight(); | |
169 } | |
170 | |
171 unsigned int GetBytesPerPixel() const | |
172 { | |
173 assert(slowAccessor_.get() != NULL); | |
174 return slowAccessor_->GetInformation().GetBytesPerPixel(); | |
145 } | 175 } |
146 | 176 |
147 unsigned int GetChannelCount() const | 177 unsigned int GetChannelCount() const |
148 { | 178 { |
149 assert(accessor_.get() != NULL); | 179 assert(slowAccessor_.get() != NULL); |
150 return accessor_->GetChannelCount(); | 180 return slowAccessor_->GetInformation().GetChannelCount(); |
151 } | 181 } |
152 | 182 |
153 const DicomIntegerPixelAccessor GetAccessor() const | 183 const DicomIntegerPixelAccessor GetAccessor() const |
154 { | 184 { |
155 assert(accessor_.get() != NULL); | 185 assert(slowAccessor_.get() != NULL); |
156 return *accessor_; | 186 return *slowAccessor_; |
187 } | |
188 | |
189 bool HasFastAccessor() const | |
190 { | |
191 return fastAccessor_.get() != NULL; | |
192 } | |
193 | |
194 const ImageAccessor& GetFastAccessor() const | |
195 { | |
196 assert(HasFastAccessor()); | |
197 return *fastAccessor_; | |
157 } | 198 } |
158 }; | 199 }; |
159 | 200 |
160 | 201 |
161 static const DicomTag DICOM_TAG_CONTENT(0x07a1, 0x100a); | 202 static const DicomTag DICOM_TAG_CONTENT(0x07a1, 0x100a); |
360 const DicomIntegerPixelAccessor& source) | 401 const DicomIntegerPixelAccessor& source) |
361 { | 402 { |
362 const PixelType minValue = std::numeric_limits<PixelType>::min(); | 403 const PixelType minValue = std::numeric_limits<PixelType>::min(); |
363 const PixelType maxValue = std::numeric_limits<PixelType>::max(); | 404 const PixelType maxValue = std::numeric_limits<PixelType>::max(); |
364 | 405 |
365 for (unsigned int y = 0; y < source.GetHeight(); y++) | 406 for (unsigned int y = 0; y < source.GetInformation().GetHeight(); y++) |
366 { | 407 { |
367 PixelType* pixel = reinterpret_cast<PixelType*>(target.GetRow(y)); | 408 PixelType* pixel = reinterpret_cast<PixelType*>(target.GetRow(y)); |
368 for (unsigned int x = 0; x < source.GetWidth(); x++) | 409 for (unsigned int x = 0; x < source.GetInformation().GetWidth(); x++) |
369 { | 410 { |
370 for (unsigned int c = 0; c < source.GetChannelCount(); c++, pixel++) | 411 for (unsigned int c = 0; c < source.GetInformation().GetChannelCount(); c++, pixel++) |
371 { | 412 { |
372 int32_t v = source.GetValue(x, y, c); | 413 int32_t v = source.GetValue(x, y, c); |
373 if (v < static_cast<int32_t>(minValue)) | 414 if (v < static_cast<int32_t>(minValue)) |
374 { | 415 { |
375 *pixel = minValue; | 416 *pixel = minValue; |