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