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