Mercurial > hg > orthanc-wsi
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 } |