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