# HG changeset patch # User Sebastien Jodogne # Date 1562915214 -7200 # Node ID f0dac1e8f736c86e26345557ab62529c85aea52f # Parent 8c279c5b28a3ee2057a051c0117a336136a276f2 access to photometric interpretation of source pyramids diff -r 8c279c5b28a3 -r f0dac1e8f736 Applications/Dicomizer.cpp --- a/Applications/Dicomizer.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Applications/Dicomizer.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -132,7 +132,7 @@ if (lowerLevelsCount != levelsCount) { LOG(WARNING) << "Constructing the " << lowerLevelsCount << " lower levels of the pyramid"; - OrthancWSI::TruncatedPyramidWriter truncated(target, lowerLevelsCount); + OrthancWSI::TruncatedPyramidWriter truncated(target, lowerLevelsCount, source.GetPhotometricInterpretation()); OrthancWSI::ReconstructPyramidCommand::PrepareBagOfTasks (tasks, truncated, source, lowerLevelsCount + 1, 0, parameters); OrthancWSI::ApplicationToolbox::Execute(tasks, parameters.GetThreadsCount()); diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/DecodedTiledPyramid.h --- a/Framework/Inputs/DecodedTiledPyramid.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/DecodedTiledPyramid.h Fri Jul 12 09:06:54 2019 +0200 @@ -68,5 +68,10 @@ { return false; // No access to the raw tiles } + + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const + { + return Orthanc::PhotometricInterpretation_RGB; + } }; } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/DicomPyramid.cpp --- a/Framework/Inputs/DicomPyramid.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/DicomPyramid.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -235,4 +235,11 @@ assert(!instances_.empty() && instances_[0] != NULL); return instances_[0]->GetPixelFormat(); } + + + Orthanc::PhotometricInterpretation DicomPyramid::GetPhotometricInterpretation() const + { + assert(!instances_.empty() && instances_[0] != NULL); + return instances_[0]->GetPhotometricInterpretation(); + } } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/DicomPyramid.h --- a/Framework/Inputs/DicomPyramid.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/DicomPyramid.h Fri Jul 12 09:06:54 2019 +0200 @@ -81,5 +81,7 @@ unsigned int tileY); virtual Orthanc::PixelFormat GetPixelFormat() const; + + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const; }; } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/DicomPyramidInstance.cpp --- a/Framework/Inputs/DicomPyramidInstance.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/DicomPyramidInstance.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -69,17 +69,21 @@ } - static Orthanc::PixelFormat DetectPixelFormat(OrthancPlugins::DicomDatasetReader& reader) + static void DetectPixelFormat(Orthanc::PixelFormat& format, + Orthanc::PhotometricInterpretation& photometric, + OrthancPlugins::DicomDatasetReader& reader) { using namespace OrthancPlugins; - std::string photometric = Orthanc::Toolbox::StripSpaces + std::string p = Orthanc::Toolbox::StripSpaces (reader.GetMandatoryStringValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION)); + + photometric = Orthanc::StringToPhotometricInterpretation(p.c_str()); - if (photometric == "PALETTE") + if (photometric == Orthanc::PhotometricInterpretation_Palette) { - LOG(ERROR) << "Unsupported photometric interpretation: " << photometric; - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, + "Unsupported photometric interpretation: " + p); } unsigned int bitsStored, samplesPerPixel, tmp; @@ -97,18 +101,17 @@ samplesPerPixel == 1 && !isSigned) { - return Orthanc::PixelFormat_Grayscale8; + format = Orthanc::PixelFormat_Grayscale8; } else if (bitsStored == 8 && samplesPerPixel == 3 && !isSigned) { - return Orthanc::PixelFormat_RGB24; + format = Orthanc::PixelFormat_RGB24; } else { - LOG(ERROR) << "Unsupported pixel format"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "Unsupported pixel format"); } } @@ -149,7 +152,7 @@ } hasCompression_ = false; - format_ = DetectPixelFormat(reader); + DetectPixelFormat(format_, photometric_, reader); unsigned int tmp; if (!reader.GetUnsignedIntegerValue(tileWidth_, DICOM_TAG_COLUMNS) || diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/DicomPyramidInstance.h --- a/Framework/Inputs/DicomPyramidInstance.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/DicomPyramidInstance.h Fri Jul 12 09:06:54 2019 +0200 @@ -43,6 +43,7 @@ unsigned int totalWidth_; unsigned int totalHeight_; std::vector frames_; + Orthanc::PhotometricInterpretation photometric_; void Load(OrthancPlugins::IOrthancConnection& orthanc, const std::string& instanceId); @@ -66,6 +67,11 @@ return format_; } + Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const + { + return photometric_; + } + unsigned int GetTotalWidth() const { return totalWidth_; diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/HierarchicalTiff.cpp --- a/Framework/Inputs/HierarchicalTiff.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/HierarchicalTiff.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -123,14 +123,15 @@ bool HierarchicalTiff::GetCurrentPixelFormat(Orthanc::PixelFormat& pixelFormat, + Orthanc::PhotometricInterpretation& photometric, ImageCompression compression) { // http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html - uint16_t channels, photometric, bpp, planar; + uint16_t channels, photometricTiff, bpp, planar; if (!TIFFGetField(tiff_, TIFFTAG_SAMPLESPERPIXEL, &channels) || channels == 0 || - !TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric) || + !TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometricTiff) || !TIFFGetField(tiff_, TIFFTAG_BITSPERSAMPLE, &bpp) || !TIFFGetField(tiff_, TIFFTAG_PLANARCONFIG, &planar)) { @@ -140,10 +141,24 @@ if (compression == ImageCompression_Jpeg && channels == 3 && // This is a color image bpp == 8 && - photometric == PHOTOMETRIC_YCBCR && planar == PLANARCONFIG_CONTIG) // This is interleaved RGB { pixelFormat = Orthanc::PixelFormat_RGB24; + + switch (photometricTiff) + { + case PHOTOMETRIC_YCBCR: + photometric = Orthanc::PhotometricInterpretation_YBRFull422; + return true; + + case PHOTOMETRIC_RGB: + photometric = Orthanc::PhotometricInterpretation_RGB; + return true; + + default: + LOG(ERROR) << "Unknown photometric interpretation in TIFF: " << photometricTiff; + return false; + } } else { @@ -164,6 +179,7 @@ uint32_t w, h, tw, th; ImageCompression compression; Orthanc::PixelFormat pixelFormat; + Orthanc::PhotometricInterpretation photometric; if (TIFFSetDirectory(tiff_, pos) && TIFFGetField(tiff_, TIFFTAG_IMAGEWIDTH, &w) && @@ -175,7 +191,7 @@ tw > 0 && th > 0 && GetCurrentCompression(compression) && - GetCurrentPixelFormat(pixelFormat, compression)) + GetCurrentPixelFormat(pixelFormat, photometric, compression)) { if (first) { @@ -183,12 +199,14 @@ tileHeight_ = th; compression_ = compression; pixelFormat_ = pixelFormat; + photometric_ = photometric; first = false; } else if (tw != tileWidth_ || th != tileHeight_ || compression_ != compression || - pixelFormat_ != pixelFormat) + pixelFormat_ != pixelFormat || + photometric_ != photometric) { LOG(ERROR) << "The tile size or compression of the TIFF file varies along levels, this is not supported"; return false; diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/HierarchicalTiff.h --- a/Framework/Inputs/HierarchicalTiff.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/HierarchicalTiff.h Fri Jul 12 09:06:54 2019 +0200 @@ -55,6 +55,7 @@ unsigned int tileWidth_; unsigned int tileHeight_; std::vector levels_; + Orthanc::PhotometricInterpretation photometric_; void Finalize(); @@ -63,6 +64,7 @@ bool GetCurrentCompression(ImageCompression& compression); bool GetCurrentPixelFormat(Orthanc::PixelFormat& pixelFormat, + Orthanc::PhotometricInterpretation& photometric, ImageCompression compression); bool Initialize(); @@ -105,6 +107,11 @@ return pixelFormat_; } + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const + { + return photometric_; + } + ImageCompression GetImageCompression() { return compression_; diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/ITiledPyramid.h --- a/Framework/Inputs/ITiledPyramid.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/ITiledPyramid.h Fri Jul 12 09:06:54 2019 +0200 @@ -63,5 +63,7 @@ unsigned int tileY) = 0; virtual Orthanc::PixelFormat GetPixelFormat() const = 0; + + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const = 0; }; } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Inputs/TiledPyramidStatistics.h --- a/Framework/Inputs/TiledPyramidStatistics.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Inputs/TiledPyramidStatistics.h Fri Jul 12 09:06:54 2019 +0200 @@ -79,5 +79,10 @@ virtual Orthanc::ImageAccessor* DecodeTile(unsigned int level, unsigned int tileX, unsigned int tileY); + + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const + { + return source_.GetPhotometricInterpretation(); + } }; } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Outputs/InMemoryTiledImage.cpp --- a/Framework/Outputs/InMemoryTiledImage.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Outputs/InMemoryTiledImage.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -41,12 +41,14 @@ unsigned int countTilesX, unsigned int countTilesY, unsigned int tileWidth, - unsigned int tileHeight) : + unsigned int tileHeight, + Orthanc::PhotometricInterpretation photometric) : format_(format), countTilesX_(countTilesX), countTilesY_(countTilesY), tileWidth_(tileWidth), - tileHeight_(tileHeight) + tileHeight_(tileHeight), + photometric_(photometric) { } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Outputs/InMemoryTiledImage.h --- a/Framework/Outputs/InMemoryTiledImage.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Outputs/InMemoryTiledImage.h Fri Jul 12 09:06:54 2019 +0200 @@ -44,13 +44,15 @@ unsigned int tileWidth_; unsigned int tileHeight_; Tiles tiles_; + Orthanc::PhotometricInterpretation photometric_; public: InMemoryTiledImage(Orthanc::PixelFormat format, unsigned int countTilesX, unsigned int countTilesY, unsigned int tileWidth, - unsigned int tileHeight); + unsigned int tileHeight, + Orthanc::PhotometricInterpretation photometric); virtual ~InMemoryTiledImage(); @@ -102,5 +104,10 @@ unsigned int level, unsigned int tileX, unsigned int tileY); + + virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const + { + return photometric_; + } }; } diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Outputs/TruncatedPyramidWriter.cpp --- a/Framework/Outputs/TruncatedPyramidWriter.cpp Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Outputs/TruncatedPyramidWriter.cpp Fri Jul 12 09:06:54 2019 +0200 @@ -27,13 +27,15 @@ namespace OrthancWSI { TruncatedPyramidWriter::TruncatedPyramidWriter(IPyramidWriter& lower, - unsigned int upperLevelIndex) : + unsigned int upperLevelIndex, + Orthanc::PhotometricInterpretation photometric) : lowerLevels_(lower), upperLevel_(lower.GetPixelFormat(), lower.GetCountTilesX(upperLevelIndex), lower.GetCountTilesY(upperLevelIndex), lower.GetTileWidth(), - lower.GetTileHeight()), + lower.GetTileHeight(), + photometric), upperLevelIndex_(upperLevelIndex) { if (upperLevelIndex > lower.GetLevelCount()) diff -r 8c279c5b28a3 -r f0dac1e8f736 Framework/Outputs/TruncatedPyramidWriter.h --- a/Framework/Outputs/TruncatedPyramidWriter.h Fri Feb 22 14:28:40 2019 +0100 +++ b/Framework/Outputs/TruncatedPyramidWriter.h Fri Jul 12 09:06:54 2019 +0200 @@ -34,7 +34,8 @@ public: TruncatedPyramidWriter(IPyramidWriter& lower, - unsigned int upperLevelIndex); + unsigned int upperLevelIndex, + Orthanc::PhotometricInterpretation photometric); virtual unsigned int GetLevelCount() const {