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