]> Creatis software - gdcm.git/blob - src/gdcmPixelReadConvert.cxx
avoid Doxygen Warnings
[gdcm.git] / src / gdcmPixelReadConvert.cxx
1 /*=========================================================================
2  
3   Program:   gdcm
4   Module:    $RCSfile: gdcmPixelReadConvert.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/09/17 12:18:25 $
7   Version:   $Revision: 1.123 $
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 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    else if ( BitsAllocated > 8 && BitsAllocated < 16 && BitsAllocated != 12 )
101    {
102       BitsAllocated = 16;
103    }
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      if( ZSize == 1 )
517        {
518        unsigned long inputlength = 0;
519        JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
520        while( jpegfrag )
521          {
522          inputlength += jpegfrag->GetLength();
523          jpegfrag = JPEGInfo->GetNextFragment();
524          }
525        gdcmAssertMacro( inputlength != 0);
526        uint8_t *inputdata = new uint8_t[inputlength];
527        char *pinputdata = (char*)inputdata;
528        jpegfrag = JPEGInfo->GetFirstFragment();
529        while( jpegfrag )
530          {
531          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
532          fp->read(pinputdata, jpegfrag->GetLength());
533          pinputdata += jpegfrag->GetLength();
534          jpegfrag = JPEGInfo->GetNextFragment();
535          }
536        // Warning the inputdata buffer is deleted in the function
537        if ( gdcm_read_JPEG2000_file( Raw,
538            (char*)inputdata, inputlength ) )
539          {
540          return true;
541          }
542        // wow what happen, must be an error
543        gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); 
544        return false;
545        }
546      else
547        {
548        if( (unsigned int)ZSize != JPEGInfo->GetFragmentCount() )
549          {
550          gdcmErrorMacro( "Sorry GDCM does not handle this type of fragments" );
551          return false;
552          }
553        // Hopefully every dicom fragment is *exactly* the j2k stream
554        JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
555        char *praw = (char*)Raw;
556        while( jpegfrag )
557          {
558          unsigned long inputlength = jpegfrag->GetLength();
559          char *inputdata = new char[inputlength];
560          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
561          fp->read(inputdata, jpegfrag->GetLength());
562          // Warning the inputdata buffer is deleted in the function
563          gdcm_read_JPEG2000_file( praw, 
564            inputdata, inputlength) ;
565          praw += XSize*YSize*SamplesPerPixel*(BitsAllocated/8);
566          jpegfrag = JPEGInfo->GetNextFragment();
567          }
568        return true;
569        }
570    }
571    else if ( IsJPEGLS )
572    {
573      // make sure this is the right JPEG compression
574      assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEG2000 );
575    // WARNING : JPEG-LS is NOT the 'classical' Jpeg Lossless : 
576    // [JPEG-LS is the basis for new lossless/near-lossless compression
577    // standard for continuous-tone images intended for JPEG2000. The standard
578    // is based on the LOCO-I algorithm (LOw COmplexity LOssless COmpression
579    // for Images) developed at Hewlett-Packard Laboratories]
580    //
581    // see http://datacompression.info/JPEGLS.shtml
582    //
583 #if 0
584    std::cerr << "count:" << JPEGInfo->GetFragmentCount() << std::endl;
585       unsigned long inputlength = 0;
586       JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
587       while( jpegfrag )
588       {
589          inputlength += jpegfrag->GetLength();
590          jpegfrag = JPEGInfo->GetNextFragment();
591       }
592       gdcmAssertMacro( inputlength != 0);
593       uint8_t *inputdata = new uint8_t[inputlength];
594       char *pinputdata = (char*)inputdata;
595       jpegfrag = JPEGInfo->GetFirstFragment();
596       while( jpegfrag )
597       {
598          fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
599          fp->read(pinputdata, jpegfrag->GetLength());
600          pinputdata += jpegfrag->GetLength();
601          jpegfrag = JPEGInfo->GetNextFragment();
602       }  
603       
604   //fp->read((char*)Raw, PixelDataLength);
605
606   std::ofstream out("/tmp/jpegls.jpg");
607   out.write((char*)inputdata, inputlength);
608   out.close();
609   delete[] inputdata;
610 #endif
611
612       gdcmWarningMacro( "Sorry, JPEG-LS not yet taken into account" );
613       fp->seekg( JPEGInfo->GetFirstFragment()->GetOffset(), std::ios::beg);
614 //    if ( ! gdcm_read_JPEGLS_file( fp,Raw ) )
615          return false;
616    }
617    else
618    {
619      // make sure this is the right JPEG compression
620      assert( !IsJPEGLS || !IsJPEG2000 );
621      // Precompute the offset localRaw will be shifted with
622      int length = XSize * YSize * ZSize * SamplesPerPixel;
623      int numberBytes = BitsAllocated / 8;
624
625       // to avoid major troubles when BitsStored == 8 && BitsAllocated==16 !
626      int dummy;
627      if (BitsStored == 8 && BitsAllocated==16)
628         dummy = 16;
629      else
630         dummy = BitsStored;
631      JPEGInfo->DecompressFromFile(fp, Raw, dummy, numberBytes, length );
632      return true;
633    }
634 }
635
636 /**
637  * \brief Build Red/Green/Blue/Alpha LUT from File when :
638  *         - (0028,0004) : Photometric Interpretation == [PALETTE COLOR ]
639  *         and
640  *         - (0028,1101),(0028,1102),(0028,1102)
641  *            xxx Palette Color Lookup Table Descriptor are found
642  *          and
643  *         - (0028,1201),(0028,1202),(0028,1202)
644  *           xxx Palette Color Lookup Table Data - are found
645  * \warning does NOT deal with :
646  *   - 0028 1100 Gray Lookup Table Descriptor (Retired)
647  *   - 0028 1221 Segmented Red Palette Color Lookup Table Data
648  *   - 0028 1222 Segmented Green Palette Color Lookup Table Data
649  *   - 0028 1223 Segmented Blue Palette Color Lookup Table Data
650  *   no known Dicom reader deals with them :-(
651  * @return a RGBA Lookup Table
652  */
653 void PixelReadConvert::BuildLUTRGBA()
654 {
655
656    // Note to code reviewers :
657    // The problem is *much more* complicated, since a lot of manufacturers
658    // Don't follow the norm :
659    // have a look at David Clunie's remark at the end of this .cxx file.
660    if ( LutRGBA )
661    
662    {
663       return;
664    }
665    // Not so easy : see
666    // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
667                                                                                 
668    if ( ! IsPaletteColor )
669    {
670       return;
671    }
672                                                                                 
673    if (   LutRedDescriptor   == GDCM_UNFOUND
674        || LutGreenDescriptor == GDCM_UNFOUND
675        || LutBlueDescriptor  == GDCM_UNFOUND )
676    {
677       gdcmWarningMacro( "(At least) a LUT Descriptor is missing" );
678       return;
679    }
680
681    ////////////////////////////////////////////
682    // Extract the info from the LUT descriptors
683    int lengthR;   // Red LUT length in Bytes
684    int debR;      // Subscript of the first Lut Value
685    int nbitsR;    // Lut item size (in Bits)
686    int nbRead;    // nb of items in LUT descriptor (must be = 3)
687
688    nbRead = sscanf( LutRedDescriptor.c_str(),
689                         "%d\\%d\\%d",
690                         &lengthR, &debR, &nbitsR );
691    if ( nbRead != 3 )
692    {
693       gdcmWarningMacro( "Wrong Red LUT descriptor" );
694    }                                                                                
695    int lengthG;  // Green LUT length in Bytes
696    int debG;     // Subscript of the first Lut Value
697    int nbitsG;   // Lut item size (in Bits)
698
699    nbRead = sscanf( LutGreenDescriptor.c_str(),
700                     "%d\\%d\\%d",
701                     &lengthG, &debG, &nbitsG );  
702    if ( nbRead != 3 )
703    {
704       gdcmWarningMacro( "Wrong Green LUT descriptor" );
705    }
706                                                                                 
707    int lengthB;  // Blue LUT length in Bytes
708    int debB;     // Subscript of the first Lut Value
709    int nbitsB;   // Lut item size (in Bits)
710    nbRead = sscanf( LutRedDescriptor.c_str(),
711                     "%d\\%d\\%d",
712                     &lengthB, &debB, &nbitsB );
713    if ( nbRead != 3 )
714    {
715       gdcmWarningMacro( "Wrong Blue LUT descriptor" );
716    }
717  
718    gdcmDebugMacro(" lengthR " << lengthR << " debR " 
719                 << debR << " nbitsR " << nbitsR);
720    gdcmDebugMacro(" lengthG " << lengthG << " debG " 
721                 << debG << " nbitsG " << nbitsG);
722    gdcmDebugMacro(" lengthB " << lengthB << " debB " 
723                 << debB << " nbitsB " << nbitsB);
724
725    if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143
726       lengthR=65536;
727    if ( !lengthG ) // if = 2^16, this shall be 0
728       lengthG=65536;
729    if ( !lengthB ) // if = 2^16, this shall be 0
730       lengthB=65536; 
731                                                                                 
732    ////////////////////////////////////////////////////////
733
734    if ( ( ! LutRedData ) || ( ! LutGreenData ) || ( ! LutBlueData ) )
735    {
736       gdcmWarningMacro( "(At least) a LUT is missing" );
737       return;
738    }
739
740    // -------------------------------------------------------------
741    
742    if ( BitsAllocated <= 8 )
743    {
744       // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT
745       LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha)
746       if ( !LutRGBA )
747          return;
748       LutItemNumber = 256;
749       LutItemSize   = 8;
750       memset( LutRGBA, 0, 1024 );
751                                                                                 
752       int mult;
753       if ( ( nbitsR == 16 ) && ( BitsAllocated == 8 ) )
754       {
755          // when LUT item size is different than pixel size
756          mult = 2; // high byte must be = low byte
757       }
758       else
759       {
760          // See PS 3.3-2003 C.11.1.1.2 p 619
761          mult = 1;
762       }
763                                                                                 
764       // if we get a black image, let's just remove the '+1'
765       // from 'i*mult+1' and check again
766       // if it works, we shall have to check the 3 Palettes
767       // to see which byte is ==0 (first one, or second one)
768       // and fix the code
769       // We give up the checking to avoid some (useless ?) overhead
770       // (optimistic asumption)
771       int i;
772       uint8_t *a;
773
774       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
775
776       //FIXME :  +1 : to get 'low value' byte
777       //         Trouble expected on Big Endian Processors ?
778       //         16 BIts Per Pixel Palette Color to be swapped?
779
780       a = LutRGBA + 0 + debR;
781       for( i=0; i < lengthR; ++i )
782       {
783          *a = LutRedData[i*mult+1]; 
784          a += 4;
785       }
786                                                                                 
787       a = LutRGBA + 1 + debG;
788       for( i=0; i < lengthG; ++i)
789       {
790          *a = LutGreenData[i*mult+1];
791          a += 4;
792       }
793                                                                                 
794       a = LutRGBA + 2 + debB;
795       for(i=0; i < lengthB; ++i)
796       {
797          *a = LutBlueData[i*mult+1];
798          a += 4;
799       }
800                                     
801       a = LutRGBA + 3 ;
802       for(i=0; i < 256; ++i)
803       {
804          *a = 1; // Alpha component
805          a += 4;
806       }
807    }
808    else
809    {
810       // Probabely the same stuff is to be done for 16 Bits Pixels
811       // with 65536 entries LUT ?!?
812       // Still looking for accurate info on the web :-(
813
814       gdcmWarningMacro( "Sorry Palette Color Lookup Tables not yet dealt with"
815                          << " for 16 Bits Per Pixel images" );
816
817       // forge the 4 * 16 Bits Red/Green/Blue/Alpha LUT
818
819       LutRGBA = (uint8_t *)new uint16_t[ 65536*4 ]; // 2^16 * 4 (R, G, B, Alpha)
820       if ( !LutRGBA )
821          return;
822       memset( LutRGBA, 0, 65536*4*2 );  // 16 bits = 2 bytes ;-)
823
824       LutItemNumber = 65536;
825       LutItemSize   = 16;
826
827       int i;
828       uint16_t *a16;
829
830       //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
831
832       a16 = (uint16_t*)LutRGBA + 0 + debR;
833       for( i=0; i < lengthR; ++i )
834       {
835          *a16 = ((uint16_t*)LutRedData)[i];
836          a16 += 4;
837       }
838                                                                               
839       a16 = (uint16_t*)LutRGBA + 1 + debG;
840       for( i=0; i < lengthG; ++i)
841       {
842          *a16 = ((uint16_t*)LutGreenData)[i];
843          a16 += 4;
844       }
845                                                                                 
846       a16 = (uint16_t*)LutRGBA + 2 + debB;
847       for(i=0; i < lengthB; ++i)
848       {
849          *a16 = ((uint16_t*)LutBlueData)[i];
850          a16 += 4;
851       }
852                                                                              
853       a16 = (uint16_t*)LutRGBA + 3 ;
854       for(i=0; i < 65536; ++i)
855       {
856          *a16 = 1; // Alpha component
857          a16 += 4;
858       }
859 /* Just to 'see' the LUT, at debug time
860 // Don't remove this commented out code.
861
862       a16=(uint16_t*)LutRGBA;
863       for (int j=0;j<65536;j++)
864       {
865          std::cout << *a16     << " " << *(a16+1) << " "
866                    << *(a16+2) << " " << *(a16+3) << std::endl;
867          a16+=4;
868       }
869 */
870    }
871 }
872
873 /**
874  * \brief Swap the bytes, according to SwapCode.
875  */
876 void PixelReadConvert::ConvertSwapZone()
877 {
878    unsigned int i;
879
880    // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', 
881    // then the header is in little endian format and the pixel data is in 
882    // big endian format.  When reading the header, GDCM has already established
883    // a byte swapping code suitable for this machine to read the
884    // header. In TS::ImplicitVRBigEndianPrivateGE, this code will need
885    // to be switched in order to read the pixel data.  This must be
886    // done REGARDLESS of the processor endianess!
887    //
888    // Example:  Assume we are on a little endian machine.  When
889    // GDCM reads the header, the header will match the machine
890    // endianess and the swap code will be established as a no-op.
891    // When GDCM reaches the pixel data, it will need to switch the
892    // swap code to do big endian to little endian conversion.
893    //
894    // Now, assume we are on a big endian machine.  When GDCM reads the
895    // header, the header will be recognized as a different endianess
896    // than the machine endianess, and a swap code will be established
897    // to convert from little endian to big endian.  When GDCM readers
898    // the pixel data, the pixel data endianess will now match the
899    // machine endianess.  But we currently have a swap code that
900    // converts from little endian to big endian.  In this case, we
901    // need to switch the swap code to a no-op.
902    //
903    // Therefore, in either case, if the file is in
904    // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
905    // the byte swapping code when entering the pixel data.
906    
907    int tempSwapCode = SwapCode;
908    if ( IsPrivateGETransferSyntax )
909    {
910       gdcmWarningMacro(" IsPrivateGETransferSyntax found; turn the SwapCode"); 
911       // PrivateGETransferSyntax only exists for 'true' Dicom images
912       // we assume there is no 'exotic' 32 bits endianess!
913       if (SwapCode == 1234) 
914       {
915          tempSwapCode = 4321;
916       }
917       else if (SwapCode == 4321)
918       {
919          tempSwapCode = 1234;
920       }
921    }
922     
923    if ( BitsAllocated == 16 )
924    {
925       uint16_t *im16 = (uint16_t*)Raw;
926       switch( tempSwapCode )
927       {
928          case 1234:
929             break;
930          case 3412:
931          case 2143:
932          case 4321:
933             for( i = 0; i < RawSize / 2; i++ )
934             {
935                im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
936             }
937             break;
938          default:
939             gdcmWarningMacro("SwapCode value (16 bits) not allowed." 
940                         << tempSwapCode);
941       }
942    }
943    else if ( BitsAllocated == 32 )
944    {
945       uint32_t s32;
946       uint16_t high;
947       uint16_t low;
948       uint32_t *im32 = (uint32_t*)Raw;
949       switch ( tempSwapCode )
950       {
951          case 1234:
952             break;
953          case 4321:
954             for( i = 0; i < RawSize / 4; i++ )
955             {
956                low     = im32[i] & 0x0000ffff;  // 4321
957                high    = im32[i] >> 16;
958                high    = ( high >> 8 ) | ( high << 8 );
959                low     = ( low  >> 8 ) | ( low  << 8 );
960                s32     = low;
961                im32[i] = ( s32 << 16 ) | high;
962             }
963             break;
964          case 2143:
965             for( i = 0; i < RawSize / 4; i++ )
966             {
967                low     = im32[i] & 0x0000ffff;   // 2143
968                high    = im32[i] >> 16;
969                high    = ( high >> 8 ) | ( high << 8 );
970                low     = ( low  >> 8 ) | ( low  << 8 );
971                s32     = high;
972                im32[i] = ( s32 << 16 ) | low;
973             }
974             break;
975          case 3412:
976             for( i = 0; i < RawSize / 4; i++ )
977             {
978                low     = im32[i] & 0x0000ffff; // 3412
979                high    = im32[i] >> 16;
980                s32     = low;
981                im32[i] = ( s32 << 16 ) | high;
982             }
983             break;
984          default:
985             gdcmWarningMacro("SwapCode value (32 bits) not allowed." << tempSwapCode );
986       }
987    }
988 }
989
990 /**
991  * \brief Deal with endianness i.e. re-arange bytes inside the integer
992  */
993 void PixelReadConvert::ConvertReorderEndianity()
994 {
995    if ( BitsAllocated != 8 )
996    {
997       ConvertSwapZone();
998    }
999
1000    // Special kludge in order to deal with xmedcon broken images:
1001    if ( BitsAllocated == 16
1002      && BitsStored < BitsAllocated
1003      && !PixelSign )
1004    {
1005       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
1006       uint16_t *deb = (uint16_t *)Raw;
1007       for(int i = 0; i<l; i++)
1008       {
1009          if ( *deb == 0xffff )
1010          {
1011            *deb = 0;
1012          }
1013          deb++;
1014       }
1015    }
1016 }
1017
1018 /**
1019  * \brief Deal with Grey levels i.e. re-arange them
1020  *        to have low values = dark, high values = bright
1021  */
1022 void PixelReadConvert::ConvertFixGreyLevels()
1023 {
1024    if (!IsMonochrome1)
1025       return;
1026
1027    uint32_t i; // to please M$VC6
1028    int16_t j;
1029
1030    if (!PixelSign)
1031    {
1032       if ( BitsAllocated == 8 )
1033       {
1034          uint8_t *deb = (uint8_t *)Raw;
1035          for (i=0; i<RawSize; i++)      
1036          {
1037             *deb = 255 - *deb;
1038             deb++;
1039          }
1040          return;
1041       }
1042
1043       if ( BitsAllocated == 16 )
1044       {
1045          uint16_t mask =1;
1046          for (j=0; j<BitsStored-1; j++)
1047          {
1048             mask = (mask << 1) +1; // will be fff when BitsStored=12
1049          }
1050
1051          uint16_t *deb = (uint16_t *)Raw;
1052          for (i=0; i<RawSize/2; i++)      
1053          {
1054             *deb = mask - *deb;
1055             deb++;
1056          }
1057          return;
1058        }
1059    }
1060    else
1061    {
1062       if ( BitsAllocated == 8 )
1063       {
1064          uint8_t smask8 = 255;
1065          uint8_t *deb = (uint8_t *)Raw;
1066          for (i=0; i<RawSize; i++)      
1067          {
1068             *deb = smask8 - *deb;
1069             deb++;
1070          }
1071          return;
1072       }
1073       if ( BitsAllocated == 16 )
1074       {
1075          uint16_t smask16 = 65535;
1076          uint16_t *deb = (uint16_t *)Raw;
1077          for (i=0; i<RawSize/2; i++)      
1078          {
1079             *deb = smask16 - *deb;
1080             deb++;
1081          }
1082          return;
1083       }
1084    }
1085 }
1086
1087 /**
1088  * \brief  Re-arrange the bits within the bytes.
1089  * @return Boolean always true
1090  */
1091 bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError )
1092 {
1093
1094    if ( BitsStored != BitsAllocated )
1095    {
1096       int l = (int)( RawSize / ( BitsAllocated / 8 ) );
1097       if ( BitsAllocated == 16 )
1098       {
1099          // pmask : to mask the 'unused bits' (may contain overlays)
1100          uint16_t pmask = 0xffff;
1101
1102          // It's up to the user to decide if he wants to ignore overlays (if any),
1103          // not to gdcm, without asking.
1104          // default is NOT TO LOAD, in order not to confuse ITK users (and others!).
1105
1106          if ( !FH->GetKeepOverlays() ) // mask spurious bits ! (overlay are NOT loaded!)
1107          {
1108             pmask = pmask >> ( BitsAllocated - BitsStored );
1109          }
1110          // else : it's up to the user to manage the 'pixels + overlays' he just loaded!
1111
1112          uint16_t *deb = (uint16_t*)Raw;
1113
1114          if ( !PixelSign )  // Pixels are unsigned
1115          {
1116             for(int i = 0; i<l; i++)
1117             {  
1118                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1119                deb++;
1120             }
1121          }
1122          else // Pixels are signed
1123          {
1124             // Hope there is never ACR-NEMA-like overlays within signed pixels (?!?)
1125
1126             // smask : to check the 'sign' when BitsStored != BitsAllocated
1127             uint16_t smask = 0x0001;
1128             smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) );
1129             // nmask : to propagate sign bit on negative values
1130             int16_t nmask = (int16_t)0x8000;  
1131             nmask = nmask >> ( BitsAllocated - BitsStored - 1 );
1132
1133             for(int i = 0; i<l; i++)
1134             {
1135                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1136                if ( *deb & smask )
1137                {
1138                   *deb = *deb | nmask;
1139                }
1140                else
1141                {
1142                   *deb = *deb & pmask;
1143                }
1144                deb++;
1145             }
1146          }
1147       }
1148       else if ( BitsAllocated == 32 )
1149       {
1150          // pmask : to mask the 'unused bits' (may contain overlays)
1151          uint32_t pmask = 0xffffffff;
1152          pmask = pmask >> ( BitsAllocated - BitsStored );
1153
1154          uint32_t *deb = (uint32_t*)Raw;
1155
1156          if ( !PixelSign )
1157          {
1158             for(int i = 0; i<l; i++)
1159             {             
1160                *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1161                deb++;
1162             }
1163          }
1164          else
1165          {
1166             // smask : to check the 'sign' when BitsStored != BitsAllocated
1167             uint32_t smask = 0x00000001;
1168             smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 ));
1169             // nmask : to propagate sign bit on negative values
1170             int32_t nmask = 0x80000000;   
1171             nmask = nmask >> ( BitsAllocated - BitsStored -1 );
1172
1173             for(int i = 0; i<l; i++)
1174             {
1175                *deb = *deb >> (BitsStored - HighBitPosition - 1);
1176                if ( *deb & smask )
1177                   *deb = *deb | nmask;
1178                else
1179                   *deb = *deb & pmask;
1180                deb++;
1181             }
1182          }
1183       }
1184       else
1185       {
1186          gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)");
1187          throw FormatError( "Weird image !?" );
1188       }
1189    }
1190    return true;
1191 }
1192
1193 /**
1194  * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
1195  * \warning Works on all the frames at a time
1196  */
1197 void PixelReadConvert::ConvertRGBPlanesToRGBPixels()
1198 {
1199    gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels");
1200
1201    uint8_t *localRaw = Raw;
1202    uint8_t *copyRaw = new uint8_t[ RawSize ];
1203    memmove( copyRaw, localRaw, RawSize );
1204
1205    int l = XSize * YSize * ZSize;
1206
1207    uint8_t *a = copyRaw;
1208    uint8_t *b = copyRaw + l;
1209    uint8_t *c = copyRaw + l + l;
1210
1211    for (int j = 0; j < l; j++)
1212    {
1213       *(localRaw++) = *(a++);
1214       *(localRaw++) = *(b++);
1215       *(localRaw++) = *(c++);
1216    }
1217    delete[] copyRaw;
1218 }
1219
1220 /**
1221  * \brief   Convert (cY plane, cB plane, cR plane) to RGB pixels
1222  * \warning Works on all the frames at a time
1223  */
1224 void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels()
1225 {
1226   // Remarks for YBR newbees :
1227   // YBR_FULL works very much like RGB, i.e. three samples per pixel, 
1228   // just the color space is YCbCr instead of RGB. This is particularly useful
1229   // for doppler ultrasound where most of the image is grayscale 
1230   // (i.e. only populates the Y components) and Cb and Cr are mostly zero,
1231   // except for the few patches of color on the image.
1232   // On such images, RLE achieves a compression ratio that is much better 
1233   // than the compression ratio on an equivalent RGB image. 
1234
1235    gdcmWarningMacro("--> ConvertYcBcRPlanesToRGBPixels");
1236
1237    uint8_t *localRaw = Raw;
1238    uint8_t *copyRaw = new uint8_t[ RawSize ];
1239    memmove( copyRaw, localRaw, RawSize );
1240
1241    // to see the tricks about YBR_FULL, YBR_FULL_422,
1242    // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
1243    // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
1244    // and be *very* affraid
1245    //
1246
1247    /// \todo : find an example to see how 3rd dim and 4th dim work together
1248    int l        = XSize * YSize * TSize;
1249    int nbFrames = ZSize;
1250
1251    uint8_t *a = copyRaw + 0;
1252    uint8_t *b = copyRaw + l;
1253    uint8_t *c = copyRaw + l+ l;
1254    int32_t R, G, B;
1255
1256    ///  We replaced easy to understand but time consuming floating point
1257    ///  computations by the 'well known' integer computation counterpart
1258    ///  Refer to :
1259    ///            http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
1260    ///  for code optimisation.
1261
1262    for ( int i = 0; i < nbFrames; i++ )
1263    {
1264       for ( int j = 0; j < l; j++ )
1265       {
1266          R = 38142 *(*a-16) + 52298 *(*c -128);
1267          G = 38142 *(*a-16) - 26640 *(*c -128) - 12845 *(*b -128);
1268          B = 38142 *(*a-16) + 66093 *(*b -128);
1269
1270          R = (R+16384)>>15;
1271          G = (G+16384)>>15;
1272          B = (B+16384)>>15;
1273
1274          if (R < 0)   R = 0;
1275          if (G < 0)   G = 0;
1276          if (B < 0)   B = 0;
1277          if (R > 255) R = 255;
1278          if (G > 255) G = 255;
1279          if (B > 255) B = 255;
1280
1281          *(localRaw++) = (uint8_t)R;
1282          *(localRaw++) = (uint8_t)G;
1283          *(localRaw++) = (uint8_t)B;
1284          a++;
1285          b++;
1286          c++;
1287       }
1288    }
1289    delete[] copyRaw;
1290 }
1291
1292 /// \brief Deals with the color decoding i.e. handle:
1293 ///   - R, G, B planes (as opposed to RGB pixels)
1294 ///   - YBR (various) encodings.
1295 ///   - LUT[s] (or "PALETTE COLOR").
1296
1297 void PixelReadConvert::ConvertHandleColor()
1298 {
1299    //////////////////////////////////
1300    // Deal with the color decoding i.e. handle:
1301    //   - R, G, B planes (as opposed to RGB pixels)
1302    //   - YBR (various) encodings.
1303    //   - LUT[s] (or "PALETTE COLOR").
1304    //
1305    // The classification in the color decoding schema is based on the blending
1306    // of two Dicom tags values:
1307    // * "Photometric Interpretation" for which we have the cases:
1308    //  - [Photo A] MONOCHROME[1|2] pictures,
1309    //  - [Photo B] RGB or YBR_FULL_422 (which acts as RGB),
1310    //  - [Photo C] YBR_* (with the above exception of YBR_FULL_422)
1311    //  - [Photo D] "PALETTE COLOR" which indicates the presence of LUT[s].
1312    // * "Planar Configuration" for which we have the cases:
1313    //  - [Planar 0] 0 then Pixels are already RGB
1314    //  - [Planar 1] 1 then we have 3 planes : R, G, B,
1315    //  - [Planar 2] 2 then we have 1 gray Plane and 3 LUTs
1316    //
1317    // Now in theory, one could expect some coherence when blending the above
1318    // cases. For example we should not encounter files belonging at the
1319    // time to case [Planar 0] and case [Photo D].
1320    // Alas, this was only theory ! Because in practice some odd (read ill
1321    // formated Dicom) files (e.g. gdcmData/US-PAL-8-10x-echo.dcm) we encounter:
1322    //     - "Planar Configuration" = 0,
1323    //     - "Photometric Interpretation" = "PALETTE COLOR".
1324    // Hence gdcm will use the folowing "heuristic" in order to be tolerant
1325    // towards Dicom-non-conformant files:
1326    //   << whatever the "Planar Configuration" value might be, a
1327    //      "Photometric Interpretation" set to "PALETTE COLOR" forces
1328    //      a LUT intervention >>
1329    //
1330    // Now we are left with the following handling of the cases:
1331    // - [Planar 0] OR  [Photo A] no color decoding (since respectively
1332    //       Pixels are already RGB and monochrome pictures have no color :),
1333    // - [Planar 1] AND [Photo B] handled with ConvertRGBPlanesToRGBPixels()
1334    // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels()
1335    // - [Planar 2] OR  [Photo D] requires LUT intervention.
1336
1337    gdcmDebugMacro("--> ConvertHandleColor "
1338                      << "Planar Configuration " << PlanarConfiguration );
1339
1340    if ( ! IsRawRGB() )
1341    {
1342       // [Planar 2] OR  [Photo D]: LUT intervention done outside
1343       gdcmDebugMacro("--> RawRGB : LUT intervention done outside");
1344       return;
1345    }
1346                                                                                 
1347    if ( PlanarConfiguration == 1 )
1348    {
1349       if ( IsYBRFull )
1350       {
1351          // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB)
1352          gdcmDebugMacro("--> YBRFull");
1353          ConvertYcBcRPlanesToRGBPixels();
1354       }
1355       else
1356       {
1357          // [Planar 1] AND [Photo C]
1358          gdcmDebugMacro("--> YBRFull");
1359          ConvertRGBPlanesToRGBPixels();
1360       }
1361       return;
1362    }
1363                                                                                 
1364    // When planarConf is 0, and RLELossless (forbidden by Dicom norm)
1365    // pixels need to be RGB-fyied anyway
1366
1367    if (IsRLELossless)
1368    { 
1369      gdcmDebugMacro("--> RLE Lossless");
1370      ConvertRGBPlanesToRGBPixels();
1371    }
1372
1373    // In *normal *case, when planarConf is 0, pixels are already in RGB
1374 }
1375
1376 /// Computes the Pixels Size
1377 void PixelReadConvert::ComputeRawAndRGBSizes()
1378 {
1379    int bitsAllocated = BitsAllocated;
1380    // Number of "Bits Allocated" is fixed to 16 when it's 12, since
1381    // in this case we will expand the image to 16 bits (see
1382    //    ReadAndDecompress12BitsTo16Bits() )
1383    if (  BitsAllocated == 12 )
1384    {
1385       bitsAllocated = 16;
1386    }
1387                                                                                 
1388    RawSize =  XSize * YSize * ZSize * TSize
1389                      * ( bitsAllocated / 8 )
1390                      * SamplesPerPixel;
1391    if ( HasLUT )
1392    {
1393       RGBSize = 3 * RawSize; // works for 8 and 16 bits per Pixel
1394    }
1395    else
1396    {
1397       RGBSize = RawSize;
1398    }
1399    RawSize += RawSize%2;
1400    RGBSize += RGBSize%2;
1401 }
1402
1403 /// Allocates room for RGB Pixels
1404 void PixelReadConvert::AllocateRGB()
1405 {
1406   if ( RGB )
1407      delete [] RGB;
1408   RGB = new uint8_t[RGBSize];
1409 }
1410
1411 /// Allocates room for RAW Pixels
1412 void PixelReadConvert::AllocateRaw()
1413 {
1414   if ( Raw )
1415      delete [] Raw;
1416   Raw = new uint8_t[RawSize];
1417 }
1418
1419 //-----------------------------------------------------------------------------
1420 // Print
1421 /**
1422  * \brief        Print self.
1423  * @param indent Indentation string to be prepended during printing.
1424  * @param os     Stream to print to.
1425  */
1426 void PixelReadConvert::Print( std::ostream &os, std::string const &indent )
1427 {
1428    os << indent
1429       << "--- Pixel information -------------------------"
1430       << std::endl;
1431    os << indent
1432       << "Pixel Data: offset " << PixelOffset
1433       << " x(" << std::hex << PixelOffset << std::dec
1434       << ")   length " << PixelDataLength
1435       << " x(" << std::hex << PixelDataLength << std::dec
1436       << ")" << std::endl;
1437
1438    if ( IsRLELossless )
1439    {
1440       if ( RLEInfo )
1441       {
1442          RLEInfo->Print( os, indent );
1443       }
1444       else
1445       {
1446          gdcmWarningMacro("Set as RLE file but NO RLEinfo present.");
1447       }
1448    }
1449
1450    if ( IsJPEG2000 || IsJPEGLossless || IsJPEGLossy || IsJPEGLS )
1451    {
1452       if ( JPEGInfo )
1453       {
1454          JPEGInfo->Print( os, indent );
1455       }
1456       else
1457       {
1458          gdcmWarningMacro("Set as JPEG file but NO JPEGinfo present.");
1459       }
1460    }
1461 }
1462
1463 /**
1464  * \brief   CallStartMethod
1465  */
1466 void PixelReadConvert::CallStartMethod()
1467 {
1468    Progress = 0.0f;
1469    Abort    = false;
1470    CommandManager::ExecuteCommand(FH,CMD_STARTPROGRESS);
1471 }
1472
1473 /**
1474  * \brief   CallProgressMethod
1475  */
1476 void PixelReadConvert::CallProgressMethod()
1477 {
1478    CommandManager::ExecuteCommand(FH,CMD_PROGRESS);
1479 }
1480
1481 /**
1482  * \brief   CallEndMethod
1483  */
1484 void PixelReadConvert::CallEndMethod()
1485 {
1486    Progress = 1.0f;
1487    CommandManager::ExecuteCommand(FH,CMD_ENDPROGRESS);
1488 }
1489
1490 //-----------------------------------------------------------------------------
1491 } // end namespace gdcm
1492
1493 // Note to developpers :
1494 // Here is a very detailled post from David Clunie, on the troubles caused 
1495 // 'non standard' LUT and LUT description
1496 // We shall have to take it into accound in our code.
1497 // Some day ...
1498
1499
1500 /*
1501 Subject: Problem with VOI LUTs in Agfa and Fuji CR and GE DX images, was Re: VOI LUT issues
1502 Date: Sun, 06 Feb 2005 17:13:40 GMT
1503 From: David Clunie <dclunie@dclunie.com>
1504 Reply-To: dclunie@dclunie.com
1505 Newsgroups: comp.protocols.dicom
1506 References: <1107553502.040221.189550@o13g2000cwo.googlegroups.com>
1507
1508 > THE LUT that comes with [my] image claims to be 16-bit, but none of the
1509 > values goes higher than 4095.  That being said, though, none of my
1510 > original pixel values goes higher than that, either.  I have read
1511 > elsewhere on this group that when that happens you are supposed to
1512 > adjust the LUT.  Can someone be more specific?  There was a thread from
1513 > 2002 where Marco and David were mentioning doing precisely that.
1514 >
1515 > Thanks
1516 >
1517 > -carlos rodriguez
1518
1519
1520 You have encountered the well known "we know what the standard says but
1521 we are going to ignore it and do what we have been doing for almost
1522 a decade regardless" CR vendor bug. Agfa started this, but they are not
1523 the only vendor doing this now; GE and Fuji may have joined the club.
1524
1525 Sadly, one needs to look at the LUT Data, figure out what the maximum
1526 value actually encoded is, and find the next highest power of 2 (e.g.
1527 212 in this case), to figure out what the range of the data is
1528 supposed to be. I have assumed that if the maximum value in the LUT
1529 data is less than a power of 2 minus 1 (e.g. 0xebc) then the intent
1530 of the vendor was not to use the maximum available grayscale range
1531 of the display (e.g. the maximum is 0xfff in this case). An alternative
1532 would be to scale to the actual maximum rather than a power of two.
1533
1534 Very irritating, and in theory not totally reliable if one really
1535 intended the full 16 bits and only used, say 15, but that is extremely
1536 unlikely since everything would be too dark, and this heuristic
1537 seems to work OK.
1538
1539 There has never been anything in the standard that describes having
1540 to go through these convolutions. Since the only value in the
1541 standard that describes the bit depth of the LUT values is LUT
1542 Descriptor value 3 and that is (usually) always required to be
1543 either 8 or 16, it mystifies me how the creators' of these images
1544 imagine that the receiver is going to divine the range that is intended. Further, the standard is quite explicit that this 3rd
1545 value defines the range of LUT values, but as far as I am aware, all
1546 the vendors are ignoring the standard and indeed sending a third value
1547 of 16 in all cases.
1548
1549 This problem is not confined to CR, and is also seen with DX products.
1550
1551 Typically I have seen:
1552
1553 - Agfa CR, which usually (always ?) sends LUTs, values up to 0x0fff
1554 - Fuji CR, which occasionally send LUTs, values up to 0x03ff
1555 - GE DX, for presentation, which always have LUTs, up to 0x3fff
1556
1557 Swissray, Siemens, Philips, Canon and Kodak never seem to send VOI LUTs
1558 at this point (which is a whole other problem). Note that the presence
1559 or absence of a VOI LUT as opposed to window values may be configurable
1560 on the modality in some cases, and I have just looked at what I happen
1561 to have received from a myriad of sites over whose configuration I have
1562 no control. This may be why the majority of Fuji images have no VOI LUTs,
1563 but a few do (or it may be the Siemens system that these Fuji images went
1564 through that perhaps added it). I do have some test Hologic DX images that
1565 are not from a clinical site that do actually get this right (a value
1566 of 12 for the third value and a max of 0xfff).
1567
1568 Since almost every vendor that I have encountered that encodes LUTs
1569 makes this mistake, perhaps it is time to amend the standard to warn
1570 implementor's of receivers and/or sanction this bad behavior. We have
1571 talked about this in the past in WG 6 but so far everyone has been
1572 reluctant to write into the standard such a comment. Maybe it is time
1573 to try again, since if one is not aware of this problem, one cannot
1574 effectively implement display using VOI LUTs, and there is a vast
1575 installed base to contend with.
1576
1577 I did not check presentation states, in which VOI LUTs could also be
1578 encountered, for the prevalence of this mistake, nor did I look at the
1579 encoding of Modality LUT's, which are unusual. Nor did I check digital
1580 mammography images. I would be interested to hear from anyone who has.
1581
1582 David
1583
1584 PS. The following older thread in this newsgroup discusses this:
1585
1586 "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"
1587
1588 PPS. From a historical perspective, the following may be of interest.
1589
1590 In the original standard in 1993, all that was said about this was a
1591 reference to the corresponding such where Modality LUTs are described
1592 that said:
1593
1594 "The third value specifies the number of bits for each entry in the
1595 LUT Data. It shall take the value 8 or 16. The LUT Data shall be stored
1596 in a format equivalent to 8 or 16 bits allocated and high bit equal
1597 1-bits allocated."
1598
1599 Since the high bit hint was not apparently explicit enough, a very
1600 early CP, CP 15 (submitted by Agfa as it happens), replaced this with:
1601
1602 "The third value conveys the range of LUT entry values. It shall take
1603 the value 8 or 16, corresponding with the LUT entry value range of
1604 256 or 65536.
1605
1606 Note:    The third value is not required for describing the
1607     LUT data and is only included for informational usage
1608     and for maintaining compatibility with ACRNEMA 2.0.
1609
1610 The LUT Data contains the LUT entry values."
1611
1612 That is how it read in the 1996, 1998 and 1999 editions.
1613
1614 By the 2000 edition, Supplement 33 that introduced presentation states
1615 extensively reworked this entire section and tried to explain this in
1616 different words:
1617
1618 "The output range is from 0 to 2^n-1 where n is the third value of LUT
1619 Descriptor. This range is always unsigned."
1620
1621 and also added a note to spell out what the output range meant in the
1622 VOI LUT section:
1623
1624 "9. The output of the Window Center/Width or VOI LUT transformation
1625 is either implicitly scaled to the full range of the display device
1626 if there is no succeeding transformation defined, or implicitly scaled
1627 to the full input range of the succeeding transformation step (such as
1628 the Presentation LUT), if present. See C.11.6.1."
1629
1630 It still reads this way in the 2004 edition.
1631
1632 Note that LUTs in other applications than the general VOI LUT allow for
1633 values other than 8 or 16 in the third value of LUT descriptor to permit
1634 ranges other than 0 to 255 or 65535.
1635
1636 In addition, the DX Image Module specializes the VOI LUT
1637 attributes as follows, in PS 3.3 section C.8.11.3.1.5 (added in Sup 32):
1638
1639 "The third value specifies the number of bits for each entry in the LUT
1640 Data (analogous to ìbits storedî). It shall be between 10-16. The LUT
1641 Data shall be stored in a format equivalent to 16 ìbits allocatedî and
1642 ìhigh bitî equal to ìbits storedî - 1. The third value conveys the range
1643 of LUT entry values. These unsigned LUT entry values shall range between
1644 0 and 2^n-1, where n is the third value of the LUT Descriptor."
1645
1646 So in the case of the GE DX for presentation images, the third value of
1647 LUT descriptor is allowed to be and probably should be 14 rather than 16.
1648
1649 */