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