Mercurial > hg > orthanc
annotate OrthancServer/ParsedDicomFile.cpp @ 1365:38ce915cb455 query-retrieve
unused tags
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 21 May 2015 17:03:15 +0200 |
parents | 60cc0ee61edb |
children | f967bdf8534e |
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" |
790 | 87 #include "../Core/Toolbox.h" |
88 #include "../Core/OrthancException.h" | |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
89 #include "../Core/ImageFormats/ImageBuffer.h" |
799 | 90 #include "../Core/ImageFormats/PngWriter.h" |
790 | 91 #include "../Core/Uuid.h" |
92 #include "../Core/DicomFormat/DicomString.h" | |
93 #include "../Core/DicomFormat/DicomNullValue.h" | |
94 #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" | |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
95 #include "../Core/ImageFormats/PngReader.h" |
790 | 96 |
97 #include <list> | |
98 #include <limits> | |
99 | |
100 #include <boost/lexical_cast.hpp> | |
101 | |
102 #include <dcmtk/dcmdata/dcchrstr.h> | |
103 #include <dcmtk/dcmdata/dcdicent.h> | |
104 #include <dcmtk/dcmdata/dcdict.h> | |
105 #include <dcmtk/dcmdata/dcfilefo.h> | |
106 #include <dcmtk/dcmdata/dcistrmb.h> | |
107 #include <dcmtk/dcmdata/dcuid.h> | |
108 #include <dcmtk/dcmdata/dcmetinf.h> | |
109 | |
110 #include <dcmtk/dcmdata/dcvrae.h> | |
111 #include <dcmtk/dcmdata/dcvras.h> | |
112 #include <dcmtk/dcmdata/dcvrcs.h> | |
113 #include <dcmtk/dcmdata/dcvrda.h> | |
114 #include <dcmtk/dcmdata/dcvrds.h> | |
115 #include <dcmtk/dcmdata/dcvrdt.h> | |
116 #include <dcmtk/dcmdata/dcvrfd.h> | |
117 #include <dcmtk/dcmdata/dcvrfl.h> | |
118 #include <dcmtk/dcmdata/dcvris.h> | |
119 #include <dcmtk/dcmdata/dcvrlo.h> | |
120 #include <dcmtk/dcmdata/dcvrlt.h> | |
121 #include <dcmtk/dcmdata/dcvrpn.h> | |
122 #include <dcmtk/dcmdata/dcvrsh.h> | |
123 #include <dcmtk/dcmdata/dcvrsl.h> | |
124 #include <dcmtk/dcmdata/dcvrss.h> | |
125 #include <dcmtk/dcmdata/dcvrst.h> | |
126 #include <dcmtk/dcmdata/dcvrtm.h> | |
127 #include <dcmtk/dcmdata/dcvrui.h> | |
128 #include <dcmtk/dcmdata/dcvrul.h> | |
129 #include <dcmtk/dcmdata/dcvrus.h> | |
130 #include <dcmtk/dcmdata/dcvrut.h> | |
131 #include <dcmtk/dcmdata/dcpixel.h> | |
132 #include <dcmtk/dcmdata/dcpixseq.h> | |
133 #include <dcmtk/dcmdata/dcpxitem.h> | |
134 | |
135 | |
136 #include <boost/math/special_functions/round.hpp> | |
137 #include <glog/logging.h> | |
138 #include <dcmtk/dcmdata/dcostrmb.h> | |
139 | |
140 | |
141 static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream"; | |
142 | |
143 | |
144 | |
145 namespace Orthanc | |
146 { | |
794 | 147 struct ParsedDicomFile::PImpl |
148 { | |
149 std::auto_ptr<DcmFileFormat> file_; | |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
150 Encoding encoding_; |
794 | 151 }; |
152 | |
153 | |
154 // This method can only be called from the constructors! | |
790 | 155 void ParsedDicomFile::Setup(const char* buffer, size_t size) |
156 { | |
157 DcmInputBufferStream is; | |
158 if (size > 0) | |
159 { | |
160 is.setBuffer(buffer, size); | |
161 } | |
162 is.setEos(); | |
163 | |
794 | 164 pimpl_->file_.reset(new DcmFileFormat); |
165 pimpl_->file_->transferInit(); | |
166 if (!pimpl_->file_->read(is).good()) | |
790 | 167 { |
794 | 168 delete pimpl_; // Avoid a memory leak due to exception |
169 // throwing, as we are in the constructor | |
170 | |
790 | 171 throw OrthancException(ErrorCode_BadFileFormat); |
172 } | |
794 | 173 pimpl_->file_->loadAllDataIntoMemory(); |
174 pimpl_->file_->transferEnd(); | |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
175 |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
176 pimpl_->encoding_ = FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset()); |
790 | 177 } |
178 | |
179 | |
180 static void SendPathValueForDictionary(RestApiOutput& output, | |
181 DcmItem& dicom) | |
182 { | |
183 Json::Value v = Json::arrayValue; | |
184 | |
185 for (unsigned long i = 0; i < dicom.card(); i++) | |
186 { | |
187 DcmElement* element = dicom.getElement(i); | |
188 if (element) | |
189 { | |
190 char buf[16]; | |
191 sprintf(buf, "%04x-%04x", element->getTag().getGTag(), element->getTag().getETag()); | |
192 v.append(buf); | |
193 } | |
194 } | |
195 | |
196 output.AnswerJson(v); | |
197 } | |
198 | |
199 static inline uint16_t GetCharValue(char c) | |
200 { | |
201 if (c >= '0' && c <= '9') | |
202 return c - '0'; | |
203 else if (c >= 'a' && c <= 'f') | |
204 return c - 'a' + 10; | |
205 else if (c >= 'A' && c <= 'F') | |
206 return c - 'A' + 10; | |
207 else | |
208 return 0; | |
209 } | |
210 | |
211 static inline uint16_t GetTagValue(const char* c) | |
212 { | |
213 return ((GetCharValue(c[0]) << 12) + | |
214 (GetCharValue(c[1]) << 8) + | |
215 (GetCharValue(c[2]) << 4) + | |
216 GetCharValue(c[3])); | |
217 } | |
218 | |
219 static void ParseTagAndGroup(DcmTagKey& key, | |
220 const std::string& tag) | |
221 { | |
222 DicomTag t = FromDcmtkBridge::ParseTag(tag); | |
223 key = DcmTagKey(t.GetGroup(), t.GetElement()); | |
224 } | |
225 | |
226 | |
227 static void SendSequence(RestApiOutput& output, | |
228 DcmSequenceOfItems& sequence) | |
229 { | |
230 // This element is a sequence | |
231 Json::Value v = Json::arrayValue; | |
232 | |
233 for (unsigned long i = 0; i < sequence.card(); i++) | |
234 { | |
235 v.append(boost::lexical_cast<std::string>(i)); | |
236 } | |
237 | |
238 output.AnswerJson(v); | |
239 } | |
240 | |
241 | |
242 static unsigned int GetPixelDataBlockCount(DcmPixelData& pixelData, | |
243 E_TransferSyntax transferSyntax) | |
244 { | |
245 DcmPixelSequence* pixelSequence = NULL; | |
246 if (pixelData.getEncapsulatedRepresentation | |
247 (transferSyntax, NULL, pixelSequence).good() && pixelSequence) | |
248 { | |
249 return pixelSequence->card(); | |
250 } | |
251 else | |
252 { | |
253 return 1; | |
254 } | |
255 } | |
256 | |
257 | |
258 static void AnswerDicomField(RestApiOutput& output, | |
259 DcmElement& element, | |
260 E_TransferSyntax transferSyntax) | |
261 { | |
262 // This element is nor a sequence, neither a pixel-data | |
263 std::string buffer; | |
264 buffer.resize(65536); | |
265 Uint32 length = element.getLength(transferSyntax); | |
266 Uint32 offset = 0; | |
267 | |
1113
ba5c0908600c
Refactoring of HttpOutput ("Content-Length" header is now always sent)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1091
diff
changeset
|
268 output.GetLowLevelOutput().SetContentType(CONTENT_TYPE_OCTET_STREAM); |
ba5c0908600c
Refactoring of HttpOutput ("Content-Length" header is now always sent)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1091
diff
changeset
|
269 output.GetLowLevelOutput().SetContentLength(length); |
790 | 270 |
271 while (offset < length) | |
272 { | |
273 Uint32 nbytes; | |
274 if (length - offset < buffer.size()) | |
275 { | |
276 nbytes = length - offset; | |
277 } | |
278 else | |
279 { | |
280 nbytes = buffer.size(); | |
281 } | |
282 | |
283 OFCondition cond = element.getPartialValue(&buffer[0], offset, nbytes); | |
284 | |
285 if (cond.good()) | |
286 { | |
1113
ba5c0908600c
Refactoring of HttpOutput ("Content-Length" header is now always sent)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1091
diff
changeset
|
287 output.GetLowLevelOutput().SendBody(&buffer[0], nbytes); |
790 | 288 offset += nbytes; |
289 } | |
290 else | |
291 { | |
292 LOG(ERROR) << "Error while sending a DICOM field: " << cond.text(); | |
293 return; | |
294 } | |
295 } | |
296 | |
297 output.MarkLowLevelOutputDone(); | |
298 } | |
299 | |
300 | |
301 static bool AnswerPixelData(RestApiOutput& output, | |
302 DcmItem& dicom, | |
303 E_TransferSyntax transferSyntax, | |
304 const std::string* blockUri) | |
305 { | |
306 DcmTag k(DICOM_TAG_PIXEL_DATA.GetGroup(), | |
307 DICOM_TAG_PIXEL_DATA.GetElement()); | |
308 | |
309 DcmElement *element = NULL; | |
310 if (!dicom.findAndGetElement(k, element).good() || | |
311 element == NULL) | |
312 { | |
313 return false; | |
314 } | |
315 | |
316 try | |
317 { | |
318 DcmPixelData& pixelData = dynamic_cast<DcmPixelData&>(*element); | |
319 if (blockUri == NULL) | |
320 { | |
321 // The user asks how many blocks are presents in this pixel data | |
322 unsigned int blocks = GetPixelDataBlockCount(pixelData, transferSyntax); | |
323 | |
324 Json::Value result(Json::arrayValue); | |
325 for (unsigned int i = 0; i < blocks; i++) | |
326 { | |
327 result.append(boost::lexical_cast<std::string>(i)); | |
328 } | |
329 | |
330 output.AnswerJson(result); | |
331 return true; | |
332 } | |
333 | |
334 | |
335 unsigned int block = boost::lexical_cast<unsigned int>(*blockUri); | |
336 | |
337 if (block < GetPixelDataBlockCount(pixelData, transferSyntax)) | |
338 { | |
339 DcmPixelSequence* pixelSequence = NULL; | |
340 if (pixelData.getEncapsulatedRepresentation | |
341 (transferSyntax, NULL, pixelSequence).good() && pixelSequence) | |
342 { | |
343 // This is the case for JPEG transfer syntaxes | |
344 if (block < pixelSequence->card()) | |
345 { | |
346 DcmPixelItem* pixelItem = NULL; | |
347 if (pixelSequence->getItem(pixelItem, block).good() && pixelItem) | |
348 { | |
349 if (pixelItem->getLength() == 0) | |
350 { | |
351 output.AnswerBuffer(NULL, 0, CONTENT_TYPE_OCTET_STREAM); | |
352 return true; | |
353 } | |
354 | |
355 Uint8* buffer = NULL; | |
356 if (pixelItem->getUint8Array(buffer).good() && buffer) | |
357 { | |
358 output.AnswerBuffer(buffer, pixelItem->getLength(), CONTENT_TYPE_OCTET_STREAM); | |
359 return true; | |
360 } | |
361 } | |
362 } | |
363 } | |
364 else | |
365 { | |
366 // This is the case for raw, uncompressed image buffers | |
367 assert(*blockUri == "0"); | |
368 AnswerDicomField(output, *element, transferSyntax); | |
369 } | |
370 } | |
371 } | |
372 catch (boost::bad_lexical_cast&) | |
373 { | |
374 // The URI entered by the user is not a number | |
375 } | |
376 catch (std::bad_cast&) | |
377 { | |
378 // This should never happen | |
379 } | |
380 | |
381 return false; | |
382 } | |
383 | |
384 | |
385 | |
386 static void SendPathValueForLeaf(RestApiOutput& output, | |
387 const std::string& tag, | |
388 DcmItem& dicom, | |
389 E_TransferSyntax transferSyntax) | |
390 { | |
391 DcmTagKey k; | |
392 ParseTagAndGroup(k, tag); | |
393 | |
394 DcmSequenceOfItems* sequence = NULL; | |
395 if (dicom.findAndGetSequence(k, sequence).good() && | |
396 sequence != NULL && | |
397 sequence->getVR() == EVR_SQ) | |
398 { | |
399 SendSequence(output, *sequence); | |
400 return; | |
401 } | |
402 | |
403 DcmElement* element = NULL; | |
404 if (dicom.findAndGetElement(k, element).good() && | |
405 element != NULL && | |
406 //element->getVR() != EVR_UNKNOWN && // This would forbid private tags | |
407 element->getVR() != EVR_SQ) | |
408 { | |
409 AnswerDicomField(output, *element, transferSyntax); | |
410 } | |
411 } | |
412 | |
413 void ParsedDicomFile::SendPathValue(RestApiOutput& output, | |
414 const UriComponents& uri) | |
415 { | |
794 | 416 DcmItem* dicom = pimpl_->file_->getDataset(); |
417 E_TransferSyntax transferSyntax = pimpl_->file_->getDataset()->getOriginalXfer(); | |
790 | 418 |
419 // Special case: Accessing the pixel data | |
420 if (uri.size() == 1 || | |
421 uri.size() == 2) | |
422 { | |
423 DcmTagKey tag; | |
424 ParseTagAndGroup(tag, uri[0]); | |
425 | |
426 if (tag.getGroup() == DICOM_TAG_PIXEL_DATA.GetGroup() && | |
427 tag.getElement() == DICOM_TAG_PIXEL_DATA.GetElement()) | |
428 { | |
429 AnswerPixelData(output, *dicom, transferSyntax, uri.size() == 1 ? NULL : &uri[1]); | |
430 return; | |
431 } | |
432 } | |
433 | |
434 // Go down in the tag hierarchy according to the URI | |
435 for (size_t pos = 0; pos < uri.size() / 2; pos++) | |
436 { | |
437 size_t index; | |
438 try | |
439 { | |
440 index = boost::lexical_cast<size_t>(uri[2 * pos + 1]); | |
441 } | |
442 catch (boost::bad_lexical_cast&) | |
443 { | |
444 return; | |
445 } | |
446 | |
447 DcmTagKey k; | |
448 DcmItem *child = NULL; | |
449 ParseTagAndGroup(k, uri[2 * pos]); | |
450 if (!dicom->findAndGetSequenceItem(k, child, index).good() || | |
451 child == NULL) | |
452 { | |
453 return; | |
454 } | |
455 | |
456 dicom = child; | |
457 } | |
458 | |
459 // We have reached the end of the URI | |
460 if (uri.size() % 2 == 0) | |
461 { | |
462 SendPathValueForDictionary(output, *dicom); | |
463 } | |
464 else | |
465 { | |
466 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax); | |
467 } | |
468 } | |
469 | |
470 | |
471 | |
472 | |
473 | |
474 static DcmElement* CreateElementForTag(const DicomTag& tag) | |
475 { | |
476 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
477 | |
478 switch (key.getEVR()) | |
479 { | |
480 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
481 | |
482 /** | |
483 * TODO. | |
484 **/ | |
485 | |
486 case EVR_OB: // other byte | |
487 case EVR_OF: // other float | |
488 case EVR_OW: // other word | |
489 case EVR_AT: // attribute tag | |
490 throw OrthancException(ErrorCode_NotImplemented); | |
491 | |
492 case EVR_UN: // unknown value representation | |
493 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
494 | |
495 | |
496 /** | |
497 * String types. | |
498 * http://support.dcmtk.org/docs/classDcmByteString.html | |
499 **/ | |
500 | |
501 case EVR_AS: // age string | |
502 return new DcmAgeString(key); | |
503 | |
504 case EVR_AE: // application entity title | |
505 return new DcmApplicationEntity(key); | |
506 | |
507 case EVR_CS: // code string | |
508 return new DcmCodeString(key); | |
509 | |
510 case EVR_DA: // date string | |
511 return new DcmDate(key); | |
512 | |
513 case EVR_DT: // date time string | |
514 return new DcmDateTime(key); | |
515 | |
516 case EVR_DS: // decimal string | |
517 return new DcmDecimalString(key); | |
518 | |
519 case EVR_IS: // integer string | |
520 return new DcmIntegerString(key); | |
521 | |
522 case EVR_TM: // time string | |
523 return new DcmTime(key); | |
524 | |
525 case EVR_UI: // unique identifier | |
526 return new DcmUniqueIdentifier(key); | |
527 | |
528 case EVR_ST: // short text | |
529 return new DcmShortText(key); | |
530 | |
531 case EVR_LO: // long string | |
532 return new DcmLongString(key); | |
533 | |
534 case EVR_LT: // long text | |
535 return new DcmLongText(key); | |
536 | |
537 case EVR_UT: // unlimited text | |
538 return new DcmUnlimitedText(key); | |
539 | |
540 case EVR_SH: // short string | |
541 return new DcmShortString(key); | |
542 | |
543 case EVR_PN: // person name | |
544 return new DcmPersonName(key); | |
545 | |
546 | |
547 /** | |
548 * Numerical types | |
549 **/ | |
550 | |
551 case EVR_SL: // signed long | |
552 return new DcmSignedLong(key); | |
553 | |
554 case EVR_SS: // signed short | |
555 return new DcmSignedShort(key); | |
556 | |
557 case EVR_UL: // unsigned long | |
558 return new DcmUnsignedLong(key); | |
559 | |
560 case EVR_US: // unsigned short | |
561 return new DcmUnsignedShort(key); | |
562 | |
563 case EVR_FL: // float single-precision | |
564 return new DcmFloatingPointSingle(key); | |
565 | |
566 case EVR_FD: // float double-precision | |
567 return new DcmFloatingPointDouble(key); | |
568 | |
569 | |
570 /** | |
571 * Sequence types, should never occur at this point. | |
572 **/ | |
573 | |
574 case EVR_SQ: // sequence of items | |
575 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
576 | |
577 | |
578 /** | |
579 * Internal to DCMTK. | |
580 **/ | |
581 | |
582 case EVR_ox: // OB or OW depending on context | |
583 case EVR_xs: // SS or US depending on context | |
584 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
585 case EVR_na: // na="not applicable", for data which has no VR | |
586 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
587 case EVR_item: // used internally for items | |
588 case EVR_metainfo: // used internally for meta info datasets | |
589 case EVR_dataset: // used internally for datasets | |
590 case EVR_fileFormat: // used internally for DICOM files | |
591 case EVR_dicomDir: // used internally for DICOMDIR objects | |
592 case EVR_dirRecord: // used internally for DICOMDIR records | |
593 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
594 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
595 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
596 case EVR_PixelData: // used internally for uncompressed pixeld data | |
597 case EVR_OverlayData: // used internally for overlay data | |
598 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
599 default: | |
600 break; | |
601 } | |
602 | |
603 throw OrthancException(ErrorCode_InternalError); | |
604 } | |
605 | |
606 | |
607 | |
608 static void FillElementWithString(DcmElement& element, | |
609 const DicomTag& tag, | |
610 const std::string& value) | |
611 { | |
612 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
613 bool ok = false; | |
614 | |
615 try | |
616 { | |
617 switch (key.getEVR()) | |
618 { | |
619 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
620 | |
621 /** | |
622 * TODO. | |
623 **/ | |
624 | |
625 case EVR_OB: // other byte | |
626 case EVR_OF: // other float | |
627 case EVR_OW: // other word | |
628 case EVR_AT: // attribute tag | |
629 throw OrthancException(ErrorCode_NotImplemented); | |
630 | |
631 case EVR_UN: // unknown value representation | |
632 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
633 | |
634 | |
635 /** | |
636 * String types. | |
637 **/ | |
638 | |
639 case EVR_DS: // decimal string | |
640 case EVR_IS: // integer string | |
641 case EVR_AS: // age string | |
642 case EVR_DA: // date string | |
643 case EVR_DT: // date time string | |
644 case EVR_TM: // time string | |
645 case EVR_AE: // application entity title | |
646 case EVR_CS: // code string | |
647 case EVR_SH: // short string | |
648 case EVR_LO: // long string | |
649 case EVR_ST: // short text | |
650 case EVR_LT: // long text | |
651 case EVR_UT: // unlimited text | |
652 case EVR_PN: // person name | |
653 case EVR_UI: // unique identifier | |
654 { | |
655 ok = element.putString(value.c_str()).good(); | |
656 break; | |
657 } | |
658 | |
659 | |
660 /** | |
661 * Numerical types | |
662 **/ | |
663 | |
664 case EVR_SL: // signed long | |
665 { | |
666 ok = element.putSint32(boost::lexical_cast<Sint32>(value)).good(); | |
667 break; | |
668 } | |
669 | |
670 case EVR_SS: // signed short | |
671 { | |
672 ok = element.putSint16(boost::lexical_cast<Sint16>(value)).good(); | |
673 break; | |
674 } | |
675 | |
676 case EVR_UL: // unsigned long | |
677 { | |
678 ok = element.putUint32(boost::lexical_cast<Uint32>(value)).good(); | |
679 break; | |
680 } | |
681 | |
682 case EVR_US: // unsigned short | |
683 { | |
684 ok = element.putUint16(boost::lexical_cast<Uint16>(value)).good(); | |
685 break; | |
686 } | |
687 | |
688 case EVR_FL: // float single-precision | |
689 { | |
690 ok = element.putFloat32(boost::lexical_cast<float>(value)).good(); | |
691 break; | |
692 } | |
693 | |
694 case EVR_FD: // float double-precision | |
695 { | |
696 ok = element.putFloat64(boost::lexical_cast<double>(value)).good(); | |
697 break; | |
698 } | |
699 | |
700 | |
701 /** | |
702 * Sequence types, should never occur at this point. | |
703 **/ | |
704 | |
705 case EVR_SQ: // sequence of items | |
706 { | |
707 ok = false; | |
708 break; | |
709 } | |
710 | |
711 | |
712 /** | |
713 * Internal to DCMTK. | |
714 **/ | |
715 | |
716 case EVR_ox: // OB or OW depending on context | |
717 case EVR_xs: // SS or US depending on context | |
718 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
719 case EVR_na: // na="not applicable", for data which has no VR | |
720 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
721 case EVR_item: // used internally for items | |
722 case EVR_metainfo: // used internally for meta info datasets | |
723 case EVR_dataset: // used internally for datasets | |
724 case EVR_fileFormat: // used internally for DICOM files | |
725 case EVR_dicomDir: // used internally for DICOMDIR objects | |
726 case EVR_dirRecord: // used internally for DICOMDIR records | |
727 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
728 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
729 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
730 case EVR_PixelData: // used internally for uncompressed pixeld data | |
731 case EVR_OverlayData: // used internally for overlay data | |
732 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
733 default: | |
734 break; | |
735 } | |
736 } | |
737 catch (boost::bad_lexical_cast&) | |
738 { | |
739 ok = false; | |
740 } | |
741 | |
742 if (!ok) | |
743 { | |
744 throw OrthancException(ErrorCode_InternalError); | |
745 } | |
746 } | |
747 | |
748 | |
749 void ParsedDicomFile::Remove(const DicomTag& tag) | |
750 { | |
751 DcmTagKey key(tag.GetGroup(), tag.GetElement()); | |
794 | 752 DcmElement* element = pimpl_->file_->getDataset()->remove(key); |
790 | 753 if (element != NULL) |
754 { | |
755 delete element; | |
756 } | |
757 } | |
758 | |
759 | |
760 | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
761 void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep) |
790 | 762 { |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
763 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
764 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
765 // Loop over the dataset to detect its private tags |
790 | 766 typedef std::list<DcmElement*> Tags; |
767 Tags privateTags; | |
768 | |
769 for (unsigned long i = 0; i < dataset.card(); i++) | |
770 { | |
771 DcmElement* element = dataset.getElement(i); | |
772 DcmTag tag(element->getTag()); | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
773 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
774 // Is this a private tag? |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
775 if (FromDcmtkBridge::IsPrivateTag(tag)) |
790 | 776 { |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
777 bool remove = true; |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
778 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
779 // 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
|
780 if (toKeep != NULL) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
781 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
782 DicomTag tmp = FromDcmtkBridge::Convert(tag); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
783 if (toKeep->find(tmp) != toKeep->end()) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
784 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
785 remove = false; // Keep it |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
786 } |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
787 } |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
788 |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
789 if (remove) |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
790 { |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
791 privateTags.push_back(element); |
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
792 } |
790 | 793 } |
794 } | |
795 | |
991
2f76b92addd4
keep private tags during anonymization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
956
diff
changeset
|
796 // Loop over the detected private tags to remove them |
790 | 797 for (Tags::iterator it = privateTags.begin(); |
798 it != privateTags.end(); ++it) | |
799 { | |
800 DcmElement* tmp = dataset.remove(*it); | |
801 if (tmp != NULL) | |
802 { | |
803 delete tmp; | |
804 } | |
805 } | |
806 } | |
807 | |
808 | |
809 | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
810 |
790 | 811 void ParsedDicomFile::Insert(const DicomTag& tag, |
812 const std::string& value) | |
813 { | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
814 OFCondition cond; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
815 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
816 if (FromDcmtkBridge::IsPrivateTag(tag)) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
817 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
818 // This is a private tag |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
819 // http://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_addprivatedata |
790 | 820 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
821 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
|
822 cond = pimpl_->file_->getDataset()->putAndInsertUint8Array |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
823 (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
|
824 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
825 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
826 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
827 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
|
828 FillElementWithString(*element, tag, value); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
829 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
830 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
|
831 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
832 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
833 if (!cond.good()) |
790 | 834 { |
835 // This field already exists | |
836 throw OrthancException(ErrorCode_InternalError); | |
837 } | |
838 } | |
839 | |
840 | |
841 void ParsedDicomFile::Replace(const DicomTag& tag, | |
842 const std::string& value, | |
843 DicomReplaceMode mode) | |
844 { | |
845 DcmTagKey key(tag.GetGroup(), tag.GetElement()); | |
846 DcmElement* element = NULL; | |
847 | |
794 | 848 if (!pimpl_->file_->getDataset()->findAndGetElement(key, element).good() || |
790 | 849 element == NULL) |
850 { | |
851 // This field does not exist, act wrt. the specified "mode" | |
852 switch (mode) | |
853 { | |
854 case DicomReplaceMode_InsertIfAbsent: | |
855 Insert(tag, value); | |
856 break; | |
857 | |
858 case DicomReplaceMode_ThrowIfAbsent: | |
859 throw OrthancException(ErrorCode_InexistentItem); | |
860 | |
861 case DicomReplaceMode_IgnoreIfAbsent: | |
862 return; | |
863 } | |
864 } | |
865 else | |
866 { | |
1307
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 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
|
870 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
871 throw OrthancException(ErrorCode_InternalError); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
872 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
873 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
874 else |
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 FillElementWithString(*element, tag, value); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
877 } |
790 | 878 } |
879 | |
880 | |
881 /** | |
882 * dcmodify will automatically correct 'Media Storage SOP Class | |
883 * UID' and 'Media Storage SOP Instance UID' in the metaheader, if | |
884 * you make changes to the related tags in the dataset ('SOP Class | |
885 * UID' and 'SOP Instance UID') via insert or modify mode | |
886 * options. You can disable this behaviour by using the -nmu | |
887 * option. | |
888 **/ | |
889 | |
890 if (tag == DICOM_TAG_SOP_CLASS_UID) | |
891 { | |
892 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_CLASS_UID, value, DicomReplaceMode_InsertIfAbsent); | |
893 } | |
894 | |
895 if (tag == DICOM_TAG_SOP_INSTANCE_UID) | |
896 { | |
897 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, value, DicomReplaceMode_InsertIfAbsent); | |
898 } | |
899 } | |
900 | |
901 | |
902 void ParsedDicomFile::Answer(RestApiOutput& output) | |
903 { | |
904 std::string serialized; | |
1004
a226e0959d8b
DicomInstanceToStore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
905 if (FromDcmtkBridge::SaveToMemoryBuffer(serialized, *pimpl_->file_->getDataset())) |
790 | 906 { |
907 output.AnswerBuffer(serialized, CONTENT_TYPE_OCTET_STREAM); | |
908 } | |
909 } | |
910 | |
911 | |
912 | |
913 bool ParsedDicomFile::GetTagValue(std::string& value, | |
914 const DicomTag& tag) | |
915 { | |
916 DcmTagKey k(tag.GetGroup(), tag.GetElement()); | |
794 | 917 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
|
918 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
919 if (FromDcmtkBridge::IsPrivateTag(tag)) |
790 | 920 { |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
921 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
|
922 long unsigned int count = 0; |
790 | 923 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
924 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
|
925 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
926 if (count > 0) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
927 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
928 assert(data != NULL); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
929 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
|
930 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
931 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
932 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
933 value.clear(); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
934 } |
790 | 935 |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
936 return true; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
937 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
938 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
939 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
940 return false; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
941 } |
790 | 942 } |
943 else | |
944 { | |
1307
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
945 DcmElement* element = NULL; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
946 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
|
947 element == NULL) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
948 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
949 return false; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
950 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
951 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
952 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
953 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
954 if (v.get() == NULL) |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
955 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
956 value = ""; |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
957 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
958 else |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
959 { |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
960 value = v->AsString(); |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
961 } |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
962 |
f796207e3df1
Fix replacement and insertion of private DICOM tags
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
963 return true; |
790 | 964 } |
965 } | |
966 | |
967 | |
968 DicomInstanceHasher ParsedDicomFile::GetHasher() | |
969 { | |
970 std::string patientId, studyUid, seriesUid, instanceUid; | |
971 | |
972 if (!GetTagValue(patientId, DICOM_TAG_PATIENT_ID) || | |
973 !GetTagValue(studyUid, DICOM_TAG_STUDY_INSTANCE_UID) || | |
974 !GetTagValue(seriesUid, DICOM_TAG_SERIES_INSTANCE_UID) || | |
975 !GetTagValue(instanceUid, DICOM_TAG_SOP_INSTANCE_UID)) | |
976 { | |
977 throw OrthancException(ErrorCode_BadFileFormat); | |
978 } | |
979 | |
980 return DicomInstanceHasher(patientId, studyUid, seriesUid, instanceUid); | |
981 } | |
982 | |
983 | |
984 template <typename T> | |
985 static void ExtractPngImageTruncate(std::string& result, | |
986 DicomIntegerPixelAccessor& accessor, | |
987 PixelFormat format) | |
988 { | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
989 assert(accessor.GetInformation().GetChannelCount() == 1); |
790 | 990 |
991 PngWriter w; | |
992 | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
993 std::vector<T> image(accessor.GetInformation().GetWidth() * accessor.GetInformation().GetHeight(), 0); |
790 | 994 T* pixel = &image[0]; |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
995 for (unsigned int y = 0; y < accessor.GetInformation().GetHeight(); y++) |
790 | 996 { |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
997 for (unsigned int x = 0; x < accessor.GetInformation().GetWidth(); x++, pixel++) |
790 | 998 { |
999 int32_t v = accessor.GetValue(x, y); | |
1000 if (v < static_cast<int32_t>(std::numeric_limits<T>::min())) | |
1001 *pixel = std::numeric_limits<T>::min(); | |
1002 else if (v > static_cast<int32_t>(std::numeric_limits<T>::max())) | |
1003 *pixel = std::numeric_limits<T>::max(); | |
1004 else | |
1005 *pixel = static_cast<T>(v); | |
1006 } | |
1007 } | |
1008 | |
853
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1009 w.WriteToMemory(result, accessor.GetInformation().GetWidth(), accessor.GetInformation().GetHeight(), |
839be3022203
DicomImageInformation
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
1010 accessor.GetInformation().GetWidth() * sizeof(T), format, &image[0]); |
790 | 1011 } |
1012 | |
1013 | |
1014 void ParsedDicomFile::SaveToMemoryBuffer(std::string& buffer) | |
1015 { | |
1004
a226e0959d8b
DicomInstanceToStore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
1016 FromDcmtkBridge::SaveToMemoryBuffer(buffer, *pimpl_->file_->getDataset()); |
790 | 1017 } |
1018 | |
1019 | |
1020 void ParsedDicomFile::SaveToFile(const std::string& path) | |
1021 { | |
1022 // TODO Avoid using a temporary memory buffer, write directly on disk | |
1023 std::string content; | |
1024 SaveToMemoryBuffer(content); | |
1025 Toolbox::WriteFile(content, path); | |
1026 } | |
1027 | |
1028 | |
794 | 1029 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl) |
790 | 1030 { |
794 | 1031 pimpl_->file_.reset(new DcmFileFormat); |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1032 pimpl_->encoding_ = Encoding_Ascii; |
790 | 1033 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient)); |
1034 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)); | |
1035 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series)); | |
1036 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); | |
1037 } | |
1038 | |
791 | 1039 |
794 | 1040 ParsedDicomFile::ParsedDicomFile(const char* content, size_t size) : pimpl_(new PImpl) |
791 | 1041 { |
1042 Setup(content, size); | |
1043 } | |
1044 | |
794 | 1045 ParsedDicomFile::ParsedDicomFile(const std::string& content) : pimpl_(new PImpl) |
791 | 1046 { |
1047 if (content.size() == 0) | |
1048 { | |
1049 Setup(NULL, 0); | |
1050 } | |
1051 else | |
1052 { | |
1053 Setup(&content[0], content.size()); | |
1054 } | |
1055 } | |
792 | 1056 |
1057 | |
794 | 1058 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) : |
1059 pimpl_(new PImpl) | |
792 | 1060 { |
794 | 1061 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone())); |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1062 |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1063 pimpl_->encoding_ = other.pimpl_->encoding_; |
792 | 1064 } |
1065 | |
1066 | |
1067 ParsedDicomFile::~ParsedDicomFile() | |
1068 { | |
794 | 1069 delete pimpl_; |
792 | 1070 } |
1071 | |
793 | 1072 |
1073 void* ParsedDicomFile::GetDcmtkObject() | |
1074 { | |
794 | 1075 return pimpl_->file_.get(); |
793 | 1076 } |
1077 | |
1078 | |
1079 ParsedDicomFile* ParsedDicomFile::Clone() | |
1080 { | |
794 | 1081 return new ParsedDicomFile(*this); |
793 | 1082 } |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1083 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1084 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1085 void ParsedDicomFile::EmbedImage(const std::string& dataUriScheme) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1086 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1087 std::string mime, content; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1088 Toolbox::DecodeDataUriScheme(mime, content, dataUriScheme); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1089 |
809
8ce2f69436ca
do not return strings with base64
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
800
diff
changeset
|
1090 std::string decoded; |
8ce2f69436ca
do not return strings with base64
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
800
diff
changeset
|
1091 Toolbox::DecodeBase64(decoded, content); |
800
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1092 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1093 if (mime == "image/png") |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1094 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1095 PngReader reader; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1096 reader.ReadFromMemory(decoded); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1097 EmbedImage(reader); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1098 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1099 else |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1100 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1101 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1102 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1103 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1104 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1105 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1106 void ParsedDicomFile::EmbedImage(const ImageAccessor& accessor) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1107 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1108 if (accessor.GetFormat() != PixelFormat_Grayscale8 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1109 accessor.GetFormat() != PixelFormat_Grayscale16 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1110 accessor.GetFormat() != PixelFormat_RGB24 && |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1111 accessor.GetFormat() != PixelFormat_RGBA32) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1112 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1113 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1114 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1115 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1116 if (accessor.GetFormat() == PixelFormat_RGBA32) |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1117 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1118 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
|
1119 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1120 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1121 // 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
|
1122 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1123 Remove(DICOM_TAG_PIXEL_DATA); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1124 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
|
1125 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
|
1126 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
|
1127 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
|
1128 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
|
1129 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
|
1130 Replace(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "MONOCHROME2"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1131 Replace(DICOM_TAG_BITS_ALLOCATED, "8"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1132 Replace(DICOM_TAG_BITS_STORED, "8"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1133 Replace(DICOM_TAG_HIGH_BIT, "7"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1134 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1135 unsigned int bytesPerPixel = 1; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1136 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1137 switch (accessor.GetFormat()) |
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 case PixelFormat_RGB24: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1140 case PixelFormat_RGBA32: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1141 Replace(DICOM_TAG_PHOTOMETRIC_INTERPRETATION, "RGB"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1142 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
|
1143 bytesPerPixel = 3; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1144 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1145 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1146 case PixelFormat_Grayscale8: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1147 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1148 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1149 case PixelFormat_Grayscale16: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1150 Replace(DICOM_TAG_BITS_ALLOCATED, "16"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1151 Replace(DICOM_TAG_BITS_STORED, "16"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1152 Replace(DICOM_TAG_HIGH_BIT, "15"); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1153 bytesPerPixel = 2; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1154 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1155 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1156 default: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1157 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1158 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1159 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1160 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
|
1161 DICOM_TAG_PIXEL_DATA.GetElement()); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1162 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1163 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
|
1164 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1165 unsigned int pitch = accessor.GetWidth() * bytesPerPixel; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1166 Uint8* target = NULL; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1167 pixels->createUint8Array(accessor.GetHeight() * pitch, target); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1168 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1169 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
|
1170 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1171 switch (accessor.GetFormat()) |
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 case PixelFormat_RGB24: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1174 case PixelFormat_Grayscale8: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1175 case PixelFormat_Grayscale16: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1176 case PixelFormat_SignedGrayscale16: |
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 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
|
1179 target += pitch; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1180 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1181 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1182 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1183 case 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 // 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
|
1186 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
|
1187 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
|
1188 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1189 target[0] = source[0]; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1190 target[1] = source[1]; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1191 target[2] = source[2]; |
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 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1194 break; |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1195 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1196 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1197 default: |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1198 throw OrthancException(ErrorCode_NotImplemented); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1199 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1200 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1201 |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1202 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
|
1203 { |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1204 throw OrthancException(ErrorCode_InternalError); |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1205 } |
ecedd89055db
generation of DICOM images from PNG files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
799
diff
changeset
|
1206 } |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1207 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1208 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1209 void ParsedDicomFile::ExtractImage(ImageBuffer& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1210 unsigned int frame) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1211 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1212 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1213 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1214 if (!DicomImageDecoder::Decode(result, dataset, frame)) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1215 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1216 throw OrthancException(ErrorCode_BadFileFormat); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1217 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1218 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1219 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1220 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1221 void ParsedDicomFile::ExtractImage(ImageBuffer& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1222 unsigned int frame, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1223 ImageExtractionMode mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1224 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1225 DcmDataset& dataset = *pimpl_->file_->getDataset(); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1226 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1227 bool ok = false; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1228 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1229 switch (mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1230 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1231 case ImageExtractionMode_UInt8: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1232 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_Grayscale8, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1233 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1234 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1235 case ImageExtractionMode_UInt16: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1236 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_Grayscale16, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1237 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1238 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1239 case ImageExtractionMode_Int16: |
1015
f009f7c75069
fix integration tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
992
diff
changeset
|
1240 ok = DicomImageDecoder::DecodeAndTruncate(result, dataset, frame, PixelFormat_SignedGrayscale16, false); |
874
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1241 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1242 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1243 case ImageExtractionMode_Preview: |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1244 ok = DicomImageDecoder::DecodePreview(result, dataset, frame); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1245 break; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1246 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1247 default: |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1248 throw OrthancException(ErrorCode_ParameterOutOfRange); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1249 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1250 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1251 if (!ok) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1252 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1253 throw OrthancException(ErrorCode_BadFileFormat); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1254 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1255 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1256 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1257 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1258 void ParsedDicomFile::ExtractPngImage(std::string& result, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1259 unsigned int frame, |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1260 ImageExtractionMode mode) |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1261 { |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1262 ImageBuffer buffer; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1263 ExtractImage(buffer, frame, mode); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1264 |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1265 ImageAccessor accessor(buffer.GetConstAccessor()); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1266 PngWriter writer; |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1267 writer.WriteToMemory(result, accessor); |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1268 } |
87791ebc1f50
download matlab images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
853
diff
changeset
|
1269 |
956
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1270 |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1271 Encoding ParsedDicomFile::GetEncoding() const |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1272 { |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1273 return pimpl_->encoding_; |
2fd5a163776d
primitives for proper encoding handling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
874
diff
changeset
|
1274 } |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1275 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1276 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1277 void ParsedDicomFile::SetEncoding(Encoding encoding) |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1278 { |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1279 std::string s; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1280 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1281 // http://www.dabsoft.ch/dicom/3/C.12.1.1.2/ |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1282 switch (encoding) |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1283 { |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1284 case Encoding_Utf8: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1285 case Encoding_Ascii: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1286 s = "ISO_IR 192"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1287 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1288 |
1347 | 1289 case Encoding_Windows1251: |
1290 // This Cyrillic codepage is not officially supported by the | |
1291 // DICOM standard. Do not set the SpecificCharacterSet tag. | |
1292 return; | |
1293 | |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1294 case Encoding_Latin1: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1295 s = "ISO_IR 100"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1296 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1297 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1298 case Encoding_Latin2: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1299 s = "ISO_IR 101"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1300 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1301 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1302 case Encoding_Latin3: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1303 s = "ISO_IR 109"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1304 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1305 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1306 case Encoding_Latin4: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1307 s = "ISO_IR 110"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1308 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1309 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1310 case Encoding_Latin5: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1311 s = "ISO_IR 148"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1312 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1313 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1314 case Encoding_Cyrillic: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1315 s = "ISO_IR 144"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1316 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1317 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1318 case Encoding_Arabic: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1319 s = "ISO_IR 127"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1320 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1321 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1322 case Encoding_Greek: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1323 s = "ISO_IR 126"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1324 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1325 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1326 case Encoding_Hebrew: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1327 s = "ISO_IR 138"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1328 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1329 |
1091 | 1330 case Encoding_Japanese: |
1331 s = "ISO_IR 13"; | |
1332 break; | |
1333 | |
1334 case Encoding_Chinese: | |
1335 s = "GB18030"; | |
1336 break; | |
1090
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1337 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1338 case Encoding_Thai: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1339 s = "ISO_IR 166"; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1340 break; |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1341 |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1342 default: |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1343 throw OrthancException(ErrorCode_ParameterOutOfRange); |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1344 } |
e494ceb8d763
support more encodings
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1018
diff
changeset
|
1345 |
1091 | 1346 Replace(DICOM_TAG_SPECIFIC_CHARACTER_SET, s, DicomReplaceMode_InsertIfAbsent); |
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 |
1160
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1349 void ParsedDicomFile::ToJson(Json::Value& target, bool simplify) |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1350 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1351 if (simplify) |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1352 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1353 Json::Value tmp; |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1354 FromDcmtkBridge::ToJson(tmp, *pimpl_->file_->getDataset()); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1355 SimplifyTags(target, tmp); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1356 } |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1357 else |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1358 { |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1359 FromDcmtkBridge::ToJson(target, *pimpl_->file_->getDataset()); |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1360 } |
80671157d051
generalization of create-dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1113
diff
changeset
|
1361 } |
790 | 1362 } |