/* * * Copyright (C) 2015-2021, Open Connections GmbH * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation are maintained by * * OFFIS e.V. * R&D Division Health * Escherweg 2 * D-26121 Oldenburg, Germany * * * Module: dcmiod * * Author: Michael Onken * * Purpose: Collection of classes representing DICOM IOD macros * */ #include "dcmtk/dcmiod/iodmacro.h" #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmiod/iodutil.h" // for static IOD helpers #include "dcmtk/ofstd/ofstream.h" // --------------------------- Code Sequence Macro --------------------------- // -- Code Sequence Macro CodeSequenceMacro::CodeSequenceMacro(OFshared_ptr item, OFshared_ptr rules, IODComponent* parent) : IODComponent(item, rules, parent) { // reset element rules resetRules(); } CodeSequenceMacro::CodeSequenceMacro(IODComponent* parent) : IODComponent(parent) { // reset element rules resetRules(); } CodeSequenceMacro::CodeSequenceMacro(const CodeSequenceMacro& rhs) : IODComponent(rhs) { } CodeSequenceMacro::~CodeSequenceMacro() { // nothing to do } CodeSequenceMacro::CodeSequenceMacro(const OFString& codeValue, const OFString& codingSchemeDesignator, const OFString& codeMeaning, const OFString& codingSchemeVersion, IODComponent* parent) : IODComponent(parent) { // reset element rules resetRules(); set(codeValue, codingSchemeDesignator, codeMeaning, codingSchemeVersion); } OFCondition CodeSequenceMacro::check(const bool /* quiet */) { OFString val; getCodeValue(val); if (!val.empty()) getCodingSchemeDesignator(val); if (!val.empty()) getCodeMeaning(val); if (!val.empty()) return EC_Normal; return EC_IllegalParameter; } CodeSequenceMacro::CodeSequenceMacro(OFshared_ptr item, OFshared_ptr rules, IODComponent* parent, const OFString& codeValue, const OFString& codingSchemeDesignator, const OFString& codeMeaning, const OFString& codingSchemeVersion) : IODComponent(item, rules, parent) { // reset element rules resetRules(); set(codeValue, codingSchemeDesignator, codeMeaning, codingSchemeVersion); } OFString CodeSequenceMacro::getName() const { return "CodeSequenceMacro"; } void CodeSequenceMacro::resetRules() { m_Rules->addRule(new IODRule(DCM_CodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); m_Rules->addRule(new IODRule(DCM_URNCodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); m_Rules->addRule(new IODRule(DCM_LongCodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); m_Rules->addRule(new IODRule(DCM_CodingSchemeDesignator, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); m_Rules->addRule(new IODRule(DCM_CodingSchemeVersion, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); m_Rules->addRule(new IODRule(DCM_CodeMeaning, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue /*overwrite old rule*/); } // -- get dicom attributes -- OFCondition CodeSequenceMacro::getCodeValue(OFString& value, const signed long pos, const OFBool autoTag) { OFString c; OFCondition cond = DcmIODUtil::getStringValueFromItem(DCM_CodeValue, *m_Item, value, pos); if (cond.good() || ((cond == EC_TagNotFound) && !autoTag)) return cond; cond = DcmIODUtil::getStringValueFromItem(DCM_URNCodeValue, *m_Item, value, pos); if (cond != EC_TagNotFound) return cond; cond = DcmIODUtil::getStringValueFromItem(DCM_LongCodeValue, *m_Item, value, pos); return cond; } OFCondition CodeSequenceMacro::getURNCodeValue(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_URNCodeValue, *m_Item, value, pos); } OFCondition CodeSequenceMacro::getLongCodeValue(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_LongCodeValue, *m_Item, value, pos); } OFCondition CodeSequenceMacro::getCodingSchemeDesignator(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_CodingSchemeDesignator, *m_Item, value, pos); } OFCondition CodeSequenceMacro::getCodingSchemeVersion(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_CodingSchemeVersion, *m_Item, value, pos); } OFCondition CodeSequenceMacro::getCodeMeaning(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_CodeMeaning, *m_Item, value, pos); } OFBool CodeSequenceMacro::empty() { OFString val; getCodeValue(val); if (val.empty()) { getCodingSchemeDesignator(val); if (val.empty()) { getCodingSchemeVersion(val); if (val.empty()) { getCodingSchemeDesignator(val); if (val.empty()) { return OFTrue; } } } } return OFFalse; } // -- set dicom attributes -- OFCondition CodeSequenceMacro::setCodeValue(const OFString& value, const OFBool checkValue, const OFBool autoTag) { OFCondition result; // Identify the code value tag to be used if (autoTag) { if ((value.find("://") != OFString_npos) || (value.compare(0, 4, "urn:") == 0)) { return setURNCodeValue(value, checkValue); } else if (value.length() > 16) // Long Code Value { return setLongCodeValue(value, checkValue); } } // Classic Code Value result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal; if (result.bad()) return result; // TODO: Should check length in characters (not bytes), since SH permits usage of // non-ASCII characters (i.e. as defined in 0008,0015). if (value.length() > 16) return EC_MaximumLengthViolated; result = m_Item->putAndInsertOFStringArray(DCM_CodeValue, value); if (result.good()) { deleteUnusedCodeValues(DCM_CodeValue); } return result; } OFCondition CodeSequenceMacro::setURNCodeValue(const OFString& value, const bool checkValue) { OFCondition result = (checkValue) ? DcmUniversalResourceIdentifierOrLocator::checkStringValue(value) : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_URNCodeValue, value); if (result.good()) { deleteUnusedCodeValues(DCM_URNCodeValue); } return result; } OFCondition CodeSequenceMacro::setLongCodeValue(const OFString& value, const bool checkValue) { OFCondition result = (checkValue) ? DcmUnlimitedCharacters::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_LongCodeValue, value); if (result.good()) { deleteUnusedCodeValues(DCM_LongCodeValue); } return result; } OFCondition CodeSequenceMacro::setCodingSchemeDesignator(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_CodingSchemeDesignator, value); return result; } OFCondition CodeSequenceMacro::setCodingSchemeVersion(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_CodingSchemeVersion, value); return result; } OFCondition CodeSequenceMacro::setCodeMeaning(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_CodeMeaning, value); return result; } OFCondition CodeSequenceMacro::set(const OFString& value, const OFString& scheme, const OFString& meaning, const OFString& schemeVersion, const OFBool checkValue, const OFBool autoTag) { OFCondition result; result = setCodeValue(value, checkValue, autoTag); if (result.good()) result = setCodingSchemeDesignator(scheme, checkValue); if (result.good()) result = setCodeMeaning(meaning, checkValue); if (result.good() && !schemeVersion.empty()) result = setCodingSchemeVersion(schemeVersion, checkValue); return result; } void CodeSequenceMacro::deleteUnusedCodeValues(const DcmTagKey& keepTag) { if (keepTag != DCM_CodeValue) m_Item->findAndDeleteElement(DCM_CodeValue); if (keepTag != DCM_URNCodeValue) m_Item->findAndDeleteElement(DCM_URNCodeValue); if (keepTag != DCM_LongCodeValue) m_Item->findAndDeleteElement(DCM_LongCodeValue); } // ---------------------- CodeWithModifiers---------------------- CodeWithModifiers::CodeWithModifiers(const OFString& modifierType, const OFString& modifierVM, const DcmTagKey& modifierSeq) : CodeSequenceMacro() , m_Modifiers() , m_ModifierType(modifierType) , m_ModifierVM(modifierVM) , m_CodeModifierSeq(modifierSeq) { resetRules(); } CodeWithModifiers::CodeWithModifiers(const CodeWithModifiers& rhs) : CodeSequenceMacro(rhs) , m_Modifiers() , m_ModifierType() , m_ModifierVM() , m_CodeModifierSeq() { if (&rhs == this) return; *this = rhs; } CodeWithModifiers& CodeWithModifiers::operator=(const CodeWithModifiers& rhs) { if (&rhs == this) return *this; CodeSequenceMacro::operator=(rhs); const CodeWithModifiers* r = OFstatic_cast(const CodeWithModifiers*, &rhs); if (r) { OFVector::const_iterator it = r->m_Modifiers.begin(); while ((it != r->m_Modifiers.end())) { m_Modifiers.push_back(new CodeSequenceMacro(*it)); it++; } } return *this; } OFCondition CodeWithModifiers::check(const OFBool quiet) { OFCondition result = CodeSequenceMacro::check(quiet); if (result.good()) { OFVector::iterator it = m_Modifiers.begin(); while (result.good() && (it != m_Modifiers.end())) { result = (*it)->check(quiet); it++; } } if (result.bad()) { if (!quiet) { DCMIOD_ERROR("Invalid code in Code Sequence Macro or its modifiers"); } } return result; } void CodeWithModifiers::clearData() { CodeSequenceMacro::clearData(); DcmIODUtil::freeContainer(m_Modifiers); } int CodeWithModifiers::compare(const IODComponent& rhs) const { const CodeWithModifiers* r = OFstatic_cast(const CodeWithModifiers*, &rhs); if (!r) return -1; if (m_Modifiers.size() < r->m_Modifiers.size()) return -1; else if (m_Modifiers.size() > r->m_Modifiers.size()) return 1; int result = IODComponent::compare(*r); if (result == 0) { for (size_t n = 0; (n < m_Modifiers.size()) && (result == 0); n++) { result = m_Modifiers[n]->compare(*r->m_Modifiers[n]); } } return result; } OFString CodeWithModifiers::getName() const { return "CodeWithModifiers"; } OFCondition CodeWithModifiers::addModifier(const CodeSequenceMacro& modifier) { OFCondition result = OFconst_cast(CodeSequenceMacro*, &modifier)->check(); if (result.good()) { m_Modifiers.push_back(new CodeSequenceMacro(modifier)); } return result; } CodeSequenceMacro* CodeWithModifiers::getModifier(const size_t index) { if (index + 1 > m_Modifiers.size()) return NULL; else return m_Modifiers[index]; } OFCondition CodeWithModifiers::read(DcmItem& source, const OFBool clearOldData) { OFCondition result = CodeSequenceMacro::read(source, clearOldData); if (result.good() && clearOldData) { DcmIODUtil::freeContainer(m_Modifiers); } if (result.good()) { result = DcmIODUtil::readSubSequence( source, m_CodeModifierSeq, m_Modifiers, getRules()->getByTag(m_CodeModifierSeq)); } return result; } void CodeWithModifiers::resetRules() { CodeSequenceMacro::resetRules(); m_Rules->addRule( new IODRule(m_CodeModifierSeq, m_ModifierVM, m_ModifierType, getName(), DcmIODTypes::IE_UNDEFINED)); } OFCondition CodeWithModifiers::write(DcmItem& destination) { OFCondition result; DcmIODUtil::writeSubSequence( result, m_CodeModifierSeq, m_Modifiers, getData(), getRules()->getByTag(m_CodeModifierSeq)); if (result.good()) { result = CodeSequenceMacro::write(destination); } return result; } CodeWithModifiers::~CodeWithModifiers() { DcmIODUtil::freeContainer(m_Modifiers); } OFString CodeSequenceMacro::toString() { OFString d, m, v; getCodeValue(v); getCodeMeaning(m); getCodingSchemeDesignator(d); OFStringStream oss; oss << "(" << d << "," << v << "," << m << ")"; OFSTRINGSTREAM_GETOFSTRING(oss, msg); return msg; } // ---------------------- SeriesAndInstanceReferenceMacro---------------------- const OFString IODSeriesAndInstanceReferenceMacro::m_ComponentName = "SeriesAndInstanceReferenceMacro"; const OFString IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::m_ComponentName = "SeriesAndInstanceReferenceMacro"; IODSeriesAndInstanceReferenceMacro::IODSeriesAndInstanceReferenceMacro(OFshared_ptr data, OFshared_ptr rules, IODComponent* parent) : IODComponent(data, rules, parent) , m_ReferencedSeriesItems() { // reset element rules resetRules(); } IODSeriesAndInstanceReferenceMacro::IODSeriesAndInstanceReferenceMacro(IODComponent* parent) : IODComponent(parent) , m_ReferencedSeriesItems() { // reset element rules resetRules(); } OFString IODSeriesAndInstanceReferenceMacro::getName() const { return m_ComponentName; } OFCondition IODSeriesAndInstanceReferenceMacro::read(DcmItem& source, const OFBool clearOldData) { if (clearOldData) clearData(); DcmIODUtil::readSubSequence >( source, DCM_ReferencedSeriesSequence, m_ReferencedSeriesItems, m_Rules->getByTag(DCM_ReferencedSeriesSequence)); return EC_Normal; } OFCondition IODSeriesAndInstanceReferenceMacro::write(DcmItem& destination) { OFCondition result = EC_Normal; DcmIODUtil::writeSubSequence >(result, DCM_ReferencedSeriesSequence, m_ReferencedSeriesItems, destination, m_Rules->getByTag(DCM_ReferencedSeriesSequence)); return result; } void IODSeriesAndInstanceReferenceMacro::clearData() { DcmIODUtil::freeContainer(m_ReferencedSeriesItems); } void IODSeriesAndInstanceReferenceMacro::resetRules() { m_Rules->addRule(new IODRule(DCM_ReferencedSeriesSequence, "1-n", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); } OFVector& IODSeriesAndInstanceReferenceMacro::getReferencedSeriesItems() { return m_ReferencedSeriesItems; } IODSeriesAndInstanceReferenceMacro::~IODSeriesAndInstanceReferenceMacro() { DcmIODUtil::freeContainer(m_ReferencedSeriesItems); } IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::ReferencedSeriesItem(OFshared_ptr item, OFshared_ptr rules, IODComponent* parent) : IODComponent(item, rules, parent) , m_ReferencedInstanceSequence() { // reset element rules resetRules(); } IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::ReferencedSeriesItem(IODComponent* parent) : IODComponent(parent) , m_ReferencedInstanceSequence() { // reset element rules resetRules(); } IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::~ReferencedSeriesItem() { clearData(); } OFString IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getName() const { return m_ComponentName; } void IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::clearData() { DcmIODUtil::freeContainer(m_ReferencedInstanceSequence); IODComponent::clearData(); } OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::read(DcmItem& source, const OFBool clearOldData) { if (clearOldData) clearData(); IODComponent::read(source, clearOldData); DcmIODUtil::readSubSequence(source, DCM_ReferencedInstanceSequence, m_ReferencedInstanceSequence, m_Rules->getByTag(DCM_ReferencedInstanceSequence)); return EC_Normal; } OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::write(DcmItem& destination) { OFCondition result = EC_Normal; DcmIODUtil::writeSubSequence >( result, DCM_ReferencedInstanceSequence, m_ReferencedInstanceSequence, *m_Item, m_Rules->getByTag(DCM_ReferencedInstanceSequence)); result = IODComponent::write(destination); return result; } void IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::resetRules() { // Parameters for Rule are tag, VM, type (1,1C,2,2C,3), module name and logical IOD level m_Rules->addRule(new IODRule(DCM_SeriesInstanceUID, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_Rules->addRule(new IODRule(DCM_ReferencedInstanceSequence, "1-n", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); } OFVector& IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getReferencedInstanceItems() { return m_ReferencedInstanceSequence; } OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getSeriesInstanceUID(OFString& value, const long signed int pos) const { return DcmIODUtil::getStringValueFromItem(DCM_SeriesInstanceUID, *m_Item, value, pos); } OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::setSeriesInstanceUID(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_SeriesInstanceUID, value); return result; } OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::addReference(const OFString& sopClassUID, const OFString& sopInstanceUID) { OFVector::iterator instance = m_ReferencedInstanceSequence.begin(); while (instance != m_ReferencedInstanceSequence.end()) { OFString c, i; (*instance)->getReferencedSOPClassUID(c); (*instance)->getReferencedSOPInstanceUID(i); if (i == sopInstanceUID) { DCMIOD_DEBUG("Skipping doubled instance reference when adding to Series and Instance Reference Macro"); return EC_Normal; } else { instance++; } } // We get here in case that we do not have this reference, add new one SOPInstanceReferenceMacro* macro = new SOPInstanceReferenceMacro(); if (!macro) { return EC_MemoryExhausted; } OFCondition result = macro->setReferencedSOPClassUID(sopClassUID); if (result.good()) result = macro->setReferencedSOPInstanceUID(sopInstanceUID); if (result.good()) { m_ReferencedInstanceSequence.push_back(macro); } else { delete macro; result = IOD_EC_InvalidElementValue; } return result; } // ---------------------- SOPInstanceReferenceMacro ---------------------- SOPInstanceReferenceMacro::SOPInstanceReferenceMacro(OFshared_ptr item, OFshared_ptr rules, IODComponent* parent) : IODComponent(item, rules, parent) { // reset element rules resetRules(); } SOPInstanceReferenceMacro::SOPInstanceReferenceMacro(IODComponent* parent) : IODComponent(parent) { // reset element rules resetRules(); } SOPInstanceReferenceMacro::~SOPInstanceReferenceMacro() { // nothing to do } OFString SOPInstanceReferenceMacro::getName() const { return "SOPInstanceReferenceMacro"; } void SOPInstanceReferenceMacro::resetRules() { // Parameters for Rule are tag, VM, type (1,1C,2,2C,3), module name and logical IOD level m_Rules->addRule(new IODRule(DCM_ReferencedSOPClassUID, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); m_Rules->addRule(new IODRule(DCM_ReferencedSOPInstanceUID, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); } // -- get dicom attributes -- OFCondition SOPInstanceReferenceMacro::getReferencedSOPClassUID(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_ReferencedSOPClassUID, *m_Item, value, pos); } OFCondition SOPInstanceReferenceMacro::getReferencedSOPInstanceUID(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromItem(DCM_ReferencedSOPInstanceUID, *m_Item, value, pos); } // -- set dicom attributes -- OFCondition SOPInstanceReferenceMacro::setReferencedSOPClassUID(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_ReferencedSOPClassUID, value); return result; } OFCondition SOPInstanceReferenceMacro::setReferencedSOPInstanceUID(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_ReferencedSOPInstanceUID, value); return result; } // ---------------------- ImageSOPInstanceReferenceMacro ---------------------- ImageSOPInstanceReferenceMacro::ImageSOPInstanceReferenceMacro() : ReferencedFrameNumber(DCM_ReferencedFrameNumber) , ReferencedSegmentNumber(DCM_ReferencedSegmentNumber) { } OFCondition ImageSOPInstanceReferenceMacro::create(const OFString& sopClassUID, const OFString& sopInstanceUID, ImageSOPInstanceReferenceMacro*& result) { result = new ImageSOPInstanceReferenceMacro(); if (!result) return EC_MemoryExhausted; OFCondition cond = result->setReferencedSOPClassUID(sopClassUID); if (cond.good()) { cond = result->setReferencedSOPInstanceUID(sopInstanceUID); } if (cond.bad()) { delete result; result = NULL; } return cond; } OFCondition ImageSOPInstanceReferenceMacro::create(const OFString& sopClassUID, const OFString& sopInstanceUID, const OFVector& refFramesOrSegments, ImageSOPInstanceReferenceMacro*& result) { OFCondition cond = create(sopClassUID, sopInstanceUID, result); if (cond.good()) { if (!refFramesOrSegments.empty()) { if (sopClassUID == UID_SegmentationStorage) { cond = result->setReferencedSegmentNumber(refFramesOrSegments); } else { cond = result->setReferencedFrameNumber(refFramesOrSegments); } } if (cond.bad()) { delete result; result = NULL; } } return cond; } ImageSOPInstanceReferenceMacro::~ImageSOPInstanceReferenceMacro() { } int ImageSOPInstanceReferenceMacro::compare(const IODComponent& rhs) const { const ImageSOPInstanceReferenceMacro* macro = OFstatic_cast(const ImageSOPInstanceReferenceMacro*, &rhs); if (macro == NULL) return -1; int result = ReferencedFrameNumber.compare(macro->ReferencedFrameNumber); if (result == 0) ReferencedSegmentNumber.compare(macro->ReferencedSegmentNumber); if (result == 0) return SOPInstanceReferenceMacro::compare(rhs); return result; } void ImageSOPInstanceReferenceMacro::clear() { SOPInstanceReferenceMacro::clearData(); ReferencedFrameNumber.clear(); ReferencedSegmentNumber.clear(); } OFCondition ImageSOPInstanceReferenceMacro::read(DcmItem& source, const OFBool clearOldData) { /* re-initialize object */ if (clearOldData) clear(); OFCondition result = SOPInstanceReferenceMacro::read(source, clearOldData); DcmIODUtil::getAndCheckElementFromDataset( source, ReferencedFrameNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro"); DcmIODUtil::getAndCheckElementFromDataset( source, ReferencedSegmentNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro"); return result; } OFCondition ImageSOPInstanceReferenceMacro::write(DcmItem& item) { OFCondition result = EC_Normal; /* copy all elements to dataset */ DcmIODUtil::copyElementToDataset( result, item, ReferencedFrameNumber, "1-n" /* VM */, "1C" /* Type */, "ImageSOPInstanceReferenceMacro"); DcmIODUtil::copyElementToDataset( result, item, ReferencedSegmentNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro"); if (result.good()) result = SOPInstanceReferenceMacro::write(item); return result; } // -- get dicom attributes -- OFCondition ImageSOPInstanceReferenceMacro::getReferencedFrameNumber(OFVector& values) { // cast away const since underlying dcmdata routine is not const... DcmIntegerString* is = OFconst_cast(DcmIntegerString*, &ReferencedFrameNumber); for (size_t n = 0; n < is->getNumberOfValues(); n++) { Sint32 sint = 0; is->getSint32(sint, OFstatic_cast(unsigned long, n)); if (sint < 0) { DCMIOD_WARN("Invalid Referenced Frame Number in Image SOP Instance Reference Macro: " << sint); return EC_CorruptedData; } values.push_back(OFstatic_cast(Uint16, sint)); } return EC_Normal; } OFCondition ImageSOPInstanceReferenceMacro::getReferencedSegmentNumber(OFVector& values) { // cast away const since underlying dcmdata routine is not const... DcmUnsignedShort* us = OFconst_cast(DcmUnsignedShort*, &ReferencedSegmentNumber); return DcmIODUtil::getUint16ValuesFromElement(*us, values); } // -- set dicom attributes -- OFCondition ImageSOPInstanceReferenceMacro::setReferencedFrameNumber(const OFVector& values, const OFBool checkValue) { return DcmIODUtil::setUint16ValuesOnElement(ReferencedFrameNumber, values, "1-n", checkValue); } OFCondition ImageSOPInstanceReferenceMacro::addReferencedFrameNumber(const Uint16& value, const OFBool checkValue) { (void)checkValue; OFString val; ReferencedFrameNumber.getOFStringArray(val); if (ReferencedFrameNumber.getNumberOfValues() > 0) { val += "\\"; } char buf[10]; sprintf(buf, "%u", value); val += buf; return ReferencedFrameNumber.putOFStringArray(val); } OFCondition ImageSOPInstanceReferenceMacro::setReferencedSegmentNumber(const OFVector& values, const OFBool checkValue) { return DcmIODUtil::setUint16ValuesOnElement(ReferencedSegmentNumber, values, "1-n", checkValue); } OFCondition ImageSOPInstanceReferenceMacro::addReferencedSegmentNumber(const Uint16& value, const OFBool checkValue) { (void)checkValue; const unsigned long count = ReferencedSegmentNumber.getNumberOfValues(); return ReferencedSegmentNumber.putUint16(value, count /* starts with 0, so add new value at the end */); } // ---------------------- GeneralAnatomyMacro ---------------------- GeneralAnatomyMacro::GeneralAnatomyMacro(const OFString& type) : m_Type(type) , m_AnatomicRegion() , m_AnatomicRegionModifier() , m_PrimaryAnatomicStructure("3" /* Modifier in Primary Anatomic Structure is always optional */, "1", DCM_PrimaryAnatomicStructureModifierSequence) { m_Type = type; } GeneralAnatomyMacro::GeneralAnatomyMacro(const GeneralAnatomyMacro& rhs) : m_Type(rhs.m_Type) , m_AnatomicRegion() , m_AnatomicRegionModifier() , m_PrimaryAnatomicStructure("3" /* Modifier in Primary Anatomic Structure is always optional */, "1", DCM_PrimaryAnatomicStructureModifierSequence) { *this = rhs; } GeneralAnatomyMacro& GeneralAnatomyMacro::operator=(const GeneralAnatomyMacro& rhs) { if (this != &rhs) { clearData(); m_Type = rhs.m_Type; m_AnatomicRegion = rhs.m_AnatomicRegion; m_PrimaryAnatomicStructure = rhs.m_PrimaryAnatomicStructure; OFVector::const_iterator it = rhs.m_AnatomicRegionModifier.begin(); while (it != rhs.m_AnatomicRegionModifier.end()) { m_AnatomicRegionModifier.push_back(new CodeSequenceMacro(**it)); it++; } } return *this; } GeneralAnatomyMacro::~GeneralAnatomyMacro() { clearData(); } void GeneralAnatomyMacro::clearData() { // m_Type stays the same m_AnatomicRegion.clearData(); DcmIODUtil::freeContainer(m_AnatomicRegionModifier); m_PrimaryAnatomicStructure.clearData(); } OFCondition GeneralAnatomyMacro::check(const OFBool quiet) { OFCondition result = m_AnatomicRegion.check(quiet); if (result.bad()) return result; OFVector::iterator it = m_AnatomicRegionModifier.begin(); while (it != m_AnatomicRegionModifier.begin()) { result = (*it)->check(quiet); if (result.bad()) return result; it++; } // Primary Anatomic Structure is optional (type 3), so only check if // user intended to fill in something. if (!m_PrimaryAnatomicStructure.empty()) { result = m_PrimaryAnatomicStructure.check(quiet); } return result; } CodeSequenceMacro& GeneralAnatomyMacro::getAnatomicRegion() { return m_AnatomicRegion; } OFVector& GeneralAnatomyMacro::getAnatomicRegionModifier() { return m_AnatomicRegionModifier; } PrimaryAnatomicStructureMacro& GeneralAnatomyMacro::getPrimaryAnatomicStructure() { return m_PrimaryAnatomicStructure; } // Reads Anatomic Region Sequence and Primary Anatomic Structure Macro from given item OFCondition GeneralAnatomyMacro::read(DcmItem& source, const OFBool clearOldData) { OFCondition result = EC_Normal; /* re-initialize object */ if (clearOldData) clearData(); /* read Anatomic Region Sequence item into Code Sequence Macro */ DcmIODUtil::readSingleItem( source, DCM_AnatomicRegionSequence, m_AnatomicRegion, m_Type, "GeneralAnatomyMacro"); /* read Primary Anatomic Structure Macro (main level, i.e.\ original item) */ DcmIODUtil::readSingleItem( source, DCM_PrimaryAnatomicStructureSequence, m_PrimaryAnatomicStructure, "3", "GeneralAnatomyMacro"); /* Get the single item from Anatomic Region Sequence and read modifier if found */ DcmItem* localItem = NULL; if (source.findAndGetSequenceItem(DCM_AnatomicRegionSequence, localItem).bad()) { return result; } /* read Anatomic Region Modifier Sequence from */ DcmIODUtil::readSubSequence >(*localItem, /* item of Anatomic Region Sequence */ DCM_AnatomicRegionModifierSequence, m_AnatomicRegionModifier, "1-n", "3", "GeneralAnatomyMacro"); return result; } /// Write Anatomic Region Sequence from given item OFCondition GeneralAnatomyMacro::write(DcmItem& item) { OFCondition result = EC_Normal; /* delete old data */ item.findAndDeleteElement(DCM_AnatomicRegionSequence); item.findAndDeleteElement(DCM_PrimaryAnatomicStructureSequence); /* Write sub structures */ DcmIODUtil::writeSingleItem( result, DCM_AnatomicRegionSequence, m_AnatomicRegion, item, m_Type, "GeneralAnatomyMacro"); if (result.good()) { DcmItem* seqItem = NULL; result = item.findAndGetSequenceItem(DCM_AnatomicRegionSequence, seqItem, 0); if (result.good()) { DcmIODUtil::writeSubSequence >(result, DCM_AnatomicRegionModifierSequence, m_AnatomicRegionModifier, *seqItem, "1-n", "3", "GeneralAnatomyMacro"); } } DcmIODUtil::writeSingleItem( result, DCM_PrimaryAnatomicStructureSequence, m_PrimaryAnatomicStructure, item, "3", "GeneralAnatomyMacro"); return result; } int GeneralAnatomyMacro::compare(const GeneralAnatomyMacro& rhs) const { int result = m_AnatomicRegion.compare(rhs.m_AnatomicRegion); if (result == 0) { if (m_AnatomicRegionModifier.size() > rhs.m_AnatomicRegionModifier.size()) { return 1; } else if (m_AnatomicRegionModifier.size() < rhs.m_AnatomicRegionModifier.size()) { return -1; } for (size_t m = 0; m < m_AnatomicRegionModifier.size(); m++) { result = m_AnatomicRegionModifier[m]->compare(*(rhs.m_AnatomicRegionModifier[m])); if (result != 0) { return result; } } result = m_PrimaryAnatomicStructure.compare(rhs.m_PrimaryAnatomicStructure); } return result; } // ---------------------- AlgorithmIdentificationMacro ---------------------- AlgorithmIdentificationMacro::AlgorithmIdentificationMacro() : m_AlgorithmFamilyCode() , m_AlgorithmNameCode() , m_AlgorithmName(DCM_AlgorithmName) , m_AlgorithmVersion(DCM_AlgorithmVersion) , m_AlgorithmParameters(DCM_AlgorithmParameters) , m_AlgorithmSource(DCM_AlgorithmSource) { } // AlgorithmIdentificationMacro::~AlgorithmIdentificationMacro() { clearData(); } void AlgorithmIdentificationMacro::clearData() { m_AlgorithmFamilyCode.clearData(); m_AlgorithmNameCode.clearData(); m_AlgorithmName.clear(); m_AlgorithmVersion.clear(); m_AlgorithmParameters.clear(); m_AlgorithmSource.clear(); } OFCondition AlgorithmIdentificationMacro::check(const OFBool quiet) { OFCondition result; result = m_AlgorithmFamilyCode.check(quiet); if (result.good()) { if (m_AlgorithmName.isEmpty() || m_AlgorithmVersion.isEmpty()) { result = EC_MissingValue; } } return result; } CodeSequenceMacro& AlgorithmIdentificationMacro::getAlgorithmFamilyCode() { return m_AlgorithmFamilyCode; } CodeSequenceMacro& AlgorithmIdentificationMacro::getAlgorithmNameCode() { return m_AlgorithmNameCode; } OFCondition AlgorithmIdentificationMacro::getAlgorithmName(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromElement(m_AlgorithmName, value, pos); } OFCondition AlgorithmIdentificationMacro::getAlgorithmVersion(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromElement(m_AlgorithmVersion, value, pos); } OFCondition AlgorithmIdentificationMacro::getAlgorithmParameters(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromElement(m_AlgorithmParameters, value, pos); } OFCondition AlgorithmIdentificationMacro::getAlgorithmSource(OFString& value, const signed long pos) { return DcmIODUtil::getStringValueFromElement(m_AlgorithmSource, value, pos); } OFCondition AlgorithmIdentificationMacro::setAlgorithmName(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_AlgorithmName.putOFStringArray(value); return result; } OFCondition AlgorithmIdentificationMacro::setAlgorithmVersion(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_AlgorithmVersion.putOFStringArray(value); return result; } OFCondition AlgorithmIdentificationMacro::setAlgorithmParameters(const OFString& value, const OFBool checkValue) { (void)checkValue; return m_AlgorithmParameters.putOFStringArray(value); } OFCondition AlgorithmIdentificationMacro::setAlgorithmSource(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_AlgorithmSource.putOFStringArray(value); return result; } /// Reads Anatomic Region Sequence and Primary Anatomic Structure Macro from given item OFCondition AlgorithmIdentificationMacro::read(DcmItem& source, const OFBool clearOldData) { OFCondition result; if (clearOldData) clearData(); DcmIODUtil::readSingleItem( source, DCM_AlgorithmFamilyCodeSequence, m_AlgorithmFamilyCode, "1", "AlgorithmIdentificationMacro"); DcmIODUtil::readSingleItem( source, DCM_AlgorithmNameCodeSequence, m_AlgorithmNameCode, "3", "AlgorithmIdentificationMacro"); DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmName, "1", "1", "AlgorithmIdentificationMacro"); DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmVersion, "1", "1", "AlgorithmIdentificationMacro"); DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmParameters, "1", "3", "AlgorithmIdentificationMacro"); DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmSource, "1", "3", "AlgorithmIdentificationMacro"); return result; } OFCondition AlgorithmIdentificationMacro::write(DcmItem& item) { OFCondition result = EC_Normal; // write to item DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmName, "1", "1", "AlgorithmIdentificationMacro"); DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmVersion, "1", "1", "AlgorithmIdentificationMacro"); DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmParameters, "1", "3", "AlgorithmIdentificationMacro"); DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmSource, "1", "3", "AlgorithmIdentificationMacro"); DcmIODUtil::writeSingleItem( result, DCM_AlgorithmFamilyCodeSequence, m_AlgorithmFamilyCode, item, "1", "AlgorithmIdentificationMacro"); DcmIODUtil::writeSingleItem( result, DCM_AlgorithmNameCodeSequence, m_AlgorithmNameCode, item, "3", "AlgorithmIdentificationMacro"); return result; } // ---------------------- ContentIdentificationMacro ---------------------- ContentIdentificationMacro::ContentIdentificationMacro() : m_InstanceNumber(DCM_InstanceNumber) , m_ContentLabel(DCM_ContentLabel) , m_ContentDescription(DCM_ContentDescription) , m_AlternateContentDescription() , m_ContentCreatorName(DCM_ContentCreatorName) , m_ContentCreatorIdentificationCode() , m_IODRules() { resetRules(); } ContentIdentificationMacro::ContentIdentificationMacro(const OFString& instanceNumber, const OFString& contentLabel, const OFString& contentDescription, const OFString& contentCreatorName) : m_InstanceNumber(DCM_InstanceNumber) , m_ContentLabel(DCM_ContentLabel) , m_ContentDescription(DCM_ContentDescription) , m_AlternateContentDescription() , m_ContentCreatorName(DCM_ContentCreatorName) , m_ContentCreatorIdentificationCode() , m_IODRules() { resetRules(); setInstanceNumber(instanceNumber); setContentLabel(contentLabel); setContentDescription(contentDescription); setContentCreatorName(contentCreatorName); } void ContentIdentificationMacro::resetRules() { m_IODRules.addRule(new IODRule(DCM_InstanceNumber, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_IODRules.addRule(new IODRule(DCM_ContentLabel, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_IODRules.addRule(new IODRule(DCM_ContentDescription, "1", "2", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_IODRules.addRule(new IODRule(DCM_ContentCreatorName, "1", "2", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_IODRules.addRule( new IODRule(DCM_AlternateContentDescriptionSequence, "1-n", "3", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); m_IODRules.addRule( new IODRule(DCM_ContentCreatorIdentificationCodeSequence, "1", "3", getName(), DcmIODTypes::IE_INSTANCE), OFTrue); } OFString ContentIdentificationMacro::getName() const { return "ContentIdentificationMacro"; } IODRules& ContentIdentificationMacro::getIODRules() { return m_IODRules; } ContentIdentificationMacro::ContentIdentificationMacro(const ContentIdentificationMacro& rhs) : m_InstanceNumber(DCM_InstanceNumber) , m_ContentLabel(DCM_ContentLabel) , m_ContentDescription(DCM_ContentDescription) , m_AlternateContentDescription() , m_ContentCreatorName(DCM_ContentCreatorName) , m_ContentCreatorIdentificationCode() , m_IODRules() { if (&rhs != this) { resetRules(); m_InstanceNumber = rhs.m_InstanceNumber; m_ContentLabel = rhs.m_ContentLabel; m_ContentDescription = rhs.m_ContentDescription; m_ContentCreatorName = rhs.m_ContentCreatorName; m_ContentCreatorIdentificationCode = rhs.m_ContentCreatorIdentificationCode; /* perform deep vector copy */ OFVector::const_iterator it = rhs.m_AlternateContentDescription.begin(); while (it != rhs.m_AlternateContentDescription.end()) { m_AlternateContentDescription.push_back(new AlternateContentDescriptionItem(**it)); it++; } } } OFCondition ContentIdentificationMacro::create(const OFString& instanceNumber, const OFString& contentLabel, const OFString& contentDescription, const OFString& contentCreatorName, ContentIdentificationMacro*& result) { result = new ContentIdentificationMacro(); if (!result) return EC_MemoryExhausted; OFCondition cond = result->setInstanceNumber(instanceNumber); if (cond.good()) { cond = result->setContentLabel(contentLabel); } if (cond.good()) { cond = result->setContentDescription(contentDescription); } if (cond.good()) { cond = result->setContentCreatorName(contentCreatorName); } if (cond.good()) { cond = result->check(); } if (cond.bad()) { delete result; result = NULL; } return cond; } ContentIdentificationMacro& ContentIdentificationMacro::operator=(const ContentIdentificationMacro& rhs) { if (&rhs != this) { this->clearData(); m_InstanceNumber = rhs.m_InstanceNumber; m_ContentLabel = rhs.m_ContentLabel; m_ContentDescription = rhs.m_ContentDescription; m_ContentCreatorName = rhs.m_ContentCreatorName; m_ContentCreatorIdentificationCode = rhs.m_ContentCreatorIdentificationCode; /* perform deep vector copy */ OFVector::const_iterator it = rhs.m_AlternateContentDescription.begin(); while (it != rhs.m_AlternateContentDescription.end()) { AlternateContentDescriptionItem* newItem = new AlternateContentDescriptionItem(); *newItem = **it; m_AlternateContentDescription.push_back(newItem); it++; } } return *this; } ContentIdentificationMacro::~ContentIdentificationMacro() { clearData(); } void ContentIdentificationMacro::clearData() { m_InstanceNumber.clear(); m_ContentLabel.clear(); m_ContentDescription.clear(); DcmIODUtil::freeContainer(m_AlternateContentDescription); m_ContentCreatorName.clear(); m_ContentCreatorIdentificationCode.clearData(); } OFCondition ContentIdentificationMacro::check(const OFBool quiet) { (void)quiet; OFCondition result; OFBool failure = m_ContentLabel.isEmpty() || m_InstanceNumber.isEmpty(); if (!failure) { if (!m_AlternateContentDescription.empty()) // type 3 { OFVector::iterator it = m_AlternateContentDescription.begin(); while (it != m_AlternateContentDescription.end() && !failure) { OFString str; (*it)->getContentDescription(str).good(); // type 1 failure = str.empty(); if (!failure) { OFString meaning, value, designator; (*it)->getLanguageCode().getCodeMeaning(meaning); (*it)->getLanguageCode().getCodeValue(value); (*it)->getLanguageCode().getCodeValue(designator); failure = meaning.empty() || value.empty() || designator.empty(); } it++; } } } if (failure) result = EC_IllegalParameter; return result; } OFCondition ContentIdentificationMacro::getInstanceNumber(OFString& value, const signed long pos) const { return DcmIODUtil::getStringValueFromElement(m_InstanceNumber, value, pos); } OFCondition ContentIdentificationMacro::getContentLabel(OFString& value, const signed long pos) const { return DcmIODUtil::getStringValueFromElement(m_ContentLabel, value, pos); } OFCondition ContentIdentificationMacro::getContentDescription(OFString& value, const signed long pos) const { return DcmIODUtil::getStringValueFromElement(m_ContentDescription, value, pos); } OFCondition ContentIdentificationMacro::getContentCreatorName(OFString& value, const signed long pos) const { return DcmIODUtil::getStringValueFromElement(m_ContentCreatorName, value, pos); } CodeSequenceMacro& ContentIdentificationMacro::getContentCreatorIdentificationCode() { return m_ContentCreatorIdentificationCode; } OFVector& ContentIdentificationMacro::getAlternateContentDescription() { return m_AlternateContentDescription; } OFCondition ContentIdentificationMacro::setInstanceNumber(const OFString& value, const OFBool checkValue) { OFCondition result; if (checkValue) { result = (checkValue) ? DcmIntegerString::checkStringValue(value, "1") : EC_Normal; } if (result.good()) { result = m_InstanceNumber.putOFStringArray(value); } return result; } OFCondition ContentIdentificationMacro::setContentLabel(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmCodeString::checkStringValue(value, m_IODRules.getByTag(DCM_ContentLabel)->getVM()) : EC_Normal; if (result.good()) result = m_ContentLabel.putOFStringArray(value); return result; } OFCondition ContentIdentificationMacro::setContentDescription(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, m_IODRules.getByTag(DCM_ContentDescription)->getVM()) : EC_Normal; if (result.good()) result = m_ContentDescription.putOFStringArray(value); return result; } OFCondition ContentIdentificationMacro::setContentCreatorName(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmPersonName::checkStringValue(value, m_IODRules.getByTag(DCM_ContentCreatorName)->getVM()) : EC_Normal; if (result.good()) result = m_ContentCreatorName.putOFStringArray(value); return result; } OFCondition ContentIdentificationMacro::read(DcmItem& source, const OFBool clearOldData) { OFCondition result; if (clearOldData) clearData(); /* flat elements */ DcmIODUtil::getAndCheckElementFromDataset(source, m_InstanceNumber, m_IODRules.getByTag(DCM_InstanceNumber)); DcmIODUtil::getAndCheckElementFromDataset(source, m_ContentLabel, m_IODRules.getByTag(DCM_ContentLabel)); DcmIODUtil::getAndCheckElementFromDataset( source, m_ContentDescription, m_IODRules.getByTag(DCM_ContentDescription)); DcmIODUtil::getAndCheckElementFromDataset( source, m_ContentCreatorName, m_IODRules.getByTag(DCM_ContentCreatorName)); /* sub sequences */ IODRule* rule = m_IODRules.getByTag(DCM_AlternateContentDescriptionSequence); DcmIODUtil::readSubSequence >(source, DCM_AlternateContentDescriptionSequence, m_AlternateContentDescription, rule->getVM(), rule->getType(), "ContentIdentificationMacro"); rule = m_IODRules.getByTag(DCM_ContentCreatorIdentificationCodeSequence); DcmIODUtil::readSingleItem(source, DCM_ContentCreatorIdentificationCodeSequence, m_ContentCreatorIdentificationCode, rule->getType(), "ContentIdentificationMacro"); return result; } OFCondition ContentIdentificationMacro::write(DcmItem& item) { OFCondition result = EC_Normal; /* flat elements */ DcmIODUtil::copyElementToDataset(result, item, m_InstanceNumber, m_IODRules.getByTag(DCM_InstanceNumber)); DcmIODUtil::copyElementToDataset(result, item, m_ContentLabel, m_IODRules.getByTag(DCM_ContentLabel)); DcmIODUtil::copyElementToDataset(result, item, m_ContentDescription, m_IODRules.getByTag(DCM_ContentDescription)); DcmIODUtil::copyElementToDataset(result, item, m_ContentCreatorName, m_IODRules.getByTag(DCM_ContentCreatorName)); IODRule* rule = m_IODRules.getByTag(DCM_ContentCreatorIdentificationCodeSequence); DcmIODUtil::writeSingleItem(result, DCM_ContentCreatorIdentificationCodeSequence, m_ContentCreatorIdentificationCode, item, rule->getType(), "ContentIdentificationMacro"); rule = m_IODRules.getByTag(DCM_AlternateContentDescriptionSequence); DcmIODUtil::writeSubSequence >( result, DCM_AlternateContentDescriptionSequence, m_AlternateContentDescription, item, rule->getVM(), rule->getType(), "ContentIdentificationMacro"); return result; } // ---------------- ContentIdentificationMacro::AlternateContentDescriptionItem ----------------- ContentIdentificationMacro::AlternateContentDescriptionItem::AlternateContentDescriptionItem() : m_ContentDescription(DCM_ContentDescription) , m_LanguageCode() { // nothing to do } ContentIdentificationMacro::AlternateContentDescriptionItem::~AlternateContentDescriptionItem() { m_LanguageCode.clearData(); } void ContentIdentificationMacro::AlternateContentDescriptionItem::clearData() { m_ContentDescription.clear(); m_LanguageCode.clearData(); } OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::read(DcmItem& source, const OFBool clearOldData) { OFCondition result; if (clearOldData) clearData(); DcmIODUtil::getAndCheckElementFromDataset(source, m_ContentDescription, "1", "1", "ContentIdentificationMacro"); DcmIODUtil::readSingleItem( source, DCM_LanguageCodeSequence, m_LanguageCode, "1", "ContentIdentificationMacro"); return result; } OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::getContentDescription(OFString& value, const long signed int pos) { return DcmIODUtil::getStringValueFromElement(m_ContentDescription, value, pos); } CodeSequenceMacro& ContentIdentificationMacro::AlternateContentDescriptionItem::getLanguageCode() { return m_LanguageCode; } OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::write(DcmItem& item) { OFCondition result = EC_Normal; // write to item DcmIODUtil::copyElementToDataset(result, item, m_ContentDescription, "1", "1", "ContentIdentificationMacro"); DcmIODUtil::writeSingleItem( result, DCM_LanguageCodeSequence, m_LanguageCode, item, "1", "ContentIdentificationMacro"); return result; } OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::setContentDescription(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_ContentDescription.putOFStringArray(value); return result; } // -------------------- HL7HierarchicDesignatorMacro -------------------- HL7HierarchicDesignatorMacro::HL7HierarchicDesignatorMacro(IODComponent* parent) : IODComponent(parent) { // reset element rules resetRules(); } HL7HierarchicDesignatorMacro::HL7HierarchicDesignatorMacro(OFshared_ptr item, OFshared_ptr rules, IODComponent* parent) : IODComponent(item, rules, parent) { // reset element rules resetRules(); } OFCondition HL7HierarchicDesignatorMacro::getUniversalEntityID(OFString& value, const long signed int pos) const { return DcmIODUtil::getStringValueFromItem(DCM_UniversalEntityID, *m_Item, value, pos); } OFCondition HL7HierarchicDesignatorMacro::getLocalNamespaceEntityID(OFString& value, const long signed int pos) const { return DcmIODUtil::getStringValueFromItem(DCM_LocalNamespaceEntityID, *m_Item, value, pos); } OFCondition HL7HierarchicDesignatorMacro::getUniversalEntityIDType(OFString& value, const long signed int pos) const { return DcmIODUtil::getStringValueFromItem(DCM_UniversalEntityIDType, *m_Item, value, pos); } OFString HL7HierarchicDesignatorMacro::getName() const { return "HL7HierarchicDesignatorMacro"; } void HL7HierarchicDesignatorMacro::resetRules() { // parameters are tag, VM, type. Overwrite old rules if any. m_Rules->addRule(new IODRule(DCM_UniversalEntityID, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); m_Rules->addRule(new IODRule(DCM_LocalNamespaceEntityID, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); m_Rules->addRule(new IODRule(DCM_UniversalEntityIDType, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); } OFCondition HL7HierarchicDesignatorMacro::setLocalNamespaceEntityID(const OFString& value, const OFBool checkValue) { (void)checkValue; return m_Item->putAndInsertOFStringArray(DCM_LocalNamespaceEntityID, value); } OFCondition HL7HierarchicDesignatorMacro::setUniversalEntityID(const OFString& value, const OFBool checkValue) { (void)checkValue; return m_Item->putAndInsertOFStringArray(DCM_UniversalEntityID, value); } OFCondition HL7HierarchicDesignatorMacro::setUniversalEntityIDType(const OFString& value, const OFBool checkValue) { OFCondition result = (checkValue) ? DcmCodeString::checkStringValue(value, "1") : EC_Normal; if (result.good()) result = m_Item->putAndInsertOFStringArray(DCM_UniversalEntityIDType, value); return result; } // -------------------- Mandatory View and Slice Progression Direction Macro -------------------- MandatoryViewAndSliceProgressionDirectionMacro::MandatoryViewAndSliceProgressionDirectionMacro( OFshared_ptr item, OFshared_ptr rules, IODComponent* parent) : IODComponent(item, rules, parent) , m_ViewCodeSequence() , m_ViewModifierCode() { resetRules(); } MandatoryViewAndSliceProgressionDirectionMacro::MandatoryViewAndSliceProgressionDirectionMacro(IODComponent* parent) : IODComponent(parent) , m_ViewCodeSequence() , m_ViewModifierCode() { resetRules(); } OFString MandatoryViewAndSliceProgressionDirectionMacro::getName() const { return "MandatoryViewAndSliceProgressionDirectionMacro"; } void MandatoryViewAndSliceProgressionDirectionMacro::resetRules() { m_Rules->addRule(new IODRule(DCM_ViewCodeSequence, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); m_Rules->addRule(new IODRule(DCM_ViewModifierCodeSequence, "1-n", "2C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); m_Rules->addRule(new IODRule(DCM_SliceProgressionDirection, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue); } void MandatoryViewAndSliceProgressionDirectionMacro::clearData() { DcmIODUtil::freeContainer(m_ViewModifierCode); m_ViewCodeSequence.clearData(); IODComponent::clearData(); } OFCondition MandatoryViewAndSliceProgressionDirectionMacro::read(DcmItem& source, const OFBool clearOldData) { if (clearOldData) { m_ViewCodeSequence.clearData(); DcmIODUtil::freeContainer(m_ViewModifierCode); } OFCondition result = EC_Normal; DcmIODUtil::readSingleItem( source, DCM_ViewCodeSequence, m_ViewCodeSequence, m_Rules->getByTag(DCM_ViewCodeSequence)); DcmIODUtil::readSubSequence( source, DCM_ViewCodeSequence, m_ViewModifierCode, m_Rules->getByTag(DCM_ViewCodeSequence)); IODComponent::read(source, clearOldData); return EC_Normal; } OFCondition MandatoryViewAndSliceProgressionDirectionMacro::write(DcmItem& item) { OFCondition result = EC_Normal; DcmIODUtil::writeSingleItem( result, DCM_ViewCodeSequence, m_ViewCodeSequence, *m_Item, m_Rules->getByTag(DCM_ViewCodeSequence)); DcmIODUtil::writeSubSequence( result, DCM_ViewCodeSequence, m_ViewModifierCode, *m_Item, m_Rules->getByTag(DCM_ViewModifierCodeSequence)); if (result.good()) result = IODComponent::write(item); return result; } CodeSequenceMacro& MandatoryViewAndSliceProgressionDirectionMacro::getViewCode() { return m_ViewCodeSequence; } OFVector& MandatoryViewAndSliceProgressionDirectionMacro::getViewModifierCode() { return m_ViewModifierCode; }