comparison OrthancServer/FromDcmtkBridge.cpp @ 676:aa5ca7a2166f

experiments with pixel data
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 03 Jan 2014 17:49:31 +0100
parents d233b5090105
children 27acbc5985f5
comparison
equal deleted inserted replaced
675:9a8716686f18 676:aa5ca7a2166f
119 #include <dcmtk/dcmdata/dcvrtm.h> 119 #include <dcmtk/dcmdata/dcvrtm.h>
120 #include <dcmtk/dcmdata/dcvrui.h> 120 #include <dcmtk/dcmdata/dcvrui.h>
121 #include <dcmtk/dcmdata/dcvrul.h> 121 #include <dcmtk/dcmdata/dcvrul.h>
122 #include <dcmtk/dcmdata/dcvrus.h> 122 #include <dcmtk/dcmdata/dcvrus.h>
123 #include <dcmtk/dcmdata/dcvrut.h> 123 #include <dcmtk/dcmdata/dcvrut.h>
124 #include <dcmtk/dcmdata/dcpixel.h>
125 #include <dcmtk/dcmdata/dcpixseq.h>
126 #include <dcmtk/dcmdata/dcpxitem.h>
127
124 128
125 #include <boost/math/special_functions/round.hpp> 129 #include <boost/math/special_functions/round.hpp>
126 #include <glog/logging.h> 130 #include <glog/logging.h>
127 #include <dcmtk/dcmdata/dcostrmb.h> 131 #include <dcmtk/dcmdata/dcostrmb.h>
128 132
207 } 211 }
208 212
209 output.AnswerJson(v); 213 output.AnswerJson(v);
210 } 214 }
211 215
216
217 static void AnswerPixelData(RestApiOutput& output,
218 DcmPixelData& pixelData,
219 E_TransferSyntax transferSyntax)
220 {
221 DcmPixelSequence* pixelSequence = NULL;
222 if (pixelData.getEncapsulatedRepresentation
223 (transferSyntax, NULL, pixelSequence).good() && pixelSequence)
224 {
225 for (unsigned long i = 0; i < pixelSequence->card(); i++)
226 {
227 DcmPixelItem* pixelItem = NULL;
228 if (pixelSequence->getItem(pixelItem, i).good() && pixelItem)
229 {
230 Uint8* b = NULL;
231 if (pixelItem->getUint8Array(b).good() && b)
232 {
233 // JPEG-LS (lossless)
234 // http://gdcm.sourceforge.net/wiki/index.php/Tools/ffmpeg#JPEG_LS
235 // http://www.stat.columbia.edu/~jakulin/jpeg-ls/
236 // http://itohws03.ee.noda.sut.ac.jp/~matsuda/mrp/
237
238 printf("ITEM: %d\n", pixelItem->getLength());
239 char buf[64];
240 sprintf(buf, "/tmp/toto-%06ld.jpg", i);
241 FILE* fp = fopen(buf, "wb");
242 fwrite(b, pixelItem->getLength(), 1, fp);
243 fclose(fp);
244 }
245 }
246 }
247 }
248 }
249
250
212 static void AnswerDicomField(RestApiOutput& output, 251 static void AnswerDicomField(RestApiOutput& output,
213 DcmElement& element) 252 DcmElement& element,
214 { 253 E_TransferSyntax transferSyntax)
215 // This element is not a sequence 254 {
255 // This element is not a sequence. Test if it is pixel data.
256 if (element.getTag().getGTag() == DICOM_TAG_PIXEL_DATA.GetGroup() &&
257 element.getTag().getETag() == DICOM_TAG_PIXEL_DATA.GetElement())
258 {
259 try
260 {
261 DcmPixelData& pixelData = dynamic_cast<DcmPixelData&>(element);
262 AnswerPixelData(output, pixelData, transferSyntax);
263 return;
264 }
265 catch (std::bad_cast&)
266 {
267 }
268 }
269
270
271 // This element is nor a sequence, neither a pixel-data
216 std::string buffer; 272 std::string buffer;
217 buffer.resize(65536); 273 buffer.resize(65536);
218 Uint32 length = element.getLength(); 274 Uint32 length = element.getLength(transferSyntax);
219 Uint32 offset = 0; 275 Uint32 offset = 0;
220 276
221 output.GetLowLevelOutput().SendOkHeader("application/octet-stream", true, length, NULL); 277 output.GetLowLevelOutput().SendOkHeader("application/octet-stream", true, length, NULL);
222 278
223 while (offset < length) 279 while (offset < length)
230 else 286 else
231 { 287 {
232 nbytes = buffer.size(); 288 nbytes = buffer.size();
233 } 289 }
234 290
235 if (element.getPartialValue(&buffer[0], offset, nbytes).good()) 291 OFCondition cond = element.getPartialValue(&buffer[0], offset, nbytes);
292
293 if (cond.good())
236 { 294 {
237 output.GetLowLevelOutput().Send(&buffer[0], nbytes); 295 output.GetLowLevelOutput().Send(&buffer[0], nbytes);
238 offset += nbytes; 296 offset += nbytes;
239 } 297 }
240 else 298 else
241 { 299 {
242 LOG(ERROR) << "Error while sending a DICOM field"; 300 LOG(ERROR) << "Error while sending a DICOM field: " << cond.text();
243 return; 301 return;
244 } 302 }
245 } 303 }
246 304
247 output.MarkLowLevelOutputDone(); 305 output.MarkLowLevelOutputDone();
248 } 306 }
249 307
250 static void SendPathValueForLeaf(RestApiOutput& output, 308 static void SendPathValueForLeaf(RestApiOutput& output,
251 const std::string& tag, 309 const std::string& tag,
252 DcmItem& dicom) 310 DcmItem& dicom,
311 E_TransferSyntax transferSyntax)
253 { 312 {
254 DcmTagKey k; 313 DcmTagKey k;
255 ParseTagAndGroup(k, tag); 314 ParseTagAndGroup(k, tag);
256 315
257 DcmSequenceOfItems* sequence = NULL; 316 DcmSequenceOfItems* sequence = NULL;
267 if (dicom.findAndGetElement(k, element).good() && 326 if (dicom.findAndGetElement(k, element).good() &&
268 element != NULL && 327 element != NULL &&
269 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags 328 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags
270 element->getVR() != EVR_SQ) 329 element->getVR() != EVR_SQ)
271 { 330 {
272 AnswerDicomField(output, *element); 331 AnswerDicomField(output, *element, transferSyntax);
273 } 332 }
274 } 333 }
275 334
276 void ParsedDicomFile::SendPathValue(RestApiOutput& output, 335 void ParsedDicomFile::SendPathValue(RestApiOutput& output,
277 const UriComponents& uri) 336 const UriComponents& uri)
308 { 367 {
309 SendPathValueForDictionary(output, *dicom); 368 SendPathValueForDictionary(output, *dicom);
310 } 369 }
311 else 370 else
312 { 371 {
313 SendPathValueForLeaf(output, uri.back(), *dicom); 372 SendPathValueForLeaf(output, uri.back(), *dicom, file_->getDataset()->getOriginalXfer());
314 } 373 }
315 } 374 }
316 375
317 376
318 377