1 /*=========================================================================
4 Module: $RCSfile: gdcmRLEFramesInfo.cxx,v $
6 Date: $Date: 2005/01/31 05:24:21 $
7 Version: $Revision: 1.9 $
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 =========================================================================*/
19 #include "gdcmRLEFramesInfo.h"
20 #include "gdcmDebug.h"
25 RLEFramesInfo::~RLEFramesInfo()
27 for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
36 * @param indent Indentation string to be prepended during printing.
37 * @param os Stream to print to.
39 void RLEFramesInfo::Print( std::ostream &os, std::string indent )
43 << "----------------- RLE frames --------------------------------"
46 << "Total number of Frames : " << Frames.size()
49 for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
52 << " frame number :" << frameNumber++
54 (*it)->Print( os, indent + " " );
58 void RLEFramesInfo::AddFrame(RLEFrame *frame)
60 Frames.push_back(frame);
63 RLEFrame *RLEFramesInfo::GetFirstFrame()
65 ItFrames = Frames.begin();
66 if (ItFrames != Frames.end())
71 RLEFrame *RLEFramesInfo::GetNextFrame()
73 gdcmAssertMacro (ItFrames != Frames.end());
76 if (ItFrames != Frames.end())
82 * \brief Reads from disk the Pixel Data of 'Run Length Encoded'
83 * Dicom encapsulated file and decompress it.
84 * @param fp already open File Pointer
85 * at which the pixel data should be copied
88 bool RLEFramesInfo::ReadAndDecompressRLEFile( std::ifstream *fp , uint8_t *raw, int xSize, int ySize, int zSize, int bitsAllocated )
90 uint8_t *subRaw = raw;
91 long RawSegmentSize = xSize * ySize;
93 // Loop on the frame[s]
94 for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
96 // Loop on the fragments
97 for( unsigned int k = 1; k <= (*it)->GetNumberOfFragments(); k++ )
99 fp->seekg((*it)->GetOffset(k),std::ios::beg);
100 ReadAndDecompressRLEFragment(subRaw,
104 subRaw += RawSegmentSize;
108 if ( bitsAllocated == 16 )
110 // Try to deal with RLE 16 Bits
111 (void)DecompressRLE16BitsFromRLE8Bits( raw, xSize, ySize, zSize );
118 * \brief Implementation of the RLE decoding algorithm for decompressing
119 * a RLE fragment. [refer to PS 3.5-2003, section G.3.2 p 86]
120 * @param subRaw Sub region of \ref Raw where the decoded fragment
122 * @param fragmentSize The length of the binary fragment as found on the disk.
123 * @param RawSegmentSize The expected length of the fragment ONCE
125 * @param fp File Pointer: on entry the position should be the one of
126 * the fragment to be decoded.
128 bool RLEFramesInfo::ReadAndDecompressRLEFragment( uint8_t *subRaw,
134 long numberOfOutputBytes = 0;
135 long numberOfReadBytes = 0;
137 while( numberOfOutputBytes < RawSegmentSize )
139 fp->read( (char*)&count, 1 );
140 numberOfReadBytes += 1;
142 // Note: count <= 127 comparison is always true due to limited range
143 // of data type int8_t [since the maximum of an exact width
144 // signed integer of width N is 2^(N-1) - 1, which for int8_t
147 fp->read( (char*)subRaw, count + 1);
148 numberOfReadBytes += count + 1;
150 numberOfOutputBytes += count + 1;
154 if ( count <= -1 && count >= -127 )
157 fp->read( (char*)&newByte, 1);
158 numberOfReadBytes += 1;
159 for( int i = 0; i < -count + 1; i++ )
163 subRaw += -count + 1;
164 numberOfOutputBytes += -count + 1;
167 // if count = 128 output nothing
169 if ( numberOfReadBytes > fragmentSize )
171 gdcmVerboseMacro( "Read more bytes than the segment size.");
179 * \brief Try to deal with RLE 16 Bits.
180 * We assume the RLE has already been parsed and loaded in
181 * Raw (through \ref ReadAndDecompressJPEGFile ).
182 * We here need to make 16 Bits Pixels from Low Byte and
183 * High Byte 'Planes'...(for what it may mean)
186 bool RLEFramesInfo::DecompressRLE16BitsFromRLE8Bits( uint8_t* raw, int xSize, int ySize,int numberOfFrames )
188 size_t pixelNumber = xSize * ySize;
189 size_t rawSize = xSize * ySize * numberOfFrames;
191 // We assumed Raw contains the decoded RLE pixels but as
192 // 8 bits per pixel. In order to convert those pixels to 16 bits
193 // per pixel we cannot work in place within Raw and hence
194 // we copy it in a safe place, say copyRaw.
196 uint8_t* copyRaw = new uint8_t[rawSize * 2];
197 memmove( copyRaw, raw, rawSize * 2 );
200 uint8_t* a = copyRaw;
201 uint8_t* b = a + pixelNumber;
203 for ( int i = 0; i < numberOfFrames; i++ )
205 for ( unsigned int j = 0; j < pixelNumber; j++ )
214 /// \todo check that operator new []didn't fail, and sometimes return false
219 } // end namespace gdcm