X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=libctsim%2Fctndicom.cpp;h=ac634c4359205f764def5c7db3ddeafa9c63b6c8;hp=02a4ed2da10073da89d6ea2a24df288e66ffc580;hb=8a7697ce57b56cdc43698cd1241ad98d49f9b5ac;hpb=20cc5536a0f941d2f04958e24af9985ac935f0d7 diff --git a/libctsim/ctndicom.cpp b/libctsim/ctndicom.cpp index 02a4ed2..ac634c4 100644 --- a/libctsim/ctndicom.cpp +++ b/libctsim/ctndicom.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: ctndicom.cpp,v 1.8 2001/03/07 16:52:52 kevin Exp $ +** $Id$ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -38,25 +38,40 @@ DicomImporter::DicomImporter (const char* const pszFile) : m_strFilename(pszFile), m_bFail(false), m_iContents(DICOM_CONTENTS_INVALID), - m_pImageFile(NULL), m_pProjections(NULL) + m_pImageFile(NULL), m_pProjections(NULL), m_pFile(NULL) { - unsigned long lOptions = DCM_ORDERLITTLEENDIAN; + unsigned long lOptions = DCM_ORDERLITTLEENDIAN | DCM_FORMATCONVERSION; DCM_Debug (FALSE); - if (DCM_OpenFile (pszFile, lOptions, &m_pFile) != DCM_NORMAL) { - m_bFail = true;; - m_strFailMessage = "Can't open file "; - m_strFailMessage += m_strFilename; + + CONDITION cond = DCM_OpenFile (pszFile, lOptions, &m_pFile); + if (cond != DCM_NORMAL) { + m_bFail = true; + char textbuf [2048]; + CONDITION cond2 = COND_TopCondition (&cond, textbuf, sizeof(textbuf)); + cond2 = DCM_NORMAL; // testing + if (cond2 != DCM_NORMAL) { + m_strFailMessage = "DCM_OpenFile failure: "; + m_strFailMessage += m_strFilename; + } else + m_strFailMessage = textbuf; + return; } unsigned short iNRows, iNCols, iBitsAllocated, iBitsStored, iHighBit, iPixRep; DCM_ELEMENT aElemRequired[] = { - {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNRows), reinterpret_cast(&iNRows)}, - {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNCols), reinterpret_cast(&iNCols)}, - {DCM_IMGBITSALLOCATED, DCM_US, "", 1, sizeof(iBitsAllocated), reinterpret_cast(&iBitsAllocated)}, - {DCM_IMGBITSSTORED, DCM_US, "", 1, sizeof(iBitsStored), reinterpret_cast(&iBitsStored)}, - {DCM_IMGHIGHBIT, DCM_US, "", 1, sizeof(iHighBit), reinterpret_cast(&iHighBit)}, - {DCM_IMGPIXELREPRESENTATION, DCM_US, "", 1, sizeof(iPixRep), reinterpret_cast(&iPixRep)} + {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNRows), + {reinterpret_cast(&iNRows)}}, + {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNCols), + {reinterpret_cast(&iNCols)}}, + {DCM_IMGBITSALLOCATED, DCM_US, "", 1, sizeof(iBitsAllocated), + {reinterpret_cast(&iBitsAllocated)}}, + {DCM_IMGBITSSTORED, DCM_US, "", 1, sizeof(iBitsStored), + {reinterpret_cast(&iBitsStored)}}, + {DCM_IMGHIGHBIT, DCM_US, "", 1, sizeof(iHighBit), + {reinterpret_cast(&iHighBit)}}, + {DCM_IMGPIXELREPRESENTATION, DCM_US, "", 1, sizeof(iPixRep), + {reinterpret_cast(&iPixRep)}}, }; int nElemRequired = sizeof (aElemRequired) / sizeof(DCM_ELEMENT); @@ -64,7 +79,7 @@ DicomImporter::DicomImporter (const char* const pszFile) loadImage (iNRows, iNCols, iBitsAllocated, iBitsStored, iHighBit, iPixRep); return; } - unsigned long lRtnLength; + U32 lRtnLength; DCM_TAG somatomTag = DCM_MAKETAG(TAG_GROUP_SOMATOM, TAG_MEMBER_SOMATOM_DATA); if (DCM_GetElementSize (&m_pFile, somatomTag, &lRtnLength) == DCM_NORMAL) loadProjections(); @@ -74,13 +89,15 @@ void DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned short iBitsAllocated, unsigned short iBitsStored, unsigned short iHighBit, unsigned short iPixRep) { - unsigned long lRtnLength; + U32 lRtnLength; unsigned short iSamplesPerPixel, iPlanarConfig; - DCM_ELEMENT elemPlanarConfig = {DCM_IMGPLANARCONFIGURATION, DCM_US, "", 1, sizeof(iPlanarConfig), - reinterpret_cast(&iPlanarConfig)}; - DCM_ELEMENT elemSamplesPerPixel = {DCM_IMGSAMPLESPERPIXEL, DCM_US, "", 1, - sizeof(iSamplesPerPixel), reinterpret_cast(&iSamplesPerPixel)}; + DCM_ELEMENT elemPlanarConfig = + {DCM_IMGPLANARCONFIGURATION, DCM_US, "", 1, sizeof(iPlanarConfig), + {reinterpret_cast(&iPlanarConfig)}}; + DCM_ELEMENT elemSamplesPerPixel = + {DCM_IMGSAMPLESPERPIXEL, DCM_US, "", 1, + sizeof(iSamplesPerPixel), {reinterpret_cast(&iSamplesPerPixel)}}; if (DCM_ParseObject (&m_pFile, &elemSamplesPerPixel, 1, NULL, 0, NULL) != DCM_NORMAL) iSamplesPerPixel = 1; // default value @@ -97,8 +114,12 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned char szRescaleIntercept[17]; double dRescaleSlope = 1; double dRescaleIntercept = 0; - DCM_ELEMENT elemRescaleSlope = {DCM_IMGRESCALESLOPE, DCM_DS, "", 1, strlen(szRescaleSlope), szRescaleSlope}; - DCM_ELEMENT elemRescaleIntercept = {DCM_IMGRESCALEINTERCEPT, DCM_DS, "", 1, strlen(szRescaleIntercept), szRescaleIntercept}; + DCM_ELEMENT elemRescaleSlope = + {DCM_IMGRESCALESLOPE, DCM_DS, "", 1, strlen(szRescaleSlope), + {szRescaleSlope}}; + DCM_ELEMENT elemRescaleIntercept = + {DCM_IMGRESCALEINTERCEPT, DCM_DS, "", 1, strlen(szRescaleIntercept), + {szRescaleIntercept}}; if (DCM_ParseObject (&m_pFile, &elemRescaleSlope, 1, NULL, 0, NULL) == DCM_NORMAL) { if (sscanf (szRescaleSlope, "%lf", &dRescaleSlope) != 1) sys_error (ERR_SEVERE, "Error parsing rescale slope"); @@ -108,7 +129,7 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned sys_error (ERR_SEVERE, "Error parsing rescale intercept"); } - DCM_ELEMENT elemPixelData = {DCM_PXLPIXELDATA, DCM_OT, "", 1, 0, NULL}; + DCM_ELEMENT elemPixelData = {DCM_PXLPIXELDATA, DCM_OT, "", 1, 0, {NULL}}; // Get the actual pixel data (the only other required element) if (DCM_GetElementSize (&m_pFile, elemPixelData.tag, &lRtnLength) != DCM_NORMAL) { m_bFail = true; @@ -141,7 +162,7 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned return; } if ((lCheckLengthInBytes < lRealLength) && (cond != DCM_GETINCOMPLETE)) { - m_bFail; + m_bFail = true; m_strFailMessage = "Should have gooten incomplete message reading pixel data"; delete pRawPixels; return; @@ -154,7 +175,7 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned if (iMaskLength > 8) iMaskLength -= 8; unsigned int iMask = (1 << iMaskLength) - 1; - for (int iy = iNRows - 1; iy >= 0; iy--) { + for (int iy = 0; iy < iNRows; iy++) { for (int ix = 0; ix < iNCols; ix++) { if (iBitsAllocated == 8) { unsigned char cV = pRawPixels[iy * iNRows + ix]; @@ -164,7 +185,7 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned unsigned char cV1 = pRawPixels[lBase]; unsigned char cV2 = pRawPixels[lBase+1] & iMask; int iV = cV1 + (cV2 << 8); - v[ix][iy] = iV * dRescaleSlope + dRescaleIntercept; + v[ix][iNRows - 1 - iy] = iV * dRescaleSlope + dRescaleIntercept; } } } @@ -174,13 +195,15 @@ DicomImporter::loadImage(unsigned short iNRows, unsigned short iNCols, unsigned void DicomImporter::loadProjections() { - unsigned long lRtnLength; + U32 lRtnLength; void* ctx = NULL; unsigned short iNViews, iNDets; DCM_ELEMENT aElemRequired[] = { - {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNViews), reinterpret_cast(&iNViews)}, - {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNDets), reinterpret_cast(&iNDets)}, + {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNViews), + {reinterpret_cast(&iNViews)}}, + {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNDets), + {reinterpret_cast(&iNDets)}}, }; int nElemRequired = sizeof (aElemRequired) / sizeof(DCM_ELEMENT); @@ -191,7 +214,7 @@ DicomImporter::loadProjections() } DCM_TAG somatomTag = DCM_MAKETAG(TAG_GROUP_SOMATOM, TAG_MEMBER_SOMATOM_DATA); - DCM_ELEMENT elemProjections = {somatomTag, DCM_UNKNOWN, "", 1, 0, NULL}; + DCM_ELEMENT elemProjections = {somatomTag, DCM_UN, "", 1, 0, {NULL}}; if (DCM_GetElementSize (&m_pFile, elemProjections.tag, &lRtnLength) != DCM_NORMAL) { m_bFail = true; m_strFailMessage = "Can't find projection data"; @@ -284,7 +307,7 @@ DicomExporter::createDicomObject() dWidth = 1E-7; double dScale = 65535. / dWidth; - double dRescaleIntercept = -dMin; + double dRescaleIntercept = dMin; double dRescaleSlope = 1 / dScale; char szRescaleIntercept[17]; char szRescaleSlope[17]; @@ -319,6 +342,12 @@ DicomExporter::createDicomObject() char szIDImageType[] = "ORIGINAL"; char szIDManufacturerModel[65] = ""; + std::ostringstream osPatComments; + m_pImageFile->printLabelsBrief (osPatComments); + size_t sizePatComments = osPatComments.str().length(); + char* pszPatComments = new char [sizePatComments+1]; + strncpy (pszPatComments, osPatComments.str().c_str(), sizePatComments); + snprintf (szIDSOPInstanceUID, sizeof(szIDSOPInstanceUID), "%s.2.1.6.1", szCTSimRoot); snprintf (szRelStudyInstanceUID, sizeof(szRelStudyInstanceUID), "%s.2.1.6.1.1", szCTSimRoot); snprintf (szRelFrameOfReferenceUID, sizeof(szRelFrameOfReferenceUID), "%s.99", szCTSimRoot); @@ -341,51 +370,77 @@ DicomExporter::createDicomObject() unsigned short iPixRep = 0; unsigned short iSamplesPerPixel = 1; DCM_ELEMENT aElemRequired[] = { - {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNRows), reinterpret_cast(&iNRows)}, - {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNCols), reinterpret_cast(&iNCols)}, - {DCM_IMGBITSALLOCATED, DCM_US, "", 1, sizeof(iBitsAllocated), reinterpret_cast(&iBitsAllocated)}, - {DCM_IMGBITSSTORED, DCM_US, "", 1, sizeof(iBitsStored), reinterpret_cast(&iBitsStored)}, - {DCM_IMGHIGHBIT, DCM_US, "", 1, sizeof(iHighBit), reinterpret_cast(&iHighBit)}, - {DCM_IMGPIXELREPRESENTATION, DCM_US, "", 1, sizeof(iPixRep), reinterpret_cast(&iPixRep)}, - {DCM_IMGSAMPLESPERPIXEL, DCM_US, "", 1, sizeof(iSamplesPerPixel), reinterpret_cast(&iSamplesPerPixel)}, - {DCM_IMGRESCALESLOPE, DCM_DS, "", 1, strlen(szRescaleSlope), szRescaleSlope}, - {DCM_IMGRESCALEINTERCEPT, DCM_DS, "", 1, strlen(szRescaleIntercept), szRescaleIntercept}, - {DCM_IMGPHOTOMETRICINTERP, DCM_CS, "", 1, strlen(szImgPhotometricInterp), szImgPhotometricInterp}, - {DCM_IMGPIXELSPACING, DCM_DS, "", 1, strlen(szPixelSpacing), szPixelSpacing}, - {DCM_RELIMAGEORIENTATIONPATIENT, DCM_DS, "", 1, strlen(szRelImageOrientationPatient), szRelImageOrientationPatient}, - {DCM_RELIMAGEPOSITIONPATIENT, DCM_DS, "", 1, strlen(szRelImagePositionPatient), szRelImagePositionPatient}, - {DCM_ACQKVP, DCM_DS, "", 1, strlen(szAcqKvp), szAcqKvp}, - {DCM_RELACQUISITIONNUMBER, DCM_IS, "", 1, strlen(szRelAcquisitionNumber), szRelAcquisitionNumber}, - {DCM_ACQSLICETHICKNESS, DCM_DS, "", 1, strlen(szRelAcquisitionNumber), szRelAcquisitionNumber}, - {DCM_RELIMAGENUMBER, DCM_IS, "", 1, strlen(szRelImageNumber), szRelImageNumber}, - {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, strlen(szIDSOPInstanceUID), szIDSOPInstanceUID}, - {DCM_IDMANUFACTURER, DCM_LO, "", 1, strlen(szIDManufacturer), szIDManufacturer}, - {DCM_RELPOSITIONREFINDICATOR, DCM_LO, "", 1, strlen(szRelPositionRefIndicator), szRelPositionRefIndicator}, - {DCM_RELFRAMEOFREFERENCEUID, DCM_UI, "", 1, strlen(szRelFrameOfReferenceUID), szRelFrameOfReferenceUID}, - {DCM_RELSERIESNUMBER, DCM_IS, "", 1, strlen(szRelSeriesNumber), szRelSeriesNumber}, - {DCM_RELSERIESINSTANCEUID, DCM_UI, "", 1, strlen(szIDAccessionNumber), szIDAccessionNumber}, - {DCM_IDACCESSIONNUMBER, DCM_SH, "", 1, strlen(szIDAccessionNumber), szIDAccessionNumber}, - {DCM_RELSTUDYID, DCM_SH, "", 1, strlen(szRelStudyID), szRelStudyID}, - {DCM_IDREFERRINGPHYSICIAN, DCM_PN, "", 1, strlen(szIDReferringPhysician), szIDReferringPhysician}, - {DCM_IDSTUDYTIME, DCM_TM, "", 1, strlen(szIDStudyTime), szIDStudyTime}, - {DCM_IDSTUDYDATE, DCM_DA, "", 1, strlen(szIDStudyDate), szIDStudyDate}, - {DCM_RELSTUDYINSTANCEUID, DCM_UI, "", 1, strlen(szRelStudyInstanceUID), szRelStudyInstanceUID}, - {DCM_PATSEX, DCM_CS, "", 1, strlen(szPatSex), szPatSex}, - {DCM_PATBIRTHDATE, DCM_DA, "", 1, strlen(szPatBirthdate), szPatBirthdate}, - {DCM_PATID, DCM_LO, "", 1, strlen(szPatID), szPatID}, - {DCM_PATNAME, DCM_PN, "", 1, strlen(szPatName), szPatName}, - {DCM_IDIMAGETYPE, DCM_CS, "", 1, strlen(szIDImageType), szIDImageType}, - {DCM_IDMODALITY, DCM_CS, "", 1, strlen(szModality), szModality}, - {DCM_IDSOPCLASSUID, DCM_UI, "", 1, strlen(szSOPClassUID), szSOPClassUID}, - {DCM_IDMANUFACTURERMODEL, DCM_LO, "", 1, strlen(szIDManufacturerModel), szIDManufacturerModel}, + {DCM_IMGROWS, DCM_US, "", 1, sizeof(iNRows), + {reinterpret_cast(&iNRows)}}, + {DCM_IMGCOLUMNS, DCM_US, "", 1, sizeof(iNCols), + {reinterpret_cast(&iNCols)}}, + {DCM_IMGBITSALLOCATED, DCM_US, "", 1, sizeof(iBitsAllocated), + {reinterpret_cast(&iBitsAllocated)}}, + {DCM_IMGBITSSTORED, DCM_US, "", 1, sizeof(iBitsStored), + {reinterpret_cast(&iBitsStored)}}, + {DCM_IMGHIGHBIT, DCM_US, "", 1, sizeof(iHighBit), + {reinterpret_cast(&iHighBit)}}, + {DCM_IMGPIXELREPRESENTATION, DCM_US, "", 1, sizeof(iPixRep), + {reinterpret_cast(&iPixRep)}}, + {DCM_IMGSAMPLESPERPIXEL, DCM_US, "", 1, sizeof(iSamplesPerPixel), + {reinterpret_cast(&iSamplesPerPixel)}}, + {DCM_IMGRESCALESLOPE, DCM_DS, "", 1, strlen(szRescaleSlope), + {szRescaleSlope}}, + {DCM_IMGRESCALEINTERCEPT, DCM_DS, "", 1, strlen(szRescaleIntercept), + {szRescaleIntercept}}, + {DCM_IMGPHOTOMETRICINTERP, DCM_CS, "", 1, strlen(szImgPhotometricInterp), + {szImgPhotometricInterp}}, + {DCM_IMGPIXELSPACING, DCM_DS, "", 1, strlen(szPixelSpacing), + {szPixelSpacing}}, + {DCM_RELIMAGEORIENTATIONPATIENT, DCM_DS, "", 1, + strlen(szRelImageOrientationPatient), {szRelImageOrientationPatient}}, + {DCM_RELIMAGEPOSITIONPATIENT, DCM_DS, "", 1, + strlen(szRelImagePositionPatient), {szRelImagePositionPatient}}, + {DCM_ACQKVP, DCM_DS, "", 1, strlen(szAcqKvp), {szAcqKvp}}, + {DCM_RELACQUISITIONNUMBER, DCM_IS, "", 1, strlen(szRelAcquisitionNumber), + {szRelAcquisitionNumber}}, + {DCM_ACQSLICETHICKNESS, DCM_DS, "", 1, strlen(szRelAcquisitionNumber), + {szRelAcquisitionNumber}}, + {DCM_RELIMAGENUMBER, DCM_IS, "", 1, strlen(szRelImageNumber), + {szRelImageNumber}}, + {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, strlen(szIDSOPInstanceUID), + {szIDSOPInstanceUID}}, + {DCM_IDMANUFACTURER, DCM_LO, "", 1, strlen(szIDManufacturer), + {szIDManufacturer}}, + {DCM_RELPOSITIONREFINDICATOR, DCM_LO, "", 1, + strlen(szRelPositionRefIndicator), {szRelPositionRefIndicator}}, + {DCM_RELFRAMEOFREFERENCEUID, DCM_UI, "", 1, + strlen(szRelFrameOfReferenceUID), {szRelFrameOfReferenceUID}}, + {DCM_RELSERIESNUMBER, DCM_IS, "", 1, strlen(szRelSeriesNumber), + {szRelSeriesNumber}}, + {DCM_RELSERIESINSTANCEUID, DCM_UI, "", 1, strlen(szIDAccessionNumber), + {szIDAccessionNumber}}, + {DCM_IDACCESSIONNUMBER, DCM_SH, "", 1, strlen(szIDAccessionNumber), + {szIDAccessionNumber}}, + {DCM_RELSTUDYID, DCM_SH, "", 1, strlen(szRelStudyID), {szRelStudyID}}, + {DCM_IDREFERRINGPHYSICIAN, DCM_PN, "", 1, strlen(szIDReferringPhysician), + {szIDReferringPhysician}}, + {DCM_IDSTUDYTIME, DCM_TM, "", 1, strlen(szIDStudyTime), {szIDStudyTime}}, + {DCM_IDSTUDYDATE, DCM_DA, "", 1, strlen(szIDStudyDate), {szIDStudyDate}}, + {DCM_RELSTUDYINSTANCEUID, DCM_UI, "", 1, strlen(szRelStudyInstanceUID), + {szRelStudyInstanceUID}}, + {DCM_PATSEX, DCM_CS, "", 1, strlen(szPatSex), {szPatSex}}, + {DCM_PATBIRTHDATE, DCM_DA, "", 1, strlen(szPatBirthdate), {szPatBirthdate}}, + {DCM_PATID, DCM_LO, "", 1, strlen(szPatID), {szPatID}}, + {DCM_PATNAME, DCM_PN, "", 1, strlen(szPatName), {szPatName}}, + {DCM_IDIMAGETYPE, DCM_CS, "", 1, strlen(szIDImageType), {szIDImageType}}, + {DCM_IDMODALITY, DCM_CS, "", 1, strlen(szModality), {szModality}}, + {DCM_IDSOPCLASSUID, DCM_UI, "", 1, strlen(szSOPClassUID), {szSOPClassUID}}, + {DCM_IDMANUFACTURERMODEL, DCM_LO, "", 1, strlen(szIDManufacturerModel), + {szIDManufacturerModel}}, + {DCM_PATCOMMENTS, DCM_LT, "", 1, strlen(pszPatComments), {pszPatComments}}, }; int nElemRequired = sizeof (aElemRequired) / sizeof(DCM_ELEMENT); int iUpdateCount; cond = DCM_ModifyElements (&m_pObject, aElemRequired, nElemRequired, NULL, 0, &iUpdateCount); - - DCM_ELEMENT elemPixelData = {DCM_PXLPIXELDATA, DCM_OT, "", 1, 0, NULL}; + DCM_ELEMENT elemPixelData = {DCM_PXLPIXELDATA, DCM_OT, "", 1, 0, {NULL}}; unsigned long lRealLength = 2 * m_pImageFile->nx() * m_pImageFile->ny(); @@ -394,10 +449,10 @@ DicomExporter::createDicomObject() elemPixelData.d.ot = pRawPixels; ImageFileArray v = m_pImageFile->getArray(); - for (int iy = iNRows - 1; iy >= 0; iy--) { + for (int iy = 0; iy < iNRows; iy++) { for (int ix = 0; ix < iNCols; ix++) { unsigned long lBase = (iy * iNRows + ix) * 2; - unsigned int iValue = nearest(dScale * (v[ix][iy] - dMin)); + unsigned int iValue = nearest(dScale * (v[ix][iNRows - 1 - iy] - dMin)); pRawPixels[lBase] = iValue & 0xFF; pRawPixels[lBase+1] = (iValue & 0xFF00) >> 8; } @@ -405,6 +460,8 @@ DicomExporter::createDicomObject() cond = DCM_ModifyElements (&m_pObject, &elemPixelData, 1, NULL, 0, &iUpdateCount); delete pRawPixels; + delete pszPatComments; + if (cond != DCM_NORMAL || iUpdateCount != 1) { m_bFail = true; m_strFailMessage = "Error modifying pixel data";