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 }