/*
*
* Copyright (C) 2000-2017, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: dcmsr
*
* Author: Joerg Riesmeier
*
* Purpose:
* classes: DSRSpatialCoordinatesValue
*
*/
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmsr/dsrscovl.h"
#include "dcmtk/dcmsr/dsrxmld.h"
#include "dcmtk/dcmdata/dcdeftag.h"
#include "dcmtk/dcmdata/dcvrui.h"
DSRSpatialCoordinatesValue::DSRSpatialCoordinatesValue()
: GraphicType(DSRTypes::GT_invalid),
GraphicDataList(),
FiducialUID()
{
}
DSRSpatialCoordinatesValue::DSRSpatialCoordinatesValue(const DSRTypes::E_GraphicType graphicType)
: GraphicType(graphicType),
GraphicDataList(),
FiducialUID()
{
}
DSRSpatialCoordinatesValue::DSRSpatialCoordinatesValue(const DSRSpatialCoordinatesValue &coordinatesValue)
: GraphicType(coordinatesValue.GraphicType),
GraphicDataList(coordinatesValue.GraphicDataList),
FiducialUID(coordinatesValue.FiducialUID)
{
}
DSRSpatialCoordinatesValue::~DSRSpatialCoordinatesValue()
{
}
DSRSpatialCoordinatesValue &DSRSpatialCoordinatesValue::operator=(const DSRSpatialCoordinatesValue &coordinatesValue)
{
GraphicType = coordinatesValue.GraphicType;
GraphicDataList = coordinatesValue.GraphicDataList;
FiducialUID = coordinatesValue.FiducialUID;
return *this;
}
OFBool DSRSpatialCoordinatesValue::operator==(const DSRSpatialCoordinatesValue &coordinatesValue) const
{
return (GraphicType == coordinatesValue.GraphicType) &&
(GraphicDataList == coordinatesValue.GraphicDataList) &&
(FiducialUID == coordinatesValue.FiducialUID);
}
OFBool DSRSpatialCoordinatesValue::operator!=(const DSRSpatialCoordinatesValue &coordinatesValue) const
{
return (GraphicType != coordinatesValue.GraphicType) ||
(GraphicDataList != coordinatesValue.GraphicDataList) ||
(FiducialUID != coordinatesValue.FiducialUID);
}
void DSRSpatialCoordinatesValue::clear()
{
GraphicType = DSRTypes::GT_invalid;
GraphicDataList.clear();
FiducialUID.clear();
}
OFBool DSRSpatialCoordinatesValue::isValid() const
{
return checkGraphicData(GraphicType, GraphicDataList).good();
}
OFBool DSRSpatialCoordinatesValue::isShort(const size_t flags) const
{
return GraphicDataList.isEmpty() || ((flags & DSRTypes::HF_renderFullData) == 0);
}
OFCondition DSRSpatialCoordinatesValue::print(STD_NAMESPACE ostream &stream,
const size_t flags) const
{
/* GraphicType */
stream << "(" << DSRTypes::graphicTypeToEnumeratedValue(GraphicType);
/* GraphicData */
if (!GraphicDataList.isEmpty())
{
stream << ",";
GraphicDataList.print(stream, flags);
}
stream << ")";
return EC_Normal;
}
OFCondition DSRSpatialCoordinatesValue::readXML(const DSRXMLDocument &doc,
DSRXMLCursor cursor,
const size_t /*flags*/)
{
OFCondition result = SR_EC_CorruptedXMLStructure;
if (cursor.valid())
{
cursor.gotoChild();
/* GraphicData (required) */
const DSRXMLCursor dataNode = doc.getNamedNode(cursor, "data");
if (dataNode.valid())
{
OFString tmpString;
/* put value to the graphic data list */
result = GraphicDataList.putString(doc.getStringFromNodeContent(dataNode, tmpString).c_str());
}
/* FiducialUID (optional) */
const DSRXMLCursor fiducialNode = doc.getNamedNode(cursor, "fiducial", OFFalse /*required*/);
if (fiducialNode.valid())
doc.getStringFromAttribute(fiducialNode, FiducialUID, "uid");
}
return result;
}
OFCondition DSRSpatialCoordinatesValue::writeXML(STD_NAMESPACE ostream &stream,
const size_t flags) const
{
/* GraphicType is written in TreeNode class */
if ((flags & DSRTypes::XF_writeEmptyTags) || !GraphicDataList.isEmpty())
{
stream << "";
GraphicDataList.print(stream);
stream << "" << OFendl;
}
if ((flags & DSRTypes::XF_writeEmptyTags) || !FiducialUID.empty())
stream << "
" : "
";
if (flags & DSRTypes::HF_currentlyInsideAnnex)
{
docStream << OFendl << "
" << OFendl; /* render graphic data list (= print)*/ docStream << "Graphic Data:" << lineBreak; GraphicDataList.print(docStream); docStream << "
"; } else { DSRTypes::createHTMLAnnexEntry(docStream, annexStream, "for more details see", annexNumber, flags); annexStream << "" << OFendl; /* render graphic data list (= print)*/ annexStream << "Graphic Data:" << lineBreak; GraphicDataList.print(annexStream); annexStream << "
" << OFendl; } } return EC_Normal; } OFCondition DSRSpatialCoordinatesValue::getValue(DSRSpatialCoordinatesValue &coordinatesValue) const { coordinatesValue = *this; return EC_Normal; } OFCondition DSRSpatialCoordinatesValue::setValue(const DSRSpatialCoordinatesValue &coordinatesValue, const OFBool check) { OFCondition result = EC_Normal; if (check) { /* check whether the passed value is valid */ result = checkGraphicData(coordinatesValue.GraphicType, coordinatesValue.GraphicDataList); if (result.good()) result = checkFiducialUID(coordinatesValue.FiducialUID); } else { /* make sure that the mandatory values are non-empty/invalid */ if ((coordinatesValue.GraphicType == DSRTypes::GT_invalid) || coordinatesValue.GraphicDataList.isEmpty()) { result = EC_IllegalParameter; } } if (result.good()) { GraphicType = coordinatesValue.GraphicType; GraphicDataList = coordinatesValue.GraphicDataList; FiducialUID = coordinatesValue.FiducialUID; } return result; } OFCondition DSRSpatialCoordinatesValue::setGraphicType(const DSRTypes::E_GraphicType graphicType, const OFBool /*check*/) { OFCondition result = EC_IllegalParameter; /* check whether the passed value is valid */ if (graphicType != DSRTypes::GT_invalid) { GraphicType = graphicType; result = EC_Normal; } return result; } OFCondition DSRSpatialCoordinatesValue::setFiducialUID(const OFString &fiducialUID, const OFBool check) { OFCondition result = EC_Normal; /* check whether the passed value is valid */ if (check) result = checkFiducialUID(fiducialUID); if (result.good()) FiducialUID = fiducialUID; return result; } // helper macro to avoid annoying check of boolean flag #define REPORT_WARNING(msg) { if (reportWarnings) DCMSR_WARN(msg); } OFCondition DSRSpatialCoordinatesValue::checkGraphicData(const DSRTypes::E_GraphicType graphicType, const DSRGraphicDataList &graphicDataList, const OFBool reportWarnings) const { OFCondition result = SR_EC_InvalidValue; // check graphic type and data if (graphicType == DSRTypes::GT_invalid) REPORT_WARNING("Invalid Graphic Type for SCOORD content item") else if (graphicDataList.isEmpty()) REPORT_WARNING("No Graphic Data for SCOORD content item") else { const size_t count = graphicDataList.getNumberOfItems(); switch (graphicType) { case DSRTypes::GT_Point: if (count > 1) REPORT_WARNING("Graphic Data has too many entries, only a single entry expected") result = EC_Normal; break; case DSRTypes::GT_Multipoint: if (count < 1) REPORT_WARNING("Graphic Data has too few entries, at least one entry expected") result = EC_Normal; break; case DSRTypes::GT_Polyline: /* // not required any more according to CP-233 if (graphicDataList.getItem(1) != graphicDataList.getItem(count)) REPORT_WARNING("First and last entry in Graphic Data are not equal (POLYLINE)") */ result = EC_Normal; break; case DSRTypes::GT_Circle: if (count < 2) REPORT_WARNING("Graphic Data has too few entries, exactly two entries expected") else { if (count > 2) REPORT_WARNING("Graphic Data has too many entries, exactly two entries expected") result = EC_Normal; } break; case DSRTypes::GT_Ellipse: if (count < 4) REPORT_WARNING("Graphic Data has too few entries, exactly four entries expected") else { if (count > 4) REPORT_WARNING("Graphic Data has too many entries, exactly four entries expected") result = EC_Normal; } break; default: /* GT_invalid */ break; } } return result; } OFCondition DSRSpatialCoordinatesValue::checkFiducialUID(const OFString &fiducialUID) const { /* fiducial UID might be empty */ return fiducialUID.empty() ? EC_Normal : DcmUniqueIdentifier::checkStringValue(fiducialUID, "1"); }