Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dirkmueller:AL:TW
dcmtk
0002-Fixed-unchecked-typecasts-and-fixed-LUT-ha...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch of Package dcmtk
From 601b227eecaab33a3a3a11dc256d84b1a62f63af Mon Sep 17 00:00:00 2001 From: Marco Eichelberg <dicom@offis.de> Date: Mon, 15 Apr 2024 12:19:33 +0200 Subject: [PATCH 2/3] Fixed unchecked typecasts and fixed LUT handling. This commit adds further fixes for unchecked typecasts of DcmItem::search() results (see description of previous commit). Furthermore, this commit specifically addresses the handling of look-up tables (LUTs) in module dcmpstat, where attribute (0028,3006) LUTData may use either US or OW value representation, and (0028,3002) LUTDescriptor may be either US or SS. The code should now properly handle all permitted value representations. LUTData is now always written as OW in order to avoid the 64k size limit for US in explicit VR encoding. Thanks to Martin Zeiser from the Cisco Talos team <vulndiscovery@external.cisco.com> for the bug report (TALOS-2024-1957). Together with the previous commit, this closes DCMTK issue #1120. --- dcmpstat/libsrc/dcmpstat.cc | 40 ++++++++++++++++------- dcmpstat/libsrc/dvpspl.cc | 34 +++++++++++++------ dcmpstat/libsrc/dvpssv.cc | 34 +++++++++++++------ dcmpstat/libsrc/dvpssvl.cc | 25 +++++++++----- dcmpstat/libsrc/dvpstat.cc | 65 +++++++++++++++++-------------------- dcmpstat/libsrc/dvpsvl.cc | 19 +++++++++-- 6 files changed, 139 insertions(+), 78 deletions(-) diff --git a/dcmpstat/libsrc/dcmpstat.cc b/dcmpstat/libsrc/dcmpstat.cc index 4a8e5af6c..a7d11abac 100644 --- a/dcmpstat/libsrc/dcmpstat.cc +++ b/dcmpstat/libsrc/dcmpstat.cc @@ -384,12 +384,16 @@ OFCondition DcmPresentationState::read(DcmItem &dset) { item = seq->getItem(0); stack.clear(); - // LUTDescriptor can be US or SS. For now we only handle US. + + // LUTDescriptor can be US or SS if ((EC_Normal == item->search((DcmTagKey &)modalityLUTDescriptor.getTag(), - stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) { - modalityLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *mLUTDescriptor = &modalityLUTDescriptor; + mLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); } + stack.clear(); if ((EC_Normal == item->search((DcmTagKey &)modalityLUTExplanation.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_LO)) @@ -400,9 +404,11 @@ OFCondition DcmPresentationState::read(DcmItem &dset) // LUTData can be OW, US or SS. For now we only handle US. if ((EC_Normal == item->search((DcmTagKey &)modalityLUTData.getTag(), - stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) { - modalityLUTData = *((DcmUnsignedShort *)(stack.top())); + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *mdata = &modalityLUTData; + mdata->operator=(*(DcmElement *)(stack.top())); } stack.clear(); if ((EC_Normal == item->search((DcmTagKey &)modalityLUTType.getTag(), @@ -879,11 +885,13 @@ OFCondition DcmPresentationState::createFromImage( { item = seq->getItem(0); stack.clear(); - // LUTDescriptor can be US or SS. For now we only handle US. + // LUTDescriptor can be US or SS if ((EC_Normal == item->search((DcmTagKey &)modalityLUTDescriptor.getTag(), - stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) { - modalityLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *mLUTDescriptor = &modalityLUTDescriptor; + mLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); } stack.clear(); if ((EC_Normal == item->search((DcmTagKey &)modalityLUTExplanation.getTag(), @@ -895,9 +903,11 @@ OFCondition DcmPresentationState::createFromImage( // LUTData can be OW, US or SS. For now we only handle US. if ((EC_Normal == item->search((DcmTagKey &)modalityLUTData.getTag(), - stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) { - modalityLUTData = *((DcmUnsignedShort *)(stack.top())); + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *mdata = &modalityLUTData; + mdata->operator=(*(DcmElement *)(stack.top())); } stack.clear(); if ((EC_Normal == item->search((DcmTagKey &)modalityLUTType.getTag(), @@ -1247,10 +1257,16 @@ OFCondition DcmPresentationState::write(DcmItem &dset, OFBool replaceSOPInstance dseq = new DcmSequenceOfItems(DCM_ModalityLUTSequence); if (dseq) { - delem = new DcmUnsignedShort(modalityLUTDescriptor); + // we clone modalityLUTDescriptor in order to retain the VR (US or SS) + delem = OFstatic_cast(DcmElement *, modalityLUTDescriptor.clone()); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; - delem = new DcmUnsignedShort(modalityLUTData); + + // we write LUTData as OW in order to avoid the 64 kByte limit for US + delem = new DcmOtherByteOtherWord(DCM_LUTData); + delem->operator=(modalityLUTData); + OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; + delem = new DcmLongString(modalityLUTType); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; if (modalityLUTExplanation.getLength() >0) diff --git a/dcmpstat/libsrc/dvpspl.cc b/dcmpstat/libsrc/dvpspl.cc index ec4cccf97..f5574ab33 100644 --- a/dcmpstat/libsrc/dvpspl.cc +++ b/dcmpstat/libsrc/dvpspl.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 1999-2018, OFFIS e.V. + * Copyright (C) 1999-2024, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -24,6 +24,7 @@ #include "dcmtk/dcmdata/dcdeftag.h" #include "dcmtk/dcmdata/dcsequen.h" #include "dcmtk/dcmdata/dcvrcs.h" +#include "dcmtk/dcmdata/dcvrobow.h" #include "dcmtk/dcmpstat/dvpspl.h" #include "dcmtk/dcmpstat/dvpsdef.h" /* for constants and macros */ #include "dcmtk/dcmnet/dimse.h" @@ -79,29 +80,36 @@ OFCondition DVPSPresentationLUT::read(DcmItem &dset, OFBool withSOPInstance) if (result==EC_Normal) { stack.clear(); - if (EC_Normal == dset.search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dset.search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) { seq=(DcmSequenceOfItems *)stack.top(); if (seq->card() ==1) { item = seq->getItem(0); stack.clear(); - if (EC_Normal == item->search((DcmTagKey &)presentationLUTDescriptor.getTag(), - stack, ESM_fromHere, OFFalse)) + + // LUTDescriptor can be US or SS + if ((EC_Normal == item->search((DcmTagKey &)presentationLUTDescriptor.getTag(), + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) { - presentationLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *pLUTDescriptor = &presentationLUTDescriptor; + pLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); } + stack.clear(); if (EC_Normal == item->search((DcmTagKey &)presentationLUTExplanation.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) { presentationLUTExplanation = *((DcmLongString *)(stack.top())); } stack.clear(); if (EC_Normal == item->search((DcmTagKey &)presentationLUTData.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) { - presentationLUTData = *((DcmUnsignedShort *)(stack.top())); + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *pldata = &presentationLUTData; + pldata->operator=(*(DcmElement *)(stack.top())); } } else { result=EC_TagNotFound; @@ -187,10 +195,16 @@ OFCondition DVPSPresentationLUT::write(DcmItem &dset, OFBool withSOPInstance) dseq = new DcmSequenceOfItems(DCM_PresentationLUTSequence); if (dseq) { - delem = new DcmUnsignedShort(presentationLUTDescriptor); + // we clone presentationLUTDescriptor in order to retain the VR (US or SS) + delem = OFstatic_cast(DcmElement *, presentationLUTDescriptor.clone()); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; - delem = new DcmUnsignedShort(presentationLUTData); + + // we write LUTData as OW in order to avoid the 64 kByte limit for US + delem = new DcmOtherByteOtherWord(DCM_LUTData); + delem->operator=(presentationLUTData); + OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; + if (presentationLUTExplanation.getLength() >0) { delem = new DcmLongString(presentationLUTExplanation); diff --git a/dcmpstat/libsrc/dvpssv.cc b/dcmpstat/libsrc/dvpssv.cc index 8e3d49bd4..4a7fd0e30 100644 --- a/dcmpstat/libsrc/dvpssv.cc +++ b/dcmpstat/libsrc/dvpssv.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 1998-2018, OFFIS e.V. + * Copyright (C) 1998-2024, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -23,6 +23,7 @@ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmdata/dcdeftag.h" #include "dcmtk/dcmdata/dcsequen.h" +#include "dcmtk/dcmdata/dcvrobow.h" #include "dcmtk/dcmpstat/dvpssv.h" #include "dcmtk/dcmpstat/dvpsri.h" /* for DVPSReferencedImage */ #include "dcmtk/dcmpstat/dvpsrsl.h" /* DVPSReferencedSeries_PList */ @@ -75,29 +76,36 @@ OFCondition DVPSSoftcopyVOI::read(DcmItem &dset) if (result==EC_Normal) { stack.clear(); - if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) { seq=(DcmSequenceOfItems *)stack.top(); if (seq->card() ==1) { item = seq->getItem(0); stack.clear(); - if (EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), - stack, ESM_fromHere, OFFalse)) + + // LUTDescriptor can be US or SS + if ((EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) { - voiLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *vLUTDescriptor = &voiLUTDescriptor; + vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); } + stack.clear(); if (EC_Normal == item->search((DcmTagKey &)voiLUTExplanation.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) { voiLUTExplanation = *((DcmLongString *)(stack.top())); } stack.clear(); if (EC_Normal == item->search((DcmTagKey &)voiLUTData.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) { - voiLUTData = *((DcmUnsignedShort *)(stack.top())); + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *vldata = &voiLUTData; + vldata->operator=(*(DcmElement *)(stack.top())); } } else { result=EC_TagNotFound; @@ -177,10 +185,16 @@ OFCondition DVPSSoftcopyVOI::write(DcmItem &dset) dseq = new DcmSequenceOfItems(DCM_VOILUTSequence); if (dseq) { - delem = new DcmUnsignedShort(voiLUTDescriptor); + // we clone voiLUTDescriptor in order to retain the VR (US or SS) + delem = OFstatic_cast(DcmElement *, voiLUTDescriptor.clone()); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; - delem = new DcmUnsignedShort(voiLUTData); + + // we write LUTData as OW in order to avoid the 64 kByte limit for US + delem = new DcmOtherByteOtherWord(DCM_LUTData); + delem->operator=(voiLUTData); + OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; + if (voiLUTExplanation.getLength() >0) { delem = new DcmLongString(voiLUTExplanation); diff --git a/dcmpstat/libsrc/dvpssvl.cc b/dcmpstat/libsrc/dvpssvl.cc index d1532db5c..efcb6a26b 100644 --- a/dcmpstat/libsrc/dvpssvl.cc +++ b/dcmpstat/libsrc/dvpssvl.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 1999-2023, OFFIS e.V. + * Copyright (C) 1999-2024, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -72,7 +72,7 @@ OFCondition DVPSSoftcopyVOI_PList::read(DcmItem &dset) DcmSequenceOfItems *dseq=NULL; DcmItem *ditem=NULL; - if (EC_Normal == dset.search(DCM_SoftcopyVOILUTSequence, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dset.search(DCM_SoftcopyVOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) { dseq=(DcmSequenceOfItems *)stack.top(); if (dseq) @@ -249,29 +249,36 @@ OFCondition DVPSSoftcopyVOI_PList::createFromImage( if (result==EC_Normal) { stack.clear(); - if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) { seq=(DcmSequenceOfItems *)stack.top(); if (seq->card() > 0) { item = seq->getItem(0); stack.clear(); - if (EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), - stack, ESM_fromHere, OFFalse)) + + // LUTDescriptor can be US or SS + if ((EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) { - voiLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *vLUTDescriptor = &voiLUTDescriptor; + vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); } + stack.clear(); if (EC_Normal == item->search((DcmTagKey &)voiLUTExplanation.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) { voiLUTExplanation = *((DcmLongString *)(stack.top())); } stack.clear(); if (EC_Normal == item->search((DcmTagKey &)voiLUTData.getTag(), - stack, ESM_fromHere, OFFalse)) + stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) { - voiLUTData = *((DcmUnsignedShort *)(stack.top())); + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *vldata = &voiLUTData; + vldata->operator=(*(DcmElement *)(stack.top())); } } else result=EC_TagNotFound; } diff --git a/dcmpstat/libsrc/dvpstat.cc b/dcmpstat/libsrc/dvpstat.cc index ce2f5ad5f..4bfe8f9cb 100644 --- a/dcmpstat/libsrc/dvpstat.cc +++ b/dcmpstat/libsrc/dvpstat.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 1998-2021, OFFIS e.V. + * Copyright (C) 1998-2024, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -578,14 +578,14 @@ OFCondition DVPresentationState::attachImage(DcmDataset *dataset, OFBool transfe currentImageSelectedFrame = 1; // default: first frame // get Modality - if (EC_Normal == dataset->search(DCM_Modality, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dataset->search(DCM_Modality, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_CS)) { currentImageModality = *((DcmCodeString *)(stack.top())); } stack.clear(); // determine default Presentation LUT Shape - if (EC_Normal == dataset->search(DCM_PhotometricInterpretation, stack, ESM_fromHere, OFFalse)) + if (EC_Normal == dataset->search(DCM_PhotometricInterpretation, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_CS)) { DcmCodeString *photometricInterpretation = (DcmCodeString *)(stack.top()); if (photometricInterpretation->getVM() == 1) @@ -598,12 +598,12 @@ OFCondition DVPresentationState::attachImage(DcmDataset *dataset, OFBool transfe stack.clear(); // get SOP class UID and SOP instance UID. - if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse))) + if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_UI)) { result = ((DcmUniqueIdentifier *)(stack.top()))->getString(currentImageSOPClassUID); } stack.clear(); - if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse))) + if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_UI)) { result = ((DcmUniqueIdentifier *)(stack.top()))->getString(currentImageSOPInstanceUID); } @@ -1124,40 +1124,36 @@ OFCondition DVPresentationState::setGammaVOILUT(double gammaValue, DVPSObjectApp numEntries16 = (Uint16)numberOfEntries; /* LUT Descriptor */ - DcmElement *lutDescriptor = NULL; - if (firstMapped < 0) + DcmUnsignedShort *lutDescriptor = new DcmUnsignedShort(DcmTag(DCM_LUTDescriptor, EVR_US)); + if (lutDescriptor == NULL) status = EC_MemoryExhausted; + else { - // LUT Descriptor is SS - lutDescriptor = new DcmSignedShort(DcmTag(DCM_LUTDescriptor, EVR_SS)); - if (lutDescriptor != NULL) + if (firstMapped < 0) { - status = lutDescriptor->putSint16((Sint16)numEntries16, 0); - if (EC_Normal == status) - status = lutDescriptor->putSint16((Sint16)firstMapped, 1); - if (EC_Normal == status) - status = lutDescriptor->putSint16((Sint16)numberOfBits, 2); - } else - status = EC_MemoryExhausted; - } else { - // LUT Descriptor is US - lutDescriptor = new DcmUnsignedShort(DcmTag(DCM_LUTDescriptor, EVR_US)); - if (lutDescriptor != NULL) - { - status = lutDescriptor->putUint16(numEntries16, 0); - if (EC_Normal == status) - status = lutDescriptor->putUint16((Uint16)firstMapped, 1); - if (EC_Normal == status) - status = lutDescriptor->putUint16((Uint16)numberOfBits, 2); - } else - status = EC_MemoryExhausted; + // LUT Descriptor is SS + DcmSignedShort ldesc(DcmTag(DCM_LUTDescriptor, EVR_SS)); + status = ldesc.putSint16((Sint16)numEntries16, 0); + if (EC_Normal == status) status = ldesc.putSint16((Sint16)firstMapped, 1); + if (EC_Normal == status) status = ldesc.putSint16((Sint16)numberOfBits, 2); + if (EC_Normal == status) + { + // copy content of SS element into DcmUnsignedShort using DcmElement::operator= + DcmElement *ld = lutDescriptor; + ld->operator=(ldesc); + } + } else { + // LUT Descriptor is US + status = lutDescriptor->putUint16(numEntries16, 0); + if (EC_Normal == status) status = lutDescriptor->putUint16((Uint16)firstMapped, 1); + if (EC_Normal == status) status = lutDescriptor->putUint16((Uint16)numberOfBits, 2); + } } /* LUT Data */ - DcmElement *lutData = NULL; + DcmUnsignedShort *lutData = NULL; if (status == EC_Normal) { - // LUT Data as OW, because of max size = 64K - lutData = new DcmOtherByteOtherWord(DcmTag(DCM_LUTData, EVR_OW)); + lutData = new DcmUnsignedShort(DcmTag(DCM_LUTData, EVR_US)); if (lutData != NULL) status = lutData->putUint16Array(data, numberOfEntries); else @@ -1186,15 +1182,14 @@ OFCondition DVPresentationState::setGammaVOILUT(double gammaValue, DVPSObjectApp if (status == EC_Normal) { if ((lutDescriptor != NULL) && (lutData != NULL) && (lutExplanation != NULL)) - status = setVOILUT(*(DcmUnsignedShort *)lutDescriptor, *(DcmUnsignedShort *)lutData, *lutExplanation, applicability); + status = setVOILUT(*lutDescriptor, *lutData, *lutExplanation, applicability); } /* delete temporary dcmtk structures */ delete lutDescriptor; delete lutData; delete lutExplanation; - } else - status = EC_MemoryExhausted; + } else status = EC_MemoryExhausted; delete[] data; } return status; diff --git a/dcmpstat/libsrc/dvpsvl.cc b/dcmpstat/libsrc/dvpsvl.cc index b10b83f20..fdba0a0e0 100644 --- a/dcmpstat/libsrc/dvpsvl.cc +++ b/dcmpstat/libsrc/dvpsvl.cc @@ -59,9 +59,24 @@ OFCondition DVPSVOILUT::read(DcmItem &dset) OFCondition result = EC_Normal; DcmStack stack; - READ_FROM_DATASET(DcmUnsignedShort, EVR_US, voiLUTDescriptor) + // LUTDescriptor can be US or SS + if ((EC_Normal == dset.search((DcmTagKey &)voiLUTDescriptor.getTag(), + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { + // We explicitly use DcmElement::operator=(), which works for US and SS + DcmElement *vLUTDescriptor = &voiLUTDescriptor; + vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } + READ_FROM_DATASET(DcmLongString, EVR_LO, voiLUTExplanation) - READ_FROM_DATASET(DcmUnsignedShort, EVR_US, voiLUTData) + + stack.clear(); + if ((EC_Normal == dset.search((DcmTagKey &)voiLUTData.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { + // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters + DcmElement *vldata = &voiLUTData; + vldata->operator=(*(DcmElement *)(stack.top())); + } if (EC_Normal == result) { -- 2.44.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor