]> Creatis software - gdcm.git/blob - src/gdcmPixelReadConvert.cxx
Add #include for BCC
[gdcm.git] / src / gdcmPixelReadConvert.cxx
1 /*=========================================================================
2  
3   Program:   gdcm
4   Module:    $RCSfile: gdcmPixelReadConvert.cxx,v $
5   Language:  C++
6   Date:      $Date: 2006/01/27 10:01:34 $
7   Version:   $Revision: 1.109 $
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 "gdcmPixelReadConvert.h"
20 #include "gdcmDebug.h"
21 #include "gdcmFile.h"
22 #include "gdcmGlobal.h"
23 #include "gdcmTS.h"
24 #include "gdcmDocEntry.h"
25 #include "gdcmRLEFramesInfo.h"
26 #include "gdcmJPEGFragmentsInfo.h"
27
28 #include <fstream>
29 #include <stdio.h> //for sscanf
30
31 #if defined(__BORLANDC__)
32    #include <mem.h> // for memset
33 #endif 
34
35 namespace gdcm
36 {
37
38 //bool ReadMPEGFile (std::ifstream *fp, char *inputdata, size_t lenght); 
39 bool gdcm_read_JPEG2000_file (void* raw, 
40                               char *inputdata, size_t inputlength);
41 //-----------------------------------------------------------------------------
42 #define str2num(str, typeNum) *((typeNum *)(str))
43
44 //-----------------------------------------------------------------------------
45 // Constructor / Destructor
46 /// Constructor
47 PixelReadConvert::PixelReadConvert() 
48 {
49    RGB          = 0;
50    RGBSize      = 0;
51    Raw          = 0;
52    RawSize      = 0;
53    LutRGBA      = 0;
54    LutRedData   = 0;
55    LutGreenData = 0;
56    LutBlueData  = 0;
57    RLEInfo      = 0;
58    JPEGInfo     = 0;
59    UserFunction = 0;
60    FileInternal = 0;
61 }
62
63 /// Canonical Destructor
64 PixelReadConvert::~PixelReadConvert() 
65 {
66    Squeeze();
67 }
68
69 //-----------------------------------------------------------------------------
70 // Public
71 /**
72  * \brief Predicate to know whether the image[s] (once Raw) is RGB.
73  * \note See comments of \ref ConvertHandleColor
74  */
75 bool PixelReadConvert::IsRawRGB()
76 {
77    if (   IsMonochrome
78        || PlanarConfiguration == 2
79        || IsPaletteColor )
80    {
81       return false;
82    }
83    return true;
84 }
85 /**
86  * \brief Gets various usefull informations from the file header
87  * @param file gdcm::File pointer
88  */
89 void PixelReadConvert::GrabInformationsFromFile( File *file, 
90                                                  FileHelper *fileHelper )
91 {
92    // Number of Bits Allocated for storing a Pixel is defaulted to 16
93    // when absent from the file.
94    BitsAllocated = file->GetBitsAllocated();
95    if ( BitsAllocated == 0 )
96    {
97       BitsAllocated = 16;
98    }
99
100    // Number of "Bits Stored", defaulted to number of "Bits Allocated"
101    // when absent from the file.
102    BitsStored = file->GetBitsStored();
103    if ( BitsStored == 0 )
104    {
105       BitsStored = BitsAllocated;
106    }
107
108    // High Bit Position, defaulted to "Bits Allocated" - 1
109    HighBitPosition = file->GetHighBitPosition();
110    if ( HighBitPosition == 0 )
111    {
112       HighBitPosition = BitsAllocated - 1;
113    }
114
115    XSize           = file->GetXSize();
116    YSize           = file->GetYSize();
117    ZSize           = file->GetZSize();
118    SamplesPerPixel = file->GetSamplesPerPixel();
119    //PixelSize       = file->GetPixelSize();  Useless
120    PixelSign       = file->IsSignedPixelData();
121    SwapCode        = file->GetSwapCode();
122  
123    IsPrivateGETransferSyntax = IsMPEG
124              = IsJPEG2000 = IsJPEGLS = IsJPEGLossy  
125              = IsJPEGLossless = IsRLELossless 
126              = false;
127      
128    if (! file->IsDicomV3() )  // Should be ACR-NEMA file
129    {
130       IsRaw = true;
131    }
132    else
133    {
134       std::string ts = file->GetTransferSyntax();
135
136       IsRaw = false;
137       while (true) // shorter to write than 'if elseif elseif elseif' ...
138       {
139          // mind the order : check the most usual first.
140          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian)         break;
141          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian )        break;
142          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian)            break;
143          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE)   break;
144          // DeflatedExplicitVRLittleEndian syntax means the whole Dataset (Header + Pixels) is compressed !
145          // Not dealt with ! (Parser hangs)
146          //if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian) break;
147          break;
148       }
149       // cache whether this is a strange GE transfer syntax (which uses
150       // a little endian transfer syntax for the header and a big endian
151       // transfer syntax for the pixel data). 
152       IsPrivateGETransferSyntax = 
153                 ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE );
154
155       IsMPEG =  IsJPEG2000 =  IsJPEGLS =  IsJPEGLossy =  IsJPEGLossless = IsRLELossless = false;  
156       if (!IsRaw)
157       {     
158          while(true)
159          {
160             // mind the order : check the most usual first.
161             if( IsJPEGLossy     = Global::GetTS()->IsJPEGLossy(ts) )    break;
162             if( IsJPEGLossless  = Global::GetTS()->IsJPEGLossless(ts) ) break;
163             if( IsRLELossless   = Global::GetTS()->IsRLELossless(ts) )  break;
164             if( IsJPEG2000      = Global::GetTS()->IsJPEG2000(ts) )     break;
165             if( IsMPEG          = Global::GetTS()->IsMPEG(ts) )         break;
166             if( IsJPEGLS        = Global::GetTS()->IsJPEGLS(ts) )       break;
167             // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' (we don't know yet haow to process !)
168             gdcmWarningMacro("Unexpected Transfer Syntax :[" << ts << "]");
169             break;
170          } 
171       }
172    }
173
174    PixelOffset     = file->GetPixelOffset();
175    PixelDataLength = file->GetPixelAreaLength();
176    RLEInfo         = file->GetRLEInfo();
177    JPEGInfo        = file->GetJPEGInfo();
178
179    IsMonochrome    = file->IsMonochrome();
180    IsMonochrome1   = file->IsMonochrome1();
181    IsPaletteColor  = file->IsPaletteColor();
182    IsYBRFull       = file->IsYBRFull();
183
184    PlanarConfiguration = file->GetPlanarConfiguration();
185
186    /////////////////////////////////////////////////////////////////
187    // LUT section:
188    HasLUT = file->HasLUT();
189    if ( HasLUT )
190    {
191       // Just in case some access to a File element requires disk access.
192       LutRedDescriptor   = file->GetEntryString( 0x0028, 0x1101 );
193       LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 );
194       LutBlueDescriptor  = file->GetEntryString( 0x0028, 0x1103 );
195    
196       // FIXME : The following comment is probabely meaningless, since LUT are *always*
197       // loaded at parsing time, whatever their length is.
198          
199       // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
200       // [ refer to invocation of Document::SetMaxSizeLoadEntry() in
201       // Document::Document() ], the loading of the value (content) of a
202       // [Bin|Val]Entry occurence migth have been hindered (read simply NOT
203       // loaded). Hence, we first try to obtain the LUTs data from the file
204       // and when this fails we read the LUTs data directly from disk.
205       // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge.
206       //       We should NOT bypass the [Bin|Val]Entry class. Instead
207       //       an access to an UNLOADED content of a [Bin|Val]Entry occurence
208       //       (e.g. DataEntry::GetBinArea()) should force disk access from
209       //       within the [Bin|Val]Entry class itself. The only problem
210       //       is that the [Bin|Val]Entry is unaware of the FILE* is was
211       //       parsed from. Fix that. FIXME.
212    
213       // //// Red round
214       file->LoadEntryBinArea(0x0028, 0x1201);
215       LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 );
216       if ( ! LutRedData )
217       {
218          gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data");
219       }
220
221       // //// Green round:
222       file->LoadEntryBinArea(0x0028, 0x1202);
223       LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
224       if ( ! LutGreenData)
225       {
226          gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data");
227       }
228
229       // //// Blue round:
230       file->LoadEntryBinArea(0x0028, 0x1203);
231       LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
232       if ( ! LutBlueData )
233       {
234          gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data");
235       }
236    }
237    FileInternal = file;   
238    FH = fileHelper;
239    ComputeRawAndRGBSizes();
240 }
241
242 /// \brief Reads from disk and decompresses Pixels
243 bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
244 {
245    // ComputeRawAndRGBSizes is already made by 
246    // ::GrabInformationsFromfile. So, the structure sizes are
247    // correct
248    Squeeze();
249
250    //////////////////////////////////////////////////
251    //// First stage: get our hands on the Pixel Data.
252    if ( !fp )
253    {
254       gdcmWarningMacro( "Unavailable file pointer." );
255       return false;
256    }
257
258    fp->seekg( PixelOffset, std::ios::beg );
259    if ( fp->fail() || fp->eof() )
260    {
261       gdcmWarningMacro( "Unable to find PixelOffset in file." );
262       return false;
263    }
264
265    AllocateRaw();
266
267    //////////////////////////////////////////////////
268    
269    CallStartMethod(); // for progress bar
270    unsigned int count = 0;
271    unsigned int frameSize;
272    unsigned int bitsAllocated = BitsAllocated;
273    if(bitsAllocated == 12)
274       bitsAllocated = 16;
275    frameSize = XSize*YSize*SamplesPerPixel*bitsAllocated/8;
276    
277    //// Second stage: read from disk and decompress.
278    
279    if ( BitsAllocated == 12 ) // We suppose 'BitsAllocated' = 12 only exist for uncompressed files
280    {
281       ReadAndDecompress12BitsTo16Bits( fp);
282    }
283    else if ( IsRaw )
284    {
285       // This problem can be found when some obvious informations are found
286       // after the field containing the image data. In this case, these
287       // bad data are added to the size of the image (in the PixelDataLength
288       // variable). But RawSize is the right size of the image !
289       if ( PixelDataLength != RawSize )
290       {
291          gdcmWarningMacro( "Mismatch between PixelReadConvert : "
292                               << PixelDataLength << " and RawSize : " << RawSize );
293       }
294       
295       //todo : is it the right patch?
296       char *raw = (char*)Raw;
297       uint32_t remainingLength;
298       unsigned int i; 
299       unsigned int lengthToRead;
300        
301       if ( PixelDataLength > RawSize )
302         lengthToRead =  RawSize;
303       else
304         lengthToRead = PixelDataLength;
305  
306       // perform a frame by frame reading
307       remainingLength = lengthToRead;
308       unsigned int nbFrames = lengthToRead / frameSize;
309       for (i=0;i<nbFrames; i++)
310       {
311          Progress = (float)(count+1)/(float)nbFrames;
312          fp->read( raw, frameSize);
313          raw +=  frameSize;
314          remainingLength -=  frameSize;
315          count++;
316       }
317       if (remainingLength !=0 )
318         fp->read( raw, remainingLength);
319                  
320       //if ( PixelDataLength > RawSize )
321       //{
322       //   fp->read( (char*)Raw, RawSize); // Read all the frames with a single fread    
323       //}
324       //else
325       //{
326       //   fp->read( (char*)Raw, PixelDataLength); // Read all the frames with a single fread
327       //}
328
329       if ( fp->fail() || fp->eof())
330       {
331          gdcmWarningMacro( "Reading of Raw pixel data failed." );
332          return false;
333       }
334    } 
335    else if ( IsRLELossless )
336    {
337       if ( ! RLEInfo->DecompressRLEFile
338                                ( fp, Raw, XSize, YSize, ZSize, BitsAllocated ) )
339       {
340          gdcmWarningMacro( "RLE decompressor failed." );
341          return false;
342       }
343    }
344    else if ( IsMPEG )
345    {
346       //gdcmWarningMacro( "Sorry, MPEG not yet taken into account" );
347       //return false;
348       // fp has already been seek to start of mpeg
349       //ReadMPEGFile(fp, (char*)Raw, PixelDataLength); 
350       return true;
351    }
352    else
353    {
354       // Default case concerns JPEG family
355       if ( ! ReadAndDecompressJPEGFile( fp ) )
356       {
357          gdcmWarningMacro( "JPEG decompressor ( ReadAndDecompressJPEGFile()"
358                               << " method ) failed." );
359          return false;
360       }
361    }
362
363    ////////////////////////////////////////////
364    //// Third stage: twigle the bytes and bits.
365    ConvertReorderEndianity();
366    ConvertReArrangeBits();
367    ConvertFixGreyLevels();
368    if (UserFunction) // user is allowed to Mirror, TopDown, Rotate,...the image
369       UserFunction( Raw, FileInternal);
370    ConvertHandleColor();
371
372    return true;
373 }
374
375 /// Deletes Pixels Area
376 void PixelReadConvert::Squeeze() 
377 {
378    if ( RGB )
379       delete [] RGB;
380    RGB = 0;
381
382    if ( Raw )
383       delete [] Raw;
384    Raw = 0;
385
386    if ( LutRGBA )
387       delete [] LutRGBA;
388    LutRGBA = 0;
389 }
390
391 /**
392  * \brief Build the RGB image from the Raw image and the LUTs.
393  */
394 bool PixelReadConvert::BuildRGBImage()
395 {
396    if ( RGB )
397    {
398       // The job is already done.
399       return true;
400    }
401
402    if ( ! Raw )
403    {
404       // The job can't be done
405       return false;
406    }
407
408    BuildLUTRGBA();
409    if ( ! LutRGBA )
410    {
411       // The job can't be done
412       return false;
413    }
414
415    gdcmDebugMacro( "--> BuildRGBImage" );
416                                                                                 
417    // Build RGB Pixels
418    AllocateRGB();
419    
420    int j;
421    if ( BitsAllocated <= 8 )
422    {
423       uint8_t *localRGB = RGB;
424       for (size_t i = 0; i < RawSize; ++i )
425       {
426          j  = Raw[i] * 4;
427          *localRGB++ = LutRGBA[j];
428          *localRGB++ = LutRGBA[j+1];
429          *localRGB++ = LutRGBA[j+2];
430       }
431     }
432  
433     else  // deal with 16 bits pixels and 16 bits Palette color
434     {
435       uint16_t *localRGB = (uint16_t *)RGB;
436       for (size_t i = 0; i < RawSize/2; ++i )
437       {
438          j  = ((uint16_t *)Raw)[i] * 4;
439          *localRGB++ = ((uint16_t *)LutRGBA)[j];
440          *localRGB++ = ((uint16_t *)LutRGBA)[j+1];
441          *localRGB++ = ((uint16_t *)LutRGBA)[j+2];
442       } 
443     }
444  
445    return true;
446 }
447
448 //-----------------------------------------------------------------------------
449 // Protected
450
451 //-----------------------------------------------------------------------------
452 // Private
453 /**
454  * \brief Read from file a 12 bits per pixel image and decompress it
455  *        into a 16 bits per pixel image.
456  */
457 void PixelReadConvert::ReadAndDecompress12BitsTo16Bits( std::ifstream *fp )
458                throw ( FormatError )
459 {
460    int nbPixels = XSize * YSize;
461    uint16_t *localDecompres = (uint16_t*)Raw;
462
463    for( int p = 0; p < nbPixels; p += 2 )
464    {
465       uint8_t b0, b1, b2;
466
467       fp->read( (char*)&b0, 1);
468       if ( fp->fail() || fp->eof() )
469       {
470          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
471                                 "Unfound first block" );
472       }
473
474       fp->read( (char*)&b1, 1 );
475       if ( fp->fail() || fp->eof())
476       {
477          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
478                                 "Unfound second block" );
479       }
480
481       fp->read( (char*)&b2, 1 );
482       if ( fp->fail() || fp->eof())
483       {
484          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
485                                 "Unfound second block" );
486       }
487
488       // Two steps are necessary to please VC++
489       //
490       // 2 pixels 12bit =     [0xABCDEF]
491       // 2 pixels 16bit = [0x0ABD] + [0x0FCE]
492       //                        A                     B                 D
493       *localDecompres++ =  ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
494       //                        F                     C                 E
495       *localDecompres++ =  ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
496
497       /// \todo JPR Troubles expected on Big-Endian processors ?
498    }
499 }
500
501 /**
502  * \brief     Reads from disk the Pixel Data of JPEG Dicom encapsulated
503  *            file and decompress it.
504  * @param     fp File Pointer
505  * @return    Boolean
506  */
507 bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
508 {
509    if ( IsJPEG2000 )
510    {
511      // make sure this is the right JPEG compression
512      assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEGLS );
513      // FIXME this is really ugly but it seems I have to load the complete
514      // jpeg2000 stream to use jasper:
515      // I don't think we'll ever be able to deal with multiple fragments properly
516
517       unsigned long inputlength = 0;
518       JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
519       while( jpegfrag )
520       {
521          inputlength += jpegfrag->GetLength();
522          jpegfrag = JPEGInfo->GetNextFragment();
523       }
524       gdcmAssertMacro( inputlength != 0);
525       uint8_t *inputdata = new uint8_t[inputlength];
526       char *pinputdata = (char*)inputdata;
527       jpegfrag = JPEGInfo->GetFirstFragment();
528       while( jpegfrag )
529       {
530          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
531          fp->read(pinputdata, jpegfrag->GetLength());
532          pinputdata += jpegfrag->GetLength();
533          jpegfrag = JPEGInfo->GetNextFragment();
534       }
535       // Warning the inputdata buffer is delete in the function
536       if ( ! gdcm_read_JPEG2000_file( Raw, 
537           (char*)inputdata, inputlength ) )
538       {
539          return true;
540       }
541       // wow what happen, must be an error
542       gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); 
543       return false;
544    }
545    else if ( IsJPEGLS )
546    {
547      // make sure this is the right JPEG compression
548      assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEG2000 );
549    // WARNING : JPEG-LS is NOT the 'classical' Jpeg Lossless : 
550    // [JPEG-LS is the basis for new lossless/near-lossless compression
551    // standard for continuous-tone images intended for JPEG2000. The standard
552    // is based on the LOCO-I algorithm (LOw COmplexity LOssless COmpression
553    // for Images) developed at Hewlett-Packard Laboratories]
554    //
555    // see http://datacompression.info/JPEGLS.shtml
556    //
557 #if 0
558    std::cerr << "count:" << JPEGInfo->GetFragmentCount() << std::endl;
559       unsigned long inputlength = 0;
560       JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
561       while( jpegfrag )
562       {
563          inputlength += jpegfrag->GetLength();
564          jpegfrag = JPEGInfo->GetNextFragment();
565       }
566       gdcmAssertMacro( inputlength != 0);
567       uint8_t *inputdata = new uint8_t[inputlength];
568       char *pinputdata = (char*)inputdata;
569       jpegfrag = JPEGInfo->GetFirstFragment();
570       while( jpegfrag )
571       {
572          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
573          fp->read(pinputdata, jpegfrag->GetLength());
574          pinputdata += jpegfrag->GetLength();
575          jpegfrag = JPEGInfo->GetNextFragment();
576       }  
577       
578   //fp->read((char*)Raw, PixelDataLength);
579
580   std::ofstream out("/tmp/jpegls.jpg");
581   out.write((char*)inputdata, inputlength);
582   out.close();
583   delete[] inputdata;
584 #endif
585
586       gdcmWarningMacro( "Sorry, JPEG-LS not yet taken into account" );
587       fp->seekg( JPEGInfo->GetFirstFragment()->GetOffset(), std::ios::beg);
588 //    if ( ! gdcm_read_JPEGLS_file( fp,Raw ) )
589          return false;
590    }
591    else
592    {
593      // make sure this is the right JPEG compression
594      assert( !IsJPEGLS || !IsJPEG2000 );
595      // Precompute the offset localRaw will be shifted with
596      int length = XSize * YSize * SamplesPerPixel;
597      int numberBytes = BitsAllocated / 8;
598
599      JPEGInfo->DecompressFromFile(fp, Raw, BitsStored, numberBytes, length );
600      return true;
601    }
602 }
603
604 /**
605  * \brief Build Red/Green/Blue/Alpha LUT from File when :
606  *         - (0028,0004) : Photometric Interpretation == [PALETTE COLOR ]
607  *         and
608  *         - (0028,1101),(0028,1102),(0028,1102)
609  *            xxx Palette Color Lookup Table Descriptor are found
610  *          and 
611  *         - (0028,1201),(0028,1202),(0028,1202)
612  *           xxx Palette Color Lookup Table Data - are found
613  * \warning does NOT deal with :
614  *   - 0028 1100 Gray Lookup Table Descriptor (Retired)
615  *   - 0028 1221 Segmented Red Palette Color Lookup Table Data
616  *   - 0028 1222 Segmented Green Palette Color Lookup Table Data
617  *   - 0028 1223 Segmented Blue Palette Color Lookup Table Data
618  *   no known Dicom reader deals with them :-(
619  * @return a RGBA Lookup Table
620  */
621 void PixelReadConvert::BuildLUTRGBA()
622 {
623
624    // Note to code reviewers :
625    // The problem is *much more* complicated, since a lot of manufacturers
626    // Don't follow the norm :
627    // have a look at David Clunie's remark at the end of this .cxx file.
628    if ( LutRGBA )
629    
630    {
631       return;
632    }
633    // Not so easy : see
634    // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
635                                                                                 
636    if ( ! IsPaletteColor )
637    {
638       return;
639    }
640                                                                                 
641    if (   LutRedDescriptor   == GDCM_UNFOUND
642        || LutGreenDescriptor == GDCM_UNFOUND
643        || LutBlueDescriptor  == GDCM_UNFOUND )
644    {
645       gdcmWarningMacro( "(At least) a LUT Descriptor is missing" );
646       return;
647    }
648
649    ////////////////////////////////////////////
650    // Extract the info from the LUT descriptors
651    int lengthR;   // Red LUT length in Bytes
652    int debR;      // Subscript of the first Lut Value
653    int nbitsR;    // Lut item size (in Bits)
654    int nbRead;    // nb of items in LUT descriptor (must be = 3)
655
656    nbRead = sscanf( LutRedDescriptor.c_str(),
657                         "%d\\%d\\%d",
658                         &lengthR, &debR, &nbitsR );
659    if ( nbRead != 3 )
660    {
661       gdcmWarningMacro( "Wrong Red LUT descriptor" );
662    }                                                                                
663    int lengthG;  // Green LUT length in Bytes
664    int debG;     // Subscript of the first Lut Value
665    int nbitsG;   // Lut item size (in Bits)
666
667    nbRead = sscanf( LutGreenDescriptor.c_str(),
668                     "%d\\%d\\%d",
669                     &lengthG, &debG, &nbitsG );  
670    if ( nbRead != 3 )
671    {
672       gdcmWarningMacro( "Wrong Green LUT descriptor" );
673    }
674                                                                                 
675    int lengthB;  // Blue LUT length in Bytes
676    int debB;     // Subscript of the first Lut Value
677    int nbitsB;   // Lut item size (in Bits)
678    nbRead = sscanf( LutRedDescriptor.c_str(),
679                     "%d\\%d\\%d",
680                     &lengthB, &debB, &nbitsB );
681    if ( nbRead != 3 )
682    {
683       gdcmWarningMacro( "Wrong Blue LUT descriptor" );
684    }
685  
686    gdcmDebugMacro(" lengthR " << lengthR << " debR " 
687                 << debR << " nbitsR " << nbitsR);
688    gdcmDebugMacro(" lengthG " << lengthG << " debG " 
689                 << debG << " nbitsG " << nbitsG);
690    gdcmDebugMacro(" lengthB " << lengthB << " debB " 
691                 << debB << " nbitsB " << nbitsB);
692
693    if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143
694       lengthR=65536;
695    if ( !lengthG ) // if = 2^16, this shall be 0
696       lengthG=65536;
697    if ( !lengthB ) // if = 2^16, this shall be 0
698       lengthB=65536; 
699                                                                                 
700    ////////////////////////////////////////////////////////
701
702    if ( ( ! LutRedData ) || ( ! LutGreenData ) || ( ! LutBlueData ) )
703    {
704       gdcmWarningMacro( "(At least) a LUT is missing" );
705       return;
706    }
707
708    // -------------------------------------------------------------
709    
710    if ( BitsAllocated <= 8 )
711    {
712       // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT
713       LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha)
714       if ( !LutRGBA )
715          return;
716       LutItemNumber = 256;
717       LutItemSize   = 8;
718       memset( LutRGBA, 0, 1024 );
719                                                                                 
720       int mult;
721       if ( ( nbitsR == 16 ) && ( BitsAllocated == 8 ) )
722       {
723          // when LUT item size is different than pixel size
724          mult = 2; // high byte must be = low byte
725       }
726       else
727       {
728          // See PS 3.3-2003 C.11.1.1.2 p 619
729          mult = 1;
730       }
731                                                                                 
732       // if we get a black image, let's just remove the '+1'
733       // from 'i*mult+1' and check again
734       // if it works, we shall have to check the 3 Palettes
735       // to see which byte is ==0 (first one, or second one)
736       // and fix the code
737       // We give up the checking to avoid some (useless ?) overhead
738       // (optimistic asumption)
739       int i;
740       uint8_t *a;
741
742       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
743
744       //FIXME :  +1 : to get 'low value' byte
745       //         Trouble expected on Big Endian Processors ?
746       //         16 BIts Per Pixel Palette Color to be swapped?
747
748       a = LutRGBA + 0 + debR;
749       for( i=0; i < lengthR; ++i )
750       {
751          *a = LutRedData[i*mult+1]; 
752          a += 4;
753       }
754                                                                                 
755       a = LutRGBA + 1 + debG;
756       for( i=0; i < lengthG; ++i)
757       {
758          *a = LutGreenData[i*mult+1];
759          a += 4;
760       }
761                                                                                 
762       a = LutRGBA + 2 + debB;
763       for(i=0; i < lengthB; ++i)
764       {
765          *a = LutBlueData[i*mult+1];
766          a += 4;
767       }
768                                     
769       a = LutRGBA + 3 ;
770       for(i=0; i < 256; ++i)
771       {
772          *a = 1; // Alpha component
773          a += 4;
774       }
775    }
776    else
777    {
778       // Probabely the same stuff is to be done for 16 Bits Pixels
779       // with 65536 entries LUT ?!?
780       // Still looking for accurate info on the web :-(
781
782       gdcmWarningMacro( "Sorry Palette Color Lookup Tables not yet dealt with"
783                          << " for 16 Bits Per Pixel images" );
784
785       // forge the 4 * 16 Bits Red/Green/Blue/Alpha LUT
786
787       LutRGBA = (uint8_t *)new uint16_t[ 65536*4 ]; // 2^16 * 4 (R, G, B, Alpha)
788       if ( !LutRGBA )
789          return;
790       memset( LutRGBA, 0, 65536*4*2 );  // 16 bits = 2 bytes ;-)
791
792       LutItemNumber = 65536;
793       LutItemSize   = 16;
794
795       int i;
796       uint16_t *a16;
797
798       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
799
800       a16 = (uint16_t*)LutRGBA + 0 + debR;
801       for( i=0; i < lengthR; ++i )
802       {
803          *a16 = ((uint16_t*)LutRedData)[i];
804          a16 += 4;
805       }
806                                                                               
807       a16 = (uint16_t*)LutRGBA + 1 + debG;
808       for( i=0; i < lengthG; ++i)
809       {
810          *a16 = ((uint16_t*)LutGreenData)[i];
811          a16 += 4;
812       }
813                                                                                 
814       a16 = (uint16_t*)LutRGBA + 2 + debB;
815       for(i=0; i < lengthB; ++i)
816       {
817          *a16 = ((uint16_t*)LutBlueData)[i];
818          a16 += 4;
819       }
820                                                                              
821       a16 = (uint16_t*)LutRGBA + 3 ;
822       for(i=0; i < 65536; ++i)
823       {
824          *a16 = 1; // Alpha component
825          a16 += 4;
826       }
827 /* Just to 'see' the LUT, at debug time
828 // Don't remove this commented out code.
829
830       a16=(uint16_t*)LutRGBA;
831       for (int j=0;j<65536;j++)
832       {
833          std::cout << *a16     << " " << *(a16+1) << " "
834                    << *(a16+2) << " " << *(a16+3) << std::endl;
835          a16+=4;
836       }
837 */
838    }
839 }
840
841 /**
842  * \brief Swap the bytes, according to \ref SwapCode.
843  */
844 void PixelReadConvert::ConvertSwapZone()
845 {
846    unsigned int i;
847    
848    // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', 
849    // then the header is in little endian format and the pixel data is in 
850    // big endian format.  When reading the header, GDCM has already established
851    // a byte swapping code suitable for this machine to read the
852    // header. In TS::ImplicitVRBigEndianPrivateGE, this code will need
853    // to be switched in order to read the pixel data.  This must be
854    // done REGARDLESS of the processor endianess!
855    //
856    // Example:  Assume we are on a little endian machine.  When
857    // GDCM reads the header, the header will match the machine
858    // endianess and the swap code will be established as a no-op.
859    // When GDCM reaches the pixel data, it will need to switch the
860    // swap code to do big endian to little endian conversion.
861    //
862    // Now, assume we are on a big endian machine.  When GDCM reads the
863    // header, the header will be recognized as a different endianess
864    // than the machine endianess, and a swap code will be established
865    // to convert from little endian to big endian.  When GDCM readers
866    // the pixel data, the pixel data endianess will now match the
867    // machine endianess.  But we currently have a swap code that
868    // converts from little endian to big endian.  In this case, we
869    // need to switch the swap code to a no-op.
870    //
871    // Therefore, in either case, if the file is in
872    // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
873    // the byte swapping code when entering the pixel data.
874    
875    int tempSwapCode = SwapCode;
876    if ( IsPrivateGETransferSyntax )
877    {
878       gdcmWarningMacro(" IsPrivateGETransferSyntax found; turn the SwapCode"); 
879       // PrivateGETransferSyntax only exists for 'true' Dicom images
880       // we assume there is no 'exotic' 32 bits endianess!
881       if (SwapCode == 1234) 
882       {
883          tempSwapCode = 4321;
884       }
885       else if (SwapCode == 4321)
886       {
887          tempSwapCode = 1234;
888       }
889    }
890     
891    if ( BitsAllocated == 16 )
892    {
893       uint16_t *im16 = (uint16_t*)Raw;
894       switch( tempSwapCode )
895       {
896          case 1234:
897             break;
898          case 3412:
899          case 2143:
900          case 4321:
901             for( i = 0; i < RawSize / 2; i++ )
902             {
903                im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
904             }
905             break;
906          default:
907             gdcmWarningMacro("SwapCode value (16 bits) not allowed." 
908                         << tempSwapCode);
909       }
910    }
911    else if ( BitsAllocated == 32 )
912    {
913       uint32_t s32;
914       uint16_t high;
915       uint16_t low;
916       uint32_t *im32 = (uint32_t*)Raw;
917       switch ( tempSwapCode )
918       {
919          case 1234:
920             break;
921          case 4321:
922             for( i = 0; i < RawSize / 4; i++ )
923             {
924                low     = im32[i] & 0x0000ffff;  // 4321
925                high    = im32[i] >> 16;
926                high    = ( high >> 8 ) | ( high << 8 );
927                low     = ( low  >> 8 ) | ( low  << 8 );
928                s32     = low;
929                im32[i] = ( s32 << 16 ) | high;
930             }
931             break;
932          case 2143:
933             for( i = 0; i < RawSize / 4; i++ )
934             {
935                low     = im32[i] & 0x0000ffff;   // 2143
936                high    = im32[i] >> 16;
937                high    = ( high >> 8 ) | ( high << 8 );
938                low     = ( low  >> 8 ) | ( low  << 8 );
939                s32     = high;
940                im32[i] = ( s32 << 16 ) | low;
941             }
942             break;
943          case 3412:
944             for( i = 0; i < RawSize / 4; i++ )
945             {
946                low     = im32[i] & 0x0000ffff; // 3412
947                high    = im32[i] >> 16;
948                s32     = low;
949                im32[i] = ( s32 << 16 ) | high;
950             }
951             break;
952          default:
953             gdcmWarningMacro("SwapCode value (32 bits) not allowed." << tempSwapCode );
954       }
955    }
956 }
957
958 /**
959  * \brief Deal with endianness i.e. re-arange bytes inside the integer
960  */
961 void PixelReadConvert::ConvertReorderEndianity()
962 {
963    if ( BitsAllocated != 8 )
964    {
965       ConvertSwapZone();
966    }
967
968    // Special kludge in order to deal with xmedcon broken images:
969    if ( BitsAllocated == 16
970      && BitsStored < BitsAllocated
971      && !PixelSign )
972    {
973       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
974       uint16_t *deb = (uint16_t *)Raw;
975       for(int i = 0; i<l; i++)
976       {
977          if ( *deb == 0xffff )
978          {
979            *deb = 0;
980          }
981          deb++;
982       }
983    }
984 }
985
986 /**
987  * \brief Deal with Grey levels i.e. re-arange them
988  *        to have low values = dark, high values = bright
989  */
990 void PixelReadConvert::ConvertFixGreyLevels()
991 {
992    if (!IsMonochrome1)
993       return;
994
995    uint32_t i; // to please M$VC6
996    int16_t j;
997
998    if (!PixelSign)
999    {
1000       if ( BitsAllocated == 8 )
1001       {
1002          uint8_t *deb = (uint8_t *)Raw;
1003          for (i=0; i<RawSize; i++)      
1004          {
1005             *deb = 255 - *deb;
1006             deb++;
1007          }
1008          return;
1009       }
1010
1011       if ( BitsAllocated == 16 )
1012       {
1013          uint16_t mask =1;
1014          for (j=0; j<BitsStored-1; j++)
1015          {
1016             mask = (mask << 1) +1; // will be fff when BitsStored=12
1017          }
1018
1019          uint16_t *deb = (uint16_t *)Raw;
1020          for (i=0; i<RawSize/2; i++)      
1021          {
1022             *deb = mask - *deb;
1023             deb++;
1024          }
1025          return;
1026        }
1027    }
1028    else
1029    {
1030       if ( BitsAllocated == 8 )
1031       {
1032          uint8_t smask8 = 255;
1033          uint8_t *deb = (uint8_t *)Raw;
1034          for (i=0; i<RawSize; i++)      
1035          {
1036             *deb = smask8 - *deb;
1037             deb++;
1038          }
1039          return;
1040       }
1041       if ( BitsAllocated == 16 )
1042       {
1043          uint16_t smask16 = 65535;
1044          uint16_t *deb = (uint16_t *)Raw;
1045          for (i=0; i<RawSize/2; i++)      
1046          {
1047             *deb = smask16 - *deb;
1048             deb++;
1049          }
1050          return;
1051       }
1052    }
1053 }
1054
1055 /**
1056  * \brief  Re-arrange the bits within the bytes.
1057  * @return Boolean always true
1058  */
1059 bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError )
1060 {
1061
1062    if ( BitsStored != BitsAllocated )
1063    {
1064       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
1065       if ( BitsAllocated == 16 )
1066       {
1067          // pmask : to mask the 'unused bits' (may contain overlays)
1068          uint16_t pmask = 0xffff;
1069          pmask = pmask >> ( BitsAllocated - BitsStored );
1070
1071          uint16_t *deb = (uint16_t*)Raw;
1072
1073          if ( !PixelSign )  // Pixels are unsigned
1074          {
1075             for(int i = 0; i<l; i++)
1076             {   
1077                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1078                deb++;
1079             }
1080          }
1081          else // Pixels are signed
1082          {
1083             // smask : to check the 'sign' when BitsStored != BitsAllocated
1084             uint16_t smask = 0x0001;
1085             smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) );
1086             // nmask : to propagate sign bit on negative values
1087             int16_t nmask = (int16_t)0x8000;  
1088             nmask = nmask >> ( BitsAllocated - BitsStored - 1 );
1089  
1090             for(int i = 0; i<l; i++)
1091             {
1092                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1093                if ( *deb & smask )
1094                {
1095                   *deb = *deb | nmask;
1096                }
1097                else
1098                {
1099                   *deb = *deb & pmask;
1100                }
1101                deb++;
1102             }
1103          }
1104       }
1105       else if ( BitsAllocated == 32 )
1106       {
1107          // pmask : to mask the 'unused bits' (may contain overlays)
1108          uint32_t pmask = 0xffffffff;
1109          pmask = pmask >> ( BitsAllocated - BitsStored );
1110
1111          uint32_t *deb = (uint32_t*)Raw;
1112
1113          if ( !PixelSign )
1114          {
1115             for(int i = 0; i<l; i++)
1116             {             
1117                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1118                deb++;
1119             }
1120          }
1121          else
1122          {
1123             // smask : to check the 'sign' when BitsStored != BitsAllocated
1124             uint32_t smask = 0x00000001;
1125             smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 ));
1126             // nmask : to propagate sign bit on negative values
1127             int32_t nmask = 0x80000000;   
1128             nmask = nmask >> ( BitsAllocated - BitsStored -1 );
1129
1130             for(int i = 0; i<l; i++)
1131             {
1132                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1133                if ( *deb & smask )
1134                   *deb = *deb | nmask;
1135                else
1136                   *deb = *deb & pmask;
1137                deb++;
1138             }
1139          }
1140       }
1141       else
1142       {
1143          gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)");
1144          throw FormatError( "Weird image !?" );
1145       }
1146    }
1147    return true;
1148 }
1149
1150 /**
1151  * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
1152  * \warning Works on all the frames at a time
1153  */
1154 void PixelReadConvert::ConvertRGBPlanesToRGBPixels()
1155 {
1156    gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels");
1157
1158    uint8_t *localRaw = Raw;
1159    uint8_t *copyRaw = new uint8_t[ RawSize ];
1160    memmove( copyRaw, localRaw, RawSize );
1161
1162    int l = XSize * YSize * ZSize;
1163
1164    uint8_t *a = copyRaw;
1165    uint8_t *b = copyRaw + l;
1166    uint8_t *c = copyRaw + l + l;
1167
1168    for (int j = 0; j < l; j++)
1169    {
1170       *(localRaw++) = *(a++);
1171       *(localRaw++) = *(b++);
1172       *(localRaw++) = *(c++);
1173    }
1174    delete[] copyRaw;
1175 }
1176
1177 /**
1178  * \brief   Convert (cY plane, cB plane, cR plane) to RGB pixels
1179  * \warning Works on all the frames at a time
1180  */
1181 void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels()
1182 {
1183   // Remarks for YBR newbees :
1184   // YBR_FULL works very much like RGB, i.e. three samples per pixel, 
1185   // just the color space is YCbCr instead of RGB. This is particularly useful
1186   // for doppler ultrasound where most of the image is grayscale 
1187   // (i.e. only populates the Y components) and Cb and Cr are mostly zero,
1188   // except for the few patches of color on the image.
1189   // On such images, RLE achieves a compression ratio that is much better 
1190   // than the compression ratio on an equivalent RGB image. 
1191  
1192    gdcmWarningMacro("--> ConvertYcBcRPlanesToRGBPixels");
1193    
1194    uint8_t *localRaw = Raw;
1195    uint8_t *copyRaw = new uint8_t[ RawSize ];
1196    memmove( copyRaw, localRaw, RawSize );
1197
1198    // to see the tricks about YBR_FULL, YBR_FULL_422,
1199    // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
1200    // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
1201    // and be *very* affraid
1202    //
1203    int l        = XSize * YSize;
1204    int nbFrames = ZSize;
1205
1206    uint8_t *a = copyRaw + 0;
1207    uint8_t *b = copyRaw + l;
1208    uint8_t *c = copyRaw + l+ l;
1209    int32_t R, G, B;
1210
1211    ///  We replaced easy to understand but time consuming floating point
1212    ///  computations by the 'well known' integer computation counterpart
1213    ///  Refer to :
1214    ///            http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
1215    ///  for code optimisation.
1216
1217    for ( int i = 0; i < nbFrames; i++ )
1218    {
1219       for ( int j = 0; j < l; j++ )
1220       {
1221          R = 38142 *(*a-16) + 52298 *(*c -128);
1222          G = 38142 *(*a-16) - 26640 *(*c -128) - 12845 *(*b -128);
1223          B = 38142 *(*a-16) + 66093 *(*b -128);
1224
1225          R = (R+16384)>>15;
1226          G = (G+16384)>>15;
1227          B = (B+16384)>>15;
1228
1229          if (R < 0)   R = 0;
1230          if (G < 0)   G = 0;
1231          if (B < 0)   B = 0;
1232          if (R > 255) R = 255;
1233          if (G > 255) G = 255;
1234          if (B > 255) B = 255;
1235
1236          *(localRaw++) = (uint8_t)R;
1237          *(localRaw++) = (uint8_t)G;
1238          *(localRaw++) = (uint8_t)B;
1239          a++;
1240          b++;
1241          c++;
1242       }
1243    }
1244    delete[] copyRaw;
1245 }
1246
1247 /// \brief Deals with the color decoding i.e. handle:
1248 ///   - R, G, B planes (as opposed to RGB pixels)
1249 ///   - YBR (various) encodings.
1250 ///   - LUT[s] (or "PALETTE COLOR").
1251
1252 void PixelReadConvert::ConvertHandleColor()
1253 {
1254    //////////////////////////////////
1255    // Deal with the color decoding i.e. handle:
1256    //   - R, G, B planes (as opposed to RGB pixels)
1257    //   - YBR (various) encodings.
1258    //   - LUT[s] (or "PALETTE COLOR").
1259    //
1260    // The classification in the color decoding schema is based on the blending
1261    // of two Dicom tags values:
1262    // * "Photometric Interpretation" for which we have the cases:
1263    //  - [Photo A] MONOCHROME[1|2] pictures,
1264    //  - [Photo B] RGB or YBR_FULL_422 (which acts as RGB),
1265    //  - [Photo C] YBR_* (with the above exception of YBR_FULL_422)
1266    //  - [Photo D] "PALETTE COLOR" which indicates the presence of LUT[s].
1267    // * "Planar Configuration" for which we have the cases:
1268    //  - [Planar 0] 0 then Pixels are already RGB
1269    //  - [Planar 1] 1 then we have 3 planes : R, G, B,
1270    //  - [Planar 2] 2 then we have 1 gray Plane and 3 LUTs
1271    //
1272    // Now in theory, one could expect some coherence when blending the above
1273    // cases. For example we should not encounter files belonging at the
1274    // time to case [Planar 0] and case [Photo D].
1275    // Alas, this was only theory ! Because in practice some odd (read ill
1276    // formated Dicom) files (e.g. gdcmData/US-PAL-8-10x-echo.dcm) we encounter:
1277    //     - "Planar Configuration" = 0,
1278    //     - "Photometric Interpretation" = "PALETTE COLOR".
1279    // Hence gdcm will use the folowing "heuristic" in order to be tolerant
1280    // towards Dicom-non-conformant files:
1281    //   << whatever the "Planar Configuration" value might be, a
1282    //      "Photometric Interpretation" set to "PALETTE COLOR" forces
1283    //      a LUT intervention >>
1284    //
1285    // Now we are left with the following handling of the cases:
1286    // - [Planar 0] OR  [Photo A] no color decoding (since respectively
1287    //       Pixels are already RGB and monochrome pictures have no color :),
1288    // - [Planar 1] AND [Photo B] handled with ConvertRGBPlanesToRGBPixels()
1289    // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels()
1290    // - [Planar 2] OR  [Photo D] requires LUT intervention.
1291
1292    gdcmDebugMacro("--> ConvertHandleColor "
1293                      << "Planar Configuration " << PlanarConfiguration );
1294
1295    if ( ! IsRawRGB() )
1296    {
1297       // [Planar 2] OR  [Photo D]: LUT intervention done outside
1298       gdcmDebugMacro("--> RawRGB : LUT intervention done outside");
1299       return;
1300    }
1301                                                                                 
1302    if ( PlanarConfiguration == 1 )
1303    {
1304       if ( IsYBRFull )
1305       {
1306          // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB)
1307          gdcmDebugMacro("--> YBRFull");
1308          ConvertYcBcRPlanesToRGBPixels();
1309       }
1310       else
1311       {
1312          // [Planar 1] AND [Photo C]
1313          gdcmDebugMacro("--> YBRFull");
1314          ConvertRGBPlanesToRGBPixels();
1315       }
1316       return;
1317    }
1318                                                                                 
1319    // When planarConf is 0, and RLELossless (forbidden by Dicom norm)
1320    // pixels need to be RGB-fyied anyway
1321
1322    if (IsRLELossless)
1323    { 
1324      gdcmDebugMacro("--> RLE Lossless");
1325      ConvertRGBPlanesToRGBPixels();
1326    }
1327
1328    // In *normal *case, when planarConf is 0, pixels are already in RGB
1329 }
1330
1331 /// Computes the Pixels Size
1332 void PixelReadConvert::ComputeRawAndRGBSizes()
1333 {
1334    int bitsAllocated = BitsAllocated;
1335    // Number of "Bits Allocated" is fixed to 16 when it's 12, since
1336    // in this case we will expand the image to 16 bits (see
1337    //    \ref ReadAndDecompress12BitsTo16Bits() )
1338    if (  BitsAllocated == 12 )
1339    {
1340       bitsAllocated = 16;
1341    }
1342                                                                                 
1343    RawSize =  XSize * YSize * ZSize
1344                      * ( bitsAllocated / 8 )
1345                      * SamplesPerPixel;
1346    if ( HasLUT )
1347    {
1348       RGBSize = 3 * RawSize; // works for 8 and 16 bits per Pixel
1349    }
1350    else
1351    {
1352       RGBSize = RawSize;
1353    }
1354 }
1355
1356 /// Allocates room for RGB Pixels
1357 void PixelReadConvert::AllocateRGB()
1358 {
1359   if ( RGB )
1360      delete [] RGB;
1361   RGB = new uint8_t[RGBSize];
1362 }
1363
1364 /// Allocates room for RAW Pixels
1365 void PixelReadConvert::AllocateRaw()
1366 {
1367   if ( Raw )
1368      delete [] Raw;
1369   Raw = new uint8_t[RawSize];
1370 }
1371
1372 //-----------------------------------------------------------------------------
1373 // Print
1374 /**
1375  * \brief        Print self.
1376  * @param indent Indentation string to be prepended during printing.
1377  * @param os     Stream to print to.
1378  */
1379 void PixelReadConvert::Print( std::ostream &os, std::string const &indent )
1380 {
1381    os << indent
1382       << "--- Pixel information -------------------------"
1383       << std::endl;
1384    os << indent
1385       << "Pixel Data: offset " << PixelOffset
1386       << " x(" << std::hex << PixelOffset << std::dec
1387       << ")   length " << PixelDataLength
1388       << " x(" << std::hex << PixelDataLength << std::dec
1389       << ")" << std::endl;
1390
1391    if ( IsRLELossless )
1392    {
1393       if ( RLEInfo )
1394       {
1395          RLEInfo->Print( os, indent );
1396       }
1397       else
1398       {
1399          gdcmWarningMacro("Set as RLE file but NO RLEinfo present.");
1400       }
1401    }
1402
1403    if ( IsJPEG2000 || IsJPEGLossless || IsJPEGLossy || IsJPEGLS )
1404    {
1405       if ( JPEGInfo )
1406       {
1407          JPEGInfo->Print( os, indent );
1408       }
1409       else
1410       {
1411          gdcmWarningMacro("Set as JPEG file but NO JPEGinfo present.");
1412       }
1413    }
1414 }
1415
1416 /**
1417  * \brief   CallStartMethod
1418  */
1419 void PixelReadConvert::CallStartMethod()
1420 {
1421    Progress = 0.0f;
1422    Abort    = false;
1423    CommandManager::ExecuteCommand(FH,CMD_STARTPROGRESS);
1424 }
1425
1426 /**
1427  * \brief   CallProgressMethod
1428  */
1429 void PixelReadConvert::CallProgressMethod()
1430 {
1431    CommandManager::ExecuteCommand(FH,CMD_PROGRESS);
1432 }
1433
1434 /**
1435  * \brief   CallEndMethod
1436  */
1437 void PixelReadConvert::CallEndMethod()
1438 {
1439    Progress = 1.0f;
1440    CommandManager::ExecuteCommand(FH,CMD_ENDPROGRESS);
1441 }
1442
1443
1444 //-----------------------------------------------------------------------------
1445 } // end namespace gdcm
1446
1447 // Note to developpers :
1448 // Here is a very detailled post from David Clunie, on the troubles caused 
1449 // 'non standard' LUT and LUT description
1450 // We shall have to take it into accound in our code.
1451 // Some day ...
1452
1453
1454 /*
1455 Subject: Problem with VOI LUTs in Agfa and Fuji CR and GE DX images, was Re: VOI LUT issues
1456 Date: Sun, 06 Feb 2005 17:13:40 GMT
1457 From: David Clunie <dclunie@dclunie.com>
1458 Reply-To: dclunie@dclunie.com
1459 Newsgroups: comp.protocols.dicom
1460 References: <1107553502.040221.189550@o13g2000cwo.googlegroups.com>
1461
1462 > THE LUT that comes with [my] image claims to be 16-bit, but none of the
1463 > values goes higher than 4095.  That being said, though, none of my
1464 > original pixel values goes higher than that, either.  I have read
1465 > elsewhere on this group that when that happens you are supposed to
1466 > adjust the LUT.  Can someone be more specific?  There was a thread from
1467 > 2002 where Marco and David were mentioning doing precisely that.
1468 >
1469 > Thanks
1470 >
1471 > -carlos rodriguez
1472
1473
1474 You have encountered the well known "we know what the standard says but
1475 we are going to ignore it and do what we have been doing for almost
1476 a decade regardless" CR vendor bug. Agfa started this, but they are not
1477 the only vendor doing this now; GE and Fuji may have joined the club.
1478
1479 Sadly, one needs to look at the LUT Data, figure out what the maximum
1480 value actually encoded is, and find the next highest power of 2 (e.g.
1481 212 in this case), to figure out what the range of the data is
1482 supposed to be. I have assumed that if the maximum value in the LUT
1483 data is less than a power of 2 minus 1 (e.g. 0xebc) then the intent
1484 of the vendor was not to use the maximum available grayscale range
1485 of the display (e.g. the maximum is 0xfff in this case). An alternative
1486 would be to scale to the actual maximum rather than a power of two.
1487
1488 Very irritating, and in theory not totally reliable if one really
1489 intended the full 16 bits and only used, say 15, but that is extremely
1490 unlikely since everything would be too dark, and this heuristic
1491 seems to work OK.
1492
1493 There has never been anything in the standard that describes having
1494 to go through these convolutions. Since the only value in the
1495 standard that describes the bit depth of the LUT values is LUT
1496 Descriptor value 3 and that is (usually) always required to be
1497 either 8 or 16, it mystifies me how the creators' of these images
1498 imagine that the receiver is going to divine the range that is intended. Further, the standard is quite explicit that this 3rd
1499 value defines the range of LUT values, but as far as I am aware, all
1500 the vendors are ignoring the standard and indeed sending a third value
1501 of 16 in all cases.
1502
1503 This problem is not confined to CR, and is also seen with DX products.
1504
1505 Typically I have seen:
1506
1507 - Agfa CR, which usually (always ?) sends LUTs, values up to 0x0fff
1508 - Fuji CR, which occasionally send LUTs, values up to 0x03ff
1509 - GE DX, for presentation, which always have LUTs, up to 0x3fff
1510
1511 Swissray, Siemens, Philips, Canon and Kodak never seem to send VOI LUTs
1512 at this point (which is a whole other problem). Note that the presence
1513 or absence of a VOI LUT as opposed to window values may be configurable
1514 on the modality in some cases, and I have just looked at what I happen
1515 to have received from a myriad of sites over whose configuration I have
1516 no control. This may be why the majority of Fuji images have no VOI LUTs,
1517 but a few do (or it may be the Siemens system that these Fuji images went
1518 through that perhaps added it). I do have some test Hologic DX images that
1519 are not from a clinical site that do actually get this right (a value
1520 of 12 for the third value and a max of 0xfff).
1521
1522 Since almost every vendor that I have encountered that encodes LUTs
1523 makes this mistake, perhaps it is time to amend the standard to warn
1524 implementor's of receivers and/or sanction this bad behavior. We have
1525 talked about this in the past in WG 6 but so far everyone has been
1526 reluctant to write into the standard such a comment. Maybe it is time
1527 to try again, since if one is not aware of this problem, one cannot
1528 effectively implement display using VOI LUTs, and there is a vast
1529 installed base to contend with.
1530
1531 I did not check presentation states, in which VOI LUTs could also be
1532 encountered, for the prevalence of this mistake, nor did I look at the
1533 encoding of Modality LUT's, which are unusual. Nor did I check digital
1534 mammography images. I would be interested to hear from anyone who has.
1535
1536 David
1537
1538 PS. The following older thread in this newsgroup discusses this:
1539
1540 "http://groups-beta.google.com/group/comp.protocols.dicom/browse_frm/t hread/6a033444802a35fc/0f0a9a1e35c1468e?q=voi+lut&_done=%2Fgroup%2Fcom p.protocols.dicom%2Fsearch%3Fgroup%3Dcomp.protocols.dicom%26q%3Dvoi+lu t%26qt_g%3D1%26searchnow%3DSearch+this+group%26&_doneTitle=Back+to+Sea rch&&d#0f0a9a1e35c1468e"
1541
1542 PPS. From a historical perspective, the following may be of interest.
1543
1544 In the original standard in 1993, all that was said about this was a
1545 reference to the corresponding such where Modality LUTs are described
1546 that said:
1547
1548 "The third value specifies the number of bits for each entry in the
1549 LUT Data. It shall take the value 8 or 16. The LUT Data shall be stored
1550 in a format equivalent to 8 or 16 bits allocated and high bit equal
1551 1-bits allocated."
1552
1553 Since the high bit hint was not apparently explicit enough, a very
1554 early CP, CP 15 (submitted by Agfa as it happens), replaced this with:
1555
1556 "The third value conveys the range of LUT entry values. It shall take
1557 the value 8 or 16, corresponding with the LUT entry value range of
1558 256 or 65536.
1559
1560 Note:    The third value is not required for describing the
1561     LUT data and is only included for informational usage
1562     and for maintaining compatibility with ACRNEMA 2.0.
1563
1564 The LUT Data contains the LUT entry values."
1565
1566 That is how it read in the 1996, 1998 and 1999 editions.
1567
1568 By the 2000 edition, Supplement 33 that introduced presentation states
1569 extensively reworked this entire section and tried to explain this in
1570 different words:
1571
1572 "The output range is from 0 to 2^n-1 where n is the third value of LUT
1573 Descriptor. This range is always unsigned."
1574
1575 and also added a note to spell out what the output range meant in the
1576 VOI LUT section:
1577
1578 "9. The output of the Window Center/Width or VOI LUT transformation
1579 is either implicitly scaled to the full range of the display device
1580 if there is no succeeding transformation defined, or implicitly scaled
1581 to the full input range of the succeeding transformation step (such as
1582 the Presentation LUT), if present. See C.11.6.1."
1583
1584 It still reads this way in the 2004 edition.
1585
1586 Note that LUTs in other applications than the general VOI LUT allow for
1587 values other than 8 or 16 in the third value of LUT descriptor to permit
1588 ranges other than 0 to 255 or 65535.
1589
1590 In addition, the DX Image Module specializes the VOI LUT
1591 attributes as follows, in PS 3.3 section C.8.11.3.1.5 (added in Sup 32):
1592
1593 "The third value specifies the number of bits for each entry in the LUT
1594 Data (analogous to ìbits storedî). It shall be between 10-16. The LUT
1595 Data shall be stored in a format equivalent to 16 ìbits allocatedî and
1596 ìhigh bitî equal to ìbits storedî - 1. The third value conveys the range
1597 of LUT entry values. These unsigned LUT entry values shall range between
1598 0 and 2^n-1, where n is the third value of the LUT Descriptor."
1599
1600 So in the case of the GE DX for presentation images, the third value of
1601 LUT descriptor is allowed to be and probably should be 14 rather than 16.
1602
1603 */