comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:4a7a53257c7d
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Affero General Public License
8 * as published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20
21 #include "Enumerations.h"
22
23 #include "Jpeg2000Reader.h"
24 #include "Orthanc/Core/OrthancException.h"
25 #include "Orthanc/Core/Toolbox.h"
26
27 #include <string.h>
28 #include <boost/algorithm/string/predicate.hpp>
29
30 #define HEADER(s) (const void*) (s), sizeof(s)-1
31
32 namespace OrthancWSI
33 {
34 const char* EnumerationToString(ImageCompression compression)
35 {
36 switch (compression)
37 {
38 case ImageCompression_Unknown:
39 return "Unknown";
40
41 case ImageCompression_None:
42 return "Raw image";
43
44 case ImageCompression_Png:
45 return "PNG";
46
47 case ImageCompression_Jpeg:
48 return "JPEG";
49
50 case ImageCompression_Jpeg2000:
51 return "JPEG2000";
52
53 case ImageCompression_Tiff:
54 return "TIFF";
55
56 case ImageCompression_Dicom:
57 return "DICOM";
58
59 default:
60 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
61 }
62 }
63
64
65 static bool MatchHeader(const void* actual,
66 size_t actualSize,
67 const void* expected,
68 size_t expectedSize)
69 {
70 if (actualSize < expectedSize)
71 {
72 return false;
73 }
74 else
75 {
76 return memcmp(actual, expected, expectedSize) == 0;
77 }
78 }
79
80
81 ImageCompression DetectFormatFromFile(const std::string& path)
82 {
83 std::string header;
84 Orthanc::Toolbox::ReadHeader(header, path, 256);
85
86 ImageCompression tmp = DetectFormatFromMemory(header.c_str(), header.size());
87 if (tmp != ImageCompression_Unknown)
88 {
89 return tmp;
90 }
91
92 // Cannot detect the format using the header, fallback to the use
93 // of the filename extension
94
95 std::string lower;
96 Orthanc::Toolbox::ToLowerCase(lower, path);
97
98 if (boost::algorithm::ends_with(lower, ".jpeg") ||
99 boost::algorithm::ends_with(lower, ".jpg"))
100 {
101 return ImageCompression_Jpeg;
102 }
103
104 if (boost::algorithm::ends_with(lower, ".png"))
105 {
106 return ImageCompression_Png;
107 }
108
109 if (boost::algorithm::ends_with(lower, ".tiff") ||
110 boost::algorithm::ends_with(lower, ".tif"))
111 {
112 return ImageCompression_Tiff;
113 }
114
115 if (boost::algorithm::ends_with(lower, ".jp2") ||
116 boost::algorithm::ends_with(lower, ".j2k"))
117 {
118 return ImageCompression_Jpeg2000;
119 }
120
121 if (boost::algorithm::ends_with(lower, ".dcm"))
122 {
123 return ImageCompression_Dicom;
124 }
125
126 return ImageCompression_Unknown;
127 }
128
129
130 ImageCompression DetectFormatFromMemory(const void* buffer,
131 size_t size)
132 {
133 if (MatchHeader(buffer, size, HEADER("\377\330\377")))
134 {
135 return ImageCompression_Jpeg;
136 }
137
138 if (MatchHeader(buffer, size, HEADER("\xff\x4f\xff\x51")) ||
139 MatchHeader(buffer, size, HEADER("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a")))
140 {
141 return ImageCompression_Jpeg2000;
142 }
143
144 if (MatchHeader(buffer, size, HEADER("\211PNG\r\n\032\n")))
145 {
146 return ImageCompression_Png;
147 }
148
149 if (MatchHeader(buffer, size, HEADER("\115\115\000\052")) ||
150 MatchHeader(buffer, size, HEADER("\111\111\052\000")) ||
151 MatchHeader(buffer, size, HEADER("\115\115\000\053\000\010\000\000")) ||
152 MatchHeader(buffer, size, HEADER("\111\111\053\000\010\000\000\000")))
153 {
154 return ImageCompression_Tiff;
155 }
156
157 if (size >= 128 + 4 &&
158 MatchHeader(reinterpret_cast<const uint8_t*>(buffer) + 128, size - 128, HEADER("DICM")))
159 {
160 bool ok = true;
161 for (size_t i = 0; ok && i < 128; i++)
162 {
163 if (reinterpret_cast<const uint8_t*>(buffer)[i] != 0)
164 {
165 ok = false;
166 }
167 }
168
169 if (ok)
170 {
171 return ImageCompression_Dicom;
172 }
173 }
174
175 Jpeg2000Format jpeg2000 = Jpeg2000Reader::DetectFormatFromMemory(buffer, size);
176 if (jpeg2000 == Jpeg2000Format_JP2 ||
177 jpeg2000 == Jpeg2000Format_J2K)
178 {
179 return ImageCompression_Jpeg2000;
180 }
181
182 return ImageCompression_Unknown;
183 }
184 }