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