Mercurial > hg > orthanc
annotate OrthancServer/ParsedDicomFile.cpp @ 1641:4e56b5a206b7
Support of binary tags encoded using data URI scheme
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Sep 2015 12:43:05 +0200 |
parents | 644c32c07306 |
children | e40fd0d925c5 |
rev | line source |
---|---|
790 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
1288
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1160
diff
changeset
|
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics |
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1160
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
790 | 5 * |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * In addition, as a special exception, the copyright holders of this | |
12 * program give permission to link the code of its release with the | |
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
14 * that use the same license as the "OpenSSL" library), and distribute | |
15 * the linked executables. You must obey the GNU General Public License | |
16 * in all respects for all of the code used other than "OpenSSL". If you | |
17 * modify file(s) with this exception, you may extend this exception to | |
18 * your version of the file(s), but you are not obligated to do so. If | |
19 * you do not wish to do so, delete this exception statement from your | |
20 * version. If you delete this exception statement from all source files | |
21 * in the program, then also delete it here. | |
22 * | |
23 * This program is distributed in the hope that it will be useful, but | |
24 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
26 * General Public License for more details. | |
27 * | |
28 * You should have received a copy of the GNU General Public License | |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30 **/ | |
31 | |
32 | |
33 | |
34 /*========================================================================= | |
35 | |
36 This file is based on portions of the following project: | |
37 | |
38 Program: GDCM (Grassroots DICOM). A DICOM library | |
39 Module: http://gdcm.sourceforge.net/Copyright.html | |
40 | |
41 Copyright (c) 2006-2011 Mathieu Malaterre | |
42 Copyright (c) 1993-2005 CREATIS | |
43 (CREATIS = Centre de Recherche et d'Applications en Traitement de l'Image) | |
44 All rights reserved. | |
45 | |
46 Redistribution and use in source and binary forms, with or without | |
47 modification, are permitted provided that the following conditions are met: | |
48 | |
49 * Redistributions of source code must retain the above copyright notice, | |
50 this list of conditions and the following disclaimer. | |
51 | |
52 * Redistributions in binary form must reproduce the above copyright notice, | |
53 this list of conditions and the following disclaimer in the documentation | |
54 and/or other materials provided with the distribution. | |
55 | |
56 * Neither name of Mathieu Malaterre, or CREATIS, nor the names of any | |
57 contributors (CNRS, INSERM, UCB, Universite Lyon I), may be used to | |
58 endorse or promote products derived from this software without specific | |
59 prior written permission. | |
60 | |
61 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' | |
62 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
63 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
64 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR | |
65 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
66 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
67 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
68 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
69 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
70 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
71 | |
72 =========================================================================*/ | |
73 | |
74 | |
831
84513f2ee1f3
pch for unit tests and server
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
824
diff
changeset
|
75 #include "PrecompiledHeadersServer.h" |
824
a811bdf8b8eb
precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
817
diff
changeset
|
76 |
790 | 77 #ifndef NOMINMAX |
78 #define NOMINMAX | |
79 #endif | |
80 | |
81 #include "ParsedDicomFile.h" | |
82 | |
1160
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
83 #include "ServerToolbox.h" |
790 | 84 #include "FromDcmtkBridge.h" |
85 #include "ToDcmtkBridge.h" | |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
86 #include "Internals/DicomImageDecoder.h" |
1486
f967bdf8534e
refactoring to Logging.h
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1347
diff
changeset
|
87 #include "../Core/Logging.h" |
790 | 88 #include "../Core/Toolbox.h" |
89 #include "../Core/OrthancException.h" | |
1612
96582230ddcb
Core/ImageFormats folder renamed as Core/Images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1566
diff
changeset
|
90 #include "../Core/Images/ImageBuffer.h" |
96582230ddcb
Core/ImageFormats folder renamed as Core/Images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1566
diff
changeset
|
91 #include "../Core/Images/PngWriter.h" |
790 | 92 #include "../Core/Uuid.h" |
93 #include "../Core/DicomFormat/DicomString.h" | |
94 #include "../Core/DicomFormat/DicomNullValue.h" | |
95 #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" | |
1612
96582230ddcb
Core/ImageFormats folder renamed as Core/Images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1566
diff
changeset
|
96 #include "../Core/Images/PngReader.h" |
790 | 97 |
98 #include <list> | |
99 #include <limits> | |
100 | |
101 #include <boost/lexical_cast.hpp> | |
102 | |
103 #include <dcmtk/dcmdata/dcchrstr.h> | |
104 #include <dcmtk/dcmdata/dcdicent.h> | |
105 #include <dcmtk/dcmdata/dcdict.h> | |
106 #include <dcmtk/dcmdata/dcfilefo.h> | |
107 #include <dcmtk/dcmdata/dcistrmb.h> | |
108 #include <dcmtk/dcmdata/dcuid.h> | |
109 #include <dcmtk/dcmdata/dcmetinf.h> | |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
110 #include <dcmtk/dcmdata/dcdeftag.h> |
790 | 111 |
112 #include <dcmtk/dcmdata/dcvrae.h> | |
113 #include <dcmtk/dcmdata/dcvras.h> | |
114 #include <dcmtk/dcmdata/dcvrcs.h> | |
115 #include <dcmtk/dcmdata/dcvrda.h> | |
116 #include <dcmtk/dcmdata/dcvrds.h> | |
117 #include <dcmtk/dcmdata/dcvrdt.h> | |
118 #include <dcmtk/dcmdata/dcvrfd.h> | |
119 #include <dcmtk/dcmdata/dcvrfl.h> | |
120 #include <dcmtk/dcmdata/dcvris.h> | |
121 #include <dcmtk/dcmdata/dcvrlo.h> | |
122 #include <dcmtk/dcmdata/dcvrlt.h> | |
123 #include <dcmtk/dcmdata/dcvrpn.h> | |
124 #include <dcmtk/dcmdata/dcvrsh.h> | |
125 #include <dcmtk/dcmdata/dcvrsl.h> | |
126 #include <dcmtk/dcmdata/dcvrss.h> | |
127 #include <dcmtk/dcmdata/dcvrst.h> | |
128 #include <dcmtk/dcmdata/dcvrtm.h> | |
129 #include <dcmtk/dcmdata/dcvrui.h> | |
130 #include <dcmtk/dcmdata/dcvrul.h> | |
131 #include <dcmtk/dcmdata/dcvrus.h> | |
132 #include <dcmtk/dcmdata/dcvrut.h> | |
133 #include <dcmtk/dcmdata/dcpixel.h> | |
134 #include <dcmtk/dcmdata/dcpixseq.h> | |
135 #include <dcmtk/dcmdata/dcpxitem.h> | |
136 | |
137 | |
138 #include <boost/math/special_functions/round.hpp> | |
139 #include <dcmtk/dcmdata/dcostrmb.h> | |
140 | |
141 | |
142 static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream"; | |
143 | |
144 | |
145 | |
146 namespace Orthanc | |
147 { | |
794 | 148 struct ParsedDicomFile::PImpl |
149 { | |
150 std::auto_ptr<DcmFileFormat> file_; | |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
151 Encoding encoding_; |
794 | 152 }; |
153 | |
154 | |
155 // This method can only be called from the constructors! | |
790 | 156 void ParsedDicomFile::Setup(const char* buffer, size_t size) |
157 { | |
158 DcmInputBufferStream is; | |
159 if (size > 0) | |
160 { | |
161 is.setBuffer(buffer, size); | |
162 } | |
163 is.setEos(); | |
164 | |
794 | 165 pimpl_->file_.reset(new DcmFileFormat); |
166 pimpl_->file_->transferInit(); | |
167 if (!pimpl_->file_->read(is).good()) | |
790 | 168 { |
794 | 169 delete pimpl_; // Avoid a memory leak due to exception |
170 // throwing, as we are in the constructor | |
171 | |
790 | 172 throw OrthancException(ErrorCode_BadFileFormat); |
173 } | |
794 | 174 pimpl_->file_->loadAllDataIntoMemory(); |
175 pimpl_->file_->transferEnd(); | |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
176 |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
177 pimpl_->encoding_ = FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset()); |
790 | 178 } |
179 | |
180 | |
181 static void SendPathValueForDictionary(RestApiOutput& output, | |
182 DcmItem& dicom) | |
183 { | |
184 Json::Value v = Json::arrayValue; | |
185 | |
186 for (unsigned long i = 0; i < dicom.card(); i++) | |
187 { | |
188 DcmElement* element = dicom.getElement(i); | |
189 if (element) | |
190 { | |
191 char buf[16]; | |
192 sprintf(buf, "%04x-%04x", element->getTag().getGTag(), element->getTag().getETag()); | |
193 v.append(buf); | |
194 } | |
195 } | |
196 | |
197 output.AnswerJson(v); | |
198 } | |
199 | |
200 static inline uint16_t GetCharValue(char c) | |
201 { | |
202 if (c >= '0' && c <= '9') | |
203 return c - '0'; | |
204 else if (c >= 'a' && c <= 'f') | |
205 return c - 'a' + 10; | |
206 else if (c >= 'A' && c <= 'F') | |
207 return c - 'A' + 10; | |
208 else | |
209 return 0; | |
210 } | |
211 | |
212 static inline uint16_t GetTagValue(const char* c) | |
213 { | |
214 return ((GetCharValue(c[0]) << 12) + | |
215 (GetCharValue(c[1]) << 8) + | |
216 (GetCharValue(c[2]) << 4) + | |
217 GetCharValue(c[3])); | |
218 } | |
219 | |
220 static void ParseTagAndGroup(DcmTagKey& key, | |
221 const std::string& tag) | |
222 { | |
223 DicomTag t = FromDcmtkBridge::ParseTag(tag); | |
224 key = DcmTagKey(t.GetGroup(), t.GetElement()); | |
225 } | |
226 | |
227 | |
228 static void SendSequence(RestApiOutput& output, | |
229 DcmSequenceOfItems& sequence) | |
230 { | |
231 // This element is a sequence | |
232 Json::Value v = Json::arrayValue; | |
233 | |
234 for (unsigned long i = 0; i < sequence.card(); i++) | |
235 { | |
236 v.append(boost::lexical_cast<std::string>(i)); | |
237 } | |
238 | |
239 output.AnswerJson(v); | |
240 } | |
241 | |
242 | |
243 static unsigned int GetPixelDataBlockCount(DcmPixelData& pixelData, | |
244 E_TransferSyntax transferSyntax) | |
245 { | |
246 DcmPixelSequence* pixelSequence = NULL; | |
247 if (pixelData.getEncapsulatedRepresentation | |
248 (transferSyntax, NULL, pixelSequence).good() && pixelSequence) | |
249 { | |
250 return pixelSequence->card(); | |
251 } | |
252 else | |
253 { | |
254 return 1; | |
255 } | |
256 } | |
257 | |
258 | |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
259 namespace |
790 | 260 { |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
261 class DicomFieldStream : public IHttpStreamAnswer |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
262 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
263 private: |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
264 DcmElement& element_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
265 uint32_t length_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
266 uint32_t offset_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
267 std::string chunk_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
268 size_t chunkSize_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
269 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
270 public: |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
271 DicomFieldStream(DcmElement& element, |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
272 E_TransferSyntax transferSyntax) : |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
273 element_(element), |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
274 length_(element.getLength(transferSyntax)), |
1616 | 275 offset_(0), |
276 chunkSize_(0) | |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
277 { |
1521 | 278 static const size_t CHUNK_SIZE = 64 * 1024; // Use chunks of max 64KB |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
279 chunk_.resize(CHUNK_SIZE); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
280 } |
790 | 281 |
1523
c388502a066d
testing FilesystemHttpSender
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1521
diff
changeset
|
282 virtual HttpCompression SetupHttpCompression(bool /*gzipAllowed*/, |
c388502a066d
testing FilesystemHttpSender
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1521
diff
changeset
|
283 bool /*deflateAllowed*/) |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
284 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
285 // No support for compression |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
286 return HttpCompression_None; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
287 } |
790 | 288 |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
289 virtual bool HasContentFilename(std::string& filename) |
790 | 290 { |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
291 return false; |
790 | 292 } |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
293 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
294 virtual std::string GetContentType() |
790 | 295 { |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
296 return ""; |
790 | 297 } |
298 | |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
299 virtual uint64_t GetContentLength() |
790 | 300 { |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
301 return length_; |
790 | 302 } |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
303 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
304 virtual bool ReadNextChunk() |
790 | 305 { |
1520 | 306 assert(offset_ <= length_); |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
307 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
308 if (offset_ == length_) |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
309 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
310 return false; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
311 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
312 else |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
313 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
314 if (length_ - offset_ < chunk_.size()) |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
315 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
316 chunkSize_ = length_ - offset_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
317 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
318 else |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
319 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
320 chunkSize_ = chunk_.size(); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
321 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
322 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
323 OFCondition cond = element_.getPartialValue(&chunk_[0], offset_, chunkSize_); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
324 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
325 offset_ += chunkSize_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
326 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
327 if (!cond.good()) |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
328 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
329 LOG(ERROR) << "Error while sending a DICOM field: " << cond.text(); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
330 throw OrthancException(ErrorCode_InternalError); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
331 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
332 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
333 return true; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
334 } |
790 | 335 } |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
336 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
337 virtual const char *GetChunkContent() |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
338 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
339 return chunk_.c_str(); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
340 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
341 |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
342 virtual size_t GetChunkSize() |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
343 { |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
344 return chunkSize_; |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
345 } |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
346 }; |
790 | 347 } |
348 | |
349 | |
350 static bool AnswerPixelData(RestApiOutput& output, | |
351 DcmItem& dicom, | |
352 E_TransferSyntax transferSyntax, | |
353 const std::string* blockUri) | |
354 { | |
355 DcmTag k(DICOM_TAG_PIXEL_DATA.GetGroup(), | |
356 DICOM_TAG_PIXEL_DATA.GetElement()); | |
357 | |
358 DcmElement *element = NULL; | |
359 if (!dicom.findAndGetElement(k, element).good() || | |
360 element == NULL) | |
361 { | |
362 return false; | |
363 } | |
364 | |
365 try | |
366 { | |
367 DcmPixelData& pixelData = dynamic_cast<DcmPixelData&>(*element); | |
368 if (blockUri == NULL) | |
369 { | |
370 // The user asks how many blocks are presents in this pixel data | |
371 unsigned int blocks = GetPixelDataBlockCount(pixelData, transferSyntax); | |
372 | |
373 Json::Value result(Json::arrayValue); | |
374 for (unsigned int i = 0; i < blocks; i++) | |
375 { | |
376 result.append(boost::lexical_cast<std::string>(i)); | |
377 } | |
378 | |
379 output.AnswerJson(result); | |
380 return true; | |
381 } | |
382 | |
383 | |
384 unsigned int block = boost::lexical_cast<unsigned int>(*blockUri); | |
385 | |
386 if (block < GetPixelDataBlockCount(pixelData, transferSyntax)) | |
387 { | |
388 DcmPixelSequence* pixelSequence = NULL; | |
389 if (pixelData.getEncapsulatedRepresentation | |
390 (transferSyntax, NULL, pixelSequence).good() && pixelSequence) | |
391 { | |
392 // This is the case for JPEG transfer syntaxes | |
393 if (block < pixelSequence->card()) | |
394 { | |
395 DcmPixelItem* pixelItem = NULL; | |
396 if (pixelSequence->getItem(pixelItem, block).good() && pixelItem) | |
397 { | |
398 if (pixelItem->getLength() == 0) | |
399 { | |
400 output.AnswerBuffer(NULL, 0, CONTENT_TYPE_OCTET_STREAM); | |
401 return true; | |
402 } | |
403 | |
404 Uint8* buffer = NULL; | |
405 if (pixelItem->getUint8Array(buffer).good() && buffer) | |
406 { | |
407 output.AnswerBuffer(buffer, pixelItem->getLength(), CONTENT_TYPE_OCTET_STREAM); | |
408 return true; | |
409 } | |
410 } | |
411 } | |
412 } | |
413 else | |
414 { | |
415 // This is the case for raw, uncompressed image buffers | |
416 assert(*blockUri == "0"); | |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
417 DicomFieldStream stream(*element, transferSyntax); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
418 output.AnswerStream(stream); |
790 | 419 } |
420 } | |
421 } | |
422 catch (boost::bad_lexical_cast&) | |
423 { | |
424 // The URI entered by the user is not a number | |
425 } | |
426 catch (std::bad_cast&) | |
427 { | |
428 // This should never happen | |
429 } | |
430 | |
431 return false; | |
432 } | |
433 | |
434 | |
435 | |
436 static void SendPathValueForLeaf(RestApiOutput& output, | |
437 const std::string& tag, | |
438 DcmItem& dicom, | |
439 E_TransferSyntax transferSyntax) | |
440 { | |
441 DcmTagKey k; | |
442 ParseTagAndGroup(k, tag); | |
443 | |
444 DcmSequenceOfItems* sequence = NULL; | |
445 if (dicom.findAndGetSequence(k, sequence).good() && | |
446 sequence != NULL && | |
447 sequence->getVR() == EVR_SQ) | |
448 { | |
449 SendSequence(output, *sequence); | |
450 return; | |
451 } | |
452 | |
453 DcmElement* element = NULL; | |
454 if (dicom.findAndGetElement(k, element).good() && | |
455 element != NULL && | |
456 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags | |
457 element->getVR() != EVR_SQ) | |
458 { | |
1519
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
459 DicomFieldStream stream(*element, transferSyntax); |
8bd0d897763f
refactoring: IHttpStreamAnswer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1486
diff
changeset
|
460 output.AnswerStream(stream); |
790 | 461 } |
462 } | |
463 | |
464 void ParsedDicomFile::SendPathValue(RestApiOutput& output, | |
465 const UriComponents& uri) | |
466 { | |
794 | 467 DcmItem* dicom = pimpl_->file_->getDataset(); |
468 E_TransferSyntax transferSyntax = pimpl_->file_->getDataset()->getOriginalXfer(); | |
790 | 469 |
470 // Special case: Accessing the pixel data | |
471 if (uri.size() == 1 || | |
472 uri.size() == 2) | |
473 { | |
474 DcmTagKey tag; | |
475 ParseTagAndGroup(tag, uri[0]); | |
476 | |
477 if (tag.getGroup() == DICOM_TAG_PIXEL_DATA.GetGroup() && | |
478 tag.getElement() == DICOM_TAG_PIXEL_DATA.GetElement()) | |
479 { | |
480 AnswerPixelData(output, *dicom, transferSyntax, uri.size() == 1 ? NULL : &uri[1]); | |
481 return; | |
482 } | |
483 } | |
484 | |
485 // Go down in the tag hierarchy according to the URI | |
486 for (size_t pos = 0; pos < uri.size() / 2; pos++) | |
487 { | |
488 size_t index; | |
489 try | |
490 { | |
491 index = boost::lexical_cast<size_t>(uri[2 * pos + 1]); | |
492 } | |
493 catch (boost::bad_lexical_cast&) | |
494 { | |
495 return; | |
496 } | |
497 | |
498 DcmTagKey k; | |
499 DcmItem *child = NULL; | |
500 ParseTagAndGroup(k, uri[2 * pos]); | |
501 if (!dicom->findAndGetSequenceItem(k, child, index).good() || | |
502 child == NULL) | |
503 { | |
504 return; | |
505 } | |
506 | |
507 dicom = child; | |
508 } | |
509 | |
510 // We have reached the end of the URI | |
511 if (uri.size() % 2 == 0) | |
512 { | |
513 SendPathValueForDictionary(output, *dicom); | |
514 } | |
515 else | |
516 { | |
517 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax); | |
518 } | |
519 } | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 static DcmElement* CreateElementForTag(const DicomTag& tag) | |
526 { | |
527 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
528 | |
529 switch (key.getEVR()) | |
530 { | |
531 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
532 | |
533 /** | |
534 * TODO. | |
535 **/ | |
536 | |
537 case EVR_OB: // other byte | |
538 case EVR_OF: // other float | |
539 case EVR_OW: // other word | |
540 case EVR_AT: // attribute tag | |
541 throw OrthancException(ErrorCode_NotImplemented); | |
542 | |
543 case EVR_UN: // unknown value representation | |
544 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
545 | |
546 | |
547 /** | |
548 * String types. | |
549 * http://support.dcmtk.org/docs/classDcmByteString.html | |
550 **/ | |
551 | |
552 case EVR_AS: // age string | |
553 return new DcmAgeString(key); | |
554 | |
555 case EVR_AE: // application entity title | |
556 return new DcmApplicationEntity(key); | |
557 | |
558 case EVR_CS: // code string | |
559 return new DcmCodeString(key); | |
560 | |
561 case EVR_DA: // date string | |
562 return new DcmDate(key); | |
563 | |
564 case EVR_DT: // date time string | |
565 return new DcmDateTime(key); | |
566 | |
567 case EVR_DS: // decimal string | |
568 return new DcmDecimalString(key); | |
569 | |
570 case EVR_IS: // integer string | |
571 return new DcmIntegerString(key); | |
572 | |
573 case EVR_TM: // time string | |
574 return new DcmTime(key); | |
575 | |
576 case EVR_UI: // unique identifier | |
577 return new DcmUniqueIdentifier(key); | |
578 | |
579 case EVR_ST: // short text | |
580 return new DcmShortText(key); | |
581 | |
582 case EVR_LO: // long string | |
583 return new DcmLongString(key); | |
584 | |
585 case EVR_LT: // long text | |
586 return new DcmLongText(key); | |
587 | |
588 case EVR_UT: // unlimited text | |
589 return new DcmUnlimitedText(key); | |
590 | |
591 case EVR_SH: // short string | |
592 return new DcmShortString(key); | |
593 | |
594 case EVR_PN: // person name | |
595 return new DcmPersonName(key); | |
596 | |
597 | |
598 /** | |
599 * Numerical types | |
600 **/ | |
601 | |
602 case EVR_SL: // signed long | |
603 return new DcmSignedLong(key); | |
604 | |
605 case EVR_SS: // signed short | |
606 return new DcmSignedShort(key); | |
607 | |
608 case EVR_UL: // unsigned long | |
609 return new DcmUnsignedLong(key); | |
610 | |
611 case EVR_US: // unsigned short | |
612 return new DcmUnsignedShort(key); | |
613 | |
614 case EVR_FL: // float single-precision | |
615 return new DcmFloatingPointSingle(key); | |
616 | |
617 case EVR_FD: // float double-precision | |
618 return new DcmFloatingPointDouble(key); | |
619 | |
620 | |
621 /** | |
622 * Sequence types, should never occur at this point. | |
623 **/ | |
624 | |
625 case EVR_SQ: // sequence of items | |
626 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
627 | |
628 | |
629 /** | |
630 * Internal to DCMTK. | |
631 **/ | |
632 | |
633 case EVR_ox: // OB or OW depending on context | |
634 case EVR_xs: // SS or US depending on context | |
635 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
636 case EVR_na: // na="not applicable", for data which has no VR | |
637 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
638 case EVR_item: // used internally for items | |
639 case EVR_metainfo: // used internally for meta info datasets | |
640 case EVR_dataset: // used internally for datasets | |
641 case EVR_fileFormat: // used internally for DICOM files | |
642 case EVR_dicomDir: // used internally for DICOMDIR objects | |
643 case EVR_dirRecord: // used internally for DICOMDIR records | |
644 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
645 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
646 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
647 case EVR_PixelData: // used internally for uncompressed pixeld data | |
648 case EVR_OverlayData: // used internally for overlay data | |
649 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
650 default: | |
651 break; | |
652 } | |
653 | |
654 throw OrthancException(ErrorCode_InternalError); | |
655 } | |
656 | |
657 | |
658 | |
659 static void FillElementWithString(DcmElement& element, | |
660 const DicomTag& tag, | |
661 const std::string& value) | |
662 { | |
663 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
664 bool ok = false; | |
665 | |
666 try | |
667 { | |
668 switch (key.getEVR()) | |
669 { | |
670 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
671 | |
672 /** | |
673 * TODO. | |
674 **/ | |
675 | |
676 case EVR_OB: // other byte | |
677 case EVR_OF: // other float | |
678 case EVR_OW: // other word | |
679 case EVR_AT: // attribute tag | |
680 throw OrthancException(ErrorCode_NotImplemented); | |
681 | |
682 case EVR_UN: // unknown value representation | |
683 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
684 | |
685 | |
686 /** | |
687 * String types. | |
688 **/ | |
689 | |
690 case EVR_DS: // decimal string | |
691 case EVR_IS: // integer string | |
692 case EVR_AS: // age string | |
693 case EVR_DA: // date string | |
694 case EVR_DT: // date time string | |
695 case EVR_TM: // time string | |
696 case EVR_AE: // application entity title | |
697 case EVR_CS: // code string | |
698 case EVR_SH: // short string | |
699 case EVR_LO: // long string | |
700 case EVR_ST: // short text | |
701 case EVR_LT: // long text | |
702 case EVR_UT: // unlimited text | |
703 case EVR_PN: // person name | |
704 case EVR_UI: // unique identifier | |
705 { | |
706 ok = element.putString(value.c_str()).good(); | |
707 break; | |
708 } | |
709 | |
710 | |
711 /** | |
712 * Numerical types | |
713 **/ | |
714 | |
715 case EVR_SL: // signed long | |
716 { | |
717 ok = element.putSint32(boost::lexical_cast<Sint32>(value)).good(); | |
718 break; | |
719 } | |
720 | |
721 case EVR_SS: // signed short | |
722 { | |
723 ok = element.putSint16(boost::lexical_cast<Sint16>(value)).good(); | |
724 break; | |
725 } | |
726 | |
727 case EVR_UL: // unsigned long | |
728 { | |
729 ok = element.putUint32(boost::lexical_cast<Uint32>(value)).good(); | |
730 break; | |
731 } | |
732 | |
733 case EVR_US: // unsigned short | |
734 { | |
735 ok = element.putUint16(boost::lexical_cast<Uint16>(value)).good(); | |
736 break; | |
737 } | |
738 | |
739 case EVR_FL: // float single-precision | |
740 { | |
741 ok = element.putFloat32(boost::lexical_cast<float>(value)).good(); | |
742 break; | |
743 } | |
744 | |
745 case EVR_FD: // float double-precision | |
746 { | |
747 ok = element.putFloat64(boost::lexical_cast<double>(value)).good(); | |
748 break; | |
749 } | |
750 | |
751 | |
752 /** | |
753 * Sequence types, should never occur at this point. | |
754 **/ | |
755 | |
756 case EVR_SQ: // sequence of items | |
757 { | |
758 ok = false; | |
759 break; | |
760 } | |
761 | |
762 | |
763 /** | |
764 * Internal to DCMTK. | |
765 **/ | |
766 | |
767 case EVR_ox: // OB or OW depending on context | |
768 case EVR_xs: // SS or US depending on context | |
769 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
770 case EVR_na: // na="not applicable", for data which has no VR | |
771 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
772 case EVR_item: // used internally for items | |
773 case EVR_metainfo: // used internally for meta info datasets | |
774 case EVR_dataset: // used internally for datasets | |
775 case EVR_fileFormat: // used internally for DICOM files | |
776 case EVR_dicomDir: // used internally for DICOMDIR objects | |
777 case EVR_dirRecord: // used internally for DICOMDIR records | |
778 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
779 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
780 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
781 case EVR_PixelData: // used internally for uncompressed pixeld data | |
782 case EVR_OverlayData: // used internally for overlay data | |
783 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
784 default: | |
785 break; | |
786 } | |
787 } | |
788 catch (boost::bad_lexical_cast&) | |
789 { | |
790 ok = false; | |
791 } | |
792 | |
793 if (!ok) | |
794 { | |
795 throw OrthancException(ErrorCode_InternalError); | |
796 } | |
797 } | |
798 | |
799 | |
800 void ParsedDicomFile::Remove(const DicomTag& tag) | |
801 { | |
802 DcmTagKey key(tag.GetGroup(), tag.GetElement()); | |
794 | 803 DcmElement* element = pimpl_->file_->getDataset()->remove(key); |
790 | 804 if (element != NULL) |
805 { | |
806 delete element; | |
807 } | |
808 } | |
809 | |
810 | |
811 | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
812 void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep) |
790 | 813 { |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
814 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
815 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
816 // Loop over the dataset to detect its private tags |
790 | 817 typedef std::list<DcmElement*> Tags; |
818 Tags privateTags; | |
819 | |
820 for (unsigned long i = 0; i < dataset.card(); i++) | |
821 { | |
822 DcmElement* element = dataset.getElement(i); | |
823 DcmTag tag(element->getTag()); | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
824 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
825 // Is this a private tag? |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
826 if (FromDcmtkBridge::IsPrivateTag(tag)) |
790 | 827 { |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
828 bool remove = true; |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
829 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
830 // Check whether this private tag is to be kept |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
831 if (toKeep != NULL) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
832 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
833 DicomTag tmp = FromDcmtkBridge::Convert(tag); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
834 if (toKeep->find(tmp) != toKeep->end()) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
835 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
836 remove = false; // Keep it |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
837 } |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
838 } |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
839 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
840 if (remove) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
841 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
842 privateTags.push_back(element); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
843 } |
790 | 844 } |
845 } | |
846 | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
847 // Loop over the detected private tags to remove them |
790 | 848 for (Tags::iterator it = privateTags.begin(); |
849 it != privateTags.end(); ++it) | |
850 { | |
851 DcmElement* tmp = dataset.remove(*it); | |
852 if (tmp != NULL) | |
853 { | |
854 delete tmp; | |
855 } | |
856 } | |
857 } | |
858 | |
859 | |
860 | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
861 |
790 | 862 void ParsedDicomFile::Insert(const DicomTag& tag, |
863 const std::string& value) | |
864 { | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
865 OFCondition cond; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
866 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
867 if (FromDcmtkBridge::IsPrivateTag(tag)) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
868 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
869 // This is a private tag |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
870 // http://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_addprivatedata |
790 | 871 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
872 DcmTag key(tag.GetGroup(), tag.GetElement(), EVR_OB); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
873 cond = pimpl_->file_->getDataset()->putAndInsertUint8Array |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
874 (key, (const Uint8*) value.c_str(), value.size(), false); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
875 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
876 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
877 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
878 std::auto_ptr<DcmElement> element(CreateElementForTag(tag)); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
879 FillElementWithString(*element, tag, value); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
880 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
881 cond = pimpl_->file_->getDataset()->insert(element.release(), false, false); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
882 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
883 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
884 if (!cond.good()) |
790 | 885 { |
886 // This field already exists | |
887 throw OrthancException(ErrorCode_InternalError); | |
888 } | |
889 } | |
890 | |
891 | |
892 void ParsedDicomFile::Replace(const DicomTag& tag, | |
893 const std::string& value, | |
894 DicomReplaceMode mode) | |
895 { | |
896 DcmTagKey key(tag.GetGroup(), tag.GetElement()); | |
897 DcmElement* element = NULL; | |
898 | |
794 | 899 if (!pimpl_->file_->getDataset()->findAndGetElement(key, element).good() || |
790 | 900 element == NULL) |
901 { | |
902 // This field does not exist, act wrt. the specified "mode" | |
903 switch (mode) | |
904 { | |
905 case DicomReplaceMode_InsertIfAbsent: | |
906 Insert(tag, value); | |
907 break; | |
908 | |
909 case DicomReplaceMode_ThrowIfAbsent: | |
910 throw OrthancException(ErrorCode_InexistentItem); | |
911 | |
912 case DicomReplaceMode_IgnoreIfAbsent: | |
913 return; | |
914 } | |
915 } | |
916 else | |
917 { | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
918 if (FromDcmtkBridge::IsPrivateTag(tag)) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
919 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
920 if (!element->putUint8Array((const Uint8*) value.c_str(), value.size()).good()) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
921 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
922 throw OrthancException(ErrorCode_InternalError); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
923 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
924 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
925 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
926 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
927 FillElementWithString(*element, tag, value); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
928 } |
790 | 929 } |
930 | |
931 | |
932 /** | |
933 * dcmodify will automatically correct 'Media Storage SOP Class | |
934 * UID' and 'Media Storage SOP Instance UID' in the metaheader, if | |
935 * you make changes to the related tags in the dataset ('SOP Class | |
936 * UID' and 'SOP Instance UID') via insert or modify mode | |
937 * options. You can disable this behaviour by using the -nmu | |
938 * option. | |
939 **/ | |
940 | |
941 if (tag == DICOM_TAG_SOP_CLASS_UID) | |
942 { | |
943 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_CLASS_UID, value, DicomReplaceMode_InsertIfAbsent); | |
944 } | |
945 | |
946 if (tag == DICOM_TAG_SOP_INSTANCE_UID) | |
947 { | |
948 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, value, DicomReplaceMode_InsertIfAbsent); | |
949 } | |
950 } | |
951 | |
952 | |
953 void ParsedDicomFile::Answer(RestApiOutput& output) | |
954 { | |
955 std::string serialized; | |
1004
a226e0959d8b
DicomInstanceToStore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
956 if (FromDcmtkBridge::SaveToMemoryBuffer(serialized, *pimpl_->file_->getDataset())) |
790 | 957 { |
958 output.AnswerBuffer(serialized, CONTENT_TYPE_OCTET_STREAM); | |
959 } | |
960 } | |
961 | |
962 | |
963 | |
964 bool ParsedDicomFile::GetTagValue(std::string& value, | |
965 const DicomTag& tag) | |
966 { | |
967 DcmTagKey k(tag.GetGroup(), tag.GetElement()); | |
794 | 968 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
969 |
1556
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
970 if (FromDcmtkBridge::IsPrivateTag(tag) || |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
971 tag == DICOM_TAG_PIXEL_DATA || |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
972 tag == DICOM_TAG_ENCAPSULATED_DOCUMENT) |
790 | 973 { |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
974 const Uint8* data = NULL; // This is freed in the destructor of the dataset |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
975 long unsigned int count = 0; |
790 | 976 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
977 if (dataset.findAndGetUint8Array(k, data, &count).good()) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
978 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
979 if (count > 0) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
980 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
981 assert(data != NULL); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
982 value.assign(reinterpret_cast<const char*>(data), count); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
983 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
984 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
985 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
986 value.clear(); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
987 } |
790 | 988 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
989 return true; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
990 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
991 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
992 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
993 return false; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
994 } |
790 | 995 } |
996 else | |
997 { | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
998 DcmElement* element = NULL; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
999 if (!dataset.findAndGetElement(k, element).good() || |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1000 element == NULL) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1001 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1002 return false; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1003 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1004 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1005 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); |
1556
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1006 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1007 if (v.get() == NULL) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1008 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1009 value = ""; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1010 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1011 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1012 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1013 value = v->AsString(); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1014 } |
1556
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1015 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
1016 return true; |
790 | 1017 } |
1018 } | |
1019 | |
1020 | |
1021 DicomInstanceHasher ParsedDicomFile::GetHasher() | |
1022 { | |
1023 std::string patientId, studyUid, seriesUid, instanceUid; | |
1024 | |
1025 if (!GetTagValue(patientId, DICOM_TAG_PATIENT_ID) || | |
1026 !GetTagValue(studyUid, DICOM_TAG_STUDY_INSTANCE_UID) || | |
1027 !GetTagValue(seriesUid, DICOM_TAG_SERIES_INSTANCE_UID) || | |
1028 !GetTagValue(instanceUid, DICOM_TAG_SOP_INSTANCE_UID)) | |
1029 { | |
1030 throw OrthancException(ErrorCode_BadFileFormat); | |
1031 } | |
1032 | |
1033 return DicomInstanceHasher(patientId, studyUid, seriesUid, instanceUid); | |
1034 } | |
1035 | |
1036 | |
1037 template <typename T> | |
1038 static void ExtractPngImageTruncate(std::string& result, | |
1039 DicomIntegerPixelAccessor& accessor, | |
1040 PixelFormat format) | |
1041 { | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1042 assert(accessor.GetInformation().GetChannelCount() == 1); |
790 | 1043 |
1044 PngWriter w; | |
1045 | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1046 std::vector<T> image(accessor.GetInformation().GetWidth() * accessor.GetInformation().GetHeight(), 0); |
790 | 1047 T* pixel = &image[0]; |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1048 for (unsigned int y = 0; y < accessor.GetInformation().GetHeight(); y++) |
790 | 1049 { |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1050 for (unsigned int x = 0; x < accessor.GetInformation().GetWidth(); x++, pixel++) |
790 | 1051 { |
1052 int32_t v = accessor.GetValue(x, y); | |
1053 if (v < static_cast<int32_t>(std::numeric_limits<T>::min())) | |
1054 *pixel = std::numeric_limits<T>::min(); | |
1055 else if (v > static_cast<int32_t>(std::numeric_limits<T>::max())) | |
1056 *pixel = std::numeric_limits<T>::max(); | |
1057 else | |
1058 *pixel = static_cast<T>(v); | |
1059 } | |
1060 } | |
1061 | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1062 w.WriteToMemory(result, accessor.GetInformation().GetWidth(), accessor.GetInformation().GetHeight(), |
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1063 accessor.GetInformation().GetWidth() * sizeof(T), format, &image[0]); |
790 | 1064 } |
1065 | |
1066 | |
1067 void ParsedDicomFile::SaveToMemoryBuffer(std::string& buffer) | |
1068 { | |
1004
a226e0959d8b
DicomInstanceToStore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
1069 FromDcmtkBridge::SaveToMemoryBuffer(buffer, *pimpl_->file_->getDataset()); |
790 | 1070 } |
1071 | |
1072 | |
1073 void ParsedDicomFile::SaveToFile(const std::string& path) | |
1074 { | |
1075 // TODO Avoid using a temporary memory buffer, write directly on disk | |
1076 std::string content; | |
1077 SaveToMemoryBuffer(content); | |
1078 Toolbox::WriteFile(content, path); | |
1079 } | |
1080 | |
1081 | |
794 | 1082 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl) |
790 | 1083 { |
794 | 1084 pimpl_->file_.reset(new DcmFileFormat); |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1085 pimpl_->encoding_ = Encoding_Ascii; |
790 | 1086 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient)); |
1087 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)); | |
1088 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series)); | |
1089 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); | |
1090 } | |
1091 | |
791 | 1092 |
794 | 1093 ParsedDicomFile::ParsedDicomFile(const char* content, size_t size) : pimpl_(new PImpl) |
791 | 1094 { |
1095 Setup(content, size); | |
1096 } | |
1097 | |
794 | 1098 ParsedDicomFile::ParsedDicomFile(const std::string& content) : pimpl_(new PImpl) |
791 | 1099 { |
1100 if (content.size() == 0) | |
1101 { | |
1102 Setup(NULL, 0); | |
1103 } | |
1104 else | |
1105 { | |
1106 Setup(&content[0], content.size()); | |
1107 } | |
1108 } | |
792 | 1109 |
1110 | |
794 | 1111 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) : |
1112 pimpl_(new PImpl) | |
792 | 1113 { |
794 | 1114 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone())); |
1564
1b7def486e62
creation of DICOM series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1562
diff
changeset
|
1115 pimpl_->encoding_ = other.pimpl_->encoding_; |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1116 |
1564
1b7def486e62
creation of DICOM series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1562
diff
changeset
|
1117 // Create a new instance-level identifier |
1b7def486e62
creation of DICOM series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1562
diff
changeset
|
1118 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); |
792 | 1119 } |
1120 | |
1121 | |
1122 ParsedDicomFile::~ParsedDicomFile() | |
1123 { | |
794 | 1124 delete pimpl_; |
792 | 1125 } |
1126 | |
793 | 1127 |
1128 void* ParsedDicomFile::GetDcmtkObject() | |
1129 { | |
794 | 1130 return pimpl_->file_.get(); |
793 | 1131 } |
1132 | |
1133 | |
1134 ParsedDicomFile* ParsedDicomFile::Clone() | |
1135 { | |
794 | 1136 return new ParsedDicomFile(*this); |
793 | 1137 } |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1138 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1139 |
1562 | 1140 void ParsedDicomFile::EmbedContent(const std::string& dataUriScheme) |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1141 { |
1641
4e56b5a206b7
Support of binary tags encoded using data URI scheme
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1616
diff
changeset
|
1142 std::string mime, content; |
4e56b5a206b7
Support of binary tags encoded using data URI scheme
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1616
diff
changeset
|
1143 Toolbox::DecodeDataUriScheme(mime, content, dataUriScheme); |
1562 | 1144 Toolbox::ToLowerCase(mime); |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1145 |
1562 | 1146 if (mime == "image/png") |
1147 { | |
1148 EmbedImage(mime, content); | |
1149 } | |
1150 else if (mime == "application/pdf") | |
1151 { | |
1152 EmbedPdf(content); | |
1153 } | |
1154 else | |
1155 { | |
1156 LOG(ERROR) << "Unsupported MIME type for the content of a new DICOM file"; | |
1157 throw OrthancException(ErrorCode_NotImplemented); | |
1158 } | |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1159 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1160 |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1161 |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1162 void ParsedDicomFile::EmbedImage(const std::string& mime, |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1163 const std::string& content) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1164 { |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1165 if (mime == "image/png") |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1166 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1167 PngReader reader; |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1168 reader.ReadFromMemory(content); |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1169 EmbedImage(reader); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1170 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1171 else |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1172 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1173 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1174 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1175 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1176 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1177 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1178 void ParsedDicomFile::EmbedImage(const ImageAccessor& accessor) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1179 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1180 if (accessor.GetFormat() != PixelFormat_Grayscale8 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1181 accessor.GetFormat() != PixelFormat_Grayscale16 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1182 accessor.GetFormat() != PixelFormat_RGB24 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1183 accessor.GetFormat() != PixelFormat_RGBA32) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1184 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1185 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1186 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1187 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1188 if (accessor.GetFormat() == PixelFormat_RGBA32) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1189 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1190 LOG(WARNING) << "Getting rid of the alpha channel when embedding a RGBA image inside DICOM"; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1191 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1192 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1193 // http://dicomiseasy.blogspot.be/2012/08/chapter-12-pixel-data.html |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1194 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1195 Remove(DICOM_TAG_PIXEL_DATA); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1196 Replace(DICOM_TAG_COLUMNS, boost::lexical_cast<std::string>(accessor.GetWidth())); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1197 Replace(DICOM_TAG_ROWS, boost::lexical_cast<std::string>(accessor.GetHeight())); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1198 Replace(DICOM_TAG_SAMPLES_PER_PIXEL, "1"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1199 Replace(DICOM_TAG_NUMBER_OF_FRAMES, "1"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1200 Replace(DICOM_TAG_PIXEL_REPRESENTATION, "0"); // Unsigned pixels |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1201 Replace(DICOM_TAG_PLANAR_CONFIGURATION, "0"); // Color channels are interleaved |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1202 Replace(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "MONOCHROME2"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1203 Replace(DICOM_TAG_BITS_ALLOCATED, "8"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1204 Replace(DICOM_TAG_BITS_STORED, "8"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1205 Replace(DICOM_TAG_HIGH_BIT, "7"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1206 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1207 unsigned int bytesPerPixel = 1; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1208 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1209 switch (accessor.GetFormat()) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1210 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1211 case PixelFormat_RGB24: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1212 case PixelFormat_RGBA32: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1213 Replace(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "RGB"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1214 Replace(DICOM_TAG_SAMPLES_PER_PIXEL, "3"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1215 bytesPerPixel = 3; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1216 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1217 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1218 case PixelFormat_Grayscale8: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1219 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1220 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1221 case PixelFormat_Grayscale16: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1222 Replace(DICOM_TAG_BITS_ALLOCATED, "16"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1223 Replace(DICOM_TAG_BITS_STORED, "16"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1224 Replace(DICOM_TAG_HIGH_BIT, "15"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1225 bytesPerPixel = 2; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1226 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1227 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1228 default: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1229 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1230 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1231 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1232 DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1233 DICOM_TAG_PIXEL_DATA.GetElement()); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1234 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1235 std::auto_ptr<DcmPixelData> pixels(new DcmPixelData(key)); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1236 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1237 unsigned int pitch = accessor.GetWidth() * bytesPerPixel; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1238 Uint8* target = NULL; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1239 pixels->createUint8Array(accessor.GetHeight() * pitch, target); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1240 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1241 for (unsigned int y = 0; y < accessor.GetHeight(); y++) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1242 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1243 switch (accessor.GetFormat()) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1244 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1245 case PixelFormat_RGB24: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1246 case PixelFormat_Grayscale8: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1247 case PixelFormat_Grayscale16: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1248 case PixelFormat_SignedGrayscale16: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1249 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1250 memcpy(target, reinterpret_cast<const Uint8*>(accessor.GetConstRow(y)), pitch); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1251 target += pitch; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1252 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1253 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1254 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1255 case PixelFormat_RGBA32: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1256 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1257 // The alpha channel is not supported by the DICOM standard |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1258 const Uint8* source = reinterpret_cast<const Uint8*>(accessor.GetConstRow(y)); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1259 for (unsigned int x = 0; x < accessor.GetWidth(); x++, target += 3, source += 4) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1260 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1261 target[0] = source[0]; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1262 target[1] = source[1]; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1263 target[2] = source[2]; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1264 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1265 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1266 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1267 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1268 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1269 default: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1270 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1271 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1272 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1273 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1274 if (!pimpl_->file_->getDataset()->insert(pixels.release(), false, false).good()) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1275 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1276 throw OrthancException(ErrorCode_InternalError); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1277 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1278 } |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1279 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1280 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1281 void ParsedDicomFile::ExtractImage(ImageBuffer& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1282 unsigned int frame) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1283 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1284 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1285 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1286 if (!DicomImageDecoder::Decode(result, dataset, frame)) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1287 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1288 throw OrthancException(ErrorCode_BadFileFormat); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1289 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1290 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1291 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1292 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1293 void ParsedDicomFile::ExtractImage(ImageBuffer& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1294 unsigned int frame, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1295 ImageExtractionMode mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1296 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1297 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1298 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1299 bool ok = false; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1300 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1301 switch (mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1302 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1303 case ImageExtractionMode_UInt8: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1304 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_Grayscale8, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1305 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1306 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1307 case ImageExtractionMode_UInt16: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1308 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_Grayscale16, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1309 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1310 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1311 case ImageExtractionMode_Int16: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1312 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_SignedGrayscale16, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1313 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1314 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1315 case ImageExtractionMode_Preview: |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1316 ok = DicomImageDecoder::DecodePreview(result, dataset, frame); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1317 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1318 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1319 default: |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1320 throw OrthancException(ErrorCode_ParameterOutOfRange); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1321 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1322 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1323 if (!ok) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1324 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1325 throw OrthancException(ErrorCode_BadFileFormat); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1326 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1327 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1328 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1329 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1330 void ParsedDicomFile::ExtractPngImage(std::string& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1331 unsigned int frame, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1332 ImageExtractionMode mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1333 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1334 ImageBuffer buffer; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1335 ExtractImage(buffer, frame, mode); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1336 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1337 ImageAccessor accessor(buffer.GetConstAccessor()); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1338 PngWriter writer; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1339 writer.WriteToMemory(result, accessor); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1340 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1341 |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1342 |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1343 Encoding ParsedDicomFile::GetEncoding() const |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1344 { |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1345 return pimpl_->encoding_; |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1346 } |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1347 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1348 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1349 void ParsedDicomFile::SetEncoding(Encoding encoding) |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1350 { |
1558
124de28b32ed
fix encodings of newly created dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1556
diff
changeset
|
1351 if (encoding == Encoding_Windows1251) |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1352 { |
1558
124de28b32ed
fix encodings of newly created dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1556
diff
changeset
|
1353 // This Cyrillic codepage is not officially supported by the |
124de28b32ed
fix encodings of newly created dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1556
diff
changeset
|
1354 // DICOM standard. Do not set the SpecificCharacterSet tag. |
124de28b32ed
fix encodings of newly created dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1556
diff
changeset
|
1355 return; |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1356 } |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1357 |
1565
4b23310eb7e8
add tags per instances in a series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1564
diff
changeset
|
1358 pimpl_->encoding_ = encoding; |
4b23310eb7e8
add tags per instances in a series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1564
diff
changeset
|
1359 |
4b23310eb7e8
add tags per instances in a series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1564
diff
changeset
|
1360 std::string s = GetDicomSpecificCharacterSet(encoding); |
1091 | 1361 Replace(DICOM_TAG_SPECIFIC_CHARACTER_SET, s, DicomReplaceMode_InsertIfAbsent); |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1362 } |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1363 |
1160
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1364 void ParsedDicomFile::ToJson(Json::Value& target, bool simplify) |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1365 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1366 if (simplify) |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1367 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1368 Json::Value tmp; |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1369 FromDcmtkBridge::ToJson(tmp, *pimpl_->file_->getDataset()); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1370 SimplifyTags(target, tmp); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1371 } |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1372 else |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1373 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1374 FromDcmtkBridge::ToJson(target, *pimpl_->file_->getDataset()); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1375 } |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1376 } |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1377 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1378 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1379 bool ParsedDicomFile::HasTag(const DicomTag& tag) const |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1380 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1381 DcmTag key(tag.GetGroup(), tag.GetElement()); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1382 return pimpl_->file_->getDataset()->tagExists(key); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1383 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1384 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1385 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1386 void ParsedDicomFile::EmbedPdf(const std::string& pdf) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1387 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1388 if (pdf.size() < 5 || // (*) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1389 strncmp("%PDF-", pdf.c_str(), 5) != 0) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1390 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1391 LOG(ERROR) << "Not a PDF file"; |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1392 throw OrthancException(ErrorCode_BadFileFormat); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1393 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1394 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1395 Replace(DICOM_TAG_SOP_CLASS_UID, UID_EncapsulatedPDFStorage); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1396 Replace(FromDcmtkBridge::Convert(DCM_Modality), "OT"); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1397 Replace(FromDcmtkBridge::Convert(DCM_ConversionType), "WSD"); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1398 Replace(FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument), "application/pdf"); |
1566 | 1399 //Replace(FromDcmtkBridge::Convert(DCM_SeriesNumber), "1"); |
1555
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1400 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1401 std::auto_ptr<DcmPolymorphOBOW> element(new DcmPolymorphOBOW(DCM_EncapsulatedDocument)); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1402 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1403 size_t s = pdf.size(); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1404 if (s & 1) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1405 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1406 // The size of the buffer must be even |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1407 s += 1; |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1408 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1409 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1410 Uint8* bytes = NULL; |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1411 OFCondition result = element->createUint8Array(s, bytes); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1412 if (!result.good() || bytes == NULL) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1413 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1414 throw OrthancException(ErrorCode_NotEnoughMemory); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1415 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1416 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1417 // Blank pad byte (no access violation, as "pdf.size() >= 5" because of (*) ) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1418 bytes[s - 1] = 0; |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1419 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1420 memcpy(bytes, pdf.c_str(), pdf.size()); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1421 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1422 DcmPolymorphOBOW* obj = element.release(); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1423 result = pimpl_->file_->getDataset()->insert(obj); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1424 |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1425 if (!result.good()) |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1426 { |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1427 delete obj; |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1428 throw OrthancException(ErrorCode_NotEnoughMemory); |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1429 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1430 } |
d6a93e12b1c1
Creation of DICOM files with encapsulated PDF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1523
diff
changeset
|
1431 |
1556
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1432 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1433 bool ParsedDicomFile::ExtractPdf(std::string& pdf) |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1434 { |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1435 std::string sop, mime; |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1436 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1437 if (!GetTagValue(sop, DICOM_TAG_SOP_CLASS_UID) || |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1438 !GetTagValue(mime, FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument)) || |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1439 sop != UID_EncapsulatedPDFStorage || |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1440 mime != "application/pdf") |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1441 { |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1442 return false; |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1443 } |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1444 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1445 if (!GetTagValue(pdf, DICOM_TAG_ENCAPSULATED_DOCUMENT)) |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1446 { |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1447 return false; |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1448 } |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1449 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1450 // Strip the possible pad byte at the end of file, because the |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1451 // encapsulated documents must always have an even length. The PDF |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1452 // format expects files to end with %%EOF followed by CR/LF. If |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1453 // the last character of the file is not a CR or LF, we assume it |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1454 // is a pad byte and remove it. |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1455 if (pdf.size() > 0) |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1456 { |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1457 char last = *pdf.rbegin(); |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1458 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1459 if (last != 10 && last != 13) |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1460 { |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1461 pdf.resize(pdf.size() - 1); |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1462 } |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1463 } |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1464 |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1465 return true; |
b8dc2f855a83
Preview of PDF files encapsulated in DICOM from Orthanc Explorer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1555
diff
changeset
|
1466 } |
790 | 1467 } |