X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFile.cxx;h=32ef12b9af921513d04fdab8312a11780cf8b17a;hb=48c3e6379fcb2517d56c15d51e45c4c79543c16c;hp=50eeeba71a8320490354f92d6e6f44e8755fd9dd;hpb=d44cb38c3275dc302d9b523c17d346810f0e6644;p=gdcm.git diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 50eeeba7..32ef12b9 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -1,23 +1,8 @@ // gdcmFile.cxx -//This is needed when compiling in debug mode -#ifdef _MSC_VER -// 'type' : forcing value to bool 'true' or 'false' (performance warning) -//#pragma warning ( disable : 4800 ) -// 'identifier' : class 'type' needs to have dll-interface to be used by -// clients of class 'type2' -#pragma warning ( disable : 4251 ) -// 'identifier' : identifier was truncated to 'number' characters in the -// debug information -#pragma warning ( disable : 4786 ) -#endif //_MSC_VER - #include "gdcmFile.h" #include "gdcmUtil.h" -#include "iddcmjpeg.h" // for the 'LibIDO' Jpeg LossLess -using namespace std; - -#define str2num(str, typeNum) *((typeNum *)(str)) +#include "jpeg/ljpg/jpegless.h" ///////////////////////////////////////////////////////////////// /** @@ -37,32 +22,33 @@ using namespace std; * @return */ -gdcmFile::gdcmFile(string & filename) +gdcmFile::gdcmFile(std::string & filename) :gdcmHeader(filename.c_str()) { - SetPixelDataSizeFromHeader(); + if (IsReadable()) + SetPixelDataSizeFromHeader(); } gdcmFile::gdcmFile(const char * filename) :gdcmHeader(filename) { - SetPixelDataSizeFromHeader(); + if (IsReadable()) + SetPixelDataSizeFromHeader(); } /** * \ingroup gdcmFile * \brief calcule la longueur (in bytes) A ALLOUER pour recevoir les - * pixels de l'image - * ou DES images dans le cas d'un multiframe - * ATTENTION : il ne s'agit PAS de la longueur du groupe des Pixels - * (dans le cas d'images compressees, elle n'a pas de sens). + * pixels de l'image ou DES images dans le cas d'un multiframe + * + * ATTENTION : il ne s'agit PAS de la longueur du groupe des Pixels + * (dans le cas d'images compressees, elle n'a pas de sens). * * @return longueur a allouer */ void gdcmFile::SetPixelDataSizeFromHeader(void) { int nb; - string str_nb; - + std::string str_nb; str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; @@ -70,20 +56,46 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { nb = atoi(str_nb.c_str() ); if (nb == 12) nb =16; } - lgrTotale = GetXSize() * GetYSize() * GetZSize() * (nb/8)* GetSamplesPerPixel(); + lgrTotale = lgrTotaleRaw = GetXSize() * GetYSize() * GetZSize() + * (nb/8)* GetSamplesPerPixel(); + std::string str_PhotometricInterpretation = + gdcmHeader::GetPubElValByNumber(0x0028,0x0004); + + /*if ( str_PhotometricInterpretation == "PALETTE COLOR " )*/ + // pb when undealt Segmented Palette Color - string str_PhotometricInterpretation = gdcmHeader::GetPubElValByNumber(0x0028,0x0004); - if ( str_PhotometricInterpretation == "PALETTE COLOR " - || str_PhotometricInterpretation == "YBR_FULL") { // --> some more to be added !! + if (HasLUT()) { lgrTotale*=3; } - - // remaining to check : - // str_PhotometricInterpretation == "YBR_FULL" - // str_PhotometricInterpretation == "YBR_FULL_422" (no LUT, no Palette) - // -->and some more !! } + // see PS 3.3-2003 : C.7.6.3.2.1 + // + // MONOCHROME1 + // MONOCHROME2 + // PALETTE COLOR + // RGB + // HSV (Retired) + // ARGB (Retired) + // CMYK (Retired) + // YBR_FULL + // YBR_FULL_422 (no LUT, no Palette) + // YBR_PARTIAL_422 + // YBR_ICT + // YBR_RCT + + // LUT's + // ex : gdcm-US-ALOKA-16.dcm + // 0028|1221 [OW] [Segmented Red Palette Color Lookup Table Data] + // 0028|1222 [OW] [Segmented Green Palette Color Lookup Table Data] + // 0028|1223 [OW] [Segmented Blue Palette Color Lookup Table Data] + + // ex : OT-PAL-8-face.dcm + // 0028|1201 [US] [Red Palette Color Lookup Table Data] + // 0028|1202 [US] [Green Palette Color Lookup Table Data] + // 0028|1203 [US] [Blue Palette Color Lookup Table Data] + + ///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile @@ -91,127 +103,12 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { * the pixel data represented in this file. * @return The size of pixel data in bytes. */ + size_t gdcmFile::GetImageDataSize(void) { return (lgrTotale); } -///////////////////////////////////////////////////////////////// -/** - * \ingroup gdcmFile - * \brief Parse pixel data from disk and *prints* the result - * \ For multi-fragment Jpeg files checking purpose *only* - * \ Allows to 'see' if the file *does* conform - * \ (some of them do not) - * \ with Dicom Part 3, Annex A (PS 3.5-2003, page 58) - * - */ -bool gdcmFile::ParsePixelData(void) { - if ( !OpenFile()) - return false; - - if ( fseek(fp, GetPixelOffset(), SEEK_SET) == -1 ) { - CloseFile(); - return false; - } - - if ( !IsDicomV3() || - IsImplicitVRLittleEndianTransferSyntax() || - IsExplicitVRLittleEndianTransferSyntax() || - IsExplicitVRBigEndianTransferSyntax() || - IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { - - printf ("gdcmFile::ParsePixelData : non JPEG File\n"); - return 0; - } - - int nb; - string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); - if (str_nb == GDCM_UNFOUND ) { - nb = 16; - } else { - nb = atoi(str_nb.c_str() ); - if (nb == 12) nb =16; - } - int nBytes= nb/8; - - //int taille = GetXSize() * GetYSize() * GetZSize() * GetSamplesPerPixel(); - int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); - - printf ("Checking the Dicom-Jpeg/RLE Pixels\n"); - - // ------------------------------- for Parsing : Position on begining of Jpeg Pixels - guint16 ItemTagGr,ItemTagEl; - int ln; - long ftellRes; - char * destination = NULL; - ftellRes=ftell(fp); - fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Basic Offset Table Item Tag Gr - fread(&ItemTagEl,2,1,fp); // Reading (e000) : Basic Offset Table Item Tag El - if(GetSwapCode()) { - ItemTagGr=SwapShort(ItemTagGr); - ItemTagEl=SwapShort(ItemTagEl); - } - printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n", - ftellRes,ItemTagGr,ItemTagEl ); - ftellRes=ftell(fp); - fread(&ln,4,1,fp); - if(GetSwapCode()) - ln=SwapLong(ln); // Basic Offset Table Item Lentgh - printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n", - ftellRes,ln,ln); - if (ln != 0) { - // What is it used for ?? - char * BasicOffsetTableItemValue= (char *)malloc(ln+1); - fread(BasicOffsetTableItemValue,ln,1,fp); - guint32 a; - for (int i=0;i> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f); + /* A */ /* B */ /* D */ + *pdestination++ = ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4); + /* F */ /* C */ /* E */ + + // Troubles expected on Big-Endian processors ? + } + return(true); + } -// ------------------------------- Uncompressed File + // ---------------------- Uncompressed File if ( !IsDicomV3() || IsImplicitVRLittleEndianTransferSyntax() || IsExplicitVRLittleEndianTransferSyntax() || IsExplicitVRBigEndianTransferSyntax() || - IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { - - size_t ItemRead = fread(destination, lgrTotale, 1, fp); + IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { + + size_t ItemRead = fread(destination, GetPixelAreaLength(), 1, fp); + if ( ItemRead != 1 ) { CloseFile(); return false; @@ -247,82 +172,37 @@ bool gdcmFile::ReadPixelData(void* destination) { return true; } } + + // ---------------------- Run Length Encoding + + if (gdcmHeader::IsRLELossLessTransferSyntax()) { + int res = (bool)gdcm_read_RLE_file (destination); + return res; + } - // ----------------------------- JPEG Compressed File . + // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 int nb; - string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); + std::string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; } else { nb = atoi(str_nb.c_str() ); - if (nb == 12) nb =16; + if (nb == 12) nb =16; // ?? 12 should be ACR-NEMA only ? } int nBytes= nb/8; - //int taille = GetXSize() * GetYSize() * GetZSize() * GetSamplesPerPixel(); - int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); - - - // ------------------------------- JPEG LossLess : call to Jpeg Libido - - if (IsJPEGLossless() && GetZSize() == 1) { - - int ln; // Position on begining of Jpeg Pixels - fseek(fp,4,SEEK_CUR); // skipping (fffe,e000) : Basic Offset Table Item - fread(&ln,4,1,fp); - if(GetSwapCode()) - ln=SwapLong(ln); // Item length - fseek(fp,ln,SEEK_CUR); // skipping Basic Offset Table ('ln' bytes) - fseek(fp,4,SEEK_CUR); // skipping (fffe,e000) : First fragment Item Tag - fread(&ln,4,1,fp); // First fragment length (just to know) - if(GetSwapCode()) - ln=SwapLong(ln); - - ClbJpeg* jpg = _IdDcmJpegRead(fp); // TODO : find a 'full' one. - // (We use the LibIDO one :-( - if(jpg == NULL) { - CloseFile(); - return false; - } - int * dataJpg = jpg->DataImg; - - switch (nBytes) { - case 1: - { - unsigned short *dest = (unsigned short *)destination; - for (int i=0; iDataImg; - unsigned short *dest = (unsigned short *)destination; - switch (nBytes) { - case 1: - { - for (int i=0; i MaxSize ) { dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: pixel data bigger" @@ -492,12 +468,13 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { highBit = nb - 1; } else { highBit = atoi(str_highBit.c_str() ); - } - - // Signe des Pixels + } + // Pixel sign + // 0 = Unsigned + // 1 = Signed str_signe=GetPubElValByNumber(0x0028,0x0103); if (str_signe == GDCM_UNFOUND ) { - signe = 1; + signe = 0; // default is unsigned } else { signe = atoi(str_signe.c_str() ); } @@ -505,7 +482,18 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { // re arange bytes inside the integer if (nb != 8) SwapZone(destination, GetSwapCode(), lgrTotale, nb); - + + // to avoid pb with some xmedcon breakers images + if (nb==16 && nbu255.0) R=255.0; + if (G>255.0) G=255.0; + if (B>255.0) B=255.0; + + *(x++) = (unsigned char)R; + *(x++) = (unsigned char)G; + *(x++) = (unsigned char)B; + a++; b++; c++; + } + } + memmove(destination,newDest,lgrTotale); free(newDest); + + } else { - // now, it's an RGB image - string spp = "3"; - gdcmHeader::SetPubElValByNumber(spp,0x0028,0x0002); - string rgb="RGB"; - gdcmHeader::SetPubElValByNumber(rgb,0x0028,0x0004); - - } else { // need to make RGB Pixels (?) - // from grey Pixels (?!) - // and Gray Lut (!?!) - unsigned char *lutGray =(unsigned char *)GetPubElValVoidAreaByNumber(0x0028,0x1200); - // Well . I'll wait till I find such an image - } + // need to make RGB Pixels from R,G,B Planes + // (all the Frames at a time) + + int l = GetXSize()*GetYSize()*GetZSize(); + + char * newDest = (char*) malloc(lgrTotale); + char * x = newDest; + char * a = (char *)destination; + char * b = a + l; + char * c = b + l; + + for (int j=0;j