]> Creatis software - gdcm.git/blob - src/gdcmRLE.cxx
Add error handling in jpeg code
[gdcm.git] / src / gdcmRLE.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmRLE.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/10/08 08:56:48 $
7   Version:   $Revision: 1.26 $
8                                                                                 
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.
12                                                                                 
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.
16                                                                                 
17 =========================================================================*/
18
19 #include "gdcmFile.h"
20 #include "gdcmDebug.h"
21 #include "gdcmPixelConvert.h"
22 #include <stdio.h>
23
24 //-----------------------------------------------------------------------------
25 /**
26  * \ingroup   gdcmFile
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 
31  * @return    Boolean 
32  */
33 bool gdcmFile::gdcm_read_RLE_file( FILE* fp, void* image_buffer )
34 {
35    char* im = (char *)image_buffer;
36    long uncompressedSegmentSize = Header->GetXSize() * Header->GetYSize();
37    
38
39    // Loop on the frame[s]
40    for( gdcmRLEFramesInfo::RLEFrameList::iterator
41         it  = Header->RLEInfo.Frames.begin();
42         it != Header->RLEInfo.Frames.end();
43       ++it )
44    {
45        std::cout << "...new frame...\n ";
46       // Loop on the fragments
47       for( unsigned int k = 1; k <= (*it)->NumberFragments; k++ )
48       {
49          fseek( fp, (*it)->Offset[k] ,SEEK_SET);  
50          (void)gdcm_read_RLE_fragment( (uint8_t**) (&im), (*it)->Length[k],
51                                       uncompressedSegmentSize, fp );
52       }
53    }
54  
55    if ( Header->GetBitsAllocated() == 16 )
56    {
57      // Try to deal with RLE 16 Bits
58      /*
59       image_buffer = (void*)gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits(
60                                              Header->GetXSize(),
61                                              Header->GetYSize(),
62                                              Header->GetZSize(),
63                                              (uint8_t*) im);
64      */
65       im = (char *)image_buffer;
66       //  need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
67
68       int l = Header->GetXSize()*Header->GetYSize();
69       int nbFrames = Header->GetZSize();
70
71       char * newDest = new char[l*nbFrames*2];
72       char *x  = newDest;
73       char * a = (char *)image_buffer;
74       char * b = a + l;
75
76       for (int i=0;i<nbFrames;i++)
77       {
78          for (int j=0;j<l; j++)
79          {
80             *(x++) = *(a++);
81             *(x++) = *(b++);
82          }
83       }
84       memmove(image_buffer,newDest,ImageDataSize);
85       delete[] newDest;
86    }
87       
88    return true;
89 }
90
91
92 // ----------------------------------------------------------------------------
93 /**
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]
96  */
97 bool gdcmFile::gdcm_read_RLE_fragment( uint8_t** decodedZone,
98                                        long fragmentSize, 
99                                        long uncompressedSegmentSize,
100                                        FILE* fp )
101 {
102    int8_t count;
103    long numberOfOutputBytes = 0;
104    long numberOfReadBytes = 0;
105
106    while( numberOfOutputBytes < uncompressedSegmentSize )
107    {
108       fread( &count, 1, 1, fp );
109       numberOfReadBytes += 1;
110       if ( count >= 0 )
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
114       //       is 127].
115       {
116          fread( *decodedZone, count + 1, 1, fp);
117          numberOfReadBytes += count + 1;
118          *decodedZone        += count + 1;
119          numberOfOutputBytes += count + 1;
120       }
121       else
122       {
123          if ( ( count <= -1 ) && ( count >= -127 ) )
124          {
125             int8_t newByte;
126             fread( &newByte, 1, 1, fp);
127             numberOfReadBytes += 1;
128             for( int i = 0; i < -count + 1; i++ )
129             {
130                (*decodedZone)[i] = newByte;  
131             }
132             *decodedZone        += -count + 1;
133             numberOfOutputBytes += -count + 1; 
134          }
135       } 
136       // if count = 128 output nothing
137
138       if ( numberOfReadBytes > fragmentSize )
139       { 
140          dbg.Verbose(0, "gdcmFile::gdcm_read_RLE_fragment: we read more "
141                         "bytes than the segment size.");
142          return false;
143       }
144    } 
145    return true;
146 }
147
148 // ----------------------------------------------------------------------------