X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFile.cxx;h=88dcdf6a04a02a7ac6ad7fac2db59db677c6674a;hb=f8e5982fc2d53058d72b5c96e8f4f53faf9a37d7;hp=a88fe481413ee0c67206f79e97b83779f14aecb2;hpb=b6e445adae1963909952eeef10ea7c1d2e0d3e0d;p=gdcm.git diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index a88fe481..88dcdf6a 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -1,23 +1,9 @@ // 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 -#define str2num(str, typeNum) *((typeNum *)(str)) - ///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile @@ -53,7 +39,7 @@ gdcmFile::gdcmFile(const char * filename) * \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 + * 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 @@ -70,18 +56,43 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { if (nb == 12) nb =16; } lgrTotale = GetXSize() * GetYSize() * GetZSize() * (nb/8)* GetSamplesPerPixel(); - std::string str_PhotometricInterpretation = gdcmHeader::GetPubElValByNumber(0x0028,0x0004); - if ( str_PhotometricInterpretation == "PALETTE COLOR " - || str_PhotometricInterpretation == "YBR_FULL") { // --> some more to be added !! + if ( str_PhotometricInterpretation == "PALETTE COLOR " ) { 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 : US-PAL-8-10x-echo.dcm, 8BitsRunLengthColor.dcm + // 0028|1201 [OW] [Red Palette Color Lookup Table Data] + // 0028|1202 [OW] [Green Palette Color Lookup Table Data] + // 0028|1203 [OW] [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] + + ///////////////////////////////////////////////////////////////// /** @@ -90,241 +101,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/Rle 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, page 85) - * - */ -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/RLE File\n"); - return 0; - } - - int nb; - 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; - } - int nBytes= nb/8; - - //int taille = GetXSize() * GetYSize() * GetZSize() * GetSamplesPerPixel(); - int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); - - printf ("Checking the Dicom-Jpeg/RLE Pixels\n"); - - guint16 ItemTagGr,ItemTagEl; - int ln; - long ftellRes; - char * destination = NULL; - - // ------------------------------- for Parsing : Position on begining of Jpeg/RLE Pixels - - if( !IsRLELossLessTransferSyntax()) { - - // JPEG Image - - cout << "JPEG image" << endl; - 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;i1) { - for(int k=1; k<=nbRleSegments-1; k++) { // skipping (not reading) RLE Segments - RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k]; - ftellRes=ftell(fp); - printf (" Segment %d : Length = %d Start at %x\n", - k,RleSegmentLength[k], ftellRes); - fseek(fp,RleSegmentLength[k],SEEK_CUR); - } - } - RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments] ; - // TODO : Check the value - ftellRes=ftell(fp); - printf (" Segment %d : Length = %d Start at %x\n", - nbRleSegments,RleSegmentLength[nbRleSegments],ftellRes); - - fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR); - - // ------------------ end of scanning fragment pixels - - ftellRes=ftell(fp); - fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr - fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El - if(GetSwapCode()) { - ItemTagGr=SwapShort(ItemTagGr); - ItemTagEl=SwapShort(ItemTagEl); - } - printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n", - ftellRes,ItemTagGr,ItemTagEl ); - } - } - return 1; -} - ///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile @@ -373,7 +155,6 @@ bool gdcmFile::ReadPixelData(void* destination) { } int nBytes= nb/8; - //int taille = GetXSize() * GetYSize() * GetZSize() * GetSamplesPerPixel(); int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); @@ -478,10 +259,11 @@ bool gdcmFile::ReadPixelData(void* destination) { if (b) res = (bool)gdcm_read_JPEG2000_file (destination); // Reading Fragment pixels - else if (IsJPEGLossless()) { // ------------- call to LibIDO Jpeg for each Frame/fragment + else if (IsJPEGLossless()) { + // ------------- call to LibIDO Jpeg for each Frame/fragment - // Warning : Works only if there is one fragment per frame - // (Or a single fragment for the multiframe file) + // Warning : Works only if there is one fragment per frame + // (Or a single fragment for the multiframe file) ClbJpeg* jpg = _IdDcmJpegRead(fp); // TODO : find a 'full' one. // (We use the LibIDO one :-( if(jpg == NULL) { @@ -538,7 +320,7 @@ bool gdcmFile::ReadPixelData(void* destination) { } //(char *) destination += taille * nBytes; - //cout << "destination" << destination << "\n"; + //std::cout << "destination" << destination << std::endl; } return res; @@ -643,94 +425,176 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: wierd image"); return (size_t)0; } - } - - // Try to deal with the color - // -------------------------- - - std::string str_PhotometricInterpretation = gdcmHeader::GetPubElValByNumber(0x0028,0x0004); - - if ( (str_PhotometricInterpretation == "MONOCHROME1 ") - || (str_PhotometricInterpretation == "MONOCHROME2 ") - || (str_PhotometricInterpretation == "RGB")) { - return lgrTotale; - } - - switch ( GetPlanarConfiguration() ) { - case 0: - // Pixels are already RGB - break; + } + +// Just to 'see' was was actually read on disk :-( +// Some troubles expected + +FILE * fpSpurious; +fpSpurious=fopen("SpuriousFile.raw","w"); +fwrite(destination,lgrTotale, 1,fpSpurious); +fclose(fpSpurious); + + + // *Try* to deal with the color + // ---------------------------- + + // Planar configuration = 0 : Pixels are already RGB + // Planar configuration = 1 : 3 planes : R, G, B + // Planar configuration = 2 : 1 gray Plane + 3 LUT + + // Well ... supposed to be ! + // See US-PAL-8-10x-echo.dcm: PlanarConfiguration=0,PhotometricInterpretation=PALETTE COLOR + // and heuristic has to be found :-( + + std::string str_PhotometricInterpretation = gdcmHeader::GetPubElValByNumber(0x0028,0x0004); - case 1: - // need to make RGB Pixels from Planes R,G,B - { - int l = lgrTotale/3 ; - - char * a = (char *)destination; - char * b = a + l; - char * c = b + l; - char * newDest = (char*) malloc(lgrTotale); - // TODO : - // any trick not to have to allocate temporary buffer is welcome ... - char *x = newDest; - for (int j=0;j255.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 { + + // need to make RGB Pixels from Planes R,G,B + + int l = GetXSize()*GetYSize(); + int nbFrames = GetZSize(); + + char * newDest = (char*) malloc(lgrTotale); + char *x = newDest; + char * a = (char *)destination; + char * b = a + l; + char * c = b + l; + + // TODO : + // any trick not to have to allocate temporary buffer is welcome ... + + for (int i=0;i