Mercurial > hg > orthanc
view Core/DicomFormat/DicomTag.cpp @ 3773:df164cc69529
fix compatibility between MSVC and Windows XP
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 18 Mar 2020 07:57:33 +0100 |
parents | 46cb00e4adbb |
children |
line wrap: on
line source
/** * Orthanc - A Lightweight, RESTful DICOM Store * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2020 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * In addition, as a special exception, the copyright holders of this * program give permission to link the code of its release with the * OpenSSL project's "OpenSSL" library (or with modified versions of it * that use the same license as the "OpenSSL" library), and distribute * the linked executables. You must obey the GNU General Public License * in all respects for all of the code used other than "OpenSSL". If you * modify file(s) with this exception, you may extend this exception to * your version of the file(s), but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source files * in the program, then also delete it here. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "../PrecompiledHeaders.h" #include "DicomTag.h" #include "../OrthancException.h" #include <iostream> #include <iomanip> #include <stdio.h> #include <string.h> namespace Orthanc { static inline uint16_t GetCharValue(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else return 0; } static inline uint16_t GetTagValue(const char* c) { return ((GetCharValue(c[0]) << 12) + (GetCharValue(c[1]) << 8) + (GetCharValue(c[2]) << 4) + GetCharValue(c[3])); } bool DicomTag::operator< (const DicomTag& other) const { if (group_ < other.group_) return true; if (group_ > other.group_) return false; return element_ < other.element_; } std::ostream& operator<< (std::ostream& o, const DicomTag& tag) { using namespace std; ios_base::fmtflags state = o.flags(); o.flags(ios::right | ios::hex); o << "(" << setfill('0') << setw(4) << tag.GetGroup() << "," << setw(4) << tag.GetElement() << ")"; o.flags(state); return o; } std::string DicomTag::Format() const { char b[16]; sprintf(b, "%04x,%04x", group_, element_); return std::string(b); } bool DicomTag::ParseHexadecimal(DicomTag& tag, const char* value) { size_t length = strlen(value); if (length == 9 && isxdigit(value[0]) && isxdigit(value[1]) && isxdigit(value[2]) && isxdigit(value[3]) && (value[4] == '-' || value[4] == ',') && isxdigit(value[5]) && isxdigit(value[6]) && isxdigit(value[7]) && isxdigit(value[8])) { uint16_t group = GetTagValue(value); uint16_t element = GetTagValue(value + 5); tag = DicomTag(group, element); return true; } else if (length == 8 && isxdigit(value[0]) && isxdigit(value[1]) && isxdigit(value[2]) && isxdigit(value[3]) && isxdigit(value[4]) && isxdigit(value[5]) && isxdigit(value[6]) && isxdigit(value[7])) { uint16_t group = GetTagValue(value); uint16_t element = GetTagValue(value + 4); tag = DicomTag(group, element); return true; } else { return false; } } const char* DicomTag::GetMainTagsName() const { if (*this == DICOM_TAG_ACCESSION_NUMBER) return "AccessionNumber"; if (*this == DICOM_TAG_SOP_INSTANCE_UID) return "SOPInstanceUID"; if (*this == DICOM_TAG_PATIENT_ID) return "PatientID"; if (*this == DICOM_TAG_SERIES_INSTANCE_UID) return "SeriesInstanceUID"; if (*this == DICOM_TAG_STUDY_INSTANCE_UID) return "StudyInstanceUID"; if (*this == DICOM_TAG_PIXEL_DATA) return "PixelData"; if (*this == DICOM_TAG_IMAGE_INDEX) return "ImageIndex"; if (*this == DICOM_TAG_INSTANCE_NUMBER) return "InstanceNumber"; if (*this == DICOM_TAG_NUMBER_OF_SLICES) return "NumberOfSlices"; if (*this == DICOM_TAG_NUMBER_OF_FRAMES) return "NumberOfFrames"; if (*this == DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES) return "CardiacNumberOfImages"; if (*this == DICOM_TAG_IMAGES_IN_ACQUISITION) return "ImagesInAcquisition"; if (*this == DICOM_TAG_PATIENT_NAME) return "PatientName"; if (*this == DICOM_TAG_IMAGE_POSITION_PATIENT) return "ImagePositionPatient"; if (*this == DICOM_TAG_IMAGE_ORIENTATION_PATIENT) return "ImageOrientationPatient"; // New in Orthanc 1.6.0, as tagged as "RETIRED_" since DCMTK 3.6.4 if (*this == DICOM_TAG_OTHER_PATIENT_IDS) return "OtherPatientIDs"; return ""; } void DicomTag::AddTagsForModule(std::set<DicomTag>& target, DicomModule module) { // REFERENCE: 11_03pu.pdf, DICOM PS 3.3 2011 - Information Object Definitions switch (module) { case DicomModule_Patient: // This is Table C.7-1 "Patient Module Attributes" (p. 373) target.insert(DicomTag(0x0010, 0x0010)); // Patient's name target.insert(DicomTag(0x0010, 0x0020)); // Patient ID target.insert(DicomTag(0x0010, 0x0030)); // Patient's birth date target.insert(DicomTag(0x0010, 0x0040)); // Patient's sex target.insert(DicomTag(0x0008, 0x1120)); // Referenced patient sequence target.insert(DicomTag(0x0010, 0x0032)); // Patient's birth time target.insert(DicomTag(0x0010, 0x1000)); // Other patient IDs target.insert(DicomTag(0x0010, 0x1002)); // Other patient IDs sequence target.insert(DicomTag(0x0010, 0x1001)); // Other patient names target.insert(DicomTag(0x0010, 0x2160)); // Ethnic group target.insert(DicomTag(0x0010, 0x4000)); // Patient comments target.insert(DicomTag(0x0010, 0x2201)); // Patient species description target.insert(DicomTag(0x0010, 0x2202)); // Patient species code sequence target.insert(DicomTag(0x0010, 0x2292)); // Patient breed description target.insert(DicomTag(0x0010, 0x2293)); // Patient breed code sequence target.insert(DicomTag(0x0010, 0x2294)); // Breed registration sequence target.insert(DicomTag(0x0010, 0x2297)); // Responsible person target.insert(DicomTag(0x0010, 0x2298)); // Responsible person role target.insert(DicomTag(0x0010, 0x2299)); // Responsible organization target.insert(DicomTag(0x0012, 0x0062)); // Patient identity removed target.insert(DicomTag(0x0012, 0x0063)); // De-identification method target.insert(DicomTag(0x0012, 0x0064)); // De-identification method code sequence // Table 10-18 ISSUER OF PATIENT ID MACRO (p. 112) target.insert(DicomTag(0x0010, 0x0021)); // Issuer of Patient ID target.insert(DicomTag(0x0010, 0x0024)); // Issuer of Patient ID qualifiers sequence break; case DicomModule_Study: // This is Table C.7-3 "General Study Module Attributes" (p. 378) target.insert(DicomTag(0x0020, 0x000d)); // Study instance UID target.insert(DicomTag(0x0008, 0x0020)); // Study date target.insert(DicomTag(0x0008, 0x0030)); // Study time target.insert(DicomTag(0x0008, 0x0090)); // Referring physician's name target.insert(DicomTag(0x0008, 0x0096)); // Referring physician identification sequence target.insert(DicomTag(0x0020, 0x0010)); // Study ID target.insert(DicomTag(0x0008, 0x0050)); // Accession number target.insert(DicomTag(0x0008, 0x0051)); // Issuer of accession number sequence target.insert(DicomTag(0x0008, 0x1030)); // Study description target.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of record target.insert(DicomTag(0x0008, 0x1049)); // Physician(s) of record identification sequence target.insert(DicomTag(0x0008, 0x1060)); // Name of physician(s) reading study target.insert(DicomTag(0x0008, 0x1062)); // Physician(s) reading study identification sequence target.insert(DicomTag(0x0032, 0x1034)); // Requesting service code sequence target.insert(DicomTag(0x0008, 0x1110)); // Referenced study sequence target.insert(DicomTag(0x0008, 0x1032)); // Procedure code sequence target.insert(DicomTag(0x0040, 0x1012)); // Reason for performed procedure code sequence break; case DicomModule_Series: // This is Table C.7-5 "General Series Module Attributes" (p. 385) target.insert(DicomTag(0x0008, 0x0060)); // Modality target.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID target.insert(DicomTag(0x0020, 0x0011)); // Series Number target.insert(DicomTag(0x0020, 0x0060)); // Laterality target.insert(DicomTag(0x0008, 0x0021)); // Series Date target.insert(DicomTag(0x0008, 0x0031)); // Series Time target.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians’ Name target.insert(DicomTag(0x0008, 0x1052)); // Performing Physician Identification Sequence target.insert(DicomTag(0x0018, 0x1030)); // Protocol Name target.insert(DicomTag(0x0008, 0x103e)); // Series Description target.insert(DicomTag(0x0008, 0x103f)); // Series Description Code Sequence target.insert(DicomTag(0x0008, 0x1070)); // Operators' Name target.insert(DicomTag(0x0008, 0x1072)); // Operator Identification Sequence target.insert(DicomTag(0x0008, 0x1111)); // Referenced Performed Procedure Step Sequence target.insert(DicomTag(0x0008, 0x1250)); // Related Series Sequence target.insert(DicomTag(0x0018, 0x0015)); // Body Part Examined target.insert(DicomTag(0x0018, 0x5100)); // Patient Position target.insert(DicomTag(0x0028, 0x0108)); // Smallest Pixel Value in Series target.insert(DicomTag(0x0029, 0x0109)); // Largest Pixel Value in Series target.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence target.insert(DicomTag(0x0010, 0x2210)); // Anatomical Orientation Type // Table 10-16 PERFORMED PROCEDURE STEP SUMMARY MACRO ATTRIBUTES target.insert(DicomTag(0x0040, 0x0253)); // Performed Procedure Step ID target.insert(DicomTag(0x0040, 0x0244)); // Performed Procedure Step Start Date target.insert(DicomTag(0x0040, 0x0245)); // Performed Procedure Step Start Time target.insert(DicomTag(0x0040, 0x0254)); // Performed Procedure Step Description target.insert(DicomTag(0x0040, 0x0260)); // Performed Protocol Code Sequence target.insert(DicomTag(0x0040, 0x0280)); // Comments on the Performed Procedure Step break; case DicomModule_Instance: // This is Table C.12-1 "SOP Common Module Attributes" (p. 1207) target.insert(DicomTag(0x0008, 0x0016)); // SOP Class UID target.insert(DicomTag(0x0008, 0x0018)); // SOP Instance UID target.insert(DicomTag(0x0008, 0x0005)); // Specific Character Set target.insert(DicomTag(0x0008, 0x0012)); // Instance Creation Date target.insert(DicomTag(0x0008, 0x0013)); // Instance Creation Time target.insert(DicomTag(0x0008, 0x0014)); // Instance Creator UID target.insert(DicomTag(0x0008, 0x001a)); // Related General SOP Class UID target.insert(DicomTag(0x0008, 0x001b)); // Original Specialized SOP Class UID target.insert(DicomTag(0x0008, 0x0110)); // Coding Scheme Identification Sequence target.insert(DicomTag(0x0008, 0x0201)); // Timezone Offset From UTC target.insert(DicomTag(0x0018, 0xa001)); // Contributing Equipment Sequence target.insert(DicomTag(0x0020, 0x0013)); // Instance Number target.insert(DicomTag(0x0100, 0x0410)); // SOP Instance Status target.insert(DicomTag(0x0100, 0x0420)); // SOP Authorization DateTime target.insert(DicomTag(0x0100, 0x0424)); // SOP Authorization Comment target.insert(DicomTag(0x0100, 0x0426)); // Authorization Equipment Certification Number target.insert(DicomTag(0x0400, 0x0500)); // Encrypted Attributes Sequence target.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence target.insert(DicomTag(0x0040, 0xa390)); // HL7 Structured Document Reference Sequence target.insert(DicomTag(0x0028, 0x0303)); // Longitudinal Temporal Information Modified // Table C.12-6 "DIGITAL SIGNATURES MACRO ATTRIBUTES" (p. 1216) target.insert(DicomTag(0x4ffe, 0x0001)); // MAC Parameters sequence target.insert(DicomTag(0xfffa, 0xfffa)); // Digital signatures sequence break; // TODO IMAGE MODULE? default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } }