/* * * Copyright (c) 2010-2021, OFFIS e.V. and ICSMED AG, Oldenburg, Germany * All rights reserved. See COPYRIGHT file for details. * * Test read and write methods of DICOM RT classes * * Generated manually * File created on 2010-05-10 * Last modified on 2012-10-09 by Riesmeier * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/ofstd/ofconapp.h" #include "dcmtk/dcmrt/drtdose.h" #include "dcmtk/dcmrt/drtimage.h" #include "dcmtk/dcmrt/drtplan.h" #include "dcmtk/dcmrt/drtstrct.h" #include "dcmtk/dcmrt/drttreat.h" #include "dcmtk/dcmrt/drtionpl.h" #include "dcmtk/dcmrt/drtiontr.h" #ifdef WITH_ZLIB #include /* for zlibVersion() */ #endif #define OFFIS_CONSOLE_APPLICATION "drtdump" static OFLogger drtdumpLogger = OFLog::getLogger("dcmtk.apps." OFFIS_CONSOLE_APPLICATION); static char rcsid[] = "$dcmtk: " OFFIS_CONSOLE_APPLICATION " v" OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $"; // ******************************************** #define DUMP_PATIENT_DATA(rtObject) \ if (rtObject.getPatientName(tmpString).good()) \ { \ OFString outString; \ out << "Patient : " << tmpString; \ if (rtObject.getPatientSex(tmpString).good()) \ appendToString(outString, tmpString); \ if (rtObject.getPatientBirthDate(tmpString).good()) \ appendToString(outString, tmpString); \ if (rtObject.getPatientID(tmpString).good()) \ appendToString(outString, tmpString, "#" /*prefix*/); \ if (!outString.empty()) \ out << " (" << outString << ")"; \ out << OFendl; \ } #define DUMP_PHYSICIAN_DATA(rtObject) \ if (rtObject.getReferringPhysicianName(tmpString).good()) \ { \ out << "Physician : " << tmpString << OFendl; \ } #define DUMP_OPERATOR_DATA(rtObject) \ if (rtObject.getOperatorsName(tmpString).good()) \ { \ out << "Operator : " << tmpString << OFendl; \ } #define DUMP_STUDY_DATA(rtObject) \ if (rtObject.getStudyDescription(tmpString).good()) \ { \ OFString outString = tmpString; \ if (rtObject.getStudyID(tmpString).good()) \ appendToString(outString, tmpString, "#" /*prefix*/); \ if (rtObject.getStudyDate(tmpString).good()) \ appendToString(outString, tmpString); \ if (rtObject.getStudyTime(tmpString).good()) \ appendToString(outString, tmpString); \ out << "Study : " << outString << OFendl; \ } #define DUMP_SERIES_DATA(rtObject) \ if (rtObject.getSeriesDescription(tmpString).good()) \ { \ OFString outString = tmpString; \ if (rtObject.getSeriesNumber(tmpString).good()) \ appendToString(outString, tmpString, "#" /*prefix*/); \ out << "Series : " << outString << OFendl; \ } #define DUMP_INSTITUTION_DATA(rtObject) \ if (rtObject.getInstitutionName(tmpString).good() || \ rtObject.getInstitutionalDepartmentName(dummyString).good()) \ { \ OFString outString = tmpString; \ if (rtObject.getInstitutionalDepartmentName(tmpString).good()) \ appendToString(outString, tmpString); \ out << "Institution : " << outString << OFendl; \ } #define DUMP_DEVICE_DATA(rtObject) \ if (rtObject.getManufacturer(tmpString).good()) \ { \ OFString outString = tmpString; \ if (rtObject.getManufacturerModelName(tmpString).good()) \ appendToString(outString, tmpString); \ if (rtObject.getStationName(tmpString).good()) \ appendToString(outString, tmpString); \ out << "Device : " << outString << OFendl; \ } // ******************************************** static void appendToString(OFString &outString, const OFString &appendString, const OFString &prefix = "", const OFString &suffix = "", const OFString &delimiter = ", ") { if (!appendString.empty()) { if (!outString.empty()) outString += delimiter; outString += prefix; outString += appendString; outString += suffix; } } static OFCondition dumpRTDose(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTDoseIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Dose object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpRTImage(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTImageIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Image object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_OPERATOR_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) out << OFendl; /* output further IOD specific data */ if (rtObject.getRTImageLabel(tmpString).good()) { OFString outString = tmpString; if (rtObject.getRTImageName(tmpString).good()) appendToString(outString, tmpString); if (rtObject.getRTImageDescription(tmpString).good()) appendToString(outString, tmpString); out << "RT Image Label/Name : " << outString << OFendl; } if (rtObject.getImageType(tmpString, -1 /*all*/).good()) { OFString outString = tmpString; if (rtObject.getConversionType(tmpString).good()) appendToString(outString, tmpString); if (rtObject.getRTImagePlane(tmpString).good()) appendToString(outString, tmpString); out << "Image/Conversion Type : " << outString << OFendl; } if (rtObject.getRadiationMachineName(tmpString).good()) { OFString outString = tmpString; if (rtObject.getRadiationMachineSAD(tmpString).good()) appendToString(outString, tmpString, "" /*prefix*/, " mm" /*suffix*/); out << "Radiation Machine : " << outString << OFendl; } Uint16 rows = 0; Uint16 columns = 0; if (rtObject.getRows(rows).good() && rtObject.getColumns(columns).good()) { out << "Image Resolution : " << columns << " x " << rows << OFendl; } Uint16 bitsAllocated = 0; Uint16 bitsStored = 0; Uint16 highBit = 0; if (rtObject.getBitsAllocated(bitsAllocated).good() && rtObject.getBitsStored(bitsStored).good() && rtObject.getHighBit(highBit).good()) { out << "Image Encoding : " << bitsAllocated << " / " << bitsStored << " / " << highBit << OFendl; } out << OFendl; } return result; } static OFCondition dumpRTPlan(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTPlanIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Plan object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_OPERATOR_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpRTStructureSet(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTStructureSetIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Structure Set object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpRTTreatmentSummaryRecord(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTTreatmentSummaryRecordIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Treatment Summary Record object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpRTIonPlan(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTIonPlanIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Ion Plan object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpRTIonBeamsTreatmentRecord(STD_NAMESPACE ostream &out, DcmDataset &dataset) { DRTIonBeamsTreatmentRecordIOD rtObject; OFCondition result = rtObject.read(dataset); if (result.good()) { OFString tmpString, dummyString; out << "RT Ion Beams Treatment Record object" << OFendl << OFendl; /* output general information */ DUMP_PATIENT_DATA(rtObject) DUMP_PHYSICIAN_DATA(rtObject) DUMP_STUDY_DATA(rtObject) DUMP_SERIES_DATA(rtObject) DUMP_INSTITUTION_DATA(rtObject) DUMP_DEVICE_DATA(rtObject) /* output further IOD specific data */ // -- TODO --- out << OFendl; } return result; } static OFCondition dumpFile(STD_NAMESPACE ostream &out, const char *ifname, const E_FileReadMode readMode, const E_TransferSyntax xfer) { OFCondition result = EC_IllegalParameter; /* check for valid input filename */ if ((ifname != NULL) && (strlen(ifname) > 0)) { /* load DICOM file or dataset */ DcmFileFormat fileformat; if (readMode == ERM_dataset) result = fileformat.getDataset()->loadFile(ifname, xfer); else result = fileformat.loadFile(ifname, xfer); if (result.good()) { DcmDataset *dataset = fileformat.getDataset(); /* check SOP Class UID for one of the supported RT objects */ OFString sopClass; if (dataset->findAndGetOFString(DCM_SOPClassUID, sopClass).good() && !sopClass.empty()) { if (sopClass == UID_RTDoseStorage) result = dumpRTDose(out, *dataset); else if (sopClass == UID_RTImageStorage) result = dumpRTImage(out, *dataset); else if (sopClass == UID_RTPlanStorage) result = dumpRTPlan(out, *dataset); else if (sopClass == UID_RTStructureSetStorage) result = dumpRTStructureSet(out, *dataset); else if (sopClass == UID_RTTreatmentSummaryRecordStorage) result = dumpRTTreatmentSummaryRecord(out, *dataset); else if (sopClass == UID_RTIonPlanStorage) result = dumpRTIonPlan(out, *dataset); else if (sopClass == UID_RTIonBeamsTreatmentRecordStorage) result = dumpRTIonBeamsTreatmentRecord(out, *dataset); else OFLOG_ERROR(drtdumpLogger, "unsupported SOPClassUID (" << sopClass << ") in file: " << ifname); } else { OFLOG_ERROR(drtdumpLogger, "SOPClassUID (0008,0016) missing or empty in file: " << ifname); } } else { OFLOG_FATAL(drtdumpLogger, OFFIS_CONSOLE_APPLICATION << ": error (" << result.text() << ") reading file: " << ifname); } } else { OFLOG_FATAL(drtdumpLogger, OFFIS_CONSOLE_APPLICATION << ": invalid filename: "); } return result; } #define SHORTCOL 3 #define LONGCOL 20 int main(int argc, char *argv[]) { OFBool opt_printFilename = OFFalse; E_FileReadMode opt_readMode = ERM_autoDetect; E_TransferSyntax opt_ixfer = EXS_Unknown; OFConsoleApplication app(OFFIS_CONSOLE_APPLICATION, "Dump DICOM RT file and data set", rcsid); OFCommandLine cmd; cmd.setOptionColumns(LONGCOL, SHORTCOL); cmd.setParamColumn(LONGCOL + SHORTCOL + 4); cmd.addParam("drtfile-in", "DICOM RT input filename to be dumped", OFCmdParam::PM_MultiMandatory); cmd.addGroup("general options:", LONGCOL, SHORTCOL + 2); cmd.addOption("--help", "-h", "print this help text and exit", OFCommandLine::AF_Exclusive); cmd.addOption("--version", "print version information and exit", OFCommandLine::AF_Exclusive); OFLog::addOptions(cmd); cmd.addGroup("input options:"); cmd.addSubGroup("input file format:"); cmd.addOption("--read-file", "+f", "read file format or data set (default)"); cmd.addOption("--read-file-only", "+fo", "read file format only"); cmd.addOption("--read-dataset", "-f", "read data set without file meta information"); cmd.addSubGroup("input transfer syntax:"); cmd.addOption("--read-xfer-auto", "-t=", "use TS recognition (default)"); cmd.addOption("--read-xfer-detect", "-td", "ignore TS specified in the file meta header"); cmd.addOption("--read-xfer-little", "-te", "read with explicit VR little endian TS"); cmd.addOption("--read-xfer-big", "-tb", "read with explicit VR big endian TS"); cmd.addOption("--read-xfer-implicit", "-ti", "read with implicit VR little endian TS"); cmd.addGroup("output options:"); cmd.addSubGroup("printing:"); cmd.addOption("--print-filename", "+Pf", "print header with filename for each input file"); /* evaluate command line */ prepareCmdLineArgs(argc, argv, OFFIS_CONSOLE_APPLICATION); if (app.parseCommandLine(cmd, argc, argv)) { /* check exclusive options first */ if (cmd.hasExclusiveOption()) { if (cmd.findOption("--version")) { app.printHeader(OFTrue /*print host identifier*/); COUT << OFendl << "External libraries used:"; #ifdef WITH_ZLIB COUT << OFendl << "- ZLIB, Version " << zlibVersion() << OFendl; #else COUT << " none" << OFendl; #endif return 0; } } /* options */ OFLog::configureFromCommandLine(cmd, app); cmd.beginOptionBlock(); if (cmd.findOption("--read-file")) opt_readMode = ERM_autoDetect; if (cmd.findOption("--read-file-only")) opt_readMode = ERM_fileOnly; if (cmd.findOption("--read-dataset")) opt_readMode = ERM_dataset; cmd.endOptionBlock(); cmd.beginOptionBlock(); if (cmd.findOption("--read-xfer-auto")) opt_ixfer = EXS_Unknown; if (cmd.findOption("--read-xfer-detect")) dcmAutoDetectDatasetXfer.set(OFTrue); if (cmd.findOption("--read-xfer-little")) { app.checkDependence("--read-xfer-little", "--read-dataset", opt_readMode == ERM_dataset); opt_ixfer = EXS_LittleEndianExplicit; } if (cmd.findOption("--read-xfer-big")) { app.checkDependence("--read-xfer-big", "--read-dataset", opt_readMode == ERM_dataset); opt_ixfer = EXS_BigEndianExplicit; } if (cmd.findOption("--read-xfer-implicit")) { app.checkDependence("--read-xfer-implicit", "--read-dataset", opt_readMode == ERM_dataset); opt_ixfer = EXS_LittleEndianImplicit; } cmd.endOptionBlock(); if (cmd.findOption("--print-filename")) opt_printFilename = OFTrue; } /* print resource identifier */ OFLOG_DEBUG(drtdumpLogger, rcsid << OFendl); /* make sure data dictionary is loaded */ if (!dcmDataDict.isDictionaryLoaded()) { OFLOG_WARN(drtdumpLogger, "no data dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE); } int errorCount = 0; const int count = cmd.getParamCount(); const char *current = NULL; for (int i = 1; i <= count; i++) { cmd.getParam(i, current); if (opt_printFilename) { if (i > 1) COUT << OFString(79, '-') << OFendl; COUT << OFFIS_CONSOLE_APPLICATION << " (" << i << "/" << count << "): " << current << OFendl << OFendl; } if (dumpFile(COUT, current, opt_readMode, opt_ixfer).bad()) errorCount++; } #ifdef DEBUG dcmDataDict.clear(); /* useful for debugging with dmalloc */ #endif return errorCount; }