Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
KDE:Extra
dcmtk
0001-Fixed-possible-overflows-when-allocating-m...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Fixed-possible-overflows-when-allocating-memory.patch of Package dcmtk
From c5d8818f68c991cb580c7d52cc2ed99391259ce9 Mon Sep 17 00:00:00 2001 From: Michael Onken <onken@open-connections.de> Date: Tue, 20 Feb 2024 10:50:28 +0100 Subject: [PATCH] Fixed possible overflows when allocating memory. Thanks to GitHub user "bananabr" (Daniel Berredo) for the report and suggested patch. --- dcmect/libsrc/enhanced_ct.cc | 14 +- dcmect/tests/CMakeLists.txt | 1 + dcmect/tests/Makefile.dep | 151 +++++++++++++++ dcmect/tests/t_overflow.cc | 360 +++++++++++++++++++++++++++++++++++ dcmect/tests/tests.cc | 3 +- 5 files changed, 527 insertions(+), 2 deletions(-) create mode 100644 dcmect/tests/t_overflow.cc diff --git a/dcmect/libsrc/enhanced_ct.cc b/dcmect/libsrc/enhanced_ct.cc index 6193742..47d6335 100644 --- a/dcmect/libsrc/enhanced_ct.cc +++ b/dcmect/libsrc/enhanced_ct.cc @@ -24,6 +24,7 @@ #include "dcmtk/dcmect/types.h" #include "dcmtk/dcmfg/concatenationcreator.h" #include "dcmtk/dcmfg/concatenationloader.h" +#include "dcmtk/dcmfg/fgtypes.h" #include "dcmtk/dcmiod/iodutil.h" #include "dcmtk/dcmiod/modimagepixel.h" @@ -100,8 +101,19 @@ struct EctEnhancedCT::WriteVisitor m_CT.getRows(rows); m_CT.getColumns(cols); const size_t numFrames = m_CT.m_Frames.size(); + if (numFrames > 2147483647) + { + DCMECT_ERROR("More than 2147483647 frames provided"); + return FG_EC_PixelDataTooLarge; + } + const size_t numPixelsFrame = OFstatic_cast(size_t, rows) * OFstatic_cast(size_t, cols); const size_t numBytesFrame = m_CT.m_Frames[0]->length; - const size_t numPixelsFrame = rows * cols; + if (numBytesFrame != numPixelsFrame * 2) + { + DCMECT_ERROR("Invalid number of bytes per frame: Expected " << numPixelsFrame * 2 << " but got " + << numBytesFrame << " frame pixel data"); + return ECT_InvalidPixelInfo; + } // Creates the correct pixel data element, based on the image pixel module used. DcmPixelData* pixData = new DcmPixelData(DCM_PixelData); OFCondition result; diff --git a/dcmect/tests/CMakeLists.txt b/dcmect/tests/CMakeLists.txt index 5d66b11..0325534 100644 --- a/dcmect/tests/CMakeLists.txt +++ b/dcmect/tests/CMakeLists.txt @@ -2,6 +2,7 @@ DCMTK_ADD_EXECUTABLE(dcmect_tests tests.cc t_huge_concat.cc + t_overflow.cc t_roundtrip.cc ) diff --git a/dcmect/tests/Makefile.dep b/dcmect/tests/Makefile.dep index 9d26f58..dfb50b8 100644 --- a/dcmect/tests/Makefile.dep +++ b/dcmect/tests/Makefile.dep @@ -192,6 +192,157 @@ t_huge_concat.o: t_huge_concat.cc \ ../../dcmfg/include/dcmtk/dcmfg/fgrealworldvaluemapping.h \ ../../dcmiod/include/dcmtk/dcmiod/iodcontentitemmacro.h \ ../../dcmfg/include/dcmtk/dcmfg/fgtemporalposition.h +t_overflow.o: t_overflow.cc ../../config/include/dcmtk/config/osconfig.h \ + ../include/dcmtk/dcmect/enhanced_ct.h ../include/dcmtk/dcmect/def.h \ + ../../ofstd/include/dcmtk/ofstd/ofexport.h \ + ../include/dcmtk/dcmect/types.h ../../oflog/include/dcmtk/oflog/oflog.h \ + ../../oflog/include/dcmtk/oflog/logger.h \ + ../../oflog/include/dcmtk/oflog/config.h \ + ../../ofstd/include/dcmtk/ofstd/ofdefine.h \ + ../../ofstd/include/dcmtk/ofstd/ofcast.h \ + ../../ofstd/include/dcmtk/ofstd/ofstdinc.h \ + ../../oflog/include/dcmtk/oflog/config/defines.h \ + ../../oflog/include/dcmtk/oflog/helpers/threadcf.h \ + ../../oflog/include/dcmtk/oflog/loglevel.h \ + ../../ofstd/include/dcmtk/ofstd/ofvector.h \ + ../../ofstd/include/dcmtk/ofstd/oftypes.h \ + ../../ofstd/include/dcmtk/ofstd/ofstream.h \ + ../../oflog/include/dcmtk/oflog/tstring.h \ + ../../ofstd/include/dcmtk/ofstd/ofstring.h \ + ../../oflog/include/dcmtk/oflog/tchar.h \ + ../../oflog/include/dcmtk/oflog/spi/apndatch.h \ + ../../oflog/include/dcmtk/oflog/appender.h \ + ../../ofstd/include/dcmtk/ofstd/ofmem.h \ + ../../ofstd/include/dcmtk/ofstd/ofutil.h \ + ../../ofstd/include/dcmtk/ofstd/oftraits.h \ + ../../ofstd/include/dcmtk/ofstd/variadic/tuplefwd.h \ + ../../oflog/include/dcmtk/oflog/layout.h \ + ../../oflog/include/dcmtk/oflog/streams.h \ + ../../oflog/include/dcmtk/oflog/helpers/pointer.h \ + ../../oflog/include/dcmtk/oflog/thread/syncprim.h \ + ../../oflog/include/dcmtk/oflog/spi/filter.h \ + ../../oflog/include/dcmtk/oflog/helpers/lockfile.h \ + ../../oflog/include/dcmtk/oflog/spi/logfact.h \ + ../../oflog/include/dcmtk/oflog/logmacro.h \ + ../../oflog/include/dcmtk/oflog/helpers/snprintf.h \ + ../../oflog/include/dcmtk/oflog/tracelog.h \ + ../../ofstd/include/dcmtk/ofstd/ofcond.h \ + ../../ofstd/include/dcmtk/ofstd/ofdiag.h \ + ../../ofstd/include/dcmtk/ofstd/diag/push.def \ + ../../ofstd/include/dcmtk/ofstd/diag/useafree.def \ + ../../ofstd/include/dcmtk/ofstd/diag/pop.def \ + ../../dcmfg/include/dcmtk/dcmfg/fginterface.h \ + ../../dcmfg/include/dcmtk/dcmfg/fg.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgbase.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcitem.h \ + ../../ofstd/include/dcmtk/ofstd/offile.h \ + ../../ofstd/include/dcmtk/ofstd/ofstd.h \ + ../../ofstd/include/dcmtk/ofstd/oflist.h \ + ../../ofstd/include/dcmtk/ofstd/oflimits.h \ + ../../config/include/dcmtk/config/arith.h \ + ../../ofstd/include/dcmtk/ofstd/oferror.h \ + ../../dcmdata/include/dcmtk/dcmdata/dctypes.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcdefine.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcobject.h \ + ../../ofstd/include/dcmtk/ofstd/ofglobal.h \ + ../../ofstd/include/dcmtk/ofstd/ofthread.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcerror.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcxfer.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvr.h \ + ../../dcmdata/include/dcmtk/dcmdata/dctag.h \ + ../../dcmdata/include/dcmtk/dcmdata/dctagkey.h \ + ../../ofstd/include/dcmtk/ofstd/diag/ignrattr.def \ + ../../dcmdata/include/dcmtk/dcmdata/dcstack.h \ + ../../dcmdata/include/dcmtk/dcmdata/dclist.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcpcache.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgtypes.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgdefine.h \ + ../../ofstd/include/dcmtk/ofstd/ofmap.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodimage.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodcommn.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodrules.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodtypes.h \ + ../../dcmiod/include/dcmtk/dcmiod/ioddef.h \ + ../../dcmiod/include/dcmtk/dcmiod/modcommoninstanceref.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodmacro.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcdeftag.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrlo.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcchrstr.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcbytstr.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcelem.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvris.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrus.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrlt.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrcs.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrpn.h \ + ../../dcmiod/include/dcmtk/dcmiod/modbase.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodreferences.h \ + ../../dcmiod/include/dcmtk/dcmiod/modequipment.h \ + ../../dcmiod/include/dcmtk/dcmiod/modfor.h \ + ../../dcmiod/include/dcmtk/dcmiod/modgeneralseries.h \ + ../../dcmiod/include/dcmtk/dcmiod/modgeneralstudy.h \ + ../../dcmiod/include/dcmtk/dcmiod/modpatient.h \ + ../../dcmiod/include/dcmtk/dcmiod/modpatientstudy.h \ + ../../dcmiod/include/dcmtk/dcmiod/modsopcommon.h \ + ../../dcmiod/include/dcmtk/dcmiod/modgeneralimage.h \ + ../../dcmiod/include/dcmtk/dcmiod/modimagepixelvariant.h \ + ../../dcmiod/include/dcmtk/dcmiod/modimagepixelbase.h \ + ../../ofstd/include/dcmtk/ofstd/ofvriant.h \ + ../../ofstd/include/dcmtk/ofstd/variadic/variant.h \ + ../../ofstd/include/dcmtk/ofstd/variadic/helpers.h \ + ../../ofstd/include/dcmtk/ofstd/ofalign.h \ + ../../ofstd/include/dcmtk/ofstd/diag/cnvrsn.def \ + ../../ofstd/include/dcmtk/ofstd/diag/vsprfw.def \ + ../../ofstd/include/dcmtk/ofstd/diag/arrybnds.def \ + ../../ofstd/include/dcmtk/ofstd/diag/unrefprm.def \ + ../../dcmiod/include/dcmtk/dcmiod/modacquisitioncontext.h \ + ../../dcmiod/include/dcmtk/dcmiod/modenhequipment.h \ + ../../dcmiod/include/dcmtk/dcmiod/modimagepixel.h \ + ../../dcmiod/include/dcmtk/dcmiod/modmultiframedimension.h \ + ../../dcmiod/include/dcmtk/dcmiod/modmultiframefg.h \ + ../../dcmiod/include/dcmtk/dcmiod/modsynchronisation.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrdt.h \ + ../../ofstd/include/dcmtk/ofstd/ofdatime.h \ + ../../ofstd/include/dcmtk/ofstd/ofdate.h \ + ../../ofstd/include/dcmtk/ofstd/oftime.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrds.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrfd.h \ + ../../ofstd/include/dcmtk/ofstd/oftempf.h \ + ../../ofstd/include/dcmtk/ofstd/oftest.h \ + ../../ofstd/include/dcmtk/ofstd/ofconapp.h \ + ../../ofstd/include/dcmtk/ofstd/ofcmdln.h \ + ../../ofstd/include/dcmtk/ofstd/ofexbl.h \ + ../../ofstd/include/dcmtk/ofstd/ofconsol.h \ + ../../ofstd/include/dcmtk/ofstd/ofexit.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcuid.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcdict.h \ + ../../dcmdata/include/dcmtk/dcmdata/dchashdi.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcfilefo.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcsequen.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcdatset.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctacquisitiondetails.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctacquisitiontype.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctadditionalxraysource.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrfl.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrsh.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctexposure.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctgeometry.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctimageframetype.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctposition.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctreconstruction.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgcttabledynamics.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgctxraydetails.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgfracon.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrul.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgframeanatomy.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgirradiationeventid.h \ + ../../dcmdata/include/dcmtk/dcmdata/dcvrui.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgpixeltransform.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgpixmsr.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgplanor.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgplanpo.h \ + ../../dcmfg/include/dcmtk/dcmfg/fgrealworldvaluemapping.h \ + ../../dcmiod/include/dcmtk/dcmiod/iodcontentitemmacro.h t_roundtrip.o: t_roundtrip.cc \ ../../config/include/dcmtk/config/osconfig.h \ ../../ofstd/include/dcmtk/ofstd/ofmem.h \ diff --git a/dcmect/tests/t_overflow.cc b/dcmect/tests/t_overflow.cc new file mode 100644 index 0000000..4e9ac8b --- /dev/null +++ b/dcmect/tests/t_overflow.cc @@ -0,0 +1,360 @@ +/* + * + * Copyright (C) 2024, 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: dcmect + * + * Author: Daniel Berredo / Michael Onken + * + * Purpose: Tests that check for pixel data overflow conditions + * + */ + + +#include <dcmtk/config/osconfig.h> /* make sure OS specific configuration is included first */ + +#include <dcmtk/dcmect/enhanced_ct.h> + +#include <dcmtk/ofstd/oftempf.h> +#include <dcmtk/ofstd/oftest.h> + +#include <dcmtk/dcmdata/dcdict.h> +#include <dcmtk/dcmdata/dcfilefo.h> + +#include <dcmtk/dcmfg/fgctacquisitiondetails.h> +#include <dcmtk/dcmfg/fgctacquisitiontype.h> +#include <dcmtk/dcmfg/fgctadditionalxraysource.h> +#include <dcmtk/dcmfg/fgctexposure.h> +#include <dcmtk/dcmfg/fgctgeometry.h> +#include <dcmtk/dcmfg/fgctimageframetype.h> +#include <dcmtk/dcmfg/fgctposition.h> +#include <dcmtk/dcmfg/fgctreconstruction.h> +#include <dcmtk/dcmfg/fgcttabledynamics.h> +#include <dcmtk/dcmfg/fgctxraydetails.h> +#include <dcmtk/dcmfg/fgfracon.h> +#include <dcmtk/dcmfg/fgframeanatomy.h> +#include <dcmtk/dcmfg/fgirradiationeventid.h> +#include <dcmtk/dcmfg/fgpixeltransform.h> +#include <dcmtk/dcmfg/fgpixmsr.h> +#include <dcmtk/dcmfg/fgplanor.h> +#include <dcmtk/dcmfg/fgplanpo.h> +#include <dcmtk/dcmfg/fgrealworldvaluemapping.h> + +static const Uint16 NUM_ROWS = 1024; +static const Uint16 NUM_COLS = 1; +static const Uint16 NUM_FRAMES = 2; +static const size_t NUM_PIXELS_PER_FRAME = 1; + +static OFString EXPECTED_DUMP; + +static EctEnhancedCT *create(); +static void configureIOD(EctEnhancedCT *ct); +static void setGenericValues(EctEnhancedCT *ct); +static void addSharedFGs(EctEnhancedCT *ct); +static void addFrames(EctEnhancedCT *ct); +static void addDimensions(EctEnhancedCT *ct); + + +OFTEST(dcmect_overflow) +{ + /* make sure data dictionary is loaded */ + if (!dcmDataDict.isDictionaryLoaded()) + { + OFCHECK(dcmDataDict.isDictionaryLoaded()); + } + + // Creation + EctEnhancedCT *ct = create(); + configureIOD(ct); + setGenericValues(ct); + addSharedFGs(ct); + addFrames(ct); + addDimensions(ct); + + // Write to dataset and compare its dump with expected result + DcmFileFormat dcmff; + + OFTempFile tf(O_RDWR, "", "t_overflow", ".dcm"); + OFCondition result; + result = ct->saveFile("output.dcm", EXS_LittleEndianExplicit); + OFCHECK_MSG(result == ECT_InvalidPixelInfo, result.text()); +} + +static EctEnhancedCT *create() +{ + IODEnhGeneralEquipmentModule::EquipmentInfo eq("Open Connections", "OC CT", "4711", "0.1"); + EctEnhancedCT *ct = NULL; + OFCondition result; + result = EctEnhancedCT::create(ct, + NUM_ROWS, + NUM_COLS, + OFFalse, + EctTypes::E_ImageType1_Original, + EctTypes::DT_ImageType3_Volume, + EctTypes::DT_ImageType4_Maximum, + "1" /* instance number */, + EctTypes::E_ContQuali_Research, + EctTypes::E_PixelPres_Monochrome, + EctTypes::E_VolProps_Volume, + EctTypes::DT_VolBasedCalcTechnique_VolumeRender, + eq, + "20190801120000" /* acquisition date */, + 2.0 /* acquisition duration */); + + OFCHECK(result.good()); + OFCHECK(ct != OFnullptr); + return ct; +} + +static void configureIOD(EctEnhancedCT *ct) +{ + if (!ct) + return; +} + +static void setGenericValues(EctEnhancedCT *ct) +{ + if (!ct) + return; + OFCHECK(ct->getPatient().setPatientName("Bond^James").good()); + OFCHECK(ct->getPatient().setPatientID("007").good()); + OFCHECK(ct->getPatient().setPatientBirthDate("19771007").good()); + OFCHECK(ct->getStudy().setStudyDate("20190801").good()); + OFCHECK(ct->getStudy().setStudyTime("120000").good()); + OFCHECK(ct->getStudy().setStudyID("1").good()); + OFCHECK(ct->getPatientStudy().setPatientAge("040Y").good()); + OFCHECK(ct->getSeries().setSeriesDescription("Test Description").good()); + OFCHECK(ct->getSeries().setSeriesNumber("1").good()); + OFCHECK(ct->getSeries().setPatientPosition("HFS").good()); + + // Those values are usually computed automatically. UIDS are generated and date/times are set to current values. + // But in order to compare the "old" dump with the freshly created image attributes, we set some values manually, + // so that they are not overwritten with new, automatically created values later. + OFCHECK(ct->getStudy().setStudyInstanceUID("1.2.276.0.7230010.3.1.2.8323329.14863.1565940357.864811").good()); + OFCHECK(ct->getFrameOfReference().setFrameOfReferenceUID("2.25.30853397773651184949181049330553108086").good()); + OFCHECK(ct->getSeries().setSeriesInstanceUID("1.2.276.0.7230010.3.1.3.8323329.14863.1565940357.864812").good()); + OFCHECK(ct->getSOPCommon().setSOPInstanceUID("1.2.276.0.7230010.3.1.4.8323329.14863.1565940357.864813").good()); + + OFCHECK(ct->getIODMultiFrameFGModule().setContentTime("092557").good()); + OFCHECK(ct->getIODMultiFrameFGModule().setContentDate("20190816").good()); +} + +static void addSharedFGs(EctEnhancedCT *ct) +{ + if (!ct) + return; + + FGPixelMeasures meas; + OFCHECK(meas.setPixelSpacing("0.1\\0.1").good()); + OFCHECK(meas.setSliceThickness("1.0").good()); + OFCHECK(meas.setSpacingBetweenSlices("0.05").good()); + + FGPlanePosPatient planpo; + OFCHECK(planpo.setImagePositionPatient("0.0", "0.0", "0.0").good()); + + FGPlaneOrientationPatient planor; + OFCHECK(planor.setImageOrientationPatient("1.0", "0.0", "0.0", "0.0", "1.0", "0.0").good()); + + FGFrameAnatomy ana; + OFCHECK(ana.setLaterality(FGFrameAnatomy::LATERALITY_BOTH).good()); + OFCHECK(ana.getAnatomy().getAnatomicRegion().set("12738006", "SCT", "Brain").good()); + + FGIrradiationEventIdentification irr; + OFCHECK(irr.setIrradiationEventUID("2.25.30853892236613436472911970638347155062").good()); + + FGCTImageFrameType itype; + OFCHECK(itype.setFrameType("ORIGINAL\\PRIMARY\\VOLUME\\MAXIMUM").good()); + OFCHECK(itype.setPixelPresentation(FGCTImageFrameType::E_PixelPres_Monochrome).good()); + OFCHECK(itype.setVolumetricProperties(FGCTImageFrameType::E_VolProp_Volume).good()); + OFCHECK(itype.setVolumeBasedCalculationTechnique(FGCTImageFrameType::DT_VolBasedCalcTechnique_VolumeRender).good()); + + FGCTAcquisitionType atype; + OFCHECK(atype.setAcquisitionType(FGCTAcquisitionType::DT_AcquisitionType_ConstantAngle).good()); + OFCHECK(atype.setTubeAngle(0.1).good()); + OFCHECK(atype.setConstantVolumeFlag(FGCTAcquisitionType::E_ConstVol_Yes).good()); + OFCHECK(atype.setFluoroscopyFlag(FGCTAcquisitionType::E_Fluoroscopy_No).good()); + + FGCTAcquisitionDetails adetails; + FGCTAcquisitionDetails::FGCTAcquisitionDetailsItem *item = new FGCTAcquisitionDetails::FGCTAcquisitionDetailsItem(); + OFCHECK(item->setRotationDirection(FGCTAcquisitionDetails::E_RotationDirection_CW).good()); + OFCHECK(item->setRevolutionTime(5).good()); + OFCHECK(item->setSingleCollimationWidth(1).good()); + OFCHECK(item->setTotalCollimationWidth(10).good()); + OFCHECK(item->setTableHeight(50).good()); + OFCHECK(item->setGantryDetectorTilt(5).good()); + OFCHECK(item->setDataCollectionDiameter(20).good()); + adetails.getCTAcquisitionDetailsItems().push_back(item); + + FGCTTableDynamics dyn; + FGCTTableDynamics::FGCTTableDynamicsItem *dyn_item = new FGCTTableDynamics::FGCTTableDynamicsItem; + OFCHECK(dyn_item); + if (dyn_item) + { + OFCHECK(dyn_item->setTableSpeed(1.0).good()); + OFCHECK(dyn_item->setTableFeedPerRotation(0.1).good()); + OFCHECK(dyn_item->setSpiralPitchFactor(0.2).good()); + dyn.getCTTableDynamicsItems().push_back(dyn_item); + } + + FGCTPosition pos; + OFCHECK(pos.setTablePosition(100.0).good()); + OFCHECK(pos.setReconstructionTargetCenterPatient(OFVector<Float64>(3, 1.0)).good()); + OFCHECK(pos.setDataCollectionCenterPatient(OFVector<Float64>(3, 2.0)).good()); + + FGCTGeometry geo; + FGCTGeometry::FGCTGeometryItem *geo_item = new FGCTGeometry::FGCTGeometryItem; + if (geo_item) + { + OFCHECK(geo_item->setDistanceSourceToDataCollectionCenter(5.0).good()); + OFCHECK(geo_item->setDistanceSourceToDetector(0.5).good()); + geo.getCTGeometryItems().push_back(geo_item); + } + + FGCTReconstruction rec; + OFCHECK(rec.setConvolutionKernel("DUMMY").good()); + OFCHECK(rec.setConvolutionKernelGroup("DUMMYGROUP").good()); + OFCHECK(rec.setImageFilter("FILTER").good()); + OFCHECK(rec.setReconstructionAlgorithm("ALGO").good()); + OFCHECK(rec.setReconstructionAngle(90.0).good()); + OFCHECK(rec.setReconstructionDiameter(100.0).good()); + // Not permitted if Reconstruction Diameter is provided instead + // OFCHECK(rec.setReconstructionFieldOfView(100.0, 100.0).good()); + OFCHECK(rec.setReconstructionPixelSpacing(0.1, 0.1).good()); + + FGCTExposure exp; + FGCTExposure::FGCTExposureItem *exp_item = new FGCTExposure::FGCTExposureItem; + if (exp_item) + { + OFCHECK(exp_item->setCTDIVol(0.1).good()); + CodeSequenceMacro *phantom_item = new CodeSequenceMacro("113682", "DCM", "ACR Accreditation Phantom - CT"); + exp_item->getCTDIPhantomTypeCodeSequence().push_back(phantom_item); + OFCHECK(exp_item->setExposureInMas(0.3).good()); + OFCHECK(exp_item->setExposureModulationType("WEIRD").good()); + OFCHECK(exp_item->setExposureTimeInMs(0.4).good()); + OFCHECK(exp_item->setImageAndFluoroscopyAreaDoseProduct(0.5).good()); + OFCHECK(exp_item->setWaterEquivalentDiameter(0.6).good()); + CodeSequenceMacro *water_code = new CodeSequenceMacro("113987", "DCM", "AAPM 220"); + exp_item->getWaterEquivalentDiameterCalculationMethodCodeSequence().push_back(water_code); + OFCHECK(exp_item->setXRayTubeCurrentInMa(0.7).good()); + exp.getCTExposureItems().push_back(exp_item); + } + + FGCTXRayDetails det; + FGCTXRayDetails::FGCTXRayDetailsItem *det_item = new FGCTXRayDetails::FGCTXRayDetailsItem; + if (det_item) + { + OFCHECK(det_item->setCalciumScoringMassFactorDevice(OFVector<Float32>(3, 1)).good()); + OFCHECK(det_item->setCalciumScoringMassFactorPatient(2).good()); + OFCHECK(det_item->setEnergyWeightingFactor(3).good()); + OFCHECK(det_item->setFilterMaterial("FILTER_MATERIAL").good()); + OFCHECK(det_item->setFilterType("FILTER_TYPE").good()); + OFCHECK(det_item->setFocalSpots(OFVector<Float64>(4, 4.4)).good()); + OFCHECK(det_item->setKVP(5.0).good()); + det.getCTXRayDetailsItems().push_back(det_item); + } + + FGPixelValueTransformation trans; + trans.setFGType(FGPixelValueTransformation::E_PixelValTrans_CT); + trans.setRescaleIntercept("0"); + trans.setRescaleSlope("1"); + trans.setRescaleType("HU"); + + FGCTAdditionalXRaySource asrc; + FGCTAdditionalXRaySource::FGCTAdditionalXRaySourceItem *asrc_item = new FGCTAdditionalXRaySource::FGCTAdditionalXRaySourceItem; + if (asrc_item) + { + OFCHECK(asrc_item->setDataCollectionDiameter(1.0).good()); + OFCHECK(asrc_item->setEnergyWeightingFactor(2.0).good()); + OFCHECK(asrc_item->setExposureInmAs(3.0).good()); + OFCHECK(asrc_item->setFilterMaterial("FILTER_MATERIAL").good()); + OFCHECK(asrc_item->setFilterType("FILTER_TYPE").good()); + OFCHECK(asrc_item->setFocalSpots(OFVector<Float64>(4, 4.4)).good()); + OFCHECK(asrc_item->setKVP(5).good()); + OFCHECK(asrc_item->setXRayTubeCurrentInmA(6).good()); + asrc.getCTAdditionalXRaySourceItems().push_back(asrc_item); + } + + OFCHECK(ct->addForAllFrames(meas).good()); + OFCHECK(ct->addForAllFrames(planpo).good()); + OFCHECK(ct->addForAllFrames(planor).good()); + OFCHECK(ct->addForAllFrames(ana).good()); + OFCHECK(ct->addForAllFrames(irr).good()); + OFCHECK(ct->addForAllFrames(itype).good()); + OFCHECK(ct->addForAllFrames(atype).good()); + OFCHECK(ct->addForAllFrames(adetails).good()); + OFCHECK(ct->addForAllFrames(dyn).good()); + OFCHECK(ct->addForAllFrames(pos).good()); + OFCHECK(ct->addForAllFrames(geo).good()); + OFCHECK(ct->addForAllFrames(rec).good()); + OFCHECK(ct->addForAllFrames(exp).good()); + OFCHECK(ct->addForAllFrames(det).good()); + OFCHECK(ct->addForAllFrames(trans).good()); + OFCHECK(ct->addForAllFrames(asrc).good()); +} + +static void addFrames(EctEnhancedCT *ct) +{ + if (!ct) + return; + + FGFrameContent *fg = new FGFrameContent(); + fg->setStackID("1"); + OFCHECK(fg); + if (fg) + { + EctEnhancedCT::FramesType frames = ct->getFrames(); + for (Uint16 frameNo = 1; frameNo <= NUM_FRAMES; frameNo++) + { + OFCHECK(fg->setFrameAcquisitionNumber(frameNo).good()); + OFCHECK(fg->setFrameReferenceDateTime("20190816092557").good()); + OFCHECK(fg->setFrameAcquisitionDateTime("20190816092557").good()); + OFCHECK(fg->setFrameAcquisitionDuration(0.001).good()); + OFCHECK(fg->setInStackPositionNumber(frameNo).good()); + OFCHECK(fg->setDimensionIndexValues(1, 0).good()); + OFCHECK(fg->setDimensionIndexValues(frameNo, 1).good()); + OFVector<FGBase *> groups; + groups.push_back(fg); + + Uint16 *data = new Uint16[NUM_PIXELS_PER_FRAME]; + for (size_t i = 0; i < NUM_PIXELS_PER_FRAME; ++i) + { + data[i] = 0x4141; + } + OFCHECK( + OFget<EctEnhancedCT::Frames<Uint16>>(&frames)->addFrame(data, NUM_PIXELS_PER_FRAME, groups).good()); + delete[] data; + } + } + delete fg; +} + +static void addDimensions(EctEnhancedCT *ct) +{ + if (!ct) + return; + IODMultiframeDimensionModule &dims = ct->getDimensions(); + OFCHECK(dims.addDimensionIndex( + DCM_StackID, "2.25.30855560781715986879861690673941231222", DCM_FrameContentSequence, "STACK_DIM") + .good()); + OFCHECK(dims.addDimensionIndex(DCM_InStackPositionNumber, + "2.25.30855560781715986879861690673941231222", + DCM_FrameContentSequence, + "STACK_DIM") + .good()); + OFunique_ptr<IODMultiframeDimensionModule::DimensionOrganizationItem> org( + new IODMultiframeDimensionModule::DimensionOrganizationItem); + if (org) + { + org->setDimensionOrganizationUID("2.25.30855560781715986879861690673941231222"); + dims.getDimensionOrganizationSequence().push_back(org.release()); + } +} diff --git a/dcmect/tests/tests.cc b/dcmect/tests/tests.cc index 54a6ca0..8639dc1 100644 --- a/dcmect/tests/tests.cc +++ b/dcmect/tests/tests.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2019, OFFIS e.V. + * Copyright (C) 2019-2024, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -23,5 +23,6 @@ #include "dcmtk/ofstd/oftest.h" OFTEST_REGISTER(dcmect_huge_concat); +OFTEST_REGISTER(dcmect_overflow); OFTEST_REGISTER(dcmect_roundtrip); OFTEST_MAIN("dcmect") -- 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