comparison Core/DicomNetworking/DicomStoreUserConnection.cpp @ 3880:cdd0cb5ec4e4 transcoding

DicomStoreUserConnection::LookupTranscoding()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 04 May 2020 22:10:55 +0200
parents a18b34dec94a
children f23ab7829a8d
comparison
equal deleted inserted replaced
3879:a18b34dec94a 3880:cdd0cb5ec4e4
82 { 82 {
83 for (std::set<DicomTransferSyntax>::const_iterator 83 for (std::set<DicomTransferSyntax>::const_iterator
84 it = syntaxes.begin(); it != syntaxes.end(); ++it) 84 it = syntaxes.begin(); it != syntaxes.end(); ++it)
85 { 85 {
86 association_->ProposePresentationContext(sopClassUid, *it); 86 association_->ProposePresentationContext(sopClassUid, *it);
87 proposedOriginalClasses_.insert(std::make_pair(sopClassUid, *it));
87 } 88 }
88 89
89 if (addLittleEndianImplicit) 90 if (addLittleEndianImplicit)
90 { 91 {
91 std::set<DicomTransferSyntax> uncompressed; 92 association_->ProposePresentationContext(sopClassUid, DicomTransferSyntax_LittleEndianImplicit);
92 uncompressed.insert(DicomTransferSyntax_LittleEndianImplicit); 93 proposedOriginalClasses_.insert(std::make_pair(sopClassUid, DicomTransferSyntax_LittleEndianImplicit));
93 association_->ProposePresentationContext(sopClassUid, uncompressed);
94 } 94 }
95 95
96 if (addLittleEndianExplicit || 96 if (addLittleEndianExplicit ||
97 addBigEndianExplicit) 97 addBigEndianExplicit)
98 { 98 {
107 { 107 {
108 uncompressed.insert(DicomTransferSyntax_BigEndianExplicit); 108 uncompressed.insert(DicomTransferSyntax_BigEndianExplicit);
109 } 109 }
110 110
111 association_->ProposePresentationContext(sopClassUid, uncompressed); 111 association_->ProposePresentationContext(sopClassUid, uncompressed);
112
113 assert(!uncompressed.empty());
114 if (addLittleEndianExplicit ^ addBigEndianExplicit)
115 {
116 // Only one transfer syntax was proposed for this presentation context
117 assert(uncompressed.size() == 1);
118 proposedOriginalClasses_.insert(std::make_pair(sopClassUid, *uncompressed.begin()));
119 }
112 } 120 }
113 121
114 return true; 122 return true;
115 } 123 }
116 } 124 }
199 const std::string& sopClassUid, 207 const std::string& sopClassUid,
200 DicomTransferSyntax transferSyntax) 208 DicomTransferSyntax transferSyntax)
201 { 209 {
202 /** 210 /**
203 * Step 1: Check whether this presentation context is already 211 * Step 1: Check whether this presentation context is already
204 * available in the previously negociated assocation. 212 * available in the previously negotiated assocation.
205 **/ 213 **/
206 214
207 if (LookupPresentationContext(presentationContextId, sopClassUid, transferSyntax)) 215 if (LookupPresentationContext(presentationContextId, sopClassUid, transferSyntax))
208 { 216 {
209 return true; 217 return true;
210 } 218 }
211 219
212 // The association must be re-negotiated 220 // The association must be re-negotiated
213 if (association_->IsOpen()) 221 if (association_->IsOpen())
214 { 222 {
215 LOG(INFO) << "Re-negociating DICOM association with " 223 LOG(INFO) << "Re-negotiating DICOM association with "
216 << parameters_.GetRemoteModality().GetApplicationEntityTitle(); 224 << parameters_.GetRemoteModality().GetApplicationEntityTitle();
217 } 225
218 226 if (proposedOriginalClasses_.find(std::make_pair(sopClassUid, transferSyntax)) !=
227 proposedOriginalClasses_.end())
228 {
229 LOG(INFO) << "The remote modality has already rejected SOP class UID \""
230 << sopClassUid << "\" with transfer syntax \""
231 << GetTransferSyntaxUid(transferSyntax) << "\", don't renegotiate";
232 return false;
233 }
234 }
235
219 association_->ClearPresentationContexts(); 236 association_->ClearPresentationContexts();
237 proposedOriginalClasses_.clear();
220 RegisterStorageClass(sopClassUid, transferSyntax); // (*) 238 RegisterStorageClass(sopClassUid, transferSyntax); // (*)
221 239
222 240
223 /** 241 /**
224 * Step 2: Propose at least the mandatory SOP class. 242 * Step 2: Propose at least the mandatory SOP class.
302 const std::string& moveOriginatorAET, 320 const std::string& moveOriginatorAET,
303 uint16_t moveOriginatorID) 321 uint16_t moveOriginatorID)
304 { 322 {
305 DicomTransferSyntax transferSyntax; 323 DicomTransferSyntax transferSyntax;
306 LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dataset); 324 LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dataset);
307 325
308 uint8_t presID; 326 uint8_t presID;
309 if (!NegotiatePresentationContext(presID, sopClassUid, transferSyntax)) 327 if (!NegotiatePresentationContext(presID, sopClassUid, transferSyntax))
310 { 328 {
311 throw OrthancException(ErrorCode_NetworkProtocol, 329 throw OrthancException(ErrorCode_NetworkProtocol,
312 "No valid presentation context was negotiated for " 330 "No valid presentation context was negotiated for "
388 } 406 }
389 407
390 StoreInternal(sopClassUid, sopInstanceUid, *dicom->getDataset(), 408 StoreInternal(sopClassUid, sopInstanceUid, *dicom->getDataset(),
391 moveOriginatorAET, moveOriginatorID); 409 moveOriginatorAET, moveOriginatorID);
392 } 410 }
411
412
413 bool DicomStoreUserConnection::LookupTranscoding(std::set<DicomTransferSyntax>& acceptedSyntaxes,
414 const std::string& sopClassUid,
415 DicomTransferSyntax sourceSyntax)
416 {
417 acceptedSyntaxes.clear();
418
419 // Make sure a negotiation has already occurred for this transfer
420 // syntax. We don't use the return code: Transcoding is possible
421 // even if the "sourceSyntax" is not supported.
422 uint8_t presID;
423 NegotiatePresentationContext(presID, sopClassUid, sourceSyntax);
424
425 std::map<DicomTransferSyntax, uint8_t> contexts;
426 if (association_->LookupAcceptedPresentationContext(contexts, sopClassUid))
427 {
428 for (std::map<DicomTransferSyntax, uint8_t>::const_iterator
429 it = contexts.begin(); it != contexts.end(); ++it)
430 {
431 acceptedSyntaxes.insert(it->first);
432 }
433
434 return true;
435 }
436 else
437 {
438 return false;
439 }
440 }
393 } 441 }