]> Creatis software - gdcm.git/blob - src/gdcmPixelReadConvert.cxx
Doxygenation
[gdcm.git] / src / gdcmPixelReadConvert.cxx
1 /*=========================================================================
2  
3   Program:   gdcm
4   Module:    $RCSfile: gdcmPixelReadConvert.cxx,v $
5   Language:  C++
6   Date:      $Date: 2006/06/29 13:27:59 $
7   Version:   $Revision: 1.112 $
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  * @param fileHelper gdcm::FileHelper pointer 
89  */
90 void PixelReadConvert::GrabInformationsFromFile( File *file,
91                                                  FileHelper *fileHelper )
92 {
93    // Number of Bits Allocated for storing a Pixel is defaulted to 16
94    // when absent from the file.
95    BitsAllocated = file->GetBitsAllocated();
96    if ( BitsAllocated == 0 )
97    {
98       BitsAllocated = 16;
99    }
100
101    // Number of "Bits Stored", defaulted to number of "Bits Allocated"
102    // when absent from the file.
103    BitsStored = file->GetBitsStored();
104    if ( BitsStored == 0 )
105    {
106       BitsStored = BitsAllocated;
107    }
108
109    // High Bit Position, defaulted to "Bits Allocated" - 1
110    HighBitPosition = file->GetHighBitPosition();
111    if ( HighBitPosition == 0 )
112    {
113       HighBitPosition = BitsAllocated - 1;
114    }
115
116    XSize           = file->GetXSize();
117    YSize           = file->GetYSize();
118    ZSize           = file->GetZSize();
119    TSize           = file->GetTSize();   
120    SamplesPerPixel = file->GetSamplesPerPixel();
121    //PixelSize       = file->GetPixelSize();  Useless
122    PixelSign       = file->IsSignedPixelData();
123    SwapCode        = file->GetSwapCode();
124
125    IsPrivateGETransferSyntax = IsMPEG
126              = IsJPEG2000 = IsJPEGLS = IsJPEGLossy  
127              = IsJPEGLossless = IsRLELossless 
128              = false;
129
130    if (! file->IsDicomV3() )  // Should be ACR-NEMA file
131    {
132       IsRaw = true;
133    }
134    else
135    {
136       std::string ts = file->GetTransferSyntax();
137
138       IsRaw = false;
139       while (true) // shorter to write than 'if elseif elseif elseif' ...
140       {
141          // mind the order : check the most usual first.
142          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian)         break;
143          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian )        break;
144          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian)            break;
145          if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE)   break;
146          // DeflatedExplicitVRLittleEndian syntax means the whole Dataset (Header + Pixels) is compressed !
147          // Not dealt with ! (Parser hangs)
148          //if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian) break;
149          break;
150       }
151       // cache whether this is a strange GE transfer syntax (which uses
152       // a little endian transfer syntax for the header and a big endian
153       // transfer syntax for the pixel data). 
154       IsPrivateGETransferSyntax = 
155                 ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE );
156
157       IsMPEG =  IsJPEG2000 =  IsJPEGLS =  IsJPEGLossy =  IsJPEGLossless = IsRLELossless = false;  
158       if (!IsRaw)
159       {     
160          while(true)
161          {
162             // mind the order : check the most usual first.
163             if( IsJPEGLossy     = Global::GetTS()->IsJPEGLossy(ts) )    break;
164             if( IsJPEGLossless  = Global::GetTS()->IsJPEGLossless(ts) ) break;
165             if( IsRLELossless   = Global::GetTS()->IsRLELossless(ts) )  break;
166             if( IsJPEG2000      = Global::GetTS()->IsJPEG2000(ts) )     break;
167             if( IsMPEG          = Global::GetTS()->IsMPEG(ts) )         break;
168             if( IsJPEGLS        = Global::GetTS()->IsJPEGLS(ts) )       break;
169             // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' (we don't know yet haow to process !)
170             gdcmWarningMacro("Unexpected Transfer Syntax :[" << ts << "]");
171             break;
172          } 
173       }
174    }
175
176    PixelOffset     = file->GetPixelOffset();
177    PixelDataLength = file->GetPixelAreaLength();
178    RLEInfo         = file->GetRLEInfo();
179    JPEGInfo        = file->GetJPEGInfo();
180
181    IsMonochrome    = file->IsMonochrome();
182    IsMonochrome1   = file->IsMonochrome1();
183    IsPaletteColor  = file->IsPaletteColor();
184    IsYBRFull       = file->IsYBRFull();
185
186    PlanarConfiguration = file->GetPlanarConfiguration();
187
188    /////////////////////////////////////////////////////////////////
189    // LUT section:
190    HasLUT = file->HasLUT();
191    if ( HasLUT )
192    {
193       // Just in case some access to a File element requires disk access.
194       LutRedDescriptor   = file->GetEntryString( 0x0028, 0x1101 );
195       LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 );
196       LutBlueDescriptor  = file->GetEntryString( 0x0028, 0x1103 );
197    
198       // FIXME : The following comment is probabely meaningless, since LUT are *always*
199       // loaded at parsing time, whatever their length is.
200          
201       // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
202       // [ refer to invocation of Document::SetMaxSizeLoadEntry() in
203       // Document::Document() ], the loading of the value (content) of a
204       // [Bin|Val]Entry occurence migth have been hindered (read simply NOT
205       // loaded). Hence, we first try to obtain the LUTs data from the file
206       // and when this fails we read the LUTs data directly from disk.
207       // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge.
208       //       We should NOT bypass the [Bin|Val]Entry class. Instead
209       //       an access to an UNLOADED content of a [Bin|Val]Entry occurence
210       //       (e.g. DataEntry::GetBinArea()) should force disk access from
211       //       within the [Bin|Val]Entry class itself. The only problem
212       //       is that the [Bin|Val]Entry is unaware of the FILE* is was
213       //       parsed from. Fix that. FIXME.
214    
215       // //// Red round
216       file->LoadEntryBinArea(0x0028, 0x1201);
217       LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 );
218       if ( ! LutRedData )
219       {
220          gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data");
221       }
222
223       // //// Green round:
224       file->LoadEntryBinArea(0x0028, 0x1202);
225       LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
226       if ( ! LutGreenData)
227       {
228          gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data");
229       }
230
231       // //// Blue round:
232       file->LoadEntryBinArea(0x0028, 0x1203);
233       LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
234       if ( ! LutBlueData )
235       {
236          gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data");
237       }
238    }
239    FileInternal = file;   
240    FH = fileHelper;
241    ComputeRawAndRGBSizes();
242 }
243
244 /// \brief Reads from disk and decompresses Pixels
245 bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
246 {
247    // ComputeRawAndRGBSizes is already made by 
248    // ::GrabInformationsFromfile. So, the structure sizes are
249    // correct
250    Squeeze();
251
252    //////////////////////////////////////////////////
253    //// First stage: get our hands on the Pixel Data.
254    if ( !fp )
255    {
256       gdcmWarningMacro( "Unavailable file pointer." );
257       return false;
258    }
259
260    fp->seekg( PixelOffset, std::ios::beg );
261    if ( fp->fail() || fp->eof() )
262    {
263       gdcmWarningMacro( "Unable to find PixelOffset in file." );
264       return false;
265    }
266
267    AllocateRaw();
268
269    //////////////////////////////////////////////////
270    
271    CallStartMethod(); // for progress bar
272    unsigned int count = 0;
273    unsigned int frameSize;
274    unsigned int bitsAllocated = BitsAllocated;
275    if(bitsAllocated == 12)
276       bitsAllocated = 16;
277    frameSize = XSize*YSize*SamplesPerPixel*bitsAllocated/8;
278    
279    //// Second stage: read from disk and decompress.
280    
281    if ( BitsAllocated == 12 ) // We suppose 'BitsAllocated' = 12 only exist for uncompressed files
282    {
283       ReadAndDecompress12BitsTo16Bits( fp);
284    }
285    else if ( IsRaw )
286    {
287       // This problem can be found when some obvious informations are found
288       // after the field containing the image data. In this case, these
289       // bad data are added to the size of the image (in the PixelDataLength
290       // variable). But RawSize is the right size of the image !
291       if ( PixelDataLength != RawSize )
292       {
293          gdcmWarningMacro( "Mismatch between PixelReadConvert : "
294                             << PixelDataLength << " and RawSize : " << RawSize );
295       }
296       
297       //todo : is it the right patch?
298       char *raw = (char*)Raw;
299       uint32_t remainingLength;
300       unsigned int i; 
301       unsigned int lengthToRead;
302        
303       if ( PixelDataLength > RawSize )
304         lengthToRead =  RawSize;
305       else
306         lengthToRead = PixelDataLength;
307  
308       // perform a frame by frame reading
309       remainingLength = lengthToRead;
310       unsigned int nbFrames = lengthToRead / frameSize;
311       for (i=0;i<nbFrames; i++)
312       {
313          Progress = (float)(count+1)/(float)nbFrames;
314          fp->read( raw, frameSize);
315          raw +=  frameSize;
316          remainingLength -=  frameSize;
317          count++;
318       }
319       if (remainingLength !=0 )
320         fp->read( raw, remainingLength);
321                  
322       if ( fp->fail() || fp->eof())
323       {
324          gdcmWarningMacro( "Reading of Raw pixel data failed." );
325          return false;
326       }
327    } 
328    else if ( IsRLELossless )
329    {
330       if ( ! RLEInfo->DecompressRLEFile
331                                ( fp, Raw, XSize, YSize, ZSize, TSize, BitsAllocated ) )
332       {
333          gdcmWarningMacro( "RLE decompressor failed." );
334          return false;
335       }
336    }
337    else if ( IsMPEG )
338    {
339       //gdcmWarningMacro( "Sorry, MPEG not yet taken into account" );
340       //return false;
341       // fp has already been seek to start of mpeg
342       //ReadMPEGFile(fp, (char*)Raw, PixelDataLength); 
343       return true;
344    }
345    else
346    {
347       // Default case concerns JPEG family
348       if ( ! ReadAndDecompressJPEGFile( fp ) )
349       {
350          gdcmWarningMacro( "JPEG decompressor ( ReadAndDecompressJPEGFile()"
351                               << " method ) failed." );
352          return false;
353       }
354    }
355
356    ////////////////////////////////////////////
357    //// Third stage: twigle the bytes and bits.
358    ConvertReorderEndianity();
359    ConvertReArrangeBits();
360    ConvertFixGreyLevels();
361    if (UserFunction) // user is allowed to Mirror, TopDown, Rotate,...the image
362       UserFunction( Raw, FileInternal);
363    ConvertHandleColor();
364
365    return true;
366 }
367
368 /// Deletes Pixels Area
369 void PixelReadConvert::Squeeze() 
370 {
371    if ( RGB )
372       delete [] RGB;
373    RGB = 0;
374
375    if ( Raw )
376       delete [] Raw;
377    Raw = 0;
378
379    if ( LutRGBA )
380       delete [] LutRGBA;
381    LutRGBA = 0;
382 }
383
384 /**
385  * \brief Build the RGB image from the Raw image and the LUTs.
386  */
387 bool PixelReadConvert::BuildRGBImage()
388 {
389    if ( RGB )
390    {
391       // The job is already done.
392       return true;
393    }
394
395    if ( ! Raw )
396    {
397       // The job can't be done
398       return false;
399    }
400
401    BuildLUTRGBA();
402    if ( ! LutRGBA )
403    {
404       // The job can't be done
405       return false;
406    }
407
408    gdcmDebugMacro( "--> BuildRGBImage" );
409                                                                                 
410    // Build RGB Pixels
411    AllocateRGB();
412    
413    int j;
414    if ( BitsAllocated <= 8 )
415    {
416       uint8_t *localRGB = RGB;
417       for (size_t i = 0; i < RawSize; ++i )
418       {
419          j  = Raw[i] * 4;
420          *localRGB++ = LutRGBA[j];
421          *localRGB++ = LutRGBA[j+1];
422          *localRGB++ = LutRGBA[j+2];
423       }
424     }
425  
426     else  // deal with 16 bits pixels and 16 bits Palette color
427     {
428       uint16_t *localRGB = (uint16_t *)RGB;
429       for (size_t i = 0; i < RawSize/2; ++i )
430       {
431          j  = ((uint16_t *)Raw)[i] * 4;
432          *localRGB++ = ((uint16_t *)LutRGBA)[j];
433          *localRGB++ = ((uint16_t *)LutRGBA)[j+1];
434          *localRGB++ = ((uint16_t *)LutRGBA)[j+2];
435       } 
436     }
437  
438    return true;
439 }
440
441 //-----------------------------------------------------------------------------
442 // Protected
443
444 //-----------------------------------------------------------------------------
445 // Private
446 /**
447  * \brief Read from file a 12 bits per pixel image and decompress it
448  *        into a 16 bits per pixel image.
449  */
450 void PixelReadConvert::ReadAndDecompress12BitsTo16Bits( std::ifstream *fp )
451                throw ( FormatError )
452 {
453    /// \todo Fix the 3D, 4D pb
454    int nbPixels = XSize * YSize * TSize;
455    uint16_t *localDecompres = (uint16_t*)Raw;
456
457    for( int p = 0; p < nbPixels; p += 2 )
458    {
459       uint8_t b0, b1, b2;
460
461       fp->read( (char*)&b0, 1);
462       if ( fp->fail() || fp->eof() )
463       {
464          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
465                                 "Unfound first block" );
466       }
467
468       fp->read( (char*)&b1, 1 );
469       if ( fp->fail() || fp->eof())
470       {
471          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
472                                 "Unfound second block" );
473       }
474
475       fp->read( (char*)&b2, 1 );
476       if ( fp->fail() || fp->eof())
477       {
478          throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
479                                 "Unfound second block" );
480       }
481
482       // Two steps are necessary to please VC++
483       //
484       // 2 pixels 12bit =     [0xABCDEF]
485       // 2 pixels 16bit = [0x0ABD] + [0x0FCE]
486       //                        A                     B                 D
487       *localDecompres++ =  ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
488       //                        F                     C                 E
489       *localDecompres++ =  ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
490
491       /// \todo JPR Troubles expected on Big-Endian processors ?
492    }
493 }
494
495 /**
496  * \brief     Reads from disk the Pixel Data of JPEG Dicom encapsulated
497  *            file and decompress it.
498  * @param     fp File Pointer
499  * @return    Boolean
500  */
501 bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
502 {
503    if ( IsJPEG2000 )
504    {
505      // make sure this is the right JPEG compression
506      assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEGLS );
507      // FIXME this is really ugly but it seems I have to load the complete
508      // jpeg2000 stream to use jasper:
509      // I don't think we'll ever be able to deal with multiple fragments properly
510
511       unsigned long inputlength = 0;
512       JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
513       while( jpegfrag )
514       {
515          inputlength += jpegfrag->GetLength();
516          jpegfrag = JPEGInfo->GetNextFragment();
517       }
518       gdcmAssertMacro( inputlength != 0);
519       uint8_t *inputdata = new uint8_t[inputlength];
520       char *pinputdata = (char*)inputdata;
521       jpegfrag = JPEGInfo->GetFirstFragment();
522       while( jpegfrag )
523       {
524          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
525          fp->read(pinputdata, jpegfrag->GetLength());
526          pinputdata += jpegfrag->GetLength();
527          jpegfrag = JPEGInfo->GetNextFragment();
528       }
529       // Warning the inputdata buffer is delete in the function
530       if ( ! gdcm_read_JPEG2000_file( Raw, 
531           (char*)inputdata, inputlength ) )
532       {
533          return true;
534       }
535       // wow what happen, must be an error
536       gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); 
537       return false;
538    }
539    else if ( IsJPEGLS )
540    {
541      // make sure this is the right JPEG compression
542      assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEG2000 );
543    // WARNING : JPEG-LS is NOT the 'classical' Jpeg Lossless : 
544    // [JPEG-LS is the basis for new lossless/near-lossless compression
545    // standard for continuous-tone images intended for JPEG2000. The standard
546    // is based on the LOCO-I algorithm (LOw COmplexity LOssless COmpression
547    // for Images) developed at Hewlett-Packard Laboratories]
548    //
549    // see http://datacompression.info/JPEGLS.shtml
550    //
551 #if 0
552    std::cerr << "count:" << JPEGInfo->GetFragmentCount() << std::endl;
553       unsigned long inputlength = 0;
554       JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
555       while( jpegfrag )
556       {
557          inputlength += jpegfrag->GetLength();
558          jpegfrag = JPEGInfo->GetNextFragment();
559       }
560       gdcmAssertMacro( inputlength != 0);
561       uint8_t *inputdata = new uint8_t[inputlength];
562       char *pinputdata = (char*)inputdata;
563       jpegfrag = JPEGInfo->GetFirstFragment();
564       while( jpegfrag )
565       {
566          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
567          fp->read(pinputdata, jpegfrag->GetLength());
568          pinputdata += jpegfrag->GetLength();
569          jpegfrag = JPEGInfo->GetNextFragment();
570       }  
571       
572   //fp->read((char*)Raw, PixelDataLength);
573
574   std::ofstream out("/tmp/jpegls.jpg");
575   out.write((char*)inputdata, inputlength);
576   out.close();
577   delete[] inputdata;
578 #endif
579
580       gdcmWarningMacro( "Sorry, JPEG-LS not yet taken into account" );
581       fp->seekg( JPEGInfo->GetFirstFragment()->GetOffset(), std::ios::beg);
582 //    if ( ! gdcm_read_JPEGLS_file( fp,Raw ) )
583          return false;
584    }
585    else
586    {
587      // make sure this is the right JPEG compression
588      assert( !IsJPEGLS || !IsJPEG2000 );
589      // Precompute the offset localRaw will be shifted with
590      int length = XSize * YSize * ZSize * SamplesPerPixel;
591      int numberBytes = BitsAllocated / 8;
592
593      JPEGInfo->DecompressFromFile(fp, Raw, BitsStored, numberBytes, length );
594      return true;
595    }
596 }
597
598 /**
599  * \brief Build Red/Green/Blue/Alpha LUT from File when :
600  *         - (0028,0004) : Photometric Interpretation == [PALETTE COLOR ]
601  *         and
602  *         - (0028,1101),(0028,1102),(0028,1102)
603  *            xxx Palette Color Lookup Table Descriptor are found
604  *          and
605  *         - (0028,1201),(0028,1202),(0028,1202)
606  *           xxx Palette Color Lookup Table Data - are found
607  * \warning does NOT deal with :
608  *   - 0028 1100 Gray Lookup Table Descriptor (Retired)
609  *   - 0028 1221 Segmented Red Palette Color Lookup Table Data
610  *   - 0028 1222 Segmented Green Palette Color Lookup Table Data
611  *   - 0028 1223 Segmented Blue Palette Color Lookup Table Data
612  *   no known Dicom reader deals with them :-(
613  * @return a RGBA Lookup Table
614  */
615 void PixelReadConvert::BuildLUTRGBA()
616 {
617
618    // Note to code reviewers :
619    // The problem is *much more* complicated, since a lot of manufacturers
620    // Don't follow the norm :
621    // have a look at David Clunie's remark at the end of this .cxx file.
622    if ( LutRGBA )
623    
624    {
625       return;
626    }
627    // Not so easy : see
628    // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
629                                                                                 
630    if ( ! IsPaletteColor )
631    {
632       return;
633    }
634                                                                                 
635    if (   LutRedDescriptor   == GDCM_UNFOUND
636        || LutGreenDescriptor == GDCM_UNFOUND
637        || LutBlueDescriptor  == GDCM_UNFOUND )
638    {
639       gdcmWarningMacro( "(At least) a LUT Descriptor is missing" );
640       return;
641    }
642
643    ////////////////////////////////////////////
644    // Extract the info from the LUT descriptors
645    int lengthR;   // Red LUT length in Bytes
646    int debR;      // Subscript of the first Lut Value
647    int nbitsR;    // Lut item size (in Bits)
648    int nbRead;    // nb of items in LUT descriptor (must be = 3)
649
650    nbRead = sscanf( LutRedDescriptor.c_str(),
651                         "%d\\%d\\%d",
652                         &lengthR, &debR, &nbitsR );
653    if ( nbRead != 3 )
654    {
655       gdcmWarningMacro( "Wrong Red LUT descriptor" );
656    }                                                                                
657    int lengthG;  // Green LUT length in Bytes
658    int debG;     // Subscript of the first Lut Value
659    int nbitsG;   // Lut item size (in Bits)
660
661    nbRead = sscanf( LutGreenDescriptor.c_str(),
662                     "%d\\%d\\%d",
663                     &lengthG, &debG, &nbitsG );  
664    if ( nbRead != 3 )
665    {
666       gdcmWarningMacro( "Wrong Green LUT descriptor" );
667    }
668                                                                                 
669    int lengthB;  // Blue LUT length in Bytes
670    int debB;     // Subscript of the first Lut Value
671    int nbitsB;   // Lut item size (in Bits)
672    nbRead = sscanf( LutRedDescriptor.c_str(),
673                     "%d\\%d\\%d",
674                     &lengthB, &debB, &nbitsB );
675    if ( nbRead != 3 )
676    {
677       gdcmWarningMacro( "Wrong Blue LUT descriptor" );
678    }
679  
680    gdcmDebugMacro(" lengthR " << lengthR << " debR " 
681                 << debR << " nbitsR " << nbitsR);
682    gdcmDebugMacro(" lengthG " << lengthG << " debG " 
683                 << debG << " nbitsG " << nbitsG);
684    gdcmDebugMacro(" lengthB " << lengthB << " debB " 
685                 << debB << " nbitsB " << nbitsB);
686
687    if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143
688       lengthR=65536;
689    if ( !lengthG ) // if = 2^16, this shall be 0
690       lengthG=65536;
691    if ( !lengthB ) // if = 2^16, this shall be 0
692       lengthB=65536; 
693                                                                                 
694    ////////////////////////////////////////////////////////
695
696    if ( ( ! LutRedData ) || ( ! LutGreenData ) || ( ! LutBlueData ) )
697    {
698       gdcmWarningMacro( "(At least) a LUT is missing" );
699       return;
700    }
701
702    // -------------------------------------------------------------
703    
704    if ( BitsAllocated <= 8 )
705    {
706       // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT
707       LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha)
708       if ( !LutRGBA )
709          return;
710       LutItemNumber = 256;
711       LutItemSize   = 8;
712       memset( LutRGBA, 0, 1024 );
713                                                                                 
714       int mult;
715       if ( ( nbitsR == 16 ) && ( BitsAllocated == 8 ) )
716       {
717          // when LUT item size is different than pixel size
718          mult = 2; // high byte must be = low byte
719       }
720       else
721       {
722          // See PS 3.3-2003 C.11.1.1.2 p 619
723          mult = 1;
724       }
725                                                                                 
726       // if we get a black image, let's just remove the '+1'
727       // from 'i*mult+1' and check again
728       // if it works, we shall have to check the 3 Palettes
729       // to see which byte is ==0 (first one, or second one)
730       // and fix the code
731       // We give up the checking to avoid some (useless ?) overhead
732       // (optimistic asumption)
733       int i;
734       uint8_t *a;
735
736       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
737
738       //FIXME :  +1 : to get 'low value' byte
739       //         Trouble expected on Big Endian Processors ?
740       //         16 BIts Per Pixel Palette Color to be swapped?
741
742       a = LutRGBA + 0 + debR;
743       for( i=0; i < lengthR; ++i )
744       {
745          *a = LutRedData[i*mult+1]; 
746          a += 4;
747       }
748                                                                                 
749       a = LutRGBA + 1 + debG;
750       for( i=0; i < lengthG; ++i)
751       {
752          *a = LutGreenData[i*mult+1];
753          a += 4;
754       }
755                                                                                 
756       a = LutRGBA + 2 + debB;
757       for(i=0; i < lengthB; ++i)
758       {
759          *a = LutBlueData[i*mult+1];
760          a += 4;
761       }
762                                     
763       a = LutRGBA + 3 ;
764       for(i=0; i < 256; ++i)
765       {
766          *a = 1; // Alpha component
767          a += 4;
768       }
769    }
770    else
771    {
772       // Probabely the same stuff is to be done for 16 Bits Pixels
773       // with 65536 entries LUT ?!?
774       // Still looking for accurate info on the web :-(
775
776       gdcmWarningMacro( "Sorry Palette Color Lookup Tables not yet dealt with"
777                          << " for 16 Bits Per Pixel images" );
778
779       // forge the 4 * 16 Bits Red/Green/Blue/Alpha LUT
780
781       LutRGBA = (uint8_t *)new uint16_t[ 65536*4 ]; // 2^16 * 4 (R, G, B, Alpha)
782       if ( !LutRGBA )
783          return;
784       memset( LutRGBA, 0, 65536*4*2 );  // 16 bits = 2 bytes ;-)
785
786       LutItemNumber = 65536;
787       LutItemSize   = 16;
788
789       int i;
790       uint16_t *a16;
791
792       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
793
794       a16 = (uint16_t*)LutRGBA + 0 + debR;
795       for( i=0; i < lengthR; ++i )
796       {
797          *a16 = ((uint16_t*)LutRedData)[i];
798          a16 += 4;
799       }
800                                                                               
801       a16 = (uint16_t*)LutRGBA + 1 + debG;
802       for( i=0; i < lengthG; ++i)
803       {
804          *a16 = ((uint16_t*)LutGreenData)[i];
805          a16 += 4;
806       }
807                                                                                 
808       a16 = (uint16_t*)LutRGBA + 2 + debB;
809       for(i=0; i < lengthB; ++i)
810       {
811          *a16 = ((uint16_t*)LutBlueData)[i];
812          a16 += 4;
813       }
814                                                                              
815       a16 = (uint16_t*)LutRGBA + 3 ;
816       for(i=0; i < 65536; ++i)
817       {
818          *a16 = 1; // Alpha component
819          a16 += 4;
820       }
821 /* Just to 'see' the LUT, at debug time
822 // Don't remove this commented out code.
823
824       a16=(uint16_t*)LutRGBA;
825       for (int j=0;j<65536;j++)
826       {
827          std::cout << *a16     << " " << *(a16+1) << " "
828                    << *(a16+2) << " " << *(a16+3) << std::endl;
829          a16+=4;
830       }
831 */
832    }
833 }
834
835 /**
836  * \brief Swap the bytes, according to \ref SwapCode.
837  */
838 void PixelReadConvert::ConvertSwapZone()
839 {
840    unsigned int i;
841
842    // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', 
843    // then the header is in little endian format and the pixel data is in 
844    // big endian format.  When reading the header, GDCM has already established
845    // a byte swapping code suitable for this machine to read the
846    // header. In TS::ImplicitVRBigEndianPrivateGE, this code will need
847    // to be switched in order to read the pixel data.  This must be
848    // done REGARDLESS of the processor endianess!
849    //
850    // Example:  Assume we are on a little endian machine.  When
851    // GDCM reads the header, the header will match the machine
852    // endianess and the swap code will be established as a no-op.
853    // When GDCM reaches the pixel data, it will need to switch the
854    // swap code to do big endian to little endian conversion.
855    //
856    // Now, assume we are on a big endian machine.  When GDCM reads the
857    // header, the header will be recognized as a different endianess
858    // than the machine endianess, and a swap code will be established
859    // to convert from little endian to big endian.  When GDCM readers
860    // the pixel data, the pixel data endianess will now match the
861    // machine endianess.  But we currently have a swap code that
862    // converts from little endian to big endian.  In this case, we
863    // need to switch the swap code to a no-op.
864    //
865    // Therefore, in either case, if the file is in
866    // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
867    // the byte swapping code when entering the pixel data.
868    
869    int tempSwapCode = SwapCode;
870    if ( IsPrivateGETransferSyntax )
871    {
872       gdcmWarningMacro(" IsPrivateGETransferSyntax found; turn the SwapCode"); 
873       // PrivateGETransferSyntax only exists for 'true' Dicom images
874       // we assume there is no 'exotic' 32 bits endianess!
875       if (SwapCode == 1234) 
876       {
877          tempSwapCode = 4321;
878       }
879       else if (SwapCode == 4321)
880       {
881          tempSwapCode = 1234;
882       }
883    }
884     
885    if ( BitsAllocated == 16 )
886    {
887       uint16_t *im16 = (uint16_t*)Raw;
888       switch( tempSwapCode )
889       {
890          case 1234:
891             break;
892          case 3412:
893          case 2143:
894          case 4321:
895             for( i = 0; i < RawSize / 2; i++ )
896             {
897                im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
898             }
899             break;
900          default:
901             gdcmWarningMacro("SwapCode value (16 bits) not allowed." 
902                         << tempSwapCode);
903       }
904    }
905    else if ( BitsAllocated == 32 )
906    {
907       uint32_t s32;
908       uint16_t high;
909       uint16_t low;
910       uint32_t *im32 = (uint32_t*)Raw;
911       switch ( tempSwapCode )
912       {
913          case 1234:
914             break;
915          case 4321:
916             for( i = 0; i < RawSize / 4; i++ )
917             {
918                low     = im32[i] & 0x0000ffff;  // 4321
919                high    = im32[i] >> 16;
920                high    = ( high >> 8 ) | ( high << 8 );
921                low     = ( low  >> 8 ) | ( low  << 8 );
922                s32     = low;
923                im32[i] = ( s32 << 16 ) | high;
924             }
925             break;
926          case 2143:
927             for( i = 0; i < RawSize / 4; i++ )
928             {
929                low     = im32[i] & 0x0000ffff;   // 2143
930                high    = im32[i] >> 16;
931                high    = ( high >> 8 ) | ( high << 8 );
932                low     = ( low  >> 8 ) | ( low  << 8 );
933                s32     = high;
934                im32[i] = ( s32 << 16 ) | low;
935             }
936             break;
937          case 3412:
938             for( i = 0; i < RawSize / 4; i++ )
939             {
940                low     = im32[i] & 0x0000ffff; // 3412
941                high    = im32[i] >> 16;
942                s32     = low;
943                im32[i] = ( s32 << 16 ) | high;
944             }
945             break;
946          default:
947             gdcmWarningMacro("SwapCode value (32 bits) not allowed." << tempSwapCode );
948       }
949    }
950 }
951
952 /**
953  * \brief Deal with endianness i.e. re-arange bytes inside the integer
954  */
955 void PixelReadConvert::ConvertReorderEndianity()
956 {
957    if ( BitsAllocated != 8 )
958    {
959       ConvertSwapZone();
960    }
961
962    // Special kludge in order to deal with xmedcon broken images:
963    if ( BitsAllocated == 16
964      && BitsStored < BitsAllocated
965      && !PixelSign )
966    {
967       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
968       uint16_t *deb = (uint16_t *)Raw;
969       for(int i = 0; i<l; i++)
970       {
971          if ( *deb == 0xffff )
972          {
973            *deb = 0;
974          }
975          deb++;
976       }
977    }
978 }
979
980 /**
981  * \brief Deal with Grey levels i.e. re-arange them
982  *        to have low values = dark, high values = bright
983  */
984 void PixelReadConvert::ConvertFixGreyLevels()
985 {
986    if (!IsMonochrome1)
987       return;
988
989    uint32_t i; // to please M$VC6
990    int16_t j;
991
992    if (!PixelSign)
993    {
994       if ( BitsAllocated == 8 )
995       {
996          uint8_t *deb = (uint8_t *)Raw;
997          for (i=0; i<RawSize; i++)      
998          {
999             *deb = 255 - *deb;
1000             deb++;
1001          }
1002          return;
1003       }
1004
1005       if ( BitsAllocated == 16 )
1006       {
1007          uint16_t mask =1;
1008          for (j=0; j<BitsStored-1; j++)
1009          {
1010             mask = (mask << 1) +1; // will be fff when BitsStored=12
1011          }
1012
1013          uint16_t *deb = (uint16_t *)Raw;
1014          for (i=0; i<RawSize/2; i++)      
1015          {
1016             *deb = mask - *deb;
1017             deb++;
1018          }
1019          return;
1020        }
1021    }
1022    else
1023    {
1024       if ( BitsAllocated == 8 )
1025       {
1026          uint8_t smask8 = 255;
1027          uint8_t *deb = (uint8_t *)Raw;
1028          for (i=0; i<RawSize; i++)      
1029          {
1030             *deb = smask8 - *deb;
1031             deb++;
1032          }
1033          return;
1034       }
1035       if ( BitsAllocated == 16 )
1036       {
1037          uint16_t smask16 = 65535;
1038          uint16_t *deb = (uint16_t *)Raw;
1039          for (i=0; i<RawSize/2; i++)      
1040          {
1041             *deb = smask16 - *deb;
1042             deb++;
1043          }
1044          return;
1045       }
1046    }
1047 }
1048
1049 /**
1050  * \brief  Re-arrange the bits within the bytes.
1051  * @return Boolean always true
1052  */
1053 bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError )
1054 {
1055
1056    if ( BitsStored != BitsAllocated )
1057    {
1058       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
1059       if ( BitsAllocated == 16 )
1060       {
1061          // pmask : to mask the 'unused bits' (may contain overlays)
1062          uint16_t pmask = 0xffff;
1063          pmask = pmask >> ( BitsAllocated - BitsStored );
1064
1065          uint16_t *deb = (uint16_t*)Raw;
1066
1067          if ( !PixelSign )  // Pixels are unsigned
1068          {
1069             for(int i = 0; i<l; i++)
1070             {   
1071                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1072                deb++;
1073             }
1074          }
1075          else // Pixels are signed
1076          {
1077             // smask : to check the 'sign' when BitsStored != BitsAllocated
1078             uint16_t smask = 0x0001;
1079             smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) );
1080             // nmask : to propagate sign bit on negative values
1081             int16_t nmask = (int16_t)0x8000;  
1082             nmask = nmask >> ( BitsAllocated - BitsStored - 1 );
1083  
1084             for(int i = 0; i<l; i++)
1085             {
1086                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1087                if ( *deb & smask )
1088                {
1089                   *deb = *deb | nmask;
1090                }
1091                else
1092                {
1093                   *deb = *deb & pmask;
1094                }
1095                deb++;
1096             }
1097          }
1098       }
1099       else if ( BitsAllocated == 32 )
1100       {
1101          // pmask : to mask the 'unused bits' (may contain overlays)
1102          uint32_t pmask = 0xffffffff;
1103          pmask = pmask >> ( BitsAllocated - BitsStored );
1104
1105          uint32_t *deb = (uint32_t*)Raw;
1106
1107          if ( !PixelSign )
1108          {
1109             for(int i = 0; i<l; i++)
1110             {             
1111                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1112                deb++;
1113             }
1114          }
1115          else
1116          {
1117             // smask : to check the 'sign' when BitsStored != BitsAllocated
1118             uint32_t smask = 0x00000001;
1119             smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 ));
1120             // nmask : to propagate sign bit on negative values
1121             int32_t nmask = 0x80000000;   
1122             nmask = nmask >> ( BitsAllocated - BitsStored -1 );
1123
1124             for(int i = 0; i<l; i++)
1125             {
1126                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1127                if ( *deb & smask )
1128                   *deb = *deb | nmask;
1129                else
1130                   *deb = *deb & pmask;
1131                deb++;
1132             }
1133          }
1134       }
1135       else
1136       {
1137          gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)");
1138          throw FormatError( "Weird image !?" );
1139       }
1140    }
1141    return true;
1142 }
1143
1144 /**
1145  * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
1146  * \warning Works on all the frames at a time
1147  */
1148 void PixelReadConvert::ConvertRGBPlanesToRGBPixels()
1149 {
1150    gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels");
1151
1152    uint8_t *localRaw = Raw;
1153    uint8_t *copyRaw = new uint8_t[ RawSize ];
1154    memmove( copyRaw, localRaw, RawSize );
1155
1156    int l = XSize * YSize * ZSize;
1157
1158    uint8_t *a = copyRaw;
1159    uint8_t *b = copyRaw + l;
1160    uint8_t *c = copyRaw + l + l;
1161
1162    for (int j = 0; j < l; j++)
1163    {
1164       *(localRaw++) = *(a++);
1165       *(localRaw++) = *(b++);
1166       *(localRaw++) = *(c++);
1167    }
1168    delete[] copyRaw;
1169 }
1170
1171 /**
1172  * \brief   Convert (cY plane, cB plane, cR plane) to RGB pixels
1173  * \warning Works on all the frames at a time
1174  */
1175 void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels()
1176 {
1177   // Remarks for YBR newbees :
1178   // YBR_FULL works very much like RGB, i.e. three samples per pixel, 
1179   // just the color space is YCbCr instead of RGB. This is particularly useful
1180   // for doppler ultrasound where most of the image is grayscale 
1181   // (i.e. only populates the Y components) and Cb and Cr are mostly zero,
1182   // except for the few patches of color on the image.
1183   // On such images, RLE achieves a compression ratio that is much better 
1184   // than the compression ratio on an equivalent RGB image. 
1185  
1186    gdcmWarningMacro("--> ConvertYcBcRPlanesToRGBPixels");
1187    
1188    uint8_t *localRaw = Raw;
1189    uint8_t *copyRaw = new uint8_t[ RawSize ];
1190    memmove( copyRaw, localRaw, RawSize );
1191
1192    // to see the tricks about YBR_FULL, YBR_FULL_422,
1193    // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
1194    // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
1195    // and be *very* affraid
1196    //
1197    
1198    /// \todo : find an example to see how 3rd dim and 4th dim work together
1199    int l        = XSize * YSize * TSize;
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 * TSize
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 */