Mercurial > hg > orthanc-wsi
diff Framework/Enumerations.cpp @ 0:4a7a53257c7d
initial commit
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 22 Oct 2016 21:48:33 +0200 |
parents | |
children | 7a88c614be04 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Enumerations.cpp Sat Oct 22 21:48:33 2016 +0200 @@ -0,0 +1,184 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, 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 "Enumerations.h" + +#include "Jpeg2000Reader.h" +#include "Orthanc/Core/OrthancException.h" +#include "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::Toolbox::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; + } +}