]> Creatis software - gdcm.git/blob - src/gdcmPixelConvert.cxx
* CLEANUP_ROUND (7) for gdcmPixelConvert (lost at sea)
[gdcm.git] / src / gdcmPixelConvert.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmPixelConvert.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/10/08 08:56:48 $
7   Version:   $Revision: 1.2 $
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 //////////////////   TEMPORARY NOT
20 // look for "fixMem" and convert that to a member of this class
21 // Removing the prefix fixMem and dealing with allocations should do the trick
22 #define str2num(str, typeNum) *((typeNum *)(str))
23
24 #include "gdcmDebug.h"
25 #include "gdcmPixelConvert.h"
26
27
28 //-----------------------------------------------------------------------------
29 // Constructor / Destructor
30 gdcmPixelConvert::gdcmPixelConvert() 
31 {
32    RGB = 0;
33    RGBSize = 0;
34    Uncompressed = 0;
35    UncompressedSize = 0;
36 }
37
38 void gdcmPixelConvert::Squeeze() 
39 {
40    if ( RGB ) {
41       delete [] RGB;
42    } 
43    if ( Uncompressed ) {
44       delete [] Uncompressed;
45    }
46 }
47
48 gdcmPixelConvert::~gdcmPixelConvert() 
49 {
50    Squeeze();
51 }
52
53 void gdcmPixelConvert::AllocateRGB()
54 {
55   if ( RGB ) {
56      delete [] RGB;
57   }
58   RGB = new uint8_t[RGBSize];
59 }
60
61 void gdcmPixelConvert::AllocateUncompressed()
62 {
63   if ( Uncompressed ) {
64      delete [] Uncompressed;
65   }
66   Uncompressed = new uint8_t[ UncompressedSize ];
67 }
68
69 /**
70  * \brief Read from file a 12 bits per pixel image and uncompress it
71  *        into a 16 bits per pixel image.
72  */
73 bool gdcmPixelConvert::ReadAndUncompress12Bits( FILE* filePointer,
74                                                 size_t uncompressedSize,
75                                                 size_t PixelNumber )
76 {
77    SetUncompressedSize( uncompressedSize );
78    AllocateUncompressed();
79
80    uint16_t* pdestination = (uint16_t*)Uncompressed;
81                                                                                 
82    for(int p = 0; p < PixelNumber; p += 2 )
83    {
84       // 2 pixels 12bit =     [0xABCDEF]
85       // 2 pixels 16bit = [0x0ABD] + [0x0FCE]
86       uint8_t b0, b1, b2;
87       size_t ItemRead;
88       ItemRead = fread( &b0, 1, 1, filePointer);
89       if ( ItemRead != 1 )
90       {
91          return false;
92       }
93       ItemRead = fread( &b1, 1, 1, filePointer);
94       if ( ItemRead != 1 )
95       {
96          return false;
97       }
98       ItemRead = fread( &b2, 1, 1, filePointer);
99       if ( ItemRead != 1 )
100       {
101          return false;
102       }
103                                                                                 
104       //Two steps are necessary to please VC++
105       *pdestination++ =  ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
106       //                     A                     B                 D
107       *pdestination++ =  ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
108       //                     F                     C                 E
109                                                                                 
110       /// \todo JPR Troubles expected on Big-Endian processors ?
111    }
112    return true;
113 }
114
115 /**
116  * \brief Read from file an uncompressed image.
117  */
118 bool gdcmPixelConvert::ReadUncompressed( FILE* filePointer,
119                                          size_t uncompressedSize,
120                                          size_t expectedSize )
121 {
122    if ( expectedSize > uncompressedSize )
123    {
124       dbg.Verbose(0, "gdcmPixelConvert::ReadUncompressed: expectedSize"
125                      "is bigger than it should");
126       return false;
127    }
128    SetUncompressedSize( uncompressedSize );
129    AllocateUncompressed();
130    size_t ItemRead = fread( (void*)Uncompressed, expectedSize, 1, filePointer);
131    if ( ItemRead != 1 )
132    {
133       return false;
134    }
135    return true;
136 }
137
138 /**
139  * \brief  Convert a Gray plane and ( Lut R, Lut G, Lut B ) into an
140  *         RGB plane.
141  * @return True on success.
142  */
143 bool gdcmPixelConvert::ConvertGrayAndLutToRGB( uint8_t *lutRGBA )
144
145 {
146    /// We assume Uncompressed contains the decompressed gray plane
147    /// and build the RGB image.
148    SetRGBSize( UncompressedSize );
149    AllocateRGB();
150
151 //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
152 //AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
153 //COPY HERE THE CODE OF GetImageDataIntoVector
154       
155    /// \todo check that operator new []didn't fail, and sometimes return false
156    return true;
157 }
158
159 /**
160  * \brief     Try to deal with RLE 16 Bits. 
161  *            We assume the RLE has allready been parsed and loaded in
162  *            Uncompressed (through \ref ReadAndUncompressRLE8Bits ).
163  *            We here need to make 16 Bits Pixels from Low Byte and
164  *            High Byte 'Planes'...(for what it may mean)
165  * @return    Boolean
166  */
167 uint8_t* gdcmPixelConvert::UncompressRLE16BitsFromRLE8Bits(
168                        int XSize,
169                        int YSize,
170                        int NumberOfFrames,
171                        uint8_t* fixMemUncompressed )
172 {
173    size_t PixelNumber = XSize * YSize;
174    size_t fixMemUncompressedSize = XSize * YSize * NumberOfFrames;
175
176    // We assumed Uncompressed contains the decoded RLE pixels but as
177    // 8 bits per pixel. In order to convert those pixels to 16 bits
178    // per pixel we cannot work in place within Uncompressed.
179    // Here is how we handle things:
180    // - First  stage: copy Uncompressed in a safe place, say OldUncompressed
181    // - Second stage: reallocate Uncompressed with the needed space
182    // - Third  stage: expand from OldUncompressed to Uncompressed
183    // - Fourth stage: clean up OldUncompressed
184
185    /// First stage:
186    uint8_t* OldUncompressed = new uint8_t[ fixMemUncompressedSize * 2 ];
187    memmove( OldUncompressed, fixMemUncompressed, fixMemUncompressedSize * 2);
188
189    /// Second stage:
190    //fixMem SetUncompressedSize( 2 * UncompressedSize );
191    //fixMem AllocateUncompressed();
192    uint8_t* fixMemNewUncompressed = new uint8_t[fixMemUncompressedSize * 2];
193
194    /// Third stage:
195    uint8_t* x = fixMemNewUncompressed;
196    uint8_t* a = OldUncompressed;
197    uint8_t* b = a + PixelNumber;
198
199    for ( int i = 0; i < NumberOfFrames; i++ )
200    {
201       for ( int j = 0; j < PixelNumber; j++ )
202       {
203          *(x++) = *(a++);
204          *(x++) = *(b++);
205       }
206    }
207
208    // Fourth stage:
209    delete[] OldUncompressed;
210       
211    /// \todo check that operator new []didn't fail, and sometimes return false
212    return fixMemNewUncompressed;
213 }