comparison OrthancFramework/Sources/Enumerations.cpp @ 4044:d25f4c0fa160 framework

splitting code into OrthancFramework and OrthancServer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 10 Jun 2020 20:30:34 +0200
parents Core/Enumerations.cpp@b3f09bc9734b
children 0327421506ad
comparison
equal deleted inserted replaced
4043:6c6239aec462 4044:d25f4c0fa160
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * In addition, as a special exception, the copyright holders of this
13 * program give permission to link the code of its release with the
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
15 * that use the same license as the "OpenSSL" library), and distribute
16 * the linked executables. You must obey the GNU General Public License
17 * in all respects for all of the code used other than "OpenSSL". If you
18 * modify file(s) with this exception, you may extend this exception to
19 * your version of the file(s), but you are not obligated to do so. If
20 * you do not wish to do so, delete this exception statement from your
21 * version. If you delete this exception statement from all source files
22 * in the program, then also delete it here.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 **/
32
33
34 #include "PrecompiledHeaders.h"
35 #include "Enumerations.h"
36
37 #include "OrthancException.h"
38 #include "Toolbox.h"
39 #include "Logging.h"
40
41 #include <boost/thread/mutex.hpp>
42 #include <string.h>
43 #include <cassert>
44
45 namespace Orthanc
46 {
47 static const char* const MIME_CSS = "text/css";
48 static const char* const MIME_DICOM = "application/dicom";
49 static const char* const MIME_GIF = "image/gif";
50 static const char* const MIME_GZIP = "application/gzip";
51 static const char* const MIME_HTML = "text/html";
52 static const char* const MIME_JAVASCRIPT = "application/javascript";
53 static const char* const MIME_JPEG2000 = "image/jp2";
54 static const char* const MIME_NACL = "application/x-nacl";
55 static const char* const MIME_PLAIN_TEXT = "text/plain";
56 static const char* const MIME_PNACL = "application/x-pnacl";
57 static const char* const MIME_SVG = "image/svg+xml";
58 static const char* const MIME_WEB_ASSEMBLY = "application/wasm";
59 static const char* const MIME_WOFF = "application/x-font-woff";
60 static const char* const MIME_WOFF2 = "font/woff2";
61 static const char* const MIME_XML_2 = "text/xml";
62 static const char* const MIME_ZIP = "application/zip";
63 static const char* const MIME_DICOM_WEB_JSON = "application/dicom+json";
64 static const char* const MIME_DICOM_WEB_XML = "application/dicom+xml";
65
66 // This function is autogenerated by the script
67 // "Resources/GenerateErrorCodes.py"
68 const char* EnumerationToString(ErrorCode error)
69 {
70 switch (error)
71 {
72 case ErrorCode_InternalError:
73 return "Internal error";
74
75 case ErrorCode_Success:
76 return "Success";
77
78 case ErrorCode_Plugin:
79 return "Error encountered within the plugin engine";
80
81 case ErrorCode_NotImplemented:
82 return "Not implemented yet";
83
84 case ErrorCode_ParameterOutOfRange:
85 return "Parameter out of range";
86
87 case ErrorCode_NotEnoughMemory:
88 return "The server hosting Orthanc is running out of memory";
89
90 case ErrorCode_BadParameterType:
91 return "Bad type for a parameter";
92
93 case ErrorCode_BadSequenceOfCalls:
94 return "Bad sequence of calls";
95
96 case ErrorCode_InexistentItem:
97 return "Accessing an inexistent item";
98
99 case ErrorCode_BadRequest:
100 return "Bad request";
101
102 case ErrorCode_NetworkProtocol:
103 return "Error in the network protocol";
104
105 case ErrorCode_SystemCommand:
106 return "Error while calling a system command";
107
108 case ErrorCode_Database:
109 return "Error with the database engine";
110
111 case ErrorCode_UriSyntax:
112 return "Badly formatted URI";
113
114 case ErrorCode_InexistentFile:
115 return "Inexistent file";
116
117 case ErrorCode_CannotWriteFile:
118 return "Cannot write to file";
119
120 case ErrorCode_BadFileFormat:
121 return "Bad file format";
122
123 case ErrorCode_Timeout:
124 return "Timeout";
125
126 case ErrorCode_UnknownResource:
127 return "Unknown resource";
128
129 case ErrorCode_IncompatibleDatabaseVersion:
130 return "Incompatible version of the database";
131
132 case ErrorCode_FullStorage:
133 return "The file storage is full";
134
135 case ErrorCode_CorruptedFile:
136 return "Corrupted file (e.g. inconsistent MD5 hash)";
137
138 case ErrorCode_InexistentTag:
139 return "Inexistent tag";
140
141 case ErrorCode_ReadOnly:
142 return "Cannot modify a read-only data structure";
143
144 case ErrorCode_IncompatibleImageFormat:
145 return "Incompatible format of the images";
146
147 case ErrorCode_IncompatibleImageSize:
148 return "Incompatible size of the images";
149
150 case ErrorCode_SharedLibrary:
151 return "Error while using a shared library (plugin)";
152
153 case ErrorCode_UnknownPluginService:
154 return "Plugin invoking an unknown service";
155
156 case ErrorCode_UnknownDicomTag:
157 return "Unknown DICOM tag";
158
159 case ErrorCode_BadJson:
160 return "Cannot parse a JSON document";
161
162 case ErrorCode_Unauthorized:
163 return "Bad credentials were provided to an HTTP request";
164
165 case ErrorCode_BadFont:
166 return "Badly formatted font file";
167
168 case ErrorCode_DatabasePlugin:
169 return "The plugin implementing a custom database back-end does not fulfill the proper interface";
170
171 case ErrorCode_StorageAreaPlugin:
172 return "Error in the plugin implementing a custom storage area";
173
174 case ErrorCode_EmptyRequest:
175 return "The request is empty";
176
177 case ErrorCode_NotAcceptable:
178 return "Cannot send a response which is acceptable according to the Accept HTTP header";
179
180 case ErrorCode_NullPointer:
181 return "Cannot handle a NULL pointer";
182
183 case ErrorCode_DatabaseUnavailable:
184 return "The database is currently not available (probably a transient situation)";
185
186 case ErrorCode_CanceledJob:
187 return "This job was canceled";
188
189 case ErrorCode_BadGeometry:
190 return "Geometry error encountered in Stone";
191
192 case ErrorCode_SslInitialization:
193 return "Cannot initialize SSL encryption, check out your certificates";
194
195 case ErrorCode_SQLiteNotOpened:
196 return "SQLite: The database is not opened";
197
198 case ErrorCode_SQLiteAlreadyOpened:
199 return "SQLite: Connection is already open";
200
201 case ErrorCode_SQLiteCannotOpen:
202 return "SQLite: Unable to open the database";
203
204 case ErrorCode_SQLiteStatementAlreadyUsed:
205 return "SQLite: This cached statement is already being referred to";
206
207 case ErrorCode_SQLiteExecute:
208 return "SQLite: Cannot execute a command";
209
210 case ErrorCode_SQLiteRollbackWithoutTransaction:
211 return "SQLite: Rolling back a nonexistent transaction (have you called Begin()?)";
212
213 case ErrorCode_SQLiteCommitWithoutTransaction:
214 return "SQLite: Committing a nonexistent transaction";
215
216 case ErrorCode_SQLiteRegisterFunction:
217 return "SQLite: Unable to register a function";
218
219 case ErrorCode_SQLiteFlush:
220 return "SQLite: Unable to flush the database";
221
222 case ErrorCode_SQLiteCannotRun:
223 return "SQLite: Cannot run a cached statement";
224
225 case ErrorCode_SQLiteCannotStep:
226 return "SQLite: Cannot step over a cached statement";
227
228 case ErrorCode_SQLiteBindOutOfRange:
229 return "SQLite: Bing a value while out of range (serious error)";
230
231 case ErrorCode_SQLitePrepareStatement:
232 return "SQLite: Cannot prepare a cached statement";
233
234 case ErrorCode_SQLiteTransactionAlreadyStarted:
235 return "SQLite: Beginning the same transaction twice";
236
237 case ErrorCode_SQLiteTransactionCommit:
238 return "SQLite: Failure when committing the transaction";
239
240 case ErrorCode_SQLiteTransactionBegin:
241 return "SQLite: Cannot start a transaction";
242
243 case ErrorCode_DirectoryOverFile:
244 return "The directory to be created is already occupied by a regular file";
245
246 case ErrorCode_FileStorageCannotWrite:
247 return "Unable to create a subdirectory or a file in the file storage";
248
249 case ErrorCode_DirectoryExpected:
250 return "The specified path does not point to a directory";
251
252 case ErrorCode_HttpPortInUse:
253 return "The TCP port of the HTTP server is privileged or already in use";
254
255 case ErrorCode_DicomPortInUse:
256 return "The TCP port of the DICOM server is privileged or already in use";
257
258 case ErrorCode_BadHttpStatusInRest:
259 return "This HTTP status is not allowed in a REST API";
260
261 case ErrorCode_RegularFileExpected:
262 return "The specified path does not point to a regular file";
263
264 case ErrorCode_PathToExecutable:
265 return "Unable to get the path to the executable";
266
267 case ErrorCode_MakeDirectory:
268 return "Cannot create a directory";
269
270 case ErrorCode_BadApplicationEntityTitle:
271 return "An application entity title (AET) cannot be empty or be longer than 16 characters";
272
273 case ErrorCode_NoCFindHandler:
274 return "No request handler factory for DICOM C-FIND SCP";
275
276 case ErrorCode_NoCMoveHandler:
277 return "No request handler factory for DICOM C-MOVE SCP";
278
279 case ErrorCode_NoCStoreHandler:
280 return "No request handler factory for DICOM C-STORE SCP";
281
282 case ErrorCode_NoApplicationEntityFilter:
283 return "No application entity filter";
284
285 case ErrorCode_NoSopClassOrInstance:
286 return "DicomUserConnection: Unable to find the SOP class and instance";
287
288 case ErrorCode_NoPresentationContext:
289 return "DicomUserConnection: No acceptable presentation context for modality";
290
291 case ErrorCode_DicomFindUnavailable:
292 return "DicomUserConnection: The C-FIND command is not supported by the remote SCP";
293
294 case ErrorCode_DicomMoveUnavailable:
295 return "DicomUserConnection: The C-MOVE command is not supported by the remote SCP";
296
297 case ErrorCode_CannotStoreInstance:
298 return "Cannot store an instance";
299
300 case ErrorCode_CreateDicomNotString:
301 return "Only string values are supported when creating DICOM instances";
302
303 case ErrorCode_CreateDicomOverrideTag:
304 return "Trying to override a value inherited from a parent module";
305
306 case ErrorCode_CreateDicomUseContent:
307 return "Use \"Content\" to inject an image into a new DICOM instance";
308
309 case ErrorCode_CreateDicomNoPayload:
310 return "No payload is present for one instance in the series";
311
312 case ErrorCode_CreateDicomUseDataUriScheme:
313 return "The payload of the DICOM instance must be specified according to Data URI scheme";
314
315 case ErrorCode_CreateDicomBadParent:
316 return "Trying to attach a new DICOM instance to an inexistent resource";
317
318 case ErrorCode_CreateDicomParentIsInstance:
319 return "Trying to attach a new DICOM instance to an instance (must be a series, study or patient)";
320
321 case ErrorCode_CreateDicomParentEncoding:
322 return "Unable to get the encoding of the parent resource";
323
324 case ErrorCode_UnknownModality:
325 return "Unknown modality";
326
327 case ErrorCode_BadJobOrdering:
328 return "Bad ordering of filters in a job";
329
330 case ErrorCode_JsonToLuaTable:
331 return "Cannot convert the given JSON object to a Lua table";
332
333 case ErrorCode_CannotCreateLua:
334 return "Cannot create the Lua context";
335
336 case ErrorCode_CannotExecuteLua:
337 return "Cannot execute a Lua command";
338
339 case ErrorCode_LuaAlreadyExecuted:
340 return "Arguments cannot be pushed after the Lua function is executed";
341
342 case ErrorCode_LuaBadOutput:
343 return "The Lua function does not give the expected number of outputs";
344
345 case ErrorCode_NotLuaPredicate:
346 return "The Lua function is not a predicate (only true/false outputs allowed)";
347
348 case ErrorCode_LuaReturnsNoString:
349 return "The Lua function does not return a string";
350
351 case ErrorCode_StorageAreaAlreadyRegistered:
352 return "Another plugin has already registered a custom storage area";
353
354 case ErrorCode_DatabaseBackendAlreadyRegistered:
355 return "Another plugin has already registered a custom database back-end";
356
357 case ErrorCode_DatabaseNotInitialized:
358 return "Plugin trying to call the database during its initialization";
359
360 case ErrorCode_SslDisabled:
361 return "Orthanc has been built without SSL support";
362
363 case ErrorCode_CannotOrderSlices:
364 return "Unable to order the slices of the series";
365
366 case ErrorCode_NoWorklistHandler:
367 return "No request handler factory for DICOM C-Find Modality SCP";
368
369 case ErrorCode_AlreadyExistingTag:
370 return "Cannot override the value of a tag that already exists";
371
372 case ErrorCode_NoCGetHandler:
373 return "No request handler factory for DICOM C-GET SCP";
374
375 case ErrorCode_NoStorageCommitmentHandler:
376 return "No request handler factory for DICOM N-ACTION SCP (storage commitment)";
377
378 case ErrorCode_UnsupportedMediaType:
379 return "Unsupported media type";
380
381 default:
382 if (error >= ErrorCode_START_PLUGINS)
383 {
384 return "Error encountered within some plugin";
385 }
386 else
387 {
388 return "Unknown error code";
389 }
390 }
391 }
392
393
394 const char* EnumerationToString(HttpMethod method)
395 {
396 switch (method)
397 {
398 case HttpMethod_Get:
399 return "GET";
400
401 case HttpMethod_Post:
402 return "POST";
403
404 case HttpMethod_Delete:
405 return "DELETE";
406
407 case HttpMethod_Put:
408 return "PUT";
409
410 default:
411 return "?";
412 }
413 }
414
415
416 const char* EnumerationToString(HttpStatus status)
417 {
418 switch (status)
419 {
420 case HttpStatus_100_Continue:
421 return "Continue";
422
423 case HttpStatus_101_SwitchingProtocols:
424 return "Switching Protocols";
425
426 case HttpStatus_102_Processing:
427 return "Processing";
428
429 case HttpStatus_200_Ok:
430 return "OK";
431
432 case HttpStatus_201_Created:
433 return "Created";
434
435 case HttpStatus_202_Accepted:
436 return "Accepted";
437
438 case HttpStatus_203_NonAuthoritativeInformation:
439 return "Non-Authoritative Information";
440
441 case HttpStatus_204_NoContent:
442 return "No Content";
443
444 case HttpStatus_205_ResetContent:
445 return "Reset Content";
446
447 case HttpStatus_206_PartialContent:
448 return "Partial Content";
449
450 case HttpStatus_207_MultiStatus:
451 return "Multi-Status";
452
453 case HttpStatus_208_AlreadyReported:
454 return "Already Reported";
455
456 case HttpStatus_226_IMUsed:
457 return "IM Used";
458
459 case HttpStatus_300_MultipleChoices:
460 return "Multiple Choices";
461
462 case HttpStatus_301_MovedPermanently:
463 return "Moved Permanently";
464
465 case HttpStatus_302_Found:
466 return "Found";
467
468 case HttpStatus_303_SeeOther:
469 return "See Other";
470
471 case HttpStatus_304_NotModified:
472 return "Not Modified";
473
474 case HttpStatus_305_UseProxy:
475 return "Use Proxy";
476
477 case HttpStatus_307_TemporaryRedirect:
478 return "Temporary Redirect";
479
480 case HttpStatus_400_BadRequest:
481 return "Bad Request";
482
483 case HttpStatus_401_Unauthorized:
484 return "Unauthorized";
485
486 case HttpStatus_402_PaymentRequired:
487 return "Payment Required";
488
489 case HttpStatus_403_Forbidden:
490 return "Forbidden";
491
492 case HttpStatus_404_NotFound:
493 return "Not Found";
494
495 case HttpStatus_405_MethodNotAllowed:
496 return "Method Not Allowed";
497
498 case HttpStatus_406_NotAcceptable:
499 return "Not Acceptable";
500
501 case HttpStatus_407_ProxyAuthenticationRequired:
502 return "Proxy Authentication Required";
503
504 case HttpStatus_408_RequestTimeout:
505 return "Request Timeout";
506
507 case HttpStatus_409_Conflict:
508 return "Conflict";
509
510 case HttpStatus_410_Gone:
511 return "Gone";
512
513 case HttpStatus_411_LengthRequired:
514 return "Length Required";
515
516 case HttpStatus_412_PreconditionFailed:
517 return "Precondition Failed";
518
519 case HttpStatus_413_RequestEntityTooLarge:
520 return "Request Entity Too Large";
521
522 case HttpStatus_414_RequestUriTooLong:
523 return "Request-URI Too Long";
524
525 case HttpStatus_415_UnsupportedMediaType:
526 return "Unsupported Media Type";
527
528 case HttpStatus_416_RequestedRangeNotSatisfiable:
529 return "Requested Range Not Satisfiable";
530
531 case HttpStatus_417_ExpectationFailed:
532 return "Expectation Failed";
533
534 case HttpStatus_422_UnprocessableEntity:
535 return "Unprocessable Entity";
536
537 case HttpStatus_423_Locked:
538 return "Locked";
539
540 case HttpStatus_424_FailedDependency:
541 return "Failed Dependency";
542
543 case HttpStatus_426_UpgradeRequired:
544 return "Upgrade Required";
545
546 case HttpStatus_500_InternalServerError:
547 return "Internal Server Error";
548
549 case HttpStatus_501_NotImplemented:
550 return "Not Implemented";
551
552 case HttpStatus_502_BadGateway:
553 return "Bad Gateway";
554
555 case HttpStatus_503_ServiceUnavailable:
556 return "Service Unavailable";
557
558 case HttpStatus_504_GatewayTimeout:
559 return "Gateway Timeout";
560
561 case HttpStatus_505_HttpVersionNotSupported:
562 return "HTTP Version Not Supported";
563
564 case HttpStatus_506_VariantAlsoNegotiates:
565 return "Variant Also Negotiates";
566
567 case HttpStatus_507_InsufficientStorage:
568 return "Insufficient Storage";
569
570 case HttpStatus_509_BandwidthLimitExceeded:
571 return "Bandwidth Limit Exceeded";
572
573 case HttpStatus_510_NotExtended:
574 return "Not Extended";
575
576 default:
577 throw OrthancException(ErrorCode_ParameterOutOfRange);
578 }
579 }
580
581
582 const char* EnumerationToString(ResourceType type)
583 {
584 switch (type)
585 {
586 case ResourceType_Patient:
587 return "Patient";
588
589 case ResourceType_Study:
590 return "Study";
591
592 case ResourceType_Series:
593 return "Series";
594
595 case ResourceType_Instance:
596 return "Instance";
597
598 default:
599 throw OrthancException(ErrorCode_ParameterOutOfRange);
600 }
601 }
602
603
604 const char* EnumerationToString(ImageFormat format)
605 {
606 switch (format)
607 {
608 case ImageFormat_Png:
609 return "Png";
610
611 default:
612 throw OrthancException(ErrorCode_ParameterOutOfRange);
613 }
614 }
615
616
617 const char* EnumerationToString(Encoding encoding)
618 {
619 switch (encoding)
620 {
621 case Encoding_Ascii:
622 return "Ascii";
623
624 case Encoding_Utf8:
625 return "Utf8";
626
627 case Encoding_Latin1:
628 return "Latin1";
629
630 case Encoding_Latin2:
631 return "Latin2";
632
633 case Encoding_Latin3:
634 return "Latin3";
635
636 case Encoding_Latin4:
637 return "Latin4";
638
639 case Encoding_Latin5:
640 return "Latin5";
641
642 case Encoding_Cyrillic:
643 return "Cyrillic";
644
645 case Encoding_Windows1251:
646 return "Windows1251";
647
648 case Encoding_Arabic:
649 return "Arabic";
650
651 case Encoding_Greek:
652 return "Greek";
653
654 case Encoding_Hebrew:
655 return "Hebrew";
656
657 case Encoding_Thai:
658 return "Thai";
659
660 case Encoding_Japanese:
661 return "Japanese";
662
663 case Encoding_Chinese:
664 return "Chinese";
665
666 case Encoding_Korean:
667 return "Korean";
668
669 case Encoding_JapaneseKanji:
670 return "JapaneseKanji";
671
672 case Encoding_SimplifiedChinese:
673 return "SimplifiedChinese";
674
675 default:
676 throw OrthancException(ErrorCode_ParameterOutOfRange);
677 }
678 }
679
680
681 const char* EnumerationToString(PhotometricInterpretation photometric)
682 {
683 switch (photometric)
684 {
685 case PhotometricInterpretation_RGB:
686 return "RGB";
687
688 case PhotometricInterpretation_Monochrome1:
689 return "MONOCHROME1";
690
691 case PhotometricInterpretation_Monochrome2:
692 return "MONOCHROME2";
693
694 case PhotometricInterpretation_ARGB:
695 return "ARGB";
696
697 case PhotometricInterpretation_CMYK:
698 return "CMYK";
699
700 case PhotometricInterpretation_HSV:
701 return "HSV";
702
703 case PhotometricInterpretation_Palette:
704 return "PALETTE COLOR";
705
706 case PhotometricInterpretation_YBRFull:
707 return "YBR_FULL";
708
709 case PhotometricInterpretation_YBRFull422:
710 return "YBR_FULL_422";
711
712 case PhotometricInterpretation_YBRPartial420:
713 return "YBR_PARTIAL_420";
714
715 case PhotometricInterpretation_YBRPartial422:
716 return "YBR_PARTIAL_422";
717
718 case PhotometricInterpretation_YBR_ICT:
719 return "YBR_ICT";
720
721 case PhotometricInterpretation_YBR_RCT:
722 return "YBR_RCT";
723
724 case PhotometricInterpretation_Unknown:
725 return "Unknown";
726
727 default:
728 throw OrthancException(ErrorCode_ParameterOutOfRange);
729 }
730 }
731
732
733 const char* EnumerationToString(RequestOrigin origin)
734 {
735 switch (origin)
736 {
737 case RequestOrigin_Unknown:
738 return "Unknown";
739
740 case RequestOrigin_DicomProtocol:
741 return "DicomProtocol";
742
743 case RequestOrigin_RestApi:
744 return "RestApi";
745
746 case RequestOrigin_Plugins:
747 return "Plugins";
748
749 case RequestOrigin_Lua:
750 return "Lua";
751
752 default:
753 throw OrthancException(ErrorCode_ParameterOutOfRange);
754 }
755 }
756
757
758 const char* EnumerationToString(PixelFormat format)
759 {
760 switch (format)
761 {
762 case PixelFormat_RGB24:
763 return "RGB24";
764
765 case PixelFormat_RGBA32:
766 return "RGBA32";
767
768 case PixelFormat_BGRA32:
769 return "BGRA32";
770
771 case PixelFormat_Grayscale8:
772 return "Grayscale (unsigned 8bpp)";
773
774 case PixelFormat_Grayscale16:
775 return "Grayscale (unsigned 16bpp)";
776
777 case PixelFormat_SignedGrayscale16:
778 return "Grayscale (signed 16bpp)";
779
780 case PixelFormat_Float32:
781 return "Grayscale (float 32bpp)";
782
783 case PixelFormat_Grayscale32:
784 return "Grayscale (unsigned 32bpp)";
785
786 case PixelFormat_Grayscale64:
787 return "Grayscale (unsigned 64bpp)";
788
789 case PixelFormat_RGB48:
790 return "RGB48";
791
792 default:
793 throw OrthancException(ErrorCode_ParameterOutOfRange);
794 }
795 }
796
797
798 const char* EnumerationToString(ModalityManufacturer manufacturer)
799 {
800 switch (manufacturer)
801 {
802 case ModalityManufacturer_Generic:
803 return "Generic";
804
805 case ModalityManufacturer_GenericNoWildcardInDates:
806 return "GenericNoWildcardInDates";
807
808 case ModalityManufacturer_GenericNoUniversalWildcard:
809 return "GenericNoUniversalWildcard";
810
811 case ModalityManufacturer_StoreScp:
812 return "StoreScp";
813
814 case ModalityManufacturer_Vitrea:
815 return "Vitrea";
816
817 case ModalityManufacturer_GE:
818 return "GE";
819
820 default:
821 throw OrthancException(ErrorCode_ParameterOutOfRange);
822 }
823 }
824
825
826 const char* EnumerationToString(DicomRequestType type)
827 {
828 switch (type)
829 {
830 case DicomRequestType_Echo:
831 return "Echo";
832 break;
833
834 case DicomRequestType_Find:
835 return "Find";
836 break;
837
838 case DicomRequestType_Get:
839 return "Get";
840 break;
841
842 case DicomRequestType_Move:
843 return "Move";
844 break;
845
846 case DicomRequestType_Store:
847 return "Store";
848 break;
849
850 case DicomRequestType_NAction:
851 return "N-ACTION";
852 break;
853
854 case DicomRequestType_NEventReport:
855 return "N-EVENT-REPORT";
856 break;
857
858 default:
859 throw OrthancException(ErrorCode_ParameterOutOfRange);
860 }
861 }
862
863
864 const char* EnumerationToString(TransferSyntax syntax)
865 {
866 switch (syntax)
867 {
868 case TransferSyntax_Deflated:
869 return "Deflated";
870
871 case TransferSyntax_Jpeg:
872 return "JPEG";
873
874 case TransferSyntax_Jpeg2000:
875 return "JPEG2000";
876
877 case TransferSyntax_JpegLossless:
878 return "JPEG Lossless";
879
880 case TransferSyntax_Jpip:
881 return "JPIP";
882
883 case TransferSyntax_Mpeg2:
884 return "MPEG2";
885
886 case TransferSyntax_Mpeg4:
887 return "MPEG4";
888
889 case TransferSyntax_Rle:
890 return "RLE";
891
892 default:
893 throw OrthancException(ErrorCode_ParameterOutOfRange);
894 }
895 }
896
897
898 const char* EnumerationToString(DicomVersion version)
899 {
900 switch (version)
901 {
902 case DicomVersion_2008:
903 return "2008";
904 break;
905
906 case DicomVersion_2017c:
907 return "2017c";
908 break;
909
910 default:
911 throw OrthancException(ErrorCode_ParameterOutOfRange);
912 }
913 }
914
915
916 const char* EnumerationToString(ValueRepresentation vr)
917 {
918 switch (vr)
919 {
920 case ValueRepresentation_ApplicationEntity: // AE
921 return "AE";
922
923 case ValueRepresentation_AgeString: // AS
924 return "AS";
925
926 case ValueRepresentation_AttributeTag: // AT (2 x uint16_t)
927 return "AT";
928
929 case ValueRepresentation_CodeString: // CS
930 return "CS";
931
932 case ValueRepresentation_Date: // DA
933 return "DA";
934
935 case ValueRepresentation_DecimalString: // DS
936 return "DS";
937
938 case ValueRepresentation_DateTime: // DT
939 return "DT";
940
941 case ValueRepresentation_FloatingPointSingle: // FL (float)
942 return "FL";
943
944 case ValueRepresentation_FloatingPointDouble: // FD (double)
945 return "FD";
946
947 case ValueRepresentation_IntegerString: // IS
948 return "IS";
949
950 case ValueRepresentation_LongString: // LO
951 return "LO";
952
953 case ValueRepresentation_LongText: // LT
954 return "LT";
955
956 case ValueRepresentation_OtherByte: // OB
957 return "OB";
958
959 case ValueRepresentation_OtherDouble: // OD
960 return "OD";
961
962 case ValueRepresentation_OtherFloat: // OF
963 return "OF";
964
965 case ValueRepresentation_OtherLong: // OL
966 return "OL";
967
968 case ValueRepresentation_OtherWord: // OW
969 return "OW";
970
971 case ValueRepresentation_PersonName: // PN
972 return "PN";
973
974 case ValueRepresentation_ShortString: // SH
975 return "SH";
976
977 case ValueRepresentation_SignedLong: // SL (int32_t)
978 return "SL";
979
980 case ValueRepresentation_Sequence: // SQ
981 return "SQ";
982
983 case ValueRepresentation_SignedShort: // SS (int16_t)
984 return "SS";
985
986 case ValueRepresentation_ShortText: // ST
987 return "ST";
988
989 case ValueRepresentation_Time: // TM
990 return "TM";
991
992 case ValueRepresentation_UnlimitedCharacters: // UC
993 return "UC";
994
995 case ValueRepresentation_UniqueIdentifier: // UI (UID)
996 return "UI";
997
998 case ValueRepresentation_UnsignedLong: // UL (uint32_t)
999 return "UL";
1000
1001 case ValueRepresentation_Unknown: // UN
1002 return "UN";
1003
1004 case ValueRepresentation_UniversalResource: // UR (URI or URL)
1005 return "UR";
1006
1007 case ValueRepresentation_UnsignedShort: // US (uint16_t)
1008 return "US";
1009
1010 case ValueRepresentation_UnlimitedText: // UT
1011 return "UT";
1012
1013 case ValueRepresentation_NotSupported:
1014 return "Not supported";
1015
1016 default:
1017 throw OrthancException(ErrorCode_ParameterOutOfRange);
1018 }
1019 }
1020
1021
1022 const char* EnumerationToString(JobState state)
1023 {
1024 switch (state)
1025 {
1026 case JobState_Pending:
1027 return "Pending";
1028
1029 case JobState_Running:
1030 return "Running";
1031
1032 case JobState_Success:
1033 return "Success";
1034
1035 case JobState_Failure:
1036 return "Failure";
1037
1038 case JobState_Paused:
1039 return "Paused";
1040
1041 case JobState_Retry:
1042 return "Retry";
1043
1044 default:
1045 throw OrthancException(ErrorCode_ParameterOutOfRange);
1046 }
1047 }
1048
1049
1050 const char* EnumerationToString(MimeType mime)
1051 {
1052 switch (mime)
1053 {
1054 case MimeType_Binary:
1055 return MIME_BINARY;
1056
1057 case MimeType_Dicom:
1058 return MIME_DICOM;
1059
1060 case MimeType_Jpeg:
1061 return MIME_JPEG;
1062
1063 case MimeType_Jpeg2000:
1064 return MIME_JPEG2000;
1065
1066 case MimeType_Json:
1067 return MIME_JSON;
1068
1069 case MimeType_Pdf:
1070 return MIME_PDF;
1071
1072 case MimeType_Png:
1073 return MIME_PNG;
1074
1075 case MimeType_Xml:
1076 return MIME_XML;
1077
1078 case MimeType_PlainText:
1079 return MIME_PLAIN_TEXT;
1080
1081 case MimeType_Pam:
1082 return MIME_PAM;
1083
1084 case MimeType_Html:
1085 return MIME_HTML;
1086
1087 case MimeType_Gzip:
1088 return MIME_GZIP;
1089
1090 case MimeType_JavaScript:
1091 return MIME_JAVASCRIPT;
1092
1093 case MimeType_Css:
1094 return MIME_CSS;
1095
1096 case MimeType_WebAssembly:
1097 return MIME_WEB_ASSEMBLY;
1098
1099 case MimeType_Gif:
1100 return MIME_GIF;
1101
1102 case MimeType_Zip:
1103 return MIME_ZIP;
1104
1105 case MimeType_NaCl:
1106 return MIME_NACL;
1107
1108 case MimeType_PNaCl:
1109 return MIME_PNACL;
1110
1111 case MimeType_Svg:
1112 return MIME_SVG;
1113
1114 case MimeType_Woff:
1115 return MIME_WOFF;
1116
1117 case MimeType_Woff2:
1118 return MIME_WOFF2;
1119
1120 case MimeType_PrometheusText:
1121 // https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format
1122 return "text/plain; version=0.0.4";
1123
1124 case MimeType_DicomWebJson:
1125 return MIME_DICOM_WEB_JSON;
1126
1127 case MimeType_DicomWebXml:
1128 return MIME_DICOM_WEB_XML;
1129
1130 default:
1131 throw OrthancException(ErrorCode_ParameterOutOfRange);
1132 }
1133 }
1134
1135
1136 const char* EnumerationToString(Endianness endianness)
1137 {
1138 switch (endianness)
1139 {
1140 case Endianness_Little:
1141 return "Little-endian";
1142
1143 case Endianness_Big:
1144 return "Big-endian";
1145
1146 case Endianness_Unknown:
1147 return "Unknown endianness";
1148
1149 default:
1150 throw OrthancException(ErrorCode_ParameterOutOfRange);
1151 }
1152 }
1153
1154
1155 const char* EnumerationToString(StorageCommitmentFailureReason reason)
1156 {
1157 switch (reason)
1158 {
1159 case StorageCommitmentFailureReason_Success:
1160 return "Success";
1161
1162 case StorageCommitmentFailureReason_ProcessingFailure:
1163 return "A general failure in processing the operation was encountered";
1164
1165 case StorageCommitmentFailureReason_NoSuchObjectInstance:
1166 return "One or more of the elements in the Referenced SOP "
1167 "Instance Sequence was not available";
1168
1169 case StorageCommitmentFailureReason_ResourceLimitation:
1170 return "The SCP does not currently have enough resources to "
1171 "store the requested SOP Instance(s)";
1172
1173 case StorageCommitmentFailureReason_ReferencedSOPClassNotSupported:
1174 return "Storage Commitment has been requested for a SOP Instance "
1175 "with a SOP Class that is not supported by the SCP";
1176
1177 case StorageCommitmentFailureReason_ClassInstanceConflict:
1178 return "The SOP Class of an element in the Referenced SOP Instance Sequence "
1179 "did not correspond to the SOP class registered for this SOP Instance at the SCP";
1180
1181 case StorageCommitmentFailureReason_DuplicateTransactionUID:
1182 return "The Transaction UID of the Storage Commitment Request is already in use";
1183
1184 default:
1185 return "Unknown failure reason";
1186 }
1187 }
1188
1189
1190 Encoding StringToEncoding(const char* encoding)
1191 {
1192 std::string s(encoding);
1193 Toolbox::ToUpperCase(s);
1194
1195 if (s == "UTF8")
1196 {
1197 return Encoding_Utf8;
1198 }
1199
1200 if (s == "ASCII")
1201 {
1202 return Encoding_Ascii;
1203 }
1204
1205 if (s == "LATIN1")
1206 {
1207 return Encoding_Latin1;
1208 }
1209
1210 if (s == "LATIN2")
1211 {
1212 return Encoding_Latin2;
1213 }
1214
1215 if (s == "LATIN3")
1216 {
1217 return Encoding_Latin3;
1218 }
1219
1220 if (s == "LATIN4")
1221 {
1222 return Encoding_Latin4;
1223 }
1224
1225 if (s == "LATIN5")
1226 {
1227 return Encoding_Latin5;
1228 }
1229
1230 if (s == "CYRILLIC")
1231 {
1232 return Encoding_Cyrillic;
1233 }
1234
1235 if (s == "WINDOWS1251")
1236 {
1237 return Encoding_Windows1251;
1238 }
1239
1240 if (s == "ARABIC")
1241 {
1242 return Encoding_Arabic;
1243 }
1244
1245 if (s == "GREEK")
1246 {
1247 return Encoding_Greek;
1248 }
1249
1250 if (s == "HEBREW")
1251 {
1252 return Encoding_Hebrew;
1253 }
1254
1255 if (s == "THAI")
1256 {
1257 return Encoding_Thai;
1258 }
1259
1260 if (s == "JAPANESE")
1261 {
1262 return Encoding_Japanese;
1263 }
1264
1265 if (s == "CHINESE")
1266 {
1267 return Encoding_Chinese;
1268 }
1269
1270 if (s == "KOREAN")
1271 {
1272 return Encoding_Korean;
1273 }
1274
1275 if (s == "JAPANESEKANJI")
1276 {
1277 return Encoding_JapaneseKanji;
1278 }
1279
1280 if (s == "SIMPLIFIEDCHINESE")
1281 {
1282 return Encoding_SimplifiedChinese;
1283 }
1284
1285 throw OrthancException(ErrorCode_ParameterOutOfRange);
1286 }
1287
1288
1289 ResourceType StringToResourceType(const char* type)
1290 {
1291 std::string s(type);
1292 Toolbox::ToUpperCase(s);
1293
1294 if (s == "PATIENT" || s == "PATIENTS")
1295 {
1296 return ResourceType_Patient;
1297 }
1298 else if (s == "STUDY" || s == "STUDIES")
1299 {
1300 return ResourceType_Study;
1301 }
1302 else if (s == "SERIES")
1303 {
1304 return ResourceType_Series;
1305 }
1306 else if (s == "INSTANCE" || s == "IMAGE" ||
1307 s == "INSTANCES" || s == "IMAGES")
1308 {
1309 return ResourceType_Instance;
1310 }
1311
1312 throw OrthancException(ErrorCode_ParameterOutOfRange);
1313 }
1314
1315
1316 ImageFormat StringToImageFormat(const char* format)
1317 {
1318 std::string s(format);
1319 Toolbox::ToUpperCase(s);
1320
1321 if (s == "PNG")
1322 {
1323 return ImageFormat_Png;
1324 }
1325
1326 throw OrthancException(ErrorCode_ParameterOutOfRange);
1327 }
1328
1329
1330 ValueRepresentation StringToValueRepresentation(const std::string& vr,
1331 bool throwIfUnsupported)
1332 {
1333 if (vr == "AE")
1334 {
1335 return ValueRepresentation_ApplicationEntity;
1336 }
1337 else if (vr == "AS")
1338 {
1339 return ValueRepresentation_AgeString;
1340 }
1341 else if (vr == "AT")
1342 {
1343 return ValueRepresentation_AttributeTag;
1344 }
1345 else if (vr == "CS")
1346 {
1347 return ValueRepresentation_CodeString;
1348 }
1349 else if (vr == "DA")
1350 {
1351 return ValueRepresentation_Date;
1352 }
1353 else if (vr == "DS")
1354 {
1355 return ValueRepresentation_DecimalString;
1356 }
1357 else if (vr == "DT")
1358 {
1359 return ValueRepresentation_DateTime;
1360 }
1361 else if (vr == "FL")
1362 {
1363 return ValueRepresentation_FloatingPointSingle;
1364 }
1365 else if (vr == "FD")
1366 {
1367 return ValueRepresentation_FloatingPointDouble;
1368 }
1369 else if (vr == "IS")
1370 {
1371 return ValueRepresentation_IntegerString;
1372 }
1373 else if (vr == "LO")
1374 {
1375 return ValueRepresentation_LongString;
1376 }
1377 else if (vr == "LT")
1378 {
1379 return ValueRepresentation_LongText;
1380 }
1381 else if (vr == "OB")
1382 {
1383 return ValueRepresentation_OtherByte;
1384 }
1385 else if (vr == "OD")
1386 {
1387 return ValueRepresentation_OtherDouble;
1388 }
1389 else if (vr == "OF")
1390 {
1391 return ValueRepresentation_OtherFloat;
1392 }
1393 else if (vr == "OL")
1394 {
1395 return ValueRepresentation_OtherLong;
1396 }
1397 else if (vr == "OW")
1398 {
1399 return ValueRepresentation_OtherWord;
1400 }
1401 else if (vr == "PN")
1402 {
1403 return ValueRepresentation_PersonName;
1404 }
1405 else if (vr == "SH")
1406 {
1407 return ValueRepresentation_ShortString;
1408 }
1409 else if (vr == "SL")
1410 {
1411 return ValueRepresentation_SignedLong;
1412 }
1413 else if (vr == "SQ")
1414 {
1415 return ValueRepresentation_Sequence;
1416 }
1417 else if (vr == "SS")
1418 {
1419 return ValueRepresentation_SignedShort;
1420 }
1421 else if (vr == "ST")
1422 {
1423 return ValueRepresentation_ShortText;
1424 }
1425 else if (vr == "TM")
1426 {
1427 return ValueRepresentation_Time;
1428 }
1429 else if (vr == "UC")
1430 {
1431 return ValueRepresentation_UnlimitedCharacters;
1432 }
1433 else if (vr == "UI")
1434 {
1435 return ValueRepresentation_UniqueIdentifier;
1436 }
1437 else if (vr == "UL")
1438 {
1439 return ValueRepresentation_UnsignedLong;
1440 }
1441 else if (vr == "UN")
1442 {
1443 return ValueRepresentation_Unknown;
1444 }
1445 else if (vr == "UR")
1446 {
1447 return ValueRepresentation_UniversalResource;
1448 }
1449 else if (vr == "US")
1450 {
1451 return ValueRepresentation_UnsignedShort;
1452 }
1453 else if (vr == "UT")
1454 {
1455 return ValueRepresentation_UnlimitedText;
1456 }
1457 else
1458 {
1459 std::string s = "Unsupported value representation encountered: " + vr;
1460
1461 if (throwIfUnsupported)
1462 {
1463 throw OrthancException(ErrorCode_ParameterOutOfRange, s);
1464 }
1465 else
1466 {
1467 LOG(INFO) << s;
1468 return ValueRepresentation_NotSupported;
1469 }
1470 }
1471 }
1472
1473
1474 PhotometricInterpretation StringToPhotometricInterpretation(const char* value)
1475 {
1476 // http://dicom.nema.org/medical/dicom/2017a/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
1477 std::string s(value);
1478
1479 if (s == "MONOCHROME1")
1480 {
1481 return PhotometricInterpretation_Monochrome1;
1482 }
1483
1484 if (s == "MONOCHROME2")
1485 {
1486 return PhotometricInterpretation_Monochrome2;
1487 }
1488
1489 if (s == "PALETTE COLOR")
1490 {
1491 return PhotometricInterpretation_Palette;
1492 }
1493
1494 if (s == "RGB")
1495 {
1496 return PhotometricInterpretation_RGB;
1497 }
1498
1499 if (s == "HSV")
1500 {
1501 return PhotometricInterpretation_HSV;
1502 }
1503
1504 if (s == "ARGB")
1505 {
1506 return PhotometricInterpretation_ARGB;
1507 }
1508
1509 if (s == "CMYK")
1510 {
1511 return PhotometricInterpretation_CMYK;
1512 }
1513
1514 if (s == "YBR_FULL")
1515 {
1516 return PhotometricInterpretation_YBRFull;
1517 }
1518
1519 if (s == "YBR_FULL_422")
1520 {
1521 return PhotometricInterpretation_YBRFull422;
1522 }
1523
1524 if (s == "YBR_PARTIAL_422")
1525 {
1526 return PhotometricInterpretation_YBRPartial422;
1527 }
1528
1529 if (s == "YBR_PARTIAL_420")
1530 {
1531 return PhotometricInterpretation_YBRPartial420;
1532 }
1533
1534 if (s == "YBR_ICT")
1535 {
1536 return PhotometricInterpretation_YBR_ICT;
1537 }
1538
1539 if (s == "YBR_RCT")
1540 {
1541 return PhotometricInterpretation_YBR_RCT;
1542 }
1543
1544 throw OrthancException(ErrorCode_ParameterOutOfRange);
1545 }
1546
1547
1548 ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer)
1549 {
1550 ModalityManufacturer result;
1551 bool obsolete = false;
1552
1553 if (manufacturer == "Generic")
1554 {
1555 return ModalityManufacturer_Generic;
1556 }
1557 else if (manufacturer == "GenericNoWildcardInDates")
1558 {
1559 return ModalityManufacturer_GenericNoWildcardInDates;
1560 }
1561 else if (manufacturer == "GenericNoUniversalWildcard")
1562 {
1563 return ModalityManufacturer_GenericNoUniversalWildcard;
1564 }
1565 else if (manufacturer == "StoreScp")
1566 {
1567 return ModalityManufacturer_StoreScp;
1568 }
1569 else if (manufacturer == "Vitrea")
1570 {
1571 return ModalityManufacturer_Vitrea;
1572 }
1573 else if (manufacturer == "GE")
1574 {
1575 return ModalityManufacturer_GE;
1576 }
1577 else if (manufacturer == "AgfaImpax" ||
1578 manufacturer == "SyngoVia")
1579 {
1580 result = ModalityManufacturer_GenericNoWildcardInDates;
1581 obsolete = true;
1582 }
1583 else if (manufacturer == "EFilm2" ||
1584 manufacturer == "MedInria" ||
1585 manufacturer == "ClearCanvas" ||
1586 manufacturer == "Dcm4Chee"
1587 )
1588 {
1589 result = ModalityManufacturer_Generic;
1590 obsolete = true;
1591 }
1592 else
1593 {
1594 throw OrthancException(ErrorCode_ParameterOutOfRange,
1595 "Unknown modality manufacturer: \"" + manufacturer + "\"");
1596 }
1597
1598 if (obsolete)
1599 {
1600 LOG(WARNING) << "The \"" << manufacturer << "\" manufacturer is now obsolete. "
1601 << "To guarantee compatibility with future Orthanc "
1602 << "releases, you should replace it by \""
1603 << EnumerationToString(result)
1604 << "\" in your configuration file.";
1605 }
1606
1607 return result;
1608 }
1609
1610
1611 DicomVersion StringToDicomVersion(const std::string& version)
1612 {
1613 if (version == "2008")
1614 {
1615 return DicomVersion_2008;
1616 }
1617 else if (version == "2017c")
1618 {
1619 return DicomVersion_2017c;
1620 }
1621 else
1622 {
1623 throw OrthancException(ErrorCode_ParameterOutOfRange);
1624 }
1625 }
1626
1627
1628 JobState StringToJobState(const std::string& state)
1629 {
1630 if (state == "Pending")
1631 {
1632 return JobState_Pending;
1633 }
1634 else if (state == "Running")
1635 {
1636 return JobState_Running;
1637 }
1638 else if (state == "Success")
1639 {
1640 return JobState_Success;
1641 }
1642 else if (state == "Failure")
1643 {
1644 return JobState_Failure;
1645 }
1646 else if (state == "Paused")
1647 {
1648 return JobState_Paused;
1649 }
1650 else if (state == "Retry")
1651 {
1652 return JobState_Retry;
1653 }
1654 else
1655 {
1656 throw OrthancException(ErrorCode_ParameterOutOfRange);
1657 }
1658 }
1659
1660
1661 RequestOrigin StringToRequestOrigin(const std::string& origin)
1662 {
1663 if (origin == "Unknown")
1664 {
1665 return RequestOrigin_Unknown;
1666 }
1667 else if (origin == "DicomProtocol")
1668 {
1669 return RequestOrigin_DicomProtocol;
1670 }
1671 else if (origin == "RestApi")
1672 {
1673 return RequestOrigin_RestApi;
1674 }
1675 else if (origin == "Plugins")
1676 {
1677 return RequestOrigin_Plugins;
1678 }
1679 else if (origin == "Lua")
1680 {
1681 return RequestOrigin_Lua;
1682 }
1683 else
1684 {
1685 throw OrthancException(ErrorCode_ParameterOutOfRange);
1686 }
1687 }
1688
1689
1690 MimeType StringToMimeType(const std::string& mime)
1691 {
1692 if (mime == MIME_BINARY)
1693 {
1694 return MimeType_Binary;
1695 }
1696 else if (mime == MIME_DICOM)
1697 {
1698 return MimeType_Dicom;
1699 }
1700 else if (mime == MIME_JPEG)
1701 {
1702 return MimeType_Jpeg;
1703 }
1704 else if (mime == MIME_JPEG2000)
1705 {
1706 return MimeType_Jpeg2000;
1707 }
1708 else if (mime == MIME_JSON)
1709 {
1710 return MimeType_Json;
1711 }
1712 else if (mime == MIME_PDF)
1713 {
1714 return MimeType_Pdf;
1715 }
1716 else if (mime == MIME_PNG)
1717 {
1718 return MimeType_Png;
1719 }
1720 else if (mime == MIME_XML ||
1721 mime == MIME_XML_2)
1722 {
1723 return MimeType_Xml;
1724 }
1725 else if (mime == MIME_PLAIN_TEXT)
1726 {
1727 return MimeType_PlainText;
1728 }
1729 else if (mime == MIME_PAM)
1730 {
1731 return MimeType_Pam;
1732 }
1733 else if (mime == MIME_HTML)
1734 {
1735 return MimeType_Html;
1736 }
1737 else if (mime == MIME_GZIP)
1738 {
1739 return MimeType_Gzip;
1740 }
1741 else if (mime == MIME_JAVASCRIPT)
1742 {
1743 return MimeType_JavaScript;
1744 }
1745 else if (mime == MIME_CSS)
1746 {
1747 return MimeType_Css;
1748 }
1749 else if (mime == MIME_WEB_ASSEMBLY)
1750 {
1751 return MimeType_WebAssembly;
1752 }
1753 else if (mime == MIME_GIF)
1754 {
1755 return MimeType_Gif;
1756 }
1757 else if (mime == MIME_ZIP)
1758 {
1759 return MimeType_Zip;
1760 }
1761 else if (mime == MIME_NACL)
1762 {
1763 return MimeType_NaCl;
1764 }
1765 else if (mime == MIME_PNACL)
1766 {
1767 return MimeType_PNaCl;
1768 }
1769 else if (mime == MIME_SVG)
1770 {
1771 return MimeType_Svg;
1772 }
1773 else if (mime == MIME_WOFF)
1774 {
1775 return MimeType_Woff;
1776 }
1777 else if (mime == MIME_WOFF2)
1778 {
1779 return MimeType_Woff2;
1780 }
1781 else if (mime == MIME_DICOM_WEB_JSON)
1782 {
1783 return MimeType_DicomWebJson;
1784 }
1785 else if (mime == MIME_DICOM_WEB_XML)
1786 {
1787 return MimeType_DicomWebXml;
1788 }
1789 else
1790 {
1791 throw OrthancException(ErrorCode_ParameterOutOfRange);
1792 }
1793 }
1794
1795
1796 unsigned int GetBytesPerPixel(PixelFormat format)
1797 {
1798 switch (format)
1799 {
1800 case PixelFormat_Grayscale8:
1801 return 1;
1802
1803 case PixelFormat_Grayscale16:
1804 case PixelFormat_SignedGrayscale16:
1805 return 2;
1806
1807 case PixelFormat_RGB24:
1808 return 3;
1809
1810 case PixelFormat_RGBA32:
1811 case PixelFormat_BGRA32:
1812 case PixelFormat_Grayscale32:
1813 return 4;
1814
1815 case PixelFormat_Float32:
1816 assert(sizeof(float) == 4);
1817 return 4;
1818
1819 case PixelFormat_RGB48:
1820 return 6;
1821
1822 case PixelFormat_Grayscale64:
1823 return 8;
1824
1825 default:
1826 throw OrthancException(ErrorCode_ParameterOutOfRange);
1827 }
1828 }
1829
1830
1831 bool GetDicomEncoding(Encoding& encoding,
1832 const char* specificCharacterSet)
1833 {
1834 std::string s = Toolbox::StripSpaces(specificCharacterSet);
1835 Toolbox::ToUpperCase(s);
1836
1837 // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2
1838 // https://github.com/dcm4che/dcm4che/blob/master/dcm4che-core/src/main/java/org/dcm4che3/data/SpecificCharacterSet.java
1839 if (s == "ISO_IR 6" ||
1840 s == "ISO 2022 IR 6")
1841 {
1842 encoding = Encoding_Ascii;
1843 }
1844 else if (s == "ISO_IR 192")
1845 {
1846 encoding = Encoding_Utf8;
1847 }
1848 else if (s == "ISO_IR 100" ||
1849 s == "ISO 2022 IR 100")
1850 {
1851 encoding = Encoding_Latin1;
1852 }
1853 else if (s == "ISO_IR 101" ||
1854 s == "ISO 2022 IR 101")
1855 {
1856 encoding = Encoding_Latin2;
1857 }
1858 else if (s == "ISO_IR 109" ||
1859 s == "ISO 2022 IR 109")
1860 {
1861 encoding = Encoding_Latin3;
1862 }
1863 else if (s == "ISO_IR 110" ||
1864 s == "ISO 2022 IR 110")
1865 {
1866 encoding = Encoding_Latin4;
1867 }
1868 else if (s == "ISO_IR 148" ||
1869 s == "ISO 2022 IR 148")
1870 {
1871 encoding = Encoding_Latin5;
1872 }
1873 else if (s == "ISO_IR 144" ||
1874 s == "ISO 2022 IR 144")
1875 {
1876 encoding = Encoding_Cyrillic;
1877 }
1878 else if (s == "ISO_IR 127" ||
1879 s == "ISO 2022 IR 127")
1880 {
1881 encoding = Encoding_Arabic;
1882 }
1883 else if (s == "ISO_IR 126" ||
1884 s == "ISO 2022 IR 126")
1885 {
1886 encoding = Encoding_Greek;
1887 }
1888 else if (s == "ISO_IR 138" ||
1889 s == "ISO 2022 IR 138")
1890 {
1891 encoding = Encoding_Hebrew;
1892 }
1893 else if (s == "ISO_IR 166" ||
1894 s == "ISO 2022 IR 166")
1895 {
1896 encoding = Encoding_Thai;
1897 }
1898 else if (s == "ISO_IR 13" ||
1899 s == "ISO 2022 IR 13")
1900 {
1901 encoding = Encoding_Japanese;
1902 }
1903 else if (s == "GB18030" || s == "GBK")
1904 {
1905 /**
1906 * According to tumashu@163.com, "In China, many dicom file's
1907 * 0008,0005 tag is set as "GBK", instead of "GB18030", GBK is a
1908 * subset of GB18030, and which is used frequently in China,
1909 * suggest support it."
1910 * https://groups.google.com/d/msg/orthanc-users/WMM8LMbjpUc/02-1f_yFCgAJ
1911 **/
1912 encoding = Encoding_Chinese;
1913 }
1914 else if (s == "ISO 2022 IR 149")
1915 {
1916 encoding = Encoding_Korean;
1917 }
1918 else if (s == "ISO 2022 IR 87")
1919 {
1920 encoding = Encoding_JapaneseKanji;
1921 }
1922 else if (s == "ISO 2022 IR 58")
1923 {
1924 encoding = Encoding_SimplifiedChinese;
1925 }
1926 /*
1927 else if (s == "ISO 2022 IR 159")
1928 {
1929 TODO - Supplementary Kanji set
1930 }
1931 */
1932 else
1933 {
1934 return false;
1935 }
1936
1937 // The encoding was properly detected
1938 return true;
1939 }
1940
1941
1942 ResourceType GetChildResourceType(ResourceType type)
1943 {
1944 switch (type)
1945 {
1946 case ResourceType_Patient:
1947 return ResourceType_Study;
1948
1949 case ResourceType_Study:
1950 return ResourceType_Series;
1951
1952 case ResourceType_Series:
1953 return ResourceType_Instance;
1954
1955 default:
1956 throw OrthancException(ErrorCode_ParameterOutOfRange);
1957 }
1958 }
1959
1960
1961 ResourceType GetParentResourceType(ResourceType type)
1962 {
1963 switch (type)
1964 {
1965 case ResourceType_Study:
1966 return ResourceType_Patient;
1967
1968 case ResourceType_Series:
1969 return ResourceType_Study;
1970
1971 case ResourceType_Instance:
1972 return ResourceType_Series;
1973
1974 default:
1975 throw OrthancException(ErrorCode_ParameterOutOfRange);
1976 }
1977 }
1978
1979
1980 bool IsResourceLevelAboveOrEqual(ResourceType level,
1981 ResourceType reference)
1982 {
1983 switch (reference)
1984 {
1985 case ResourceType_Patient:
1986 return (level == ResourceType_Patient);
1987
1988 case ResourceType_Study:
1989 return (level == ResourceType_Patient ||
1990 level == ResourceType_Study);
1991
1992 case ResourceType_Series:
1993 return (level == ResourceType_Patient ||
1994 level == ResourceType_Study ||
1995 level == ResourceType_Series);
1996
1997 case ResourceType_Instance:
1998 return (level == ResourceType_Patient ||
1999 level == ResourceType_Study ||
2000 level == ResourceType_Series ||
2001 level == ResourceType_Instance);
2002
2003 default:
2004 throw OrthancException(ErrorCode_ParameterOutOfRange);
2005 }
2006 }
2007
2008
2009 DicomModule GetModule(ResourceType type)
2010 {
2011 switch (type)
2012 {
2013 case ResourceType_Patient:
2014 return DicomModule_Patient;
2015
2016 case ResourceType_Study:
2017 return DicomModule_Study;
2018
2019 case ResourceType_Series:
2020 return DicomModule_Series;
2021
2022 default:
2023 throw OrthancException(ErrorCode_ParameterOutOfRange);
2024 }
2025 }
2026
2027
2028
2029 const char* GetDicomSpecificCharacterSet(Encoding encoding)
2030 {
2031 // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2
2032 switch (encoding)
2033 {
2034 case Encoding_Ascii:
2035 return "ISO_IR 6";
2036
2037 case Encoding_Utf8:
2038 return "ISO_IR 192";
2039
2040 case Encoding_Latin1:
2041 return "ISO_IR 100";
2042
2043 case Encoding_Latin2:
2044 return "ISO_IR 101";
2045
2046 case Encoding_Latin3:
2047 return "ISO_IR 109";
2048
2049 case Encoding_Latin4:
2050 return "ISO_IR 110";
2051
2052 case Encoding_Latin5:
2053 return "ISO_IR 148";
2054
2055 case Encoding_Cyrillic:
2056 return "ISO_IR 144";
2057
2058 case Encoding_Arabic:
2059 return "ISO_IR 127";
2060
2061 case Encoding_Greek:
2062 return "ISO_IR 126";
2063
2064 case Encoding_Hebrew:
2065 return "ISO_IR 138";
2066
2067 case Encoding_Japanese:
2068 return "ISO_IR 13";
2069
2070 case Encoding_Chinese:
2071 return "GB18030";
2072
2073 case Encoding_Thai:
2074 return "ISO_IR 166";
2075
2076 case Encoding_Korean:
2077 return "ISO 2022 IR 149";
2078
2079 case Encoding_JapaneseKanji:
2080 return "ISO 2022 IR 87";
2081
2082 case Encoding_SimplifiedChinese:
2083 return "ISO 2022 IR 58";
2084
2085 default:
2086 throw OrthancException(ErrorCode_ParameterOutOfRange);
2087 }
2088 }
2089
2090
2091 // This function is autogenerated by the script
2092 // "Resources/GenerateErrorCodes.py"
2093 HttpStatus ConvertErrorCodeToHttpStatus(ErrorCode error)
2094 {
2095 switch (error)
2096 {
2097 case ErrorCode_Success:
2098 return HttpStatus_200_Ok;
2099
2100 case ErrorCode_ParameterOutOfRange:
2101 return HttpStatus_400_BadRequest;
2102
2103 case ErrorCode_BadParameterType:
2104 return HttpStatus_400_BadRequest;
2105
2106 case ErrorCode_InexistentItem:
2107 return HttpStatus_404_NotFound;
2108
2109 case ErrorCode_BadRequest:
2110 return HttpStatus_400_BadRequest;
2111
2112 case ErrorCode_UriSyntax:
2113 return HttpStatus_400_BadRequest;
2114
2115 case ErrorCode_InexistentFile:
2116 return HttpStatus_404_NotFound;
2117
2118 case ErrorCode_BadFileFormat:
2119 return HttpStatus_400_BadRequest;
2120
2121 case ErrorCode_UnknownResource:
2122 return HttpStatus_404_NotFound;
2123
2124 case ErrorCode_InexistentTag:
2125 return HttpStatus_404_NotFound;
2126
2127 case ErrorCode_BadJson:
2128 return HttpStatus_400_BadRequest;
2129
2130 case ErrorCode_Unauthorized:
2131 return HttpStatus_401_Unauthorized;
2132
2133 case ErrorCode_NotAcceptable:
2134 return HttpStatus_406_NotAcceptable;
2135
2136 case ErrorCode_DatabaseUnavailable:
2137 return HttpStatus_503_ServiceUnavailable;
2138
2139 case ErrorCode_CreateDicomNotString:
2140 return HttpStatus_400_BadRequest;
2141
2142 case ErrorCode_CreateDicomOverrideTag:
2143 return HttpStatus_400_BadRequest;
2144
2145 case ErrorCode_CreateDicomUseContent:
2146 return HttpStatus_400_BadRequest;
2147
2148 case ErrorCode_CreateDicomNoPayload:
2149 return HttpStatus_400_BadRequest;
2150
2151 case ErrorCode_CreateDicomUseDataUriScheme:
2152 return HttpStatus_400_BadRequest;
2153
2154 case ErrorCode_CreateDicomBadParent:
2155 return HttpStatus_400_BadRequest;
2156
2157 case ErrorCode_CreateDicomParentIsInstance:
2158 return HttpStatus_400_BadRequest;
2159
2160 case ErrorCode_UnsupportedMediaType:
2161 return HttpStatus_415_UnsupportedMediaType;
2162
2163 default:
2164 return HttpStatus_500_InternalServerError;
2165 }
2166 }
2167
2168
2169 bool IsUserContentType(FileContentType type)
2170 {
2171 return (type >= FileContentType_StartUser &&
2172 type <= FileContentType_EndUser);
2173 }
2174
2175
2176 bool IsBinaryValueRepresentation(ValueRepresentation vr)
2177 {
2178 // http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html
2179
2180 switch (vr)
2181 {
2182 case ValueRepresentation_ApplicationEntity: // AE
2183 case ValueRepresentation_AgeString: // AS
2184 case ValueRepresentation_CodeString: // CS
2185 case ValueRepresentation_Date: // DA
2186 case ValueRepresentation_DecimalString: // DS
2187 case ValueRepresentation_DateTime: // DT
2188 case ValueRepresentation_IntegerString: // IS
2189 case ValueRepresentation_LongString: // LO
2190 case ValueRepresentation_LongText: // LT
2191 case ValueRepresentation_PersonName: // PN
2192 case ValueRepresentation_ShortString: // SH
2193 case ValueRepresentation_ShortText: // ST
2194 case ValueRepresentation_Time: // TM
2195 case ValueRepresentation_UnlimitedCharacters: // UC
2196 case ValueRepresentation_UniqueIdentifier: // UI (UID)
2197 case ValueRepresentation_UniversalResource: // UR (URI or URL)
2198 case ValueRepresentation_UnlimitedText: // UT
2199 {
2200 return false;
2201 }
2202
2203 /**
2204 * Below are all the VR whose character repertoire is tagged as
2205 * "not applicable"
2206 **/
2207 case ValueRepresentation_AttributeTag: // AT (2 x uint16_t)
2208 case ValueRepresentation_FloatingPointSingle: // FL (float)
2209 case ValueRepresentation_FloatingPointDouble: // FD (double)
2210 case ValueRepresentation_OtherByte: // OB
2211 case ValueRepresentation_OtherDouble: // OD
2212 case ValueRepresentation_OtherFloat: // OF
2213 case ValueRepresentation_OtherLong: // OL
2214 case ValueRepresentation_OtherWord: // OW
2215 case ValueRepresentation_SignedLong: // SL (int32_t)
2216 case ValueRepresentation_Sequence: // SQ
2217 case ValueRepresentation_SignedShort: // SS (int16_t)
2218 case ValueRepresentation_UnsignedLong: // UL (uint32_t)
2219 case ValueRepresentation_Unknown: // UN
2220 case ValueRepresentation_UnsignedShort: // US (uint16_t)
2221 {
2222 return true;
2223 }
2224
2225 case ValueRepresentation_NotSupported:
2226 default:
2227 throw OrthancException(ErrorCode_ParameterOutOfRange);
2228 }
2229 }
2230
2231
2232 static boost::mutex defaultEncodingMutex_; // Should not be necessary
2233 static Encoding defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING;
2234
2235 Encoding GetDefaultDicomEncoding()
2236 {
2237 boost::mutex::scoped_lock lock(defaultEncodingMutex_);
2238 return defaultEncoding_;
2239 }
2240
2241 void SetDefaultDicomEncoding(Encoding encoding)
2242 {
2243 std::string name = EnumerationToString(encoding);
2244
2245 {
2246 boost::mutex::scoped_lock lock(defaultEncodingMutex_);
2247 defaultEncoding_ = encoding;
2248 }
2249
2250 LOG(INFO) << "Default encoding for DICOM was changed to: " << name;
2251 }
2252 }
2253
2254
2255 #include "./Enumerations_TransferSyntaxes.impl.h"