Mercurial > hg > orthanc-wsi
view Framework/Enumerations.cpp @ 100:16b8e1cc9bbf
Fix issue #30: Bad colorspace if using OpenSlide
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 20 Jan 2017 13:15:05 +0100 |
parents | ff0ef01c332c |
children | a51dee6a1515 |
line wrap: on
line source
/** * Orthanc - A Lightweight, RESTful DICOM Store * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017 Osimis, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "PrecompiledHeadersWSI.h" #include "Enumerations.h" #include "Jpeg2000Reader.h" #include "../Resources/Orthanc/Core/OrthancException.h" #include "../Resources/Orthanc/Core/SystemToolbox.h" #include "../Resources/Orthanc/Core/Toolbox.h" #include <string.h> #include <boost/algorithm/string/predicate.hpp> #define HEADER(s) (const void*) (s), sizeof(s)-1 namespace OrthancWSI { const char* EnumerationToString(ImageCompression compression) { switch (compression) { case ImageCompression_Unknown: return "Unknown"; case ImageCompression_None: return "Raw image"; case ImageCompression_Png: return "PNG"; case ImageCompression_Jpeg: return "JPEG"; case ImageCompression_Jpeg2000: return "JPEG2000"; case ImageCompression_Tiff: return "TIFF"; case ImageCompression_Dicom: return "DICOM"; default: throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } } static bool MatchHeader(const void* actual, size_t actualSize, const void* expected, size_t expectedSize) { if (actualSize < expectedSize) { return false; } else { return memcmp(actual, expected, expectedSize) == 0; } } ImageCompression DetectFormatFromFile(const std::string& path) { std::string header; Orthanc::SystemToolbox::ReadHeader(header, path, 256); ImageCompression tmp = DetectFormatFromMemory(header.c_str(), header.size()); if (tmp != ImageCompression_Unknown) { return tmp; } // Cannot detect the format using the header, fallback to the use // of the filename extension std::string lower; Orthanc::Toolbox::ToLowerCase(lower, path); if (boost::algorithm::ends_with(lower, ".jpeg") || boost::algorithm::ends_with(lower, ".jpg")) { return ImageCompression_Jpeg; } if (boost::algorithm::ends_with(lower, ".png")) { return ImageCompression_Png; } if (boost::algorithm::ends_with(lower, ".tiff") || boost::algorithm::ends_with(lower, ".tif")) { return ImageCompression_Tiff; } if (boost::algorithm::ends_with(lower, ".jp2") || boost::algorithm::ends_with(lower, ".j2k")) { return ImageCompression_Jpeg2000; } if (boost::algorithm::ends_with(lower, ".dcm")) { return ImageCompression_Dicom; } return ImageCompression_Unknown; } ImageCompression DetectFormatFromMemory(const void* buffer, size_t size) { if (MatchHeader(buffer, size, HEADER("\377\330\377"))) { return ImageCompression_Jpeg; } if (MatchHeader(buffer, size, HEADER("\xff\x4f\xff\x51")) || MatchHeader(buffer, size, HEADER("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"))) { return ImageCompression_Jpeg2000; } if (MatchHeader(buffer, size, HEADER("\211PNG\r\n\032\n"))) { return ImageCompression_Png; } if (MatchHeader(buffer, size, HEADER("\115\115\000\052")) || MatchHeader(buffer, size, HEADER("\111\111\052\000")) || MatchHeader(buffer, size, HEADER("\115\115\000\053\000\010\000\000")) || MatchHeader(buffer, size, HEADER("\111\111\053\000\010\000\000\000"))) { return ImageCompression_Tiff; } if (size >= 128 + 4 && MatchHeader(reinterpret_cast<const uint8_t*>(buffer) + 128, size - 128, HEADER("DICM"))) { bool ok = true; for (size_t i = 0; ok && i < 128; i++) { if (reinterpret_cast<const uint8_t*>(buffer)[i] != 0) { ok = false; } } if (ok) { return ImageCompression_Dicom; } } Jpeg2000Format jpeg2000 = Jpeg2000Reader::DetectFormatFromMemory(buffer, size); if (jpeg2000 == Jpeg2000Format_JP2 || jpeg2000 == Jpeg2000Format_J2K) { return ImageCompression_Jpeg2000; } return ImageCompression_Unknown; } }