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