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