Mercurial > hg > orthanc
comparison Core/DicomParsing/IDicomTranscoder.cpp @ 3946:1f33ed7f82e6 transcoding
automatic test of transcoding
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 19 May 2020 13:44:56 +0200 |
parents | 0b3256c3ee14 |
children | 5fe8c6d3212e |
comparison
equal
deleted
inserted
replaced
3945:0b3256c3ee14 | 3946:1f33ed7f82e6 |
---|---|
37 #include "../OrthancException.h" | 37 #include "../OrthancException.h" |
38 #include "FromDcmtkBridge.h" | 38 #include "FromDcmtkBridge.h" |
39 #include "ParsedDicomFile.h" | 39 #include "ParsedDicomFile.h" |
40 | 40 |
41 #include <dcmtk/dcmdata/dcfilefo.h> | 41 #include <dcmtk/dcmdata/dcfilefo.h> |
42 #include <dcmtk/dcmdata/dcdeftag.h> | |
42 | 43 |
43 namespace Orthanc | 44 namespace Orthanc |
44 { | 45 { |
46 IDicomTranscoder::TranscodingType IDicomTranscoder::GetTranscodingType(DicomTransferSyntax target, | |
47 DicomTransferSyntax source) | |
48 { | |
49 if (target == source) | |
50 { | |
51 return TranscodingType_Lossless; | |
52 } | |
53 else if (target == DicomTransferSyntax_LittleEndianImplicit || | |
54 target == DicomTransferSyntax_LittleEndianExplicit || | |
55 target == DicomTransferSyntax_BigEndianExplicit || | |
56 target == DicomTransferSyntax_DeflatedLittleEndianExplicit || | |
57 target == DicomTransferSyntax_JPEGProcess14 || | |
58 target == DicomTransferSyntax_JPEGProcess14SV1 || | |
59 target == DicomTransferSyntax_JPEGLSLossless || | |
60 target == DicomTransferSyntax_JPEG2000LosslessOnly || | |
61 target == DicomTransferSyntax_JPEG2000MulticomponentLosslessOnly) | |
62 { | |
63 return TranscodingType_Lossless; | |
64 } | |
65 else if (target == DicomTransferSyntax_JPEGProcess1 || | |
66 target == DicomTransferSyntax_JPEGProcess2_4 || | |
67 target == DicomTransferSyntax_JPEGLSLossy || | |
68 target == DicomTransferSyntax_JPEG2000 || | |
69 target == DicomTransferSyntax_JPEG2000Multicomponent) | |
70 { | |
71 return TranscodingType_Lossy; | |
72 } | |
73 else | |
74 { | |
75 return TranscodingType_Unknown; | |
76 } | |
77 } | |
78 | |
79 | |
80 std::string IDicomTranscoder::GetSopInstanceUid(DcmFileFormat& dicom) | |
81 { | |
82 if (dicom.getDataset() == NULL) | |
83 { | |
84 throw OrthancException(ErrorCode_InternalError); | |
85 } | |
86 | |
87 DcmDataset& dataset = *dicom.getDataset(); | |
88 | |
89 const char* v = NULL; | |
90 | |
91 if (dataset.findAndGetString(DCM_SOPInstanceUID, v).good() && | |
92 v != NULL) | |
93 { | |
94 return std::string(v); | |
95 } | |
96 else | |
97 { | |
98 throw OrthancException(ErrorCode_BadFileFormat, "File without SOP instance UID"); | |
99 } | |
100 } | |
101 | |
102 | |
103 void IDicomTranscoder::CheckTranscoding(IDicomTranscoder::DicomImage& transcoded, | |
104 bool hasSopInstanceUidChanged, | |
105 DicomTransferSyntax sourceSyntax, | |
106 const std::string& sourceSopInstanceUid, | |
107 const std::set<DicomTransferSyntax>& allowedSyntaxes, | |
108 bool allowNewSopInstanceUid) | |
109 { | |
110 DcmFileFormat& parsed = transcoded.GetParsed(); | |
111 | |
112 if (parsed.getDataset() == NULL) | |
113 { | |
114 throw OrthancException(ErrorCode_InternalError); | |
115 } | |
116 | |
117 std::string targetSopInstanceUid = GetSopInstanceUid(parsed); | |
118 | |
119 if (hasSopInstanceUidChanged && (targetSopInstanceUid == sourceSopInstanceUid)) | |
120 { | |
121 throw OrthancException(ErrorCode_InternalError); | |
122 } | |
123 | |
124 if (!hasSopInstanceUidChanged && (targetSopInstanceUid != sourceSopInstanceUid)) | |
125 { | |
126 throw OrthancException(ErrorCode_InternalError); | |
127 } | |
128 | |
129 if (parsed.getDataset()->tagExists(DCM_PixelData)) | |
130 { | |
131 if (!allowNewSopInstanceUid && (targetSopInstanceUid != sourceSopInstanceUid)) | |
132 { | |
133 throw OrthancException(ErrorCode_InternalError); | |
134 } | |
135 } | |
136 else | |
137 { | |
138 if (hasSopInstanceUidChanged || | |
139 targetSopInstanceUid != sourceSopInstanceUid) | |
140 { | |
141 throw OrthancException(ErrorCode_InternalError, | |
142 "No pixel data: Transcoding must not change the SOP instance UID"); | |
143 } | |
144 } | |
145 | |
146 DicomTransferSyntax targetSyntax; | |
147 if (!FromDcmtkBridge::LookupOrthancTransferSyntax(targetSyntax, parsed)) | |
148 { | |
149 return; // Unknown transfer syntax, cannot do further test | |
150 } | |
151 | |
152 if (allowedSyntaxes.find(sourceSyntax) != allowedSyntaxes.end()) | |
153 { | |
154 // No transcoding should have happened | |
155 if (targetSopInstanceUid != sourceSopInstanceUid || | |
156 hasSopInstanceUidChanged) | |
157 { | |
158 throw OrthancException(ErrorCode_InternalError); | |
159 } | |
160 } | |
161 | |
162 if (allowedSyntaxes.find(targetSyntax) == allowedSyntaxes.end()) | |
163 { | |
164 throw OrthancException(ErrorCode_InternalError, "An incorrect output transfer syntax was chosen"); | |
165 } | |
166 | |
167 if (parsed.getDataset()->tagExists(DCM_PixelData)) | |
168 { | |
169 switch (GetTranscodingType(targetSyntax, sourceSyntax)) | |
170 { | |
171 case TranscodingType_Lossy: | |
172 if (targetSopInstanceUid == sourceSopInstanceUid) | |
173 { | |
174 throw OrthancException(ErrorCode_InternalError); | |
175 } | |
176 break; | |
177 | |
178 case TranscodingType_Lossless: | |
179 if (targetSopInstanceUid != sourceSopInstanceUid) | |
180 { | |
181 throw OrthancException(ErrorCode_InternalError); | |
182 } | |
183 break; | |
184 | |
185 default: | |
186 break; | |
187 } | |
188 } | |
189 } | |
190 | |
191 | |
45 void IDicomTranscoder::DicomImage::Parse() | 192 void IDicomTranscoder::DicomImage::Parse() |
46 { | 193 { |
47 if (parsed_.get() != NULL) | 194 if (parsed_.get() != NULL) |
48 { | 195 { |
49 // Already parsed | 196 // Already parsed |