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