From 33413fc6fb41f4fd7efbce32083f943f252e8b6f Mon Sep 17 00:00:00 2001 From: jpr Date: Thu, 23 Oct 2003 12:08:32 +0000 Subject: [PATCH] gdcm now deals with 16 Bits Run Length Encoded images --- src/gdcmFile.cxx | 129 +++++++++++++++++++++------------------------ src/gdcmHeader.cxx | 13 +++-- src/gdcmRLE.cxx | 49 +++++++++-------- 3 files changed, 91 insertions(+), 100 deletions(-) diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 4490655c..af62cd8f 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -126,7 +126,7 @@ bool gdcmFile::ReadPixelData(void* destination) { CloseFile(); return false; } - + // ------------------------- Compacted File (12 Bits Per Pixel) /* unpack 12 Bits pixels into 16 Bits pixels */ @@ -152,7 +152,7 @@ bool gdcmFile::ReadPixelData(void* destination) { } return(true); } - + // ------------------------- Uncompressed File @@ -171,8 +171,18 @@ bool gdcmFile::ReadPixelData(void* destination) { return true; } } + + +// ------------------------- Run Length Encoding + + if (gdcmHeader::IsRLELossLessTransferSyntax()) { + int res = (bool)gdcm_read_RLE_file (destination); + return res; + } + + - // ------------------------ Compressed File . +// ----------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 int nb; std::string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); @@ -184,22 +194,11 @@ bool gdcmFile::ReadPixelData(void* destination) { } int nBytes= nb/8; - int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); - - - - // ---------------- RLE - - if (gdcmHeader::IsRLELossLessTransferSyntax()) { - int res = (bool)gdcm_read_RLE_file (destination); - return res; - } - - // ----------------- SingleFrame/Multiframe JPEG - + int taille = GetXSize() * GetYSize() * GetSamplesPerPixel(); long fragmentBegining; // for ftell, fseek - bool b = gdcmHeader::IsJPEG2000(); + bool jpg2000 = IsJPEG2000(); + bool jpgLossless = IsJPEGLossless(); bool res = true; guint16 ItemTagGr,ItemTagEl; @@ -243,39 +242,30 @@ bool gdcmFile::ReadPixelData(void* destination) { fragmentBegining=ftell(fp); - if (b) + if (jpg2000) { // JPEG 2000 : call to ??? + res = (bool)gdcm_read_JPEG2000_file (destination); // Not Yet written - - else if (IsJPEGLossless()) { // JPEG LossLess : call to xmedcom JPEG + + } // ------------------------------------- endif (JPEG2000) + + else if (jpgLossless) { // JPEG LossLess : call to xmedcom JPEG - JPEGLosslessDecodeImage (fp, + JPEGLosslessDecodeImage (fp, // Reading Fragment pixels (unsigned short *)destination, GetPixelSize()*8* GetSamplesPerPixel(), - ln); - + ln); res=1; // in order not to break the loop - } // ------------------------------------- endif (IsJPEGLossless()) + } // ------------------------------------- endif (JPEGLossless) - else { // JPEG Lossy : call to xmedcon JPEG - // (just to see if it works) --> it does NOT ! - /* - JPEGLosslessDecodeImage (fp, - (unsigned short *)destination, - GetPixelSize()*8* GetSamplesPerPixel(), - ln); - - */ - // JPEG Lossy : call to IJG 6b + else { // JPEG Lossy : call to IJG 6b if (GetBitsStored() == 8) { res = (bool)gdcm_read_JPEG_file (destination); // Reading Fragment pixels } else { res = (bool)gdcm_read_JPEG_file12 (destination);// Reading Fragment pixels } - - - } + } // ------------------------------------- endif (JPEGLossy) if (!res) break; @@ -404,25 +394,28 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { // *Try* to deal with the color // ---------------------------- - + + std::string str_PhotometricInterpretation = + gdcmHeader::GetPubElValByNumber(0x0028,0x0004); + + if ( (str_PhotometricInterpretation == "MONOCHROME1 ") + || (str_PhotometricInterpretation == "MONOCHROME2 ") ) { + return lgrTotale; + } + // 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 + // 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); - - if ( (str_PhotometricInterpretation == "MONOCHROME1 ") - || (str_PhotometricInterpretation == "MONOCHROME2 ") - || (str_PhotometricInterpretation == "RGB")) { - return lgrTotale; - } int planConf=GetPlanarConfiguration(); - // Whatever Planar Configuration is, "PALETTE COLOR " implies that we deal with the palette. + // Whatever Planar Configuration is, + // "PALETTE COLOR " implies that we deal with the palette. if (str_PhotometricInterpretation == "PALETTE COLOR ") planConf=2; @@ -455,9 +448,9 @@ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { // integer computation counterpart for (int i=0;i Warning : This fourth fiels is NOT part +// ---> Warning : This fourth field is NOT part // of the 'official' Dicom Dictionnary // and should NOT be used. // (Not defined for all the groups @@ -672,14 +672,14 @@ void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) { return 0; TotalLength += 4; // We even have to decount the group and element - if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ { + if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ { char msg[100]; // for sprintf. Sorry sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n); dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg); errno = 1; return 0; } - if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */ + if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */ FoundSequenceDelimiter = true; else if ( n != 0xe000 ){ char msg[100]; // for sprintf. Sorry @@ -1767,7 +1767,7 @@ void gdcmHeader::PrintPubElVal(std::ostream & os) { /** * \ingroup gdcmHeader - * \brief + * \brief * @return */ void gdcmHeader::PrintPubDict(std::ostream & os) { @@ -1777,7 +1777,7 @@ void gdcmHeader::PrintPubDict(std::ostream & os) { /** * \ingroup gdcmHeader * \brief - * @return + * @return integer, acts as a Boolean */ int gdcmHeader::Write(FILE * fp, FileType type) { @@ -1841,7 +1841,6 @@ void * gdcmHeader::LoadElementVoidArea(guint16 Group, guint16 Elem) { free(a); return NULL; } - // TODO : finish the function !!! return a; } diff --git a/src/gdcmRLE.cxx b/src/gdcmRLE.cxx index 8930df21..bb993d48 100644 --- a/src/gdcmRLE.cxx +++ b/src/gdcmRLE.cxx @@ -11,9 +11,6 @@ static int _gdcm_read_RLE_fragment (char ** image_buffer, FILE* fp); // static because nothing but gdcm_read_RLE_file may call it -#define DEBUG 0 -// Will be removed - // ---------------------------------------------------------------------------- /** * \ingroup gdcmFile @@ -35,7 +32,6 @@ int gdcmFile::gdcm_read_RLE_file (void * image_buffer) { long fragmentBegining; // for ftell, fseek char * im = (char *)image_buffer; - if (DEBUG)std::cout << "RLE image" << std::endl; long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;; long ftellRes, ln; @@ -43,7 +39,6 @@ gdcmFile::gdcm_read_RLE_file (void * image_buffer) { guint32 RleSegmentOffsetTable[15]; guint16 ItemTagGr,ItemTagEl; uncompressedSegmentSize=GetXSize()*GetYSize(); - if (DEBUG)printf("uncompressedSegmentSize %d\n",uncompressedSegmentSize); ftellRes=ftell(fp); // Basic Offset Table with Item Value // Item Tag @@ -53,15 +48,11 @@ gdcmFile::gdcm_read_RLE_file (void * image_buffer) { ItemTagGr=SwapShort(ItemTagGr); ItemTagEl=SwapShort(ItemTagEl); } - if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n", - ftellRes,ItemTagGr,ItemTagEl ); // Item Length ftellRes=ftell(fp); fread(&ln,4,1,fp); if(GetSwapCode()) ln=SwapLong(ln); // Basic Offset Table Item Lentgh - if (DEBUG)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); @@ -69,7 +60,6 @@ gdcmFile::gdcm_read_RLE_file (void * image_buffer) { guint32 a; for (int i=0;i1) { for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k]; ftellRes=ftell(fp); - if (DEBUG)printf (" (in) Segment %d : Length = %d x(%x) Start at %x\n", - k,RleSegmentLength[k],RleSegmentLength[k], ftellRes); fragmentBegining=ftell(fp); _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp); fseek(fp,fragmentBegining,SEEK_SET); @@ -123,10 +104,6 @@ gdcmFile::gdcm_read_RLE_file (void * image_buffer) { } RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments]; ftellRes=ftell(fp); - if (DEBUG)printf (" (out)Segment %d : Length = %d x(%x) Start at %x\n", - nbRleSegments, - RleSegmentLength[nbRleSegments],RleSegmentLength[nbRleSegments], - ftellRes); fragmentBegining=ftell(fp); _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp); fseek(fp,fragmentBegining,SEEK_SET); @@ -141,9 +118,31 @@ gdcmFile::gdcm_read_RLE_file (void * image_buffer) { ItemTagGr=SwapShort(ItemTagGr); ItemTagEl=SwapShort(ItemTagEl); } - if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n", - ftellRes,ItemTagGr,ItemTagEl ); } + + if (GetBitsAllocated()==16) { // try to deal with RLE 16 Bits + + im = (char *)image_buffer; + // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes' + + int l = GetXSize()*GetYSize(); + int nbFrames = GetZSize(); + + char * newDest = (char*) malloc(l*nbFrames*2); + char *x = newDest; + char * a = (char *)image_buffer; + char * b = a + l; + + for (int i=0;i