/* * * Copyright (C) 1998-2020, 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: dcmpstat * * Author: Marco Eichelberg * * Purpose: * classes: DVPSCurve * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmpstat/dvpscu.h" #include "dcmtk/dcmdata/dctk.h" #include "dcmtk/ofstd/ofbmanip.h" DVPSCurve::DVPSCurve() : curveGroup(0) , numberOfPoints(0) , typeOfData(DVPSL_polylineCurve) , curveData(NULL) , curveDescription() , curveLabel() , axisUnitsX() , axisUnitsY() { } DVPSCurve::DVPSCurve(const DVPSCurve& copy) : curveGroup(copy.curveGroup) , numberOfPoints(copy.numberOfPoints) , typeOfData(copy.typeOfData) , curveData(NULL) , curveDescription(copy.curveDescription) , curveLabel(copy.curveLabel) , axisUnitsX(copy.axisUnitsX) , axisUnitsY(copy.axisUnitsY) { if (copy.curveData) { curveData = new double[2*numberOfPoints]; if (curveData) { OFBitmanipTemplate::copyMem(copy.curveData, curveData, 2*numberOfPoints); } } } DVPSCurve::~DVPSCurve() { if (curveData) delete[] curveData; } OFCondition DVPSCurve::read(DcmItem &dset, Uint8 group) { OFCondition result = EC_Normal; DcmStack stack; curveGroup = group; DcmElement *d_curveDimensions = NULL; DcmElement *d_numberOfPoints = NULL; DcmElement *d_typeOfData = NULL; DcmElement *d_dataVR = NULL; DcmElement *d_curveData = NULL; DcmElement *d_curveDescription = NULL; DcmElement *d_axisUnits = NULL; DcmElement *d_curveLabel = NULL; /* first we look for the Curve Data */ DcmTagKey key(0x5000 + group,0x3000); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_curveData = (DcmElement *)(stack.top()); } else return EC_IllegalCall; key.setElement(0x0005); // Curve Dimensions stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_curveDimensions = (DcmElement *)(stack.top()); } else return EC_IllegalCall; key.setElement(0x0110); // Curve Data Descriptor stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { return EC_IllegalCall; // we don't support curves with Curve Data Descriptor! } key.setElement(0x0010); // Number of Points stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_numberOfPoints = (DcmElement *)(stack.top()); } else return EC_IllegalCall; key.setElement(0x0020); // Type of Data stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_typeOfData = (DcmElement *)(stack.top()); } else return EC_IllegalCall; key.setElement(0x0103); // Data Value Representation stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_dataVR = (DcmElement *)(stack.top()); } else return EC_IllegalCall; key.setElement(0x0022); // Curve Description stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_curveDescription = (DcmElement *)(stack.top()); } key.setElement(0x0030); // Axis Units stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_axisUnits = (DcmElement *)(stack.top()); } key.setElement(0x2500); // Curve Label stack.clear(); if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) { d_curveLabel = (DcmElement *)(stack.top()); } Uint16 u=0; if ((EC_Normal != d_curveDimensions->getUint16(u,0))||(u != 2)) { // Curve Dimensions unreadable or != 2, bail out return EC_IllegalCall; } u=0; if ((EC_Normal != d_numberOfPoints->getUint16(u,0))||(u == 0)) { // Number of Points == 0 or unreadable, bail out. return EC_IllegalCall; } else numberOfPoints = u; OFString aString; if (EC_Normal != d_typeOfData->getOFString(aString,0)) { // cannot read type of data, bail out return EC_IllegalCall; } else { if (aString == "ROI") typeOfData=DVPSL_roiCurve; else if (aString == "POLY") typeOfData=DVPSL_polylineCurve; else return EC_IllegalCall; // unsupported type of data, bail out } if ((d_curveDescription) &&(EC_Normal == d_curveDescription->getOFString(aString,0))) { curveDescription = aString; } if ((d_axisUnits) &&(EC_Normal == d_axisUnits->getOFString(aString,0))) { axisUnitsX = aString; } if ((d_axisUnits) &&(EC_Normal == d_axisUnits->getOFString(aString,1))) { axisUnitsY = aString; } if ((d_curveLabel) &&(EC_Normal == d_curveLabel->getOFString(aString,0))) { curveLabel = aString; } Uint16 dataVR=0; if (EC_Normal != d_dataVR->getUint16(dataVR,0)) { // cannot read curve data VR, bail out return EC_IllegalCall; } curveData = new double[numberOfPoints*2]; if (curveData==NULL) return EC_MemoryExhausted; void *rawData=NULL; size_t align=0; Uint8 *pui8=NULL; Uint16 *pui16=NULL; Sint16 *psi16=NULL; Float32 *pfl32=NULL; Float64 *pfl64=NULL; Sint32 *psi32=NULL; switch (d_curveData->ident()) { case EVR_OB: case EVR_OW: case EVR_ox: case EVR_px: case EVR_US: if (EC_Normal == d_curveData->getUint8Array(pui8)) { rawData = pui8; align = 1; } else if (EC_Normal == d_curveData->getUint16Array(pui16)) { rawData = pui16; align = sizeof(Uint16); } else result = EC_IllegalCall; break; case EVR_SS: if (EC_Normal == d_curveData->getSint16Array(psi16)) { rawData = psi16; align = sizeof(Sint16); } else result = EC_IllegalCall; break; case EVR_FL: if (EC_Normal == d_curveData->getFloat32Array(pfl32)) { rawData = pfl32; align = sizeof(Float32); } else result = EC_IllegalCall; break; case EVR_FD: if (EC_Normal == d_curveData->getFloat64Array(pfl64)) { rawData = pfl64; align = sizeof(Float64); } else result = EC_IllegalCall; break; case EVR_SL: if (EC_Normal == d_curveData->getSint32Array(psi32)) { rawData = psi32; align = sizeof(Sint32); } else result = EC_IllegalCall; break; default: result = EC_IllegalCall; break; } size_t byteLength = (size_t)(d_curveData->getLength()); size_t maxidx = 2*numberOfPoints; size_t i; switch (dataVR) { case 0: // VR=US. align can be 1 or 2 if ((align==1)||(align==sizeof(Uint16))) { if (align==1) swapIfNecessary(gLocalByteOrder, EBO_LittleEndian, rawData, OFstatic_cast(Uint32, byteLength), sizeof(Uint16)); if (maxidx*sizeof(Uint16) <= byteLength) { for (i=0; i