X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFile.cxx;h=a43e5b7afb2d6f5b037515082c6f8a4bae35e432;hb=7c26892f568c67ce60f08f1a21fa64105bf6bb2d;hp=fff552358a69c7065db477b7bf9cc2110deb11c4;hpb=ef8ed3af8c91289da3f6a6e64da7aafda69b8b62;p=gdcm.git diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index fff55235..a43e5b7a 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2005/03/11 11:12:13 $ - Version: $Revision: 1.230 $ + Date: $Date: 2005/05/17 12:44:09 $ + Version: $Revision: 1.238 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -46,12 +46,25 @@ namespace gdcm { //----------------------------------------------------------------------------- // Constructor / Destructor + +/** + * \brief Constructor used when we want to generate dicom files from scratch + */ +File::File(): + Document() +{ + RLEInfo = new RLEFramesInfo; + JPEGInfo = new JPEGFragmentsInfo; + GrPixel = 0x7fe0; + NumPixel = 0x0010; +} + /** * \brief Constructor * @param filename name of the file whose header we want to analyze */ File::File( std::string const &filename ) - :Document( filename ) + :Document(filename) { RLEInfo = new RLEFramesInfo; JPEGInfo = new JPEGFragmentsInfo; @@ -145,17 +158,6 @@ File::File( std::string const &filename ) } } -/** - * \brief Constructor used when we want to generate dicom files from scratch - */ -File::File(): - Document() -{ - RLEInfo = new RLEFramesInfo; - JPEGInfo = new JPEGFragmentsInfo; - GrPixel = 0x7fe0; - NumPixel = 0x0010; -} /** * \brief Canonical destructor. @@ -170,6 +172,8 @@ File::~File () //----------------------------------------------------------------------------- // Public + + /** * \brief This predicate, based on hopefully reasonable heuristics, * decides whether or not the current File was properly parsed @@ -264,10 +268,14 @@ ModalityType File::GetModality() else if ( strModality.find("PT") < strModality.length()) return PT; else if ( strModality.find("RF") < strModality.length()) return RF; else if ( strModality.find("RG") < strModality.length()) return RG; - else if ( strModality.find("RTDOSE") < strModality.length()) return RTDOSE; - else if ( strModality.find("RTIMAGE") < strModality.length()) return RTIMAGE; - else if ( strModality.find("RTPLAN") < strModality.length()) return RTPLAN; - else if ( strModality.find("RTSTRUCT") < strModality.length()) return RTSTRUCT; + else if ( strModality.find("RTDOSE") + < strModality.length()) return RTDOSE; + else if ( strModality.find("RTIMAGE") + < strModality.length()) return RTIMAGE; + else if ( strModality.find("RTPLAN") + < strModality.length()) return RTPLAN; + else if ( strModality.find("RTSTRUCT") + < strModality.length()) return RTSTRUCT; else if ( strModality.find("SM") < strModality.length()) return SM; else if ( strModality.find("ST") < strModality.length()) return ST; else if ( strModality.find("TG") < strModality.length()) return TG; @@ -356,6 +364,7 @@ int File::GetZSize() /** * \brief gets the info from 0028,0030 : Pixel Spacing + * (first in 0018,1164 : ImagerPixelSpacing) * else 1.0 * @return X dimension of a pixel */ @@ -363,6 +372,32 @@ float File::GetXSpacing() { float xspacing = 1.0; float yspacing = 1.0; + int nbValues; + + // To follow David Clunie's advice, we first check ImagerPixelSpacing + // (never saw any image with that field :-( + + const std::string &strImagerPixelSpacing = GetEntryValue(0x0018,0x1164); + if( strImagerPixelSpacing != GDCM_UNFOUND ) + { + if( ( nbValues = sscanf( strImagerPixelSpacing.c_str(), + "%f\\%f", &yspacing, &xspacing)) != 2 ) + { + // if no values, xspacing is set to 1.0 + if( nbValues == 0 ) + xspacing = 1.0; + // if single value is found, xspacing is defaulted to yspacing + if( nbValues == 1 ) + xspacing = yspacing; + + if ( xspacing == 0.0 ) + xspacing = 1.0; + + return xspacing; + } + } + + const std::string &strSpacing = GetEntryValue(0x0028,0x0030); if( strSpacing == GDCM_UNFOUND ) @@ -371,9 +406,8 @@ float File::GetXSpacing() return 1.; } - int nbValues; if( ( nbValues = sscanf( strSpacing.c_str(), - "%f\\%f", &yspacing, &xspacing)) != 2 ) + "%f \\%f ", &yspacing, &xspacing)) != 2 ) { // if no values, xspacing is set to 1.0 if( nbValues == 0 ) @@ -397,7 +431,7 @@ float File::GetXSpacing() { gdcmWarningMacro("gdcmData/CT-MONO2-8-abdo.dcm-like problem"); // seems to be a bug in the header ... - nbValues = sscanf( strSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing); + nbValues = sscanf( strSpacing.c_str(), "%f \\0\\%f ", &yspacing, &xspacing); gdcmAssertMacro( nbValues == 2 ); } @@ -406,14 +440,33 @@ float File::GetXSpacing() /** * \brief gets the info from 0028,0030 : Pixel Spacing + * (first in 0018,1164 : ImagerPixelSpacing) * else 1.0 * @return Y dimension of a pixel */ float File::GetYSpacing() { float yspacing = 1.; - std::string strSpacing = GetEntryValue(0x0028,0x0030); - + int nbValues; + // To follow David Clunie's advice, we first check ImagerPixelSpacing + // (never saw any image with that field :-( + + const std::string &strImagerPixelSpacing = GetEntryValue(0x0018,0x1164); + if( strImagerPixelSpacing != GDCM_UNFOUND ) + { + nbValues = sscanf( strImagerPixelSpacing.c_str(), "%f", &yspacing); + + // if sscanf cannot read any float value, it won't affect yspacing + if( nbValues == 0 ) + yspacing = 1.0; + + if ( yspacing == 0.0 ) + yspacing = 1.0; + + return yspacing; + } + + std::string strSpacing = GetEntryValue(0x0028,0x0030); if ( strSpacing == GDCM_UNFOUND ) { gdcmWarningMacro("Unfound Pixel Spacing (0028,0030)"); @@ -421,9 +474,9 @@ float File::GetYSpacing() } // if sscanf cannot read any float value, it won't affect yspacing - int nbValues = sscanf( strSpacing.c_str(), "%f", &yspacing); + nbValues = sscanf( strSpacing.c_str(), "%f", &yspacing); - // if no values, xspacing is set to 1.0 + // if no values, yspacing is set to 1.0 if( nbValues == 0 ) yspacing = 1.0; @@ -497,7 +550,7 @@ float File::GetXOrigin() } } - if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3 ) + if( sscanf( strImPos.c_str(), "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos) != 3 ) { return 0.; } @@ -527,7 +580,7 @@ float File::GetYOrigin() } } - if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3 ) + if( sscanf( strImPos.c_str(), "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos) != 3 ) { return 0.; } @@ -550,7 +603,7 @@ float File::GetZOrigin() if ( strImPos != GDCM_UNFOUND ) { - if( sscanf( strImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) + if( sscanf( strImPos.c_str(), "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos) != 3) { gdcmWarningMacro( "Wrong Image Position Patient (0020,0032)"); return 0.; // bug in the element 0x0020,0x0032 @@ -565,7 +618,7 @@ float File::GetZOrigin() if ( strImPos != GDCM_UNFOUND ) { if( sscanf( strImPos.c_str(), - "%f\\%f\\%f", &xImPos, &yImPos, &zImPos ) != 3 ) + "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos ) != 3 ) { gdcmWarningMacro( "Wrong Image Position (RET) (0020,0030)"); return 0.; // bug in the element 0x0020,0x0032 @@ -579,7 +632,7 @@ float File::GetZOrigin() std::string strSliceLocation = GetEntryValue(0x0020,0x1041); // for *very* old ACR-NEMA images if ( strSliceLocation != GDCM_UNFOUND ) { - if( sscanf( strSliceLocation.c_str(), "%f", &zImPos) != 1) + if( sscanf( strSliceLocation.c_str(), "%f ", &zImPos) != 1) { gdcmWarningMacro( "Wrong Slice Location (0020,1041)"); return 0.; // bug in the element 0x0020,0x1041 @@ -594,7 +647,7 @@ float File::GetZOrigin() std::string strLocation = GetEntryValue(0x0020,0x0050); if ( strLocation != GDCM_UNFOUND ) { - if( sscanf( strLocation.c_str(), "%f", &zImPos) != 1) + if( sscanf( strLocation.c_str(), "%f ", &zImPos) != 1) { gdcmWarningMacro( "Wrong Location (0020,0050)"); return 0.; // bug in the element 0x0020,0x0050 @@ -624,7 +677,7 @@ void File::GetImageOrientationPatient( float iop[6] ) // 0020 0037 DS REL Image Orientation (Patient) if ( (strImOriPat = GetEntryValue(0x0020,0x0037)) != GDCM_UNFOUND ) { - if( sscanf( strImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", + if( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 ) { gdcmWarningMacro( "Wrong Image Orientation Patient (0020,0037). Less than 6 values were found." ); @@ -634,7 +687,7 @@ void File::GetImageOrientationPatient( float iop[6] ) // 0020 0035 DS REL Image Orientation (RET) else if ( (strImOriPat = GetEntryValue(0x0020,0x0035)) != GDCM_UNFOUND ) { - if( sscanf( strImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", + if( sscanf( strImOriPat.c_str(), "%f \\ %f \\%f \\%f \\%f \\%f ", &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6 ) { gdcmWarningMacro( "wrong Image Orientation Patient (0020,0035). Less than 6 values were found." ); @@ -669,7 +722,7 @@ int File::GetBitsStored() int File::GetBitsAllocated() { std::string strSize = GetEntryValue(0x0028,0x0100); - if ( strSize == GDCM_UNFOUND ) + if ( strSize == GDCM_UNFOUND ) { gdcmWarningMacro( "(0028,0100) is supposed to be mandatory"); return 0; // It's supposed to be mandatory @@ -819,20 +872,21 @@ std::string File::GetPixelType() } /** - * \brief Check whether the pixels are signed or UNsigned data. - * \warning The method defaults to false (UNsigned) when information is Missing. + * \brief Check whether the pixels are signed (1) or UNsigned (0) data. + * \warning The method defaults to false (UNsigned) when tag 0028|0103 + * is missing. * The responsability of checking this value is left to the caller. * @return True when signed, false when UNsigned */ bool File::IsSignedPixelData() { - std::string strSize = GetEntryValue( 0x0028, 0x0103 ); - if ( strSize == GDCM_UNFOUND ) + std::string strSign = GetEntryValue( 0x0028, 0x0103 ); + if ( strSign == GDCM_UNFOUND ) { gdcmWarningMacro( "(0028,0103) is supposed to be mandatory"); return false; } - int sign = atoi( strSize.c_str() ); + int sign = atoi( strSign.c_str() ); if ( sign == 0 ) { return false; @@ -1007,7 +1061,7 @@ float File::GetRescaleIntercept() const std::string &strRescInter = GetEntryValue(0x0028,0x1052); if ( strRescInter != GDCM_UNFOUND ) { - if( sscanf( strRescInter.c_str(), "%f", &resInter) != 1 ) + if( sscanf( strRescInter.c_str(), "%f ", &resInter) != 1 ) { // bug in the element 0x0028,0x1052 gdcmWarningMacro( "Rescale Intercept (0028,1052) is empty." ); @@ -1028,7 +1082,7 @@ float File::GetRescaleSlope() std::string strRescSlope = GetEntryValue(0x0028,0x1053); if ( strRescSlope != GDCM_UNFOUND ) { - if( sscanf( strRescSlope.c_str(), "%f", &resSlope) != 1) + if( sscanf( strRescSlope.c_str(), "%f ", &resSlope) != 1) { // bug in the element 0x0028,0x1053 gdcmWarningMacro( "Rescale Slope (0028,1053) is empty."); @@ -1338,12 +1392,6 @@ bool File::Write(std::string fileName, FileType writetype) e0000->SetValue(sLen.str()); } - // Bits Allocated - if ( GetEntryValue(0x0028,0x0100) == "12") - { - SetValEntry("16", 0x0028,0x0100); - } - int i_lgPix = GetEntryLength(GrPixel, NumPixel); if (i_lgPix != -2) { @@ -1353,48 +1401,6 @@ bool File::Write(std::string fileName, FileType writetype) InsertValEntry(s_lgPix,GrPixel, 0x0000); } - // FIXME : should be nice if we could move it to File - // (or in future gdcmPixelData class) - - // Drop Palette Color, if necessary - if ( GetEntryValue(0x0028,0x0002).c_str()[0] == '3' ) - { - // if SamplesPerPixel = 3, sure we don't need any LUT ! - // Drop 0028|1101, 0028|1102, 0028|1103 - // Drop 0028|1201, 0028|1202, 0028|1203 - - DocEntry *e = GetDocEntry(0x0028,0x01101); - if (e) - { - RemoveEntryNoDestroy(e); - } - e = GetDocEntry(0x0028,0x1102); - if (e) - { - RemoveEntryNoDestroy(e); - } - e = GetDocEntry(0x0028,0x1103); - if (e) - { - RemoveEntryNoDestroy(e); - } - e = GetDocEntry(0x0028,0x01201); - if (e) - { - RemoveEntryNoDestroy(e); - } - e = GetDocEntry(0x0028,0x1202); - if (e) - { - RemoveEntryNoDestroy(e); - } - e = GetDocEntry(0x0028,0x1203); - if (e) - { - RemoveEntryNoDestroy(e); - } - } - Document::WriteContent(fp, writetype); fp->close(); @@ -1445,7 +1451,7 @@ void File::ComputeRLEInfo() // - when more than one frame are present, then we are in // the case of a multi-frame image. long frameLength; - while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) ) + while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) != 0 ) { // Parse the RLE Header and store the corresponding RLE Segment // Offset Table information on fragments of this current Frame. @@ -1524,7 +1530,7 @@ void File::ComputeJPEGFragmentInfo() // Loop on the fragments[s] and store the parsed information in a // JPEGInfo. long fragmentLength; - while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) ) + while ( (fragmentLength = ReadTagLength(0xfffe, 0xe000)) != 0 ) { long fragmentOffset = Fp->tellg();