From 67845c7dc1241480f5c5fcfa0cfc2e86918dad1e Mon Sep 17 00:00:00 2001 From: frog Date: Fri, 8 Oct 2004 16:27:19 +0000 Subject: [PATCH] * CLEANUP_ROUND (8) for gdcmPixelConvert (end of RLE nigthmare) - src/gdcmRLE.cxx removed - src/gdcmPixelConvert.cxx all RLE code is now in PixelConvert:: - src/CMakeLists.txt gdcmFile.[cxx|h] changed accordingly - src/gdcmRLEFrame*.h gdcmPixelConvert is now a friend class. --- ChangeLog | 5 ++ src/CMakeLists.txt | 1 - src/gdcmFile.cxx | 13 +++- src/gdcmFile.h | 14 +--- src/gdcmPixelConvert.cxx | 134 +++++++++++++++++++++++++++++------ src/gdcmPixelConvert.h | 21 +++++- src/gdcmRLE.cxx | 148 --------------------------------------- src/gdcmRLEFrame.h | 5 +- src/gdcmRLEFramesInfo.h | 5 +- 9 files changed, 155 insertions(+), 191 deletions(-) delete mode 100644 src/gdcmRLE.cxx diff --git a/ChangeLog b/ChangeLog index 1cda6248..c8163a29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ * CLEANUP_ROUND (7) for gdcmPixelConvert (lost at sea) - src/gdcmFile.h gdcmPixelConvert.cxx gdcmPixelConvert.h gdcmRLE.cxx: clean up of RLE related code. + * CLEANUP_ROUND (8) for gdcmPixelConvert (end of RLE nigthmare) + - src/gdcmRLE.cxx removed + - src/gdcmPixelConvert.cxx all RLE code is now in PixelConvert:: + - src/CMakeLists.txt gdcmFile.[cxx|h] changed accordingly + - src/gdcmRLEFrame*.h gdcmPixelConvert is now a friend class. 2004-10-07 Eric Boix * CLEANUP_ROUND (5) for gdcmPixelConvert (Upshit creek without a paddle) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4794655..bc7a730a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,6 @@ SET(libgdcm_la_SOURCES gdcmJpeg2000.cxx gdcmParsePixels.cxx gdcmPixelConvert.cxx - gdcmRLE.cxx gdcmRLEFramesInfo.cxx gdcmSeqEntry.cxx gdcmSQItem.cxx diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 6b9138b2..7a3c1fcc 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2004/10/01 12:40:57 $ - Version: $Revision: 1.134 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.135 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -18,6 +18,7 @@ #include "gdcmFile.h" #include "gdcmDebug.h" +#include "gdcmPixelConvert.h" #include "jpeg/ljpg/jpegless.h" typedef std::pair IterHT; @@ -1083,7 +1084,13 @@ bool gdcmFile::ReadPixelData(void* destination) // ---------------------- Run Length Encoding if ( Header->IsRLELossLessTransferSyntax() ) { - bool res = gdcm_read_RLE_file (fp,destination); + bool res = gdcmPixelConvert::gdcm_read_RLE_file ( destination, + Header->GetXSize(), + Header->GetYSize(), + Header->GetZSize(), + Header->GetBitsAllocated(), + &(Header->RLEInfo), + fp ); Header->CloseFile(); return res; } diff --git a/src/gdcmFile.h b/src/gdcmFile.h index c814acbb..3bb74872 100644 --- a/src/gdcmFile.h +++ b/src/gdcmFile.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.h,v $ Language: C++ - Date: $Date: 2004/10/08 08:56:48 $ - Version: $Revision: 1.56 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.57 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -121,16 +121,6 @@ private: // For JPEG 2000, body in file gdcmJpeg2000.cxx bool gdcm_read_JPEG2000_file (FILE* fp, void* image_buffer); - // For Run Length Encoding - bool gdcm_read_RLE_file (FILE* fp, void* image_buffer); -// FIXME : *sure* it's NOT static (C++) -// (would be static in C, or embedded in ADA) -// It's NOT a method, but a not user intended fonction. -// How do we write that in C++ ?) - static bool gdcm_read_RLE_fragment( uint8_t** decodedZone, - long fragmentSize, - long uncompressedSegmentSize, FILE* fp); - void SaveInitialValues(); // will belong to the future gdcmPixelData class void RestoreInitialValues(); // will belong to the future gdcmPixelData class void DeleteInitialValues(); // will belong to the future gdcmPixelData class diff --git a/src/gdcmPixelConvert.cxx b/src/gdcmPixelConvert.cxx index 0f00fe6c..789a600a 100644 --- a/src/gdcmPixelConvert.cxx +++ b/src/gdcmPixelConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelConvert.cxx,v $ Language: C++ - Date: $Date: 2004/10/08 08:56:48 $ - Version: $Revision: 1.2 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.3 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -164,7 +164,7 @@ bool gdcmPixelConvert::ConvertGrayAndLutToRGB( uint8_t *lutRGBA ) * High Byte 'Planes'...(for what it may mean) * @return Boolean */ -uint8_t* gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( +bool gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( int XSize, int YSize, int NumberOfFrames, @@ -175,24 +175,13 @@ uint8_t* gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( // We assumed Uncompressed contains the decoded RLE pixels but as // 8 bits per pixel. In order to convert those pixels to 16 bits - // per pixel we cannot work in place within Uncompressed. - // Here is how we handle things: - // - First stage: copy Uncompressed in a safe place, say OldUncompressed - // - Second stage: reallocate Uncompressed with the needed space - // - Third stage: expand from OldUncompressed to Uncompressed - // - Fourth stage: clean up OldUncompressed - - /// First stage: + // per pixel we cannot work in place within Uncompressed and hence + // we copy Uncompressed in a safe place, say OldUncompressed. + uint8_t* OldUncompressed = new uint8_t[ fixMemUncompressedSize * 2 ]; memmove( OldUncompressed, fixMemUncompressed, fixMemUncompressedSize * 2); - /// Second stage: - //fixMem SetUncompressedSize( 2 * UncompressedSize ); - //fixMem AllocateUncompressed(); - uint8_t* fixMemNewUncompressed = new uint8_t[fixMemUncompressedSize * 2]; - - /// Third stage: - uint8_t* x = fixMemNewUncompressed; + uint8_t* x = fixMemUncompressed; uint8_t* a = OldUncompressed; uint8_t* b = a + PixelNumber; @@ -205,9 +194,114 @@ uint8_t* gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( } } - // Fourth stage: delete[] OldUncompressed; /// \todo check that operator new []didn't fail, and sometimes return false - return fixMemNewUncompressed; + return true; +} + +/** + * \brief Implementation of the RLE decoding algorithm for uncompressing + * a RLE fragment. [refer to PS 3.5-2003, section G.3.2 p 86] + */ +bool gdcmPixelConvert::ReadAndUncompressRLEFragment( uint8_t* decodedZone, + long fragmentSize, + long uncompressedSegmentSize, + FILE* fp ) +{ + int8_t count; + long numberOfOutputBytes = 0; + long numberOfReadBytes = 0; + + while( numberOfOutputBytes < uncompressedSegmentSize ) + { + fread( &count, 1, 1, fp ); + numberOfReadBytes += 1; + if ( count >= 0 ) + // Note: count <= 127 comparison is always true due to limited range + // of data type int8_t [since the maximum of an exact width + // signed integer of width N is 2^(N-1) - 1, which for int8_t + // is 127]. + { + fread( decodedZone, count + 1, 1, fp); + numberOfReadBytes += count + 1; + decodedZone += count + 1; + numberOfOutputBytes += count + 1; + } + else + { + if ( ( count <= -1 ) && ( count >= -127 ) ) + { + int8_t newByte; + fread( &newByte, 1, 1, fp); + numberOfReadBytes += 1; + for( int i = 0; i < -count + 1; i++ ) + { + decodedZone[i] = newByte; + } + decodedZone += -count + 1; + numberOfOutputBytes += -count + 1; + } + } + // if count = 128 output nothing + + if ( numberOfReadBytes > fragmentSize ) + { + dbg.Verbose(0, "gdcmFile::gdcm_read_RLE_fragment: we read more " + "bytes than the segment size."); + return false; + } + } + return true; } + +/** + * \brief Reads from disk the Pixel Data of 'Run Length Encoded' + * Dicom encapsulated file and uncompress it. + * @param fp already open File Pointer + * @param image_buffer destination Address (in caller's memory space) + * at which the pixel data should be copied + * @return Boolean + */ +bool gdcmPixelConvert::gdcm_read_RLE_file( void* image_buffer, + int XSize, + int YSize, + int ZSize, + int BitsAllocated, + gdcmRLEFramesInfo* RLEInfo, + FILE* fp ) +{ + uint8_t* im = (uint8_t*)image_buffer; + long uncompressedSegmentSize = XSize * YSize; + + + // Loop on the frame[s] + for( gdcmRLEFramesInfo::RLEFrameList::iterator + it = RLEInfo->Frames.begin(); + it != RLEInfo->Frames.end(); + ++it ) + { + // Loop on the fragments + for( unsigned int k = 1; k <= (*it)->NumberFragments; k++ ) + { + fseek( fp, (*it)->Offset[k] ,SEEK_SET); + (void)gdcmPixelConvert::ReadAndUncompressRLEFragment( + (uint8_t*) im, (*it)->Length[k], + uncompressedSegmentSize, fp ); + im += uncompressedSegmentSize; + } + } + + if ( BitsAllocated == 16 ) + { + // Try to deal with RLE 16 Bits + (void)gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( + XSize, + YSize, + ZSize, + (uint8_t*) image_buffer); + } + + return true; +} + diff --git a/src/gdcmPixelConvert.h b/src/gdcmPixelConvert.h index b9090889..1dd425a0 100644 --- a/src/gdcmPixelConvert.h +++ b/src/gdcmPixelConvert.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelConvert.h,v $ Language: C++ - Date: $Date: 2004/10/08 08:56:48 $ - Version: $Revision: 1.2 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.3 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -21,6 +21,7 @@ #define GDCMPIXELCONVERTL_H #include "gdcmCommon.h" +#include "gdcmRLEFramesInfo.h" /* * \brief Utility container for gathering the various forms the pixel data @@ -59,11 +60,25 @@ bool ReadUncompressed( FILE* filePointer, size_t expectedSize ); bool ConvertGrayAndLutToRGB( uint8_t *lutRGBA ); bool ReadAndUncompressRLE8Bits(FILE* fp, size_t uncompressedSize ); -static uint8_t* UncompressRLE16BitsFromRLE8Bits( +static bool UncompressRLE16BitsFromRLE8Bits( int XSize, int YSize, int NumberOfFrames, uint8_t* fixMemUncompressed ); +static bool ReadAndUncompressRLEFragment( + uint8_t* decodedZone, + long fragmentSize, + long uncompressedSegmentSize, + FILE* fp ); +static bool gdcm_read_RLE_file ( void* image_buffer, + int XSize, + int YSize, + int ZSize, + int BitsAllocated, + gdcmRLEFramesInfo* RLEInfo, + FILE* fp ); + + }; diff --git a/src/gdcmRLE.cxx b/src/gdcmRLE.cxx deleted file mode 100644 index 6593cc9e..00000000 --- a/src/gdcmRLE.cxx +++ /dev/null @@ -1,148 +0,0 @@ -/*========================================================================= - - Program: gdcm - Module: $RCSfile: gdcmRLE.cxx,v $ - Language: C++ - Date: $Date: 2004/10/08 08:56:48 $ - Version: $Revision: 1.26 $ - - Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de - l'Image). All rights reserved. See Doc/License.txt or - http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. - - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -#include "gdcmFile.h" -#include "gdcmDebug.h" -#include "gdcmPixelConvert.h" -#include - -//----------------------------------------------------------------------------- -/** - * \ingroup gdcmFile - * \brief Reads a 'Run Length Encoded' Dicom encapsulated file - * @param fp already open File Pointer - * @param image_buffer destination Address (in caller's memory space) - * at which the pixel data should be copied - * @return Boolean - */ -bool gdcmFile::gdcm_read_RLE_file( FILE* fp, void* image_buffer ) -{ - char* im = (char *)image_buffer; - long uncompressedSegmentSize = Header->GetXSize() * Header->GetYSize(); - - - // Loop on the frame[s] - for( gdcmRLEFramesInfo::RLEFrameList::iterator - it = Header->RLEInfo.Frames.begin(); - it != Header->RLEInfo.Frames.end(); - ++it ) - { - std::cout << "...new frame...\n "; - // Loop on the fragments - for( unsigned int k = 1; k <= (*it)->NumberFragments; k++ ) - { - fseek( fp, (*it)->Offset[k] ,SEEK_SET); - (void)gdcm_read_RLE_fragment( (uint8_t**) (&im), (*it)->Length[k], - uncompressedSegmentSize, fp ); - } - } - - if ( Header->GetBitsAllocated() == 16 ) - { - // Try to deal with RLE 16 Bits - /* - image_buffer = (void*)gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( - Header->GetXSize(), - Header->GetYSize(), - Header->GetZSize(), - (uint8_t*) im); - */ - im = (char *)image_buffer; - // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes' - - int l = Header->GetXSize()*Header->GetYSize(); - int nbFrames = Header->GetZSize(); - - char * newDest = new char[l*nbFrames*2]; - char *x = newDest; - char * a = (char *)image_buffer; - char * b = a + l; - - for (int i=0;i= 0 ) - // Note: count <= 127 comparison is always true due to limited range - // of data type int8_t [since the maximum of an exact width - // signed integer of width N is 2^(N-1) - 1, which for int8_t - // is 127]. - { - fread( *decodedZone, count + 1, 1, fp); - numberOfReadBytes += count + 1; - *decodedZone += count + 1; - numberOfOutputBytes += count + 1; - } - else - { - if ( ( count <= -1 ) && ( count >= -127 ) ) - { - int8_t newByte; - fread( &newByte, 1, 1, fp); - numberOfReadBytes += 1; - for( int i = 0; i < -count + 1; i++ ) - { - (*decodedZone)[i] = newByte; - } - *decodedZone += -count + 1; - numberOfOutputBytes += -count + 1; - } - } - // if count = 128 output nothing - - if ( numberOfReadBytes > fragmentSize ) - { - dbg.Verbose(0, "gdcmFile::gdcm_read_RLE_fragment: we read more " - "bytes than the segment size."); - return false; - } - } - return true; -} - -// ---------------------------------------------------------------------------- diff --git a/src/gdcmRLEFrame.h b/src/gdcmRLEFrame.h index f6589426..3f288ecf 100644 --- a/src/gdcmRLEFrame.h +++ b/src/gdcmRLEFrame.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLEFrame.h,v $ Language: C++ - Date: $Date: 2004/10/08 08:42:11 $ - Version: $Revision: 1.3 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.4 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -42,6 +42,7 @@ class GDCM_EXPORT gdcmRLEFrame { friend class gdcmDocument; friend class gdcmFile; +friend class gdcmPixelConvert; int NumberFragments; long Offset[15]; long Length[15]; diff --git a/src/gdcmRLEFramesInfo.h b/src/gdcmRLEFramesInfo.h index 0e3f608a..843ab0ed 100644 --- a/src/gdcmRLEFramesInfo.h +++ b/src/gdcmRLEFramesInfo.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLEFramesInfo.h,v $ Language: C++ - Date: $Date: 2004/10/08 08:42:11 $ - Version: $Revision: 1.2 $ + Date: $Date: 2004/10/08 16:27:20 $ + Version: $Revision: 1.3 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -41,6 +41,7 @@ class GDCM_EXPORT gdcmRLEFramesInfo typedef std::list< gdcmRLEFrame* > RLEFrameList; friend class gdcmDocument; friend class gdcmFile; +friend class gdcmPixelConvert; RLEFrameList Frames; public: ~gdcmRLEFramesInfo(); -- 2.48.1