Mercurial > hg > orthanc-wsi
comparison Framework/Inputs/DicomPyramidInstance.cpp @ 330:c42083d50ddf
Added support for DICOM tag "Recommended Absent Pixel CIELab" (0048,0015)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 18 Oct 2024 13:08:55 +0200 |
parents | 0683312e21ba |
children |
comparison
equal
deleted
inserted
replaced
329:ae2d769215d2 | 330:c42083d50ddf |
---|---|
22 | 22 |
23 | 23 |
24 #include "../PrecompiledHeadersWSI.h" | 24 #include "../PrecompiledHeadersWSI.h" |
25 #include "DicomPyramidInstance.h" | 25 #include "DicomPyramidInstance.h" |
26 | 26 |
27 #include "../ColorSpaces.h" | |
27 #include "../DicomToolbox.h" | 28 #include "../DicomToolbox.h" |
28 #include "../../Resources/Orthanc/Stone/DicomDatasetReader.h" | 29 #include "../../Resources/Orthanc/Stone/DicomDatasetReader.h" |
29 #include "../../Resources/Orthanc/Stone/FullOrthancDataset.h" | 30 #include "../../Resources/Orthanc/Stone/FullOrthancDataset.h" |
30 | 31 |
31 #include <Logging.h> | 32 #include <Logging.h> |
49 static const Orthanc::DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a); | 50 static const Orthanc::DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a); |
50 static const Orthanc::DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f); | 51 static const Orthanc::DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f); |
51 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006); | 52 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006); |
52 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007); | 53 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007); |
53 static const Orthanc::DicomTag DICOM_TAG_IMAGE_TYPE(0x0008, 0x0008); | 54 static const Orthanc::DicomTag DICOM_TAG_IMAGE_TYPE(0x0008, 0x0008); |
55 static const Orthanc::DicomTag DICOM_TAG_RECOMMENDED_ABSENT_PIXEL_CIELAB(0x0048, 0x0015); | |
54 | 56 |
55 static ImageCompression DetectImageCompression(OrthancStone::IOrthancConnection& orthanc, | 57 static ImageCompression DetectImageCompression(OrthancStone::IOrthancConnection& orthanc, |
56 const std::string& instanceId) | 58 const std::string& instanceId) |
57 { | 59 { |
58 using namespace OrthancStone; | 60 using namespace OrthancStone; |
261 { | 263 { |
262 frames_[i].first = i % w; | 264 frames_[i].first = i % w; |
263 frames_[i].second = i / w; | 265 frames_[i].second = i / w; |
264 } | 266 } |
265 } | 267 } |
268 | |
269 // New in WSI 2.1 | |
270 std::string background; | |
271 if (dataset.GetStringValue(background, Orthanc::DicomPath(DICOM_TAG_RECOMMENDED_ABSENT_PIXEL_CIELAB))) | |
272 { | |
273 LABColor lab; | |
274 if (LABColor::DecodeDicomRecommendedAbsentPixelCIELab(lab, background)) | |
275 { | |
276 XYZColor xyz(lab); | |
277 sRGBColor srgb(xyz); | |
278 RGBColor rgb(srgb); | |
279 hasBackgroundColor_ = true; | |
280 backgroundRed_ = rgb.GetR(); | |
281 backgroundGreen_ = rgb.GetG(); | |
282 backgroundBlue_ = rgb.GetB(); | |
283 } | |
284 } | |
266 } | 285 } |
267 | 286 |
268 | 287 |
269 DicomPyramidInstance::DicomPyramidInstance(OrthancStone::IOrthancConnection& orthanc, | 288 DicomPyramidInstance::DicomPyramidInstance(OrthancStone::IOrthancConnection& orthanc, |
270 const std::string& instanceId, | 289 const std::string& instanceId, |
271 bool useCache) : | 290 bool useCache) : |
272 instanceId_(instanceId), | 291 instanceId_(instanceId), |
273 hasCompression_(false), | 292 hasCompression_(false), |
274 compression_(ImageCompression_None) // Dummy initialization for serialization | 293 compression_(ImageCompression_None), // Dummy initialization for serialization |
294 hasBackgroundColor_(false), | |
295 backgroundRed_(0), | |
296 backgroundGreen_(0), | |
297 backgroundBlue_(0) | |
275 { | 298 { |
276 if (useCache) | 299 if (useCache) |
277 { | 300 { |
278 try | 301 try |
279 { | 302 { |
325 static const char* const TILE_HEIGHT = "TileHeight"; | 348 static const char* const TILE_HEIGHT = "TileHeight"; |
326 static const char* const TOTAL_WIDTH = "TotalWidth"; | 349 static const char* const TOTAL_WIDTH = "TotalWidth"; |
327 static const char* const TOTAL_HEIGHT = "TotalHeight"; | 350 static const char* const TOTAL_HEIGHT = "TotalHeight"; |
328 static const char* const PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; | 351 static const char* const PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; |
329 static const char* const IMAGE_TYPE = "ImageType"; | 352 static const char* const IMAGE_TYPE = "ImageType"; |
353 static const char* const BACKGROUND_COLOR = "BackgroundColor"; | |
330 | 354 |
331 | 355 |
332 void DicomPyramidInstance::Serialize(std::string& result) const | 356 void DicomPyramidInstance::Serialize(std::string& result) const |
333 { | 357 { |
334 Json::Value frames = Json::arrayValue; | 358 Json::Value frames = Json::arrayValue; |
353 content[TOTAL_WIDTH] = totalWidth_; | 377 content[TOTAL_WIDTH] = totalWidth_; |
354 content[TOTAL_HEIGHT] = totalHeight_; | 378 content[TOTAL_HEIGHT] = totalHeight_; |
355 content[PHOTOMETRIC_INTERPRETATION] = Orthanc::EnumerationToString(photometric_); | 379 content[PHOTOMETRIC_INTERPRETATION] = Orthanc::EnumerationToString(photometric_); |
356 content[IMAGE_TYPE] = imageType_; | 380 content[IMAGE_TYPE] = imageType_; |
357 | 381 |
382 if (hasBackgroundColor_) | |
383 { | |
384 Json::Value color = Json::arrayValue; | |
385 color.append(backgroundRed_); | |
386 color.append(backgroundGreen_); | |
387 color.append(backgroundBlue_); | |
388 content[BACKGROUND_COLOR] = color; | |
389 } | |
390 | |
358 #if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 9, 0) | 391 #if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 9, 0) |
359 Orthanc::Toolbox::WriteFastJson(result, content); | 392 Orthanc::Toolbox::WriteFastJson(result, content); |
360 #else | 393 #else |
361 Json::FastWriter writer; | 394 Json::FastWriter writer; |
362 result = writer.write(content); | 395 result = writer.write(content); |
405 } | 438 } |
406 | 439 |
407 frames_[i].first = f[i][0].asInt(); | 440 frames_[i].first = f[i][0].asInt(); |
408 frames_[i].second = f[i][1].asInt(); | 441 frames_[i].second = f[i][1].asInt(); |
409 } | 442 } |
443 | |
444 hasBackgroundColor_ = false; | |
445 if (content.isMember(BACKGROUND_COLOR)) | |
446 { | |
447 const Json::Value& color = content[BACKGROUND_COLOR]; | |
448 if (color.type() == Json::arrayValue && | |
449 color.size() == 3u && | |
450 color[0].isUInt() && | |
451 color[1].isUInt() && | |
452 color[2].isUInt()) | |
453 { | |
454 hasBackgroundColor_ = true; | |
455 backgroundRed_ = color[0].asUInt(); | |
456 backgroundGreen_ = color[1].asUInt(); | |
457 backgroundBlue_ = color[2].asUInt(); | |
458 } | |
459 } | |
460 } | |
461 | |
462 | |
463 uint8_t DicomPyramidInstance::GetBackgroundRed() const | |
464 { | |
465 if (hasBackgroundColor_) | |
466 { | |
467 return backgroundRed_; | |
468 } | |
469 else | |
470 { | |
471 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
472 } | |
473 } | |
474 | |
475 | |
476 uint8_t DicomPyramidInstance::GetBackgroundGreen() const | |
477 { | |
478 if (hasBackgroundColor_) | |
479 { | |
480 return backgroundGreen_; | |
481 } | |
482 else | |
483 { | |
484 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
485 } | |
486 } | |
487 | |
488 | |
489 uint8_t DicomPyramidInstance::GetBackgroundBlue() const | |
490 { | |
491 if (hasBackgroundColor_) | |
492 { | |
493 return backgroundBlue_; | |
494 } | |
495 else | |
496 { | |
497 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
498 } | |
410 } | 499 } |
411 } | 500 } |