Mercurial > hg > orthanc
comparison PalantirServer/FromDcmtkBridge.cpp @ 42:ea48f38afe5f
access to raw images
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 03 Sep 2012 11:34:00 +0200 |
parents | c1097a676eca |
children |
comparison
equal
deleted
inserted
replaced
41:c1097a676eca | 42:ea48f38afe5f |
---|---|
377 FromDcmtkBridge::ToJson(target, *dicom.getDataset(), maxStringLength); | 377 FromDcmtkBridge::ToJson(target, *dicom.getDataset(), maxStringLength); |
378 } | 378 } |
379 } | 379 } |
380 | 380 |
381 | 381 |
382 void FromDcmtkBridge::ExtractPreviewImage(std::string& result, | 382 static void ExtractPngImagePreview(std::string& result, |
383 DcmDataset& dataset) | 383 DicomIntegerPixelAccessor& accessor) |
384 { | |
385 PngWriter w; | |
386 | |
387 int32_t min, max; | |
388 accessor.GetExtremeValues(min, max); | |
389 | |
390 std::vector<uint8_t> image(accessor.GetWidth() * accessor.GetHeight(), 0); | |
391 if (min != max) | |
392 { | |
393 uint8_t* pixel = &image[0]; | |
394 for (unsigned int y = 0; y < accessor.GetHeight(); y++) | |
395 { | |
396 for (unsigned int x = 0; x < accessor.GetWidth(); x++, pixel++) | |
397 { | |
398 int32_t v = accessor.GetValue(x, y); | |
399 *pixel = static_cast<uint8_t>( | |
400 boost::math::lround(static_cast<float>(v - min) / | |
401 static_cast<float>(max - min) * 255.0f)); | |
402 } | |
403 } | |
404 } | |
405 | |
406 w.WriteToMemory(result, accessor.GetWidth(), accessor.GetHeight(), | |
407 accessor.GetWidth(), PixelFormat_Grayscale8, &image[0]); | |
408 } | |
409 | |
410 | |
411 template <typename T> | |
412 static void ExtractPngImageTruncate(std::string& result, | |
413 DicomIntegerPixelAccessor& accessor, | |
414 PixelFormat format) | |
415 { | |
416 PngWriter w; | |
417 | |
418 std::vector<T> image(accessor.GetWidth() * accessor.GetHeight(), 0); | |
419 T* pixel = &image[0]; | |
420 for (unsigned int y = 0; y < accessor.GetHeight(); y++) | |
421 { | |
422 for (unsigned int x = 0; x < accessor.GetWidth(); x++, pixel++) | |
423 { | |
424 int32_t v = accessor.GetValue(x, y); | |
425 if (v < std::numeric_limits<T>::min()) | |
426 *pixel = std::numeric_limits<T>::min(); | |
427 else if (v > std::numeric_limits<T>::max()) | |
428 *pixel = std::numeric_limits<T>::max(); | |
429 else | |
430 *pixel = static_cast<T>(v); | |
431 } | |
432 } | |
433 | |
434 w.WriteToMemory(result, accessor.GetWidth(), accessor.GetHeight(), | |
435 accessor.GetWidth() * sizeof(T), format, &image[0]); | |
436 } | |
437 | |
438 | |
439 void FromDcmtkBridge::ExtractPngImage(std::string& result, | |
440 DcmDataset& dataset, | |
441 ImageExtractionMode mode) | |
384 { | 442 { |
385 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data | 443 // See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data |
386 | 444 |
387 PngWriter w; | |
388 std::auto_ptr<DicomIntegerPixelAccessor> accessor; | 445 std::auto_ptr<DicomIntegerPixelAccessor> accessor; |
389 | 446 |
390 DicomMap m; | 447 DicomMap m; |
391 FromDcmtkBridge::Convert(m, dataset); | 448 FromDcmtkBridge::Convert(m, dataset); |
392 | 449 |
399 { | 456 { |
400 accessor.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); | 457 accessor.reset(new DicomIntegerPixelAccessor(m, pixData, e->getLength())); |
401 } | 458 } |
402 } | 459 } |
403 | 460 |
461 PixelFormat format; | |
462 switch (mode) | |
463 { | |
464 case ImageExtractionMode_Preview: | |
465 case ImageExtractionMode_UInt8: | |
466 format = PixelFormat_Grayscale8; | |
467 break; | |
468 | |
469 case ImageExtractionMode_UInt16: | |
470 format = PixelFormat_Grayscale16; | |
471 break; | |
472 | |
473 default: | |
474 throw PalantirException(ErrorCode_NotImplemented); | |
475 } | |
476 | |
404 if (accessor.get() == NULL || | 477 if (accessor.get() == NULL || |
405 accessor->GetWidth() == 0 || | 478 accessor->GetWidth() == 0 || |
406 accessor->GetHeight() == 0) | 479 accessor->GetHeight() == 0) |
407 { | 480 { |
408 w.WriteToMemory(result, 0, 0, 0, PixelFormat_Grayscale8, NULL); | 481 PngWriter w; |
482 w.WriteToMemory(result, 0, 0, 0, format, NULL); | |
409 } | 483 } |
410 else | 484 else |
411 { | 485 { |
412 int32_t min, max; | 486 switch (mode) |
413 accessor->GetExtremeValues(min, max); | 487 { |
414 | 488 case ImageExtractionMode_Preview: |
415 std::vector<uint8_t> image(accessor->GetWidth() * accessor->GetHeight(), 0); | 489 ExtractPngImagePreview(result, *accessor); |
416 if (min != max) | 490 break; |
417 { | 491 |
418 uint8_t* result = &image[0]; | 492 case ImageExtractionMode_UInt8: |
419 for (unsigned int y = 0; y < accessor->GetHeight(); y++) | 493 ExtractPngImageTruncate<uint8_t>(result, *accessor, format); |
420 { | 494 break; |
421 for (unsigned int x = 0; x < accessor->GetWidth(); x++, result++) | 495 |
422 { | 496 case ImageExtractionMode_UInt16: |
423 int32_t v = accessor->GetValue(x, y); | 497 ExtractPngImageTruncate<uint16_t>(result, *accessor, format); |
424 *result = static_cast<uint8_t>(boost::math::lround(static_cast<float>(v - min) / static_cast<float>(max - min) * 255.0f)); | 498 break; |
425 } | 499 |
426 } | 500 default: |
427 } | 501 throw PalantirException(ErrorCode_NotImplemented); |
428 | 502 } |
429 w.WriteToMemory(result, accessor->GetWidth(), accessor->GetHeight(), | 503 } |
430 accessor->GetWidth(), PixelFormat_Grayscale8, &image[0]); | 504 } |
431 } | 505 |
432 } | 506 |
433 | 507 void FromDcmtkBridge::ExtractPngImage(std::string& result, |
434 | 508 const std::string& dicomContent, |
435 void FromDcmtkBridge::ExtractPreviewImage(std::string& result, | 509 ImageExtractionMode mode) |
436 const std::string& dicomContent) | |
437 { | 510 { |
438 DcmInputBufferStream is; | 511 DcmInputBufferStream is; |
439 if (dicomContent.size() > 0) | 512 if (dicomContent.size() > 0) |
440 { | 513 { |
441 is.setBuffer(&dicomContent[0], dicomContent.size()); | 514 is.setBuffer(&dicomContent[0], dicomContent.size()); |
443 is.setEos(); | 516 is.setEos(); |
444 | 517 |
445 DcmFileFormat dicom; | 518 DcmFileFormat dicom; |
446 if (dicom.read(is).good()) | 519 if (dicom.read(is).good()) |
447 { | 520 { |
448 ExtractPreviewImage(result, *dicom.getDataset()); | 521 ExtractPngImage(result, *dicom.getDataset(), mode); |
449 } | 522 } |
450 else | 523 else |
451 { | 524 { |
452 throw PalantirException(ErrorCode_BadFileFormat); | 525 throw PalantirException(ErrorCode_BadFileFormat); |
453 } | 526 } |