comparison Framework/ImageToolbox.cpp @ 217:20bc074ec19a

Viewer can display DICOM pyramids whose tile sizes vary across levels
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 Jan 2021 14:24:18 +0100
parents c35a3a0627b9
children c6e7dda9ac14
comparison
equal deleted inserted replaced
216:c35a3a0627b9 217:20bc074ec19a
386 << result->GetWidth() << "x" << result->GetHeight(); 386 << result->GetWidth() << "x" << result->GetHeight();
387 387
388 const unsigned int width = result->GetWidth(); 388 const unsigned int width = result->GetWidth();
389 const unsigned int height = result->GetHeight(); 389 const unsigned int height = result->GetHeight();
390 390
391 for (unsigned int y = 0; y < height; y += pyramid.GetTileHeight()) 391 for (unsigned int y = 0; y < height; y += pyramid.GetTileHeight(level))
392 { 392 {
393 for (unsigned int x = 0; x < width; x += pyramid.GetTileWidth()) 393 for (unsigned int x = 0; x < width; x += pyramid.GetTileWidth(level))
394 { 394 {
395 std::unique_ptr<Orthanc::ImageAccessor> tile(pyramid.DecodeTile(level, 395 std::unique_ptr<Orthanc::ImageAccessor> tile(
396 x / pyramid.GetTileWidth(), 396 pyramid.DecodeTile(level,
397 y / pyramid.GetTileHeight())); 397 x / pyramid.GetTileWidth(level),
398 y / pyramid.GetTileHeight(level)));
398 Embed(*result, *tile, x, y); 399 Embed(*result, *tile, x, y);
399 } 400 }
400 } 401 }
401 402
402 return result.release(); 403 return result.release();
404 }
405
406
407 void CheckConstantTileSize(const ITiledPyramid& source)
408 {
409 if (source.GetLevelCount() == 0)
410 {
411 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize,
412 "Input pyramid has no level");
413 }
414 else
415 {
416 for (unsigned int level = 0; level < source.GetLevelCount(); level++)
417 {
418 if (source.GetTileWidth(level) != source.GetTileWidth(0) ||
419 source.GetTileHeight(level) != source.GetTileHeight(0))
420 {
421 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize,
422 "The DICOMizer requires that the input pyramid has constant "
423 "tile sizes across all its levels, which is not the case");
424 }
425 }
426 }
427 }
428
429
430 void ConvertJpegYCbCrToRgb(Orthanc::ImageAccessor& image)
431 {
432 #if defined(ORTHANC_FRAMEWORK_VERSION_IS_ABOVE) && ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 9, 0)
433 Orthanc::ImageProcessing::ConvertJpegYCbCrToRgb(image);
434 #else
435 # warning You are using an old version of the Orthanc framework
436 const unsigned int width = image.GetWidth();
437 const unsigned int height = image.GetHeight();
438 const unsigned int pitch = image.GetPitch();
439 uint8_t* buffer = reinterpret_cast<uint8_t*>(image.GetBuffer());
440
441 if (image.GetFormat() != Orthanc::PixelFormat_RGB24 ||
442 pitch < 3 * width)
443 {
444 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
445 }
446
447 for (unsigned int y = 0; y < height; y++)
448 {
449 uint8_t* p = buffer + y * pitch;
450
451 for (unsigned int x = 0; x < width; x++, p += 3)
452 {
453 const float Y = p[0];
454 const float Cb = p[1];
455 const float Cr = p[2];
456
457 const float result[3] = {
458 Y + 1.402f * (Cr - 128.0f),
459 Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f),
460 Y + 1.772f * (Cb - 128.0f)
461 };
462
463 for (uint8_t i = 0; i < 3 ; i++)
464 {
465 if (result[i] < 0)
466 {
467 p[i] = 0;
468 }
469 else if (result[i] > 255)
470 {
471 p[i] = 255;
472 }
473 else
474 {
475 p[i] = static_cast<uint8_t>(result[i]);
476 }
477 }
478 }
479 }
480 #endif
403 } 481 }
404 } 482 }
405 } 483 }