From 6bbf9cb61993d024630bf9b05b82e4346559c5b2 Mon Sep 17 00:00:00 2001 From: frog Date: Fri, 8 Oct 2004 08:56:48 +0000 Subject: [PATCH] * CLEANUP_ROUND (7) for gdcmPixelConvert (lost at sea) - src/gdcmFile.h gdcmPixelConvert.cxx gdcmPixelConvert.h gdcmRLE.cxx: clean up of RLE related code. --- ChangeLog | 6 +++ src/gdcmFile.h | 9 ++-- src/gdcmPixelConvert.cxx | 49 ++++++++++++--------- src/gdcmPixelConvert.h | 15 ++++--- src/gdcmRLE.cxx | 93 +++++++++++++++++++++++++--------------- 5 files changed, 106 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe76d8f2..1cda6248 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-10-08 Eric Boix + * src/gdcmCommon.h now declares int8_t for non stdint.h plateforms. + * CLEANUP_ROUND (7) for gdcmPixelConvert (lost at sea) + - src/gdcmFile.h gdcmPixelConvert.cxx gdcmPixelConvert.h gdcmRLE.cxx: + clean up of RLE related code. + 2004-10-07 Eric Boix * CLEANUP_ROUND (5) for gdcmPixelConvert (Upshit creek without a paddle) - src/gdcmDocument.[cxx|h] Parse7Fe0 renamed to ComputeRLEInfo. diff --git a/src/gdcmFile.h b/src/gdcmFile.h index a69011f8..c814acbb 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/01 12:40:57 $ - Version: $Revision: 1.55 $ + Date: $Date: 2004/10/08 08:56:48 $ + Version: $Revision: 1.56 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -127,8 +127,9 @@ private: // (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 int gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode, - long uncompressedSegmentSize, FILE* fp); + 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 diff --git a/src/gdcmPixelConvert.cxx b/src/gdcmPixelConvert.cxx index 5923d8de..0f00fe6c 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/09/29 17:33:17 $ - Version: $Revision: 1.1 $ + Date: $Date: 2004/10/08 08:56:48 $ + Version: $Revision: 1.2 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -16,7 +16,9 @@ =========================================================================*/ -////// #include +////////////////// TEMPORARY NOT +// look for "fixMem" and convert that to a member of this class +// Removing the prefix fixMem and dealing with allocations should do the trick #define str2num(str, typeNum) *((typeNum *)(str)) #include "gdcmDebug.h" @@ -162,30 +164,35 @@ bool gdcmPixelConvert::ConvertGrayAndLutToRGB( uint8_t *lutRGBA ) * High Byte 'Planes'...(for what it may mean) * @return Boolean */ -bool gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( - size_t PixelNumber, - int NumberOfFrames ) - +uint8_t* gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( + int XSize, + int YSize, + int NumberOfFrames, + uint8_t* fixMemUncompressed ) { - /// 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 need to double the space. Hence we cannot work in - /// place within Uncompressed. So, 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 + size_t PixelNumber = XSize * YSize; + size_t fixMemUncompressedSize = XSize * YSize * NumberOfFrames; + + // 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: - uint8_t* OldUncompressed = new uint8_t[UncompressedSize * 2]; - memmove( OldUncompressed, Uncompressed, UncompressedSize); + uint8_t* OldUncompressed = new uint8_t[ fixMemUncompressedSize * 2 ]; + memmove( OldUncompressed, fixMemUncompressed, fixMemUncompressedSize * 2); /// Second stage: - SetUncompressedSize( 2 * UncompressedSize ); - AllocateUncompressed(); + //fixMem SetUncompressedSize( 2 * UncompressedSize ); + //fixMem AllocateUncompressed(); + uint8_t* fixMemNewUncompressed = new uint8_t[fixMemUncompressedSize * 2]; /// Third stage: - uint8_t* x = Uncompressed; + uint8_t* x = fixMemNewUncompressed; uint8_t* a = OldUncompressed; uint8_t* b = a + PixelNumber; @@ -202,5 +209,5 @@ bool gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits( delete[] OldUncompressed; /// \todo check that operator new []didn't fail, and sometimes return false - return true; + return fixMemNewUncompressed; } diff --git a/src/gdcmPixelConvert.h b/src/gdcmPixelConvert.h index f567a304..b9090889 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/09/29 17:33:17 $ - Version: $Revision: 1.1 $ + Date: $Date: 2004/10/08 08:56:48 $ + Version: $Revision: 1.2 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -59,11 +59,12 @@ bool ReadUncompressed( FILE* filePointer, size_t expectedSize ); bool ConvertGrayAndLutToRGB( uint8_t *lutRGBA ); bool ReadAndUncompressRLE8Bits(FILE* fp, size_t uncompressedSize ); -bool UncompressRLE16BitsFromRLE8Bits( size_t PixelNumber, int NumberOfFrames ); - - - - +static uint8_t* UncompressRLE16BitsFromRLE8Bits( + int XSize, + int YSize, + int NumberOfFrames, + uint8_t* fixMemUncompressed ); + }; diff --git a/src/gdcmRLE.cxx b/src/gdcmRLE.cxx index 229c13a5..6593cc9e 100644 --- a/src/gdcmRLE.cxx +++ b/src/gdcmRLE.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLE.cxx,v $ Language: C++ - Date: $Date: 2004/10/08 04:52:55 $ - Version: $Revision: 1.25 $ + 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 @@ -17,8 +17,9 @@ =========================================================================*/ #include "gdcmFile.h" - -#define str2num(str, typeNum) *((typeNum *)(str)) +#include "gdcmDebug.h" +#include "gdcmPixelConvert.h" +#include //----------------------------------------------------------------------------- /** @@ -29,9 +30,9 @@ * at which the pixel data should be copied * @return Boolean */ -bool gdcmFile::gdcm_read_RLE_file (FILE* fp,void* image_buffer) +bool gdcmFile::gdcm_read_RLE_file( FILE* fp, void* image_buffer ) { - char * im = (char *)image_buffer; + char* im = (char *)image_buffer; long uncompressedSegmentSize = Header->GetXSize() * Header->GetYSize(); @@ -46,17 +47,23 @@ bool gdcmFile::gdcm_read_RLE_file (FILE* fp,void* image_buffer) for( unsigned int k = 1; k <= (*it)->NumberFragments; k++ ) { fseek( fp, (*it)->Offset[k] ,SEEK_SET); - gdcm_read_RLE_fragment( &im, (*it)->Length[k], - uncompressedSegmentSize, fp ); + (void)gdcm_read_RLE_fragment( (uint8_t**) (&im), (*it)->Length[k], + uncompressedSegmentSize, fp ); } } - - if (Header->GetBitsAllocated()==16) + + if ( Header->GetBitsAllocated() == 16 ) { - // try to deal with RLE 16 Bits - + // 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' + // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes' int l = Header->GetXSize()*Header->GetYSize(); int nbFrames = Header->GetZSize(); @@ -83,41 +90,59 @@ bool gdcmFile::gdcm_read_RLE_file (FILE* fp,void* image_buffer) // ---------------------------------------------------------------------------- -// RLE LossLess Fragment -int gdcmFile::gdcm_read_RLE_fragment(char** areaToRead, long lengthToDecode, - long uncompressedSegmentSize, FILE* fp) +/** + * \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 gdcmFile::gdcm_read_RLE_fragment( uint8_t** decodedZone, + long fragmentSize, + long uncompressedSegmentSize, + FILE* fp ) { - (void)lengthToDecode; //FIXME - int count; - long numberOfOutputBytes=0; - char n, car; + int8_t count; + long numberOfOutputBytes = 0; + long numberOfReadBytes = 0; while( numberOfOutputBytes < uncompressedSegmentSize ) { - fread(&n,sizeof(char),1,fp); - count=n; - if (count >= 0 && count <= 127) + 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(*areaToRead,(count+1)*sizeof(char),1,fp); - *areaToRead+=count+1; - numberOfOutputBytes+=count+1; + fread( *decodedZone, count + 1, 1, fp); + numberOfReadBytes += count + 1; + *decodedZone += count + 1; + numberOfOutputBytes += count + 1; } else { - if (count <= -1 && count >= -127) + if ( ( count <= -1 ) && ( count >= -127 ) ) { - fread(&car,sizeof(char),1,fp); - for(int i=0; i<-count+1; i++) + int8_t newByte; + fread( &newByte, 1, 1, fp); + numberOfReadBytes += 1; + for( int i = 0; i < -count + 1; i++ ) { - (*areaToRead)[i]=car; + (*decodedZone)[i] = newByte; } - *areaToRead+=(-count+1); - numberOfOutputBytes+=(-count+1); + *decodedZone += -count + 1; + numberOfOutputBytes += -count + 1; } } - // if count = 128 output nothing (See : PS 3.5-2003 Page 86) + // 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 1; + return true; } // ---------------------------------------------------------------------------- -- 2.48.1