Mercurial > hg > orthanc-wsi
changeset 166:f0dac1e8f736
access to photometric interpretation of source pyramids
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 12 Jul 2019 09:06:54 +0200 |
parents | 8c279c5b28a3 |
children | 605247fc8758 |
files | Applications/Dicomizer.cpp Framework/Inputs/DecodedTiledPyramid.h Framework/Inputs/DicomPyramid.cpp Framework/Inputs/DicomPyramid.h Framework/Inputs/DicomPyramidInstance.cpp Framework/Inputs/DicomPyramidInstance.h Framework/Inputs/HierarchicalTiff.cpp Framework/Inputs/HierarchicalTiff.h Framework/Inputs/ITiledPyramid.h Framework/Inputs/TiledPyramidStatistics.h Framework/Outputs/InMemoryTiledImage.cpp Framework/Outputs/InMemoryTiledImage.h Framework/Outputs/TruncatedPyramidWriter.cpp Framework/Outputs/TruncatedPyramidWriter.h |
diffstat | 14 files changed, 89 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- 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());
--- 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; + } }; }
--- 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(); + } }
--- 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; }; }
--- 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) ||
--- 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<FrameLocation> 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_;
--- 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;
--- 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<Level> 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_;
--- 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; }; }
--- 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(); + } }; }
--- 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) { }
--- 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_; + } }; }
--- 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())
--- 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 {