1 /*=========================================================================
4 Module: $RCSfile: gdcmRLE.cxx,v $
6 Date: $Date: 2004/10/08 08:56:48 $
7 Version: $Revision: 1.26 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 #include "gdcmDebug.h"
21 #include "gdcmPixelConvert.h"
24 //-----------------------------------------------------------------------------
27 * \brief Reads a 'Run Length Encoded' Dicom encapsulated file
28 * @param fp already open File Pointer
29 * @param image_buffer destination Address (in caller's memory space)
30 * at which the pixel data should be copied
33 bool gdcmFile::gdcm_read_RLE_file( FILE* fp, void* image_buffer )
35 char* im = (char *)image_buffer;
36 long uncompressedSegmentSize = Header->GetXSize() * Header->GetYSize();
39 // Loop on the frame[s]
40 for( gdcmRLEFramesInfo::RLEFrameList::iterator
41 it = Header->RLEInfo.Frames.begin();
42 it != Header->RLEInfo.Frames.end();
45 std::cout << "...new frame...\n ";
46 // Loop on the fragments
47 for( unsigned int k = 1; k <= (*it)->NumberFragments; k++ )
49 fseek( fp, (*it)->Offset[k] ,SEEK_SET);
50 (void)gdcm_read_RLE_fragment( (uint8_t**) (&im), (*it)->Length[k],
51 uncompressedSegmentSize, fp );
55 if ( Header->GetBitsAllocated() == 16 )
57 // Try to deal with RLE 16 Bits
59 image_buffer = (void*)gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits(
65 im = (char *)image_buffer;
66 // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
68 int l = Header->GetXSize()*Header->GetYSize();
69 int nbFrames = Header->GetZSize();
71 char * newDest = new char[l*nbFrames*2];
73 char * a = (char *)image_buffer;
76 for (int i=0;i<nbFrames;i++)
78 for (int j=0;j<l; j++)
84 memmove(image_buffer,newDest,ImageDataSize);
92 // ----------------------------------------------------------------------------
94 * \brief Implementation of the RLE decoding algorithm for uncompressing
95 * a RLE fragment. [refer to PS 3.5-2003, section G.3.2 p 86]
97 bool gdcmFile::gdcm_read_RLE_fragment( uint8_t** decodedZone,
99 long uncompressedSegmentSize,
103 long numberOfOutputBytes = 0;
104 long numberOfReadBytes = 0;
106 while( numberOfOutputBytes < uncompressedSegmentSize )
108 fread( &count, 1, 1, fp );
109 numberOfReadBytes += 1;
111 // Note: count <= 127 comparison is always true due to limited range
112 // of data type int8_t [since the maximum of an exact width
113 // signed integer of width N is 2^(N-1) - 1, which for int8_t
116 fread( *decodedZone, count + 1, 1, fp);
117 numberOfReadBytes += count + 1;
118 *decodedZone += count + 1;
119 numberOfOutputBytes += count + 1;
123 if ( ( count <= -1 ) && ( count >= -127 ) )
126 fread( &newByte, 1, 1, fp);
127 numberOfReadBytes += 1;
128 for( int i = 0; i < -count + 1; i++ )
130 (*decodedZone)[i] = newByte;
132 *decodedZone += -count + 1;
133 numberOfOutputBytes += -count + 1;
136 // if count = 128 output nothing
138 if ( numberOfReadBytes > fragmentSize )
140 dbg.Verbose(0, "gdcmFile::gdcm_read_RLE_fragment: we read more "
141 "bytes than the segment size.");
148 // ----------------------------------------------------------------------------