1 /*=========================================================================
4 Module: $RCSfile: gdcmPixelReadConvert.cxx,v $
6 Date: $Date: 2005/10/25 17:54:55 $
7 Version: $Revision: 1.87 $
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.
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.
17 =========================================================================*/
19 #include "gdcmPixelReadConvert.h"
20 #include "gdcmDebug.h"
22 #include "gdcmGlobal.h"
24 #include "gdcmDocEntry.h"
25 #include "gdcmRLEFramesInfo.h"
26 #include "gdcmJPEGFragmentsInfo.h"
29 #include <stdio.h> //for sscanf
34 //bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t lenght);
35 bool gdcm_read_JPEG2000_file (void* raw,
36 char *inputdata, size_t inputlength);
37 //-----------------------------------------------------------------------------
38 #define str2num(str, typeNum) *((typeNum *)(str))
40 //-----------------------------------------------------------------------------
41 // Constructor / Destructor
43 PixelReadConvert::PixelReadConvert()
59 /// Canonical Destructor
60 PixelReadConvert::~PixelReadConvert()
65 //-----------------------------------------------------------------------------
68 * \brief Predicate to know whether the image[s] (once Raw) is RGB.
69 * \note See comments of \ref ConvertHandleColor
71 bool PixelReadConvert::IsRawRGB()
74 || PlanarConfiguration == 2
82 * \brief Gets various usefull informations from the file header
83 * @param file gdcm::File pointer
85 void PixelReadConvert::GrabInformationsFromFile( File *file )
87 // Number of Bits Allocated for storing a Pixel is defaulted to 16
88 // when absent from the file.
89 BitsAllocated = file->GetBitsAllocated();
90 if ( BitsAllocated == 0 )
95 // Number of "Bits Stored", defaulted to number of "Bits Allocated"
96 // when absent from the file.
97 BitsStored = file->GetBitsStored();
98 if ( BitsStored == 0 )
100 BitsStored = BitsAllocated;
103 // High Bit Position, defaulted to "Bits Allocated" - 1
104 HighBitPosition = file->GetHighBitPosition();
105 if ( HighBitPosition == 0 )
107 HighBitPosition = BitsAllocated - 1;
110 XSize = file->GetXSize();
111 YSize = file->GetYSize();
112 ZSize = file->GetZSize();
113 SamplesPerPixel = file->GetSamplesPerPixel();
114 //PixelSize = file->GetPixelSize(); Useless
115 PixelSign = file->IsSignedPixelData();
116 SwapCode = file->GetSwapCode();
117 std::string ts = file->GetTransferSyntax();
118 if ( ts == GDCM_UNKNOWN )
119 gdcmErrorMacro( "Could someone tell me how in the world could this happen !" );
121 ( ! file->IsDicomV3() )
122 || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian
123 || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE
124 || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian
125 || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian
126 || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian;
128 IsPrivateGETransferSyntax =
129 ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE );
131 IsMPEG = Global::GetTS()->IsMPEG(ts);
132 IsJPEG2000 = Global::GetTS()->IsJPEG2000(ts);
133 IsJPEGLS = Global::GetTS()->IsJPEGLS(ts);
134 IsJPEGLossy = Global::GetTS()->IsJPEGLossy(ts);
135 IsJPEGLossless = Global::GetTS()->IsJPEGLossless(ts);
136 IsRLELossless = Global::GetTS()->IsRLELossless(ts);
138 PixelOffset = file->GetPixelOffset();
139 PixelDataLength = file->GetPixelAreaLength();
140 RLEInfo = file->GetRLEInfo();
141 JPEGInfo = file->GetJPEGInfo();
143 IsMonochrome = file->IsMonochrome();
144 IsMonochrome1 = file->IsMonochrome1();
145 IsPaletteColor = file->IsPaletteColor();
146 IsYBRFull = file->IsYBRFull();
148 PlanarConfiguration = file->GetPlanarConfiguration();
150 /////////////////////////////////////////////////////////////////
152 HasLUT = file->HasLUT();
155 // Just in case some access to a File element requires disk access.
156 LutRedDescriptor = file->GetEntryString( 0x0028, 0x1101 );
157 LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 );
158 LutBlueDescriptor = file->GetEntryString( 0x0028, 0x1103 );
160 // The following comment is probabely meaningless, since LUT are *always*
161 // loaded at parsing time, whatever their length is.
163 // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
164 // [ refer to invocation of Document::SetMaxSizeLoadEntry() in
165 // Document::Document() ], the loading of the value (content) of a
166 // [Bin|Val]Entry occurence migth have been hindered (read simply NOT
167 // loaded). Hence, we first try to obtain the LUTs data from the file
168 // and when this fails we read the LUTs data directly from disk.
169 // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge.
170 // We should NOT bypass the [Bin|Val]Entry class. Instead
171 // an access to an UNLOADED content of a [Bin|Val]Entry occurence
172 // (e.g. DataEntry::GetBinArea()) should force disk access from
173 // within the [Bin|Val]Entry class itself. The only problem
174 // is that the [Bin|Val]Entry is unaware of the FILE* is was
175 // parsed from. Fix that. FIXME.
178 file->LoadEntryBinArea(0x0028, 0x1201);
179 LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 );
182 gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data");
186 file->LoadEntryBinArea(0x0028, 0x1202);
187 LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
190 gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data");
194 file->LoadEntryBinArea(0x0028, 0x1203);
195 LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
198 gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data");
203 ComputeRawAndRGBSizes();
206 /// \brief Reads from disk and decompresses Pixels
207 bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
209 // ComputeRawAndRGBSizes is already made by
210 // ::GrabInformationsFromfile. So, the structure sizes are
214 //////////////////////////////////////////////////
215 //// First stage: get our hands on the Pixel Data.
218 gdcmWarningMacro( "Unavailable file pointer." );
222 fp->seekg( PixelOffset, std::ios::beg );
223 if ( fp->fail() || fp->eof() )
225 gdcmWarningMacro( "Unable to find PixelOffset in file." );
231 //////////////////////////////////////////////////
232 //// Second stage: read from disk and decompress.
233 if ( BitsAllocated == 12 )
235 ReadAndDecompress12BitsTo16Bits( fp);
239 // This problem can be found when some obvious informations are found
240 // after the field containing the image data. In this case, these
241 // bad data are added to the size of the image (in the PixelDataLength
242 // variable). But RawSize is the right size of the image !
243 if ( PixelDataLength != RawSize )
245 gdcmWarningMacro( "Mismatch between PixelReadConvert : "
246 << PixelDataLength << " and RawSize : " << RawSize );
248 if ( PixelDataLength > RawSize )
250 fp->read( (char*)Raw, RawSize);
254 fp->read( (char*)Raw, PixelDataLength);
257 if ( fp->fail() || fp->eof())
259 gdcmWarningMacro( "Reading of Raw pixel data failed." );
263 else if ( IsRLELossless )
265 if ( ! RLEInfo->DecompressRLEFile
266 ( fp, Raw, XSize, YSize, ZSize, BitsAllocated ) )
268 gdcmWarningMacro( "RLE decompressor failed." );
274 //gdcmWarningMacro( "Sorry, MPEG not yet taken into account" );
276 // fp has already been seek to start of mpeg
277 //ReadMPEGFile(fp, Raw, PixelDataLength);
282 // Default case concerns JPEG family
283 if ( ! ReadAndDecompressJPEGFile( fp ) )
285 gdcmWarningMacro( "JPEG decompressor failed." );
290 ////////////////////////////////////////////
291 //// Third stage: twigle the bytes and bits.
292 ConvertReorderEndianity();
293 ConvertReArrangeBits();
294 ConvertFixGreyLevels();
295 if (UserFunction) // user is allowed to Mirror, TopDown, Rotate,...the image
296 UserFunction( Raw, FileInternal);
297 ConvertHandleColor();
302 /// Deletes Pixels Area
303 void PixelReadConvert::Squeeze()
319 * \brief Build the RGB image from the Raw image and the LUTs.
321 bool PixelReadConvert::BuildRGBImage()
325 // The job is already done.
331 // The job can't be done
338 // The job can't be done
342 gdcmWarningMacro( "--> BuildRGBImage" );
348 if ( BitsAllocated <= 8 )
350 uint8_t *localRGB = RGB;
351 for (size_t i = 0; i < RawSize; ++i )
354 *localRGB++ = LutRGBA[j];
355 *localRGB++ = LutRGBA[j+1];
356 *localRGB++ = LutRGBA[j+2];
360 else // deal with 16 bits pixels and 16 bits Palette color
362 uint16_t *localRGB = (uint16_t *)RGB;
363 for (size_t i = 0; i < RawSize/2; ++i )
365 j = ((uint16_t *)Raw)[i] * 4;
366 *localRGB++ = ((uint16_t *)LutRGBA)[j];
367 *localRGB++ = ((uint16_t *)LutRGBA)[j+1];
368 *localRGB++ = ((uint16_t *)LutRGBA)[j+2];
375 //-----------------------------------------------------------------------------
378 //-----------------------------------------------------------------------------
381 * \brief Read from file a 12 bits per pixel image and decompress it
382 * into a 16 bits per pixel image.
384 void PixelReadConvert::ReadAndDecompress12BitsTo16Bits( std::ifstream *fp )
385 throw ( FormatError )
387 int nbPixels = XSize * YSize;
388 uint16_t *localDecompres = (uint16_t*)Raw;
390 for( int p = 0; p < nbPixels; p += 2 )
394 fp->read( (char*)&b0, 1);
395 if ( fp->fail() || fp->eof() )
397 throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
398 "Unfound first block" );
401 fp->read( (char*)&b1, 1 );
402 if ( fp->fail() || fp->eof())
404 throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
405 "Unfound second block" );
408 fp->read( (char*)&b2, 1 );
409 if ( fp->fail() || fp->eof())
411 throw FormatError( "PixelReadConvert::ReadAndDecompress12BitsTo16Bits()",
412 "Unfound second block" );
415 // Two steps are necessary to please VC++
417 // 2 pixels 12bit = [0xABCDEF]
418 // 2 pixels 16bit = [0x0ABD] + [0x0FCE]
420 *localDecompres++ = ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
422 *localDecompres++ = ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
424 /// \todo JPR Troubles expected on Big-Endian processors ?
429 * \brief Reads from disk the Pixel Data of JPEG Dicom encapsulated
430 * file and decompress it.
431 * @param fp File Pointer
434 bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
438 // make sure this is the right JPEG compression
439 assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEGLS );
440 // FIXME this is really ugly but it seems I have to load the complete
441 // jpeg2000 stream to use jasper:
442 // I don't think we'll ever be able to deal with multiple fragments properly
444 unsigned long inputlength = 0;
445 JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
448 inputlength += jpegfrag->GetLength();
449 jpegfrag = JPEGInfo->GetNextFragment();
451 gdcmAssertMacro( inputlength != 0);
452 uint8_t *inputdata = new uint8_t[inputlength];
453 char *pinputdata = (char*)inputdata;
454 jpegfrag = JPEGInfo->GetFirstFragment();
457 fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
458 fp->read(pinputdata, jpegfrag->GetLength());
459 pinputdata += jpegfrag->GetLength();
460 jpegfrag = JPEGInfo->GetNextFragment();
462 // Warning the inputdata buffer is delete in the function
463 if ( ! gdcm_read_JPEG2000_file( Raw,
464 (char*)inputdata, inputlength ) )
468 // wow what happen, must be an error
473 // make sure this is the right JPEG compression
474 assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEG2000 );
475 // WARNING : JPEG-LS is NOT the 'classical' Jpeg Lossless :
476 // [JPEG-LS is the basis for new lossless/near-lossless compression
477 // standard for continuous-tone images intended for JPEG2000. The standard
478 // is based on the LOCO-I algorithm (LOw COmplexity LOssless COmpression
479 // for Images) developed at Hewlett-Packard Laboratories]
481 // see http://datacompression.info/JPEGLS.shtml
484 std::cerr << "count:" << JPEGInfo->GetFragmentCount() << std::endl;
485 unsigned long inputlength = 0;
486 JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment();
489 inputlength += jpegfrag->GetLength();
490 jpegfrag = JPEGInfo->GetNextFragment();
492 gdcmAssertMacro( inputlength != 0);
493 uint8_t *inputdata = new uint8_t[inputlength];
494 char *pinputdata = (char*)inputdata;
495 jpegfrag = JPEGInfo->GetFirstFragment();
498 fp->seekg( jpegfrag->GetOffset(), std::ios::beg);
499 fp->read(pinputdata, jpegfrag->GetLength());
500 pinputdata += jpegfrag->GetLength();
501 jpegfrag = JPEGInfo->GetNextFragment();
504 //fp->read((char*)Raw, PixelDataLength);
506 std::ofstream out("/tmp/jpegls.jpg");
507 out.write((char*)inputdata, inputlength);
512 gdcmWarningMacro( "Sorry, JPEG-LS not yet taken into account" );
513 fp->seekg( JPEGInfo->GetFirstFragment()->GetOffset(), std::ios::beg);
514 // if ( ! gdcm_read_JPEGLS_file( fp,Raw ) )
519 // make sure this is the right JPEG compression
520 assert( !IsJPEGLS || !IsJPEG2000 );
521 // Precompute the offset localRaw will be shifted with
522 int length = XSize * YSize * SamplesPerPixel;
523 int numberBytes = BitsAllocated / 8;
525 JPEGInfo->DecompressFromFile(fp, Raw, BitsStored, numberBytes, length );
531 * \brief Build Red/Green/Blue/Alpha LUT from File when :
532 * - (0028,0004) : Photometric Interpretation == [PALETTE COLOR ]
534 * - (0028,1101),(0028,1102),(0028,1102)
535 * xxx Palette Color Lookup Table Descriptor are found
537 * - (0028,1201),(0028,1202),(0028,1202)
538 * xxx Palette Color Lookup Table Data - are found
539 * \warning does NOT deal with :
540 * - 0028 1100 Gray Lookup Table Descriptor (Retired)
541 * - 0028 1221 Segmented Red Palette Color Lookup Table Data
542 * - 0028 1222 Segmented Green Palette Color Lookup Table Data
543 * - 0028 1223 Segmented Blue Palette Color Lookup Table Data
544 * no known Dicom reader deals with them :-(
545 * @return a RGBA Lookup Table
547 void PixelReadConvert::BuildLUTRGBA()
550 // Note to code reviewers :
551 // The problem is *much more* complicated, since a lot of manufacturers
552 // Don't follow the norm :
553 // have a look at David Clunie's remark at the end of this .cxx file.
560 // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
562 if ( ! IsPaletteColor )
567 if ( LutRedDescriptor == GDCM_UNFOUND
568 || LutGreenDescriptor == GDCM_UNFOUND
569 || LutBlueDescriptor == GDCM_UNFOUND )
571 gdcmWarningMacro( "(At least) a LUT Descriptor is missing" );
575 ////////////////////////////////////////////
576 // Extract the info from the LUT descriptors
577 int lengthR; // Red LUT length in Bytes
578 int debR; // Subscript of the first Lut Value
579 int nbitsR; // Lut item size (in Bits)
580 int nbRead; // nb of items in LUT descriptor (must be = 3)
582 nbRead = sscanf( LutRedDescriptor.c_str(),
584 &lengthR, &debR, &nbitsR );
587 gdcmWarningMacro( "Wrong Red LUT descriptor" );
589 int lengthG; // Green LUT length in Bytes
590 int debG; // Subscript of the first Lut Value
591 int nbitsG; // Lut item size (in Bits)
593 nbRead = sscanf( LutGreenDescriptor.c_str(),
595 &lengthG, &debG, &nbitsG );
598 gdcmWarningMacro( "Wrong Green LUT descriptor" );
601 int lengthB; // Blue LUT length in Bytes
602 int debB; // Subscript of the first Lut Value
603 int nbitsB; // Lut item size (in Bits)
604 nbRead = sscanf( LutRedDescriptor.c_str(),
606 &lengthB, &debB, &nbitsB );
609 gdcmWarningMacro( "Wrong Blue LUT descriptor" );
612 gdcmWarningMacro(" lengthR " << lengthR << " debR "
613 << debR << " nbitsR " << nbitsR);
614 gdcmWarningMacro(" lengthG " << lengthG << " debG "
615 << debG << " nbitsG " << nbitsG);
616 gdcmWarningMacro(" lengthB " << lengthB << " debB "
617 << debB << " nbitsB " << nbitsB);
619 if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143
621 if ( !lengthG ) // if = 2^16, this shall be 0
623 if ( !lengthB ) // if = 2^16, this shall be 0
626 ////////////////////////////////////////////////////////
628 if ( ( ! LutRedData ) || ( ! LutGreenData ) || ( ! LutBlueData ) )
630 gdcmWarningMacro( "(At least) a LUT is missing" );
634 // -------------------------------------------------------------
636 if ( BitsAllocated <= 8 )
638 // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT
639 LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha)
644 memset( LutRGBA, 0, 1024 );
647 if ( ( nbitsR == 16 ) && ( BitsAllocated == 8 ) )
649 // when LUT item size is different than pixel size
650 mult = 2; // high byte must be = low byte
654 // See PS 3.3-2003 C.11.1.1.2 p 619
658 // if we get a black image, let's just remove the '+1'
659 // from 'i*mult+1' and check again
660 // if it works, we shall have to check the 3 Palettes
661 // to see which byte is ==0 (first one, or second one)
663 // We give up the checking to avoid some (useless ?) overhead
664 // (optimistic asumption)
668 //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
670 //FIXME : +1 : to get 'low value' byte
671 // Trouble expected on Big Endian Processors ?
672 // 16 BIts Per Pixel Palette Color to be swapped?
674 a = LutRGBA + 0 + debR;
675 for( i=0; i < lengthR; ++i )
677 *a = LutRedData[i*mult+1];
681 a = LutRGBA + 1 + debG;
682 for( i=0; i < lengthG; ++i)
684 *a = LutGreenData[i*mult+1];
688 a = LutRGBA + 2 + debB;
689 for(i=0; i < lengthB; ++i)
691 *a = LutBlueData[i*mult+1];
696 for(i=0; i < 256; ++i)
698 *a = 1; // Alpha component
704 // Probabely the same stuff is to be done for 16 Bits Pixels
705 // with 65536 entries LUT ?!?
706 // Still looking for accurate info on the web :-(
708 gdcmWarningMacro( "Sorry Palette Color Lookup Tables not yet dealt with"
709 << " for 16 Bits Per Pixel images" );
711 // forge the 4 * 16 Bits Red/Green/Blue/Alpha LUT
713 LutRGBA = (uint8_t *)new uint16_t[ 65536*4 ]; // 2^16 * 4 (R, G, B, Alpha)
716 memset( LutRGBA, 0, 65536*4*2 ); // 16 bits = 2 bytes ;-)
718 LutItemNumber = 65536;
724 //take "Subscript of the first Lut Value" (debR,debG,debB) into account!
726 a16 = (uint16_t*)LutRGBA + 0 + debR;
727 for( i=0; i < lengthR; ++i )
729 *a16 = ((uint16_t*)LutRedData)[i];
733 a16 = (uint16_t*)LutRGBA + 1 + debG;
734 for( i=0; i < lengthG; ++i)
736 *a16 = ((uint16_t*)LutGreenData)[i];
740 a16 = (uint16_t*)LutRGBA + 2 + debB;
741 for(i=0; i < lengthB; ++i)
743 *a16 = ((uint16_t*)LutBlueData)[i];
747 a16 = (uint16_t*)LutRGBA + 3 ;
748 for(i=0; i < 65536; ++i)
750 *a16 = 1; // Alpha component
753 /* Just to 'see' the LUT, at debug time
754 // Don't remove this commented out code.
756 a16=(uint16_t*)LutRGBA;
757 for (int j=0;j<65536;j++)
759 std::cout << *a16 << " " << *(a16+1) << " "
760 << *(a16+2) << " " << *(a16+3) << std::endl;
768 * \brief Swap the bytes, according to \ref SwapCode.
770 void PixelReadConvert::ConvertSwapZone()
773 uint16_t localSwapCode = SwapCode;
775 // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax',
776 // then the header is in little endian format and the pixel data is in
777 // big endian format. When reading the header, GDCM has already established
778 // a byte swapping code suitable for this machine to read the
779 // header. In TS::ImplicitVRBigEndianPrivateGE, this code will need
780 // to be switched in order to read the pixel data. This must be
781 // done REGARDLESS of the processor endianess!
783 // Example: Assume we are on a little endian machine. When
784 // GDCM reads the header, the header will match the machine
785 // endianess and the swap code will be established as a no-op.
786 // When GDCM reaches the pixel data, it will need to switch the
787 // swap code to do big endian to little endian conversion.
789 // Now, assume we are on a big endian machine. When GDCM reads the
790 // header, the header will be recognized as a different endianess
791 // than the machine endianess, and a swap code will be established
792 // to convert from little endian to big endian. When GDCM readers
793 // the pixel data, the pixel data endianess will now match the
794 // machine endianess. But we currently have a swap code that
795 // converts from little endian to big endian. In this case, we
796 // need to switch the swap code to a no-op.
798 // Therefore, in either case, if the file is in
799 // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
800 // the byte swapping code when entering the pixel data.
802 /* //Let me check something.
803 //I wait for the Dashboard !
804 if ( IsPrivateGETransferSyntax )
806 // PrivateGETransferSyntax only exists for 'true' Dicom images
807 // we assume there is no 'exotic' 32 bits endianess!
808 switch (localSwapCode)
811 localSwapCode = 4321;
814 localSwapCode = 1234;
819 if ( BitsAllocated == 16 )
821 uint16_t *im16 = (uint16_t*)Raw;
822 switch( localSwapCode )
829 for( i = 0; i < RawSize / 2; i++ )
831 im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
835 gdcmWarningMacro("SwapCode value (16 bits) not allowed.");
838 else if ( BitsAllocated == 32 )
843 uint32_t *im32 = (uint32_t*)Raw;
844 switch ( localSwapCode )
849 for( i = 0; i < RawSize / 4; i++ )
851 low = im32[i] & 0x0000ffff; // 4321
852 high = im32[i] >> 16;
853 high = ( high >> 8 ) | ( high << 8 );
854 low = ( low >> 8 ) | ( low << 8 );
856 im32[i] = ( s32 << 16 ) | high;
860 for( i = 0; i < RawSize / 4; i++ )
862 low = im32[i] & 0x0000ffff; // 2143
863 high = im32[i] >> 16;
864 high = ( high >> 8 ) | ( high << 8 );
865 low = ( low >> 8 ) | ( low << 8 );
867 im32[i] = ( s32 << 16 ) | low;
871 for( i = 0; i < RawSize / 4; i++ )
873 low = im32[i] & 0x0000ffff; // 3412
874 high = im32[i] >> 16;
876 im32[i] = ( s32 << 16 ) | high;
880 gdcmWarningMacro("SwapCode value (32 bits) not allowed." );
886 * \brief Deal with endianness i.e. re-arange bytes inside the integer
888 void PixelReadConvert::ConvertReorderEndianity()
890 if ( BitsAllocated != 8 )
895 // Special kludge in order to deal with xmedcon broken images:
896 if ( BitsAllocated == 16
897 && BitsStored < BitsAllocated
900 int l = (int)( RawSize / ( BitsAllocated / 8 ) );
901 uint16_t *deb = (uint16_t *)Raw;
902 for(int i = 0; i<l; i++)
904 if ( *deb == 0xffff )
914 * \brief Deal with Grey levels i.e. re-arange them
915 * to have low values = dark, high values = bright
917 void PixelReadConvert::ConvertFixGreyLevels()
922 uint32_t i; // to please M$VC6
927 if ( BitsAllocated == 8 )
929 uint8_t *deb = (uint8_t *)Raw;
930 for (i=0; i<RawSize; i++)
938 if ( BitsAllocated == 16 )
941 for (j=0; j<BitsStored-1; j++)
943 mask = (mask << 1) +1; // will be fff when BitsStored=12
946 uint16_t *deb = (uint16_t *)Raw;
947 for (i=0; i<RawSize/2; i++)
957 if ( BitsAllocated == 8 )
959 uint8_t smask8 = 255;
960 uint8_t *deb = (uint8_t *)Raw;
961 for (i=0; i<RawSize; i++)
963 *deb = smask8 - *deb;
968 if ( BitsAllocated == 16 )
970 uint16_t smask16 = 65535;
971 uint16_t *deb = (uint16_t *)Raw;
972 for (i=0; i<RawSize/2; i++)
974 *deb = smask16 - *deb;
983 * \brief Re-arrange the bits within the bytes.
984 * @return Boolean always true
986 bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError )
989 if ( BitsStored != BitsAllocated )
991 int l = (int)( RawSize / ( BitsAllocated / 8 ) );
992 if ( BitsAllocated == 16 )
994 // pmask : to mask the 'unused bits' (may contain overlays)
995 uint16_t pmask = 0xffff;
996 pmask = pmask >> ( BitsAllocated - BitsStored );
998 uint16_t *deb = (uint16_t*)Raw;
1000 if ( !PixelSign ) // Pixels are unsigned
1002 for(int i = 0; i<l; i++)
1004 *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1008 else // Pixels are signed
1010 // smask : to check the 'sign' when BitsStored != BitsAllocated
1011 uint16_t smask = 0x0001;
1012 smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) );
1013 // nmask : to propagate sign bit on negative values
1014 int16_t nmask = (int16_t)0x8000;
1015 nmask = nmask >> ( BitsAllocated - BitsStored - 1 );
1017 for(int i = 0; i<l; i++)
1019 *deb = *deb >> (BitsStored - HighBitPosition - 1);
1022 *deb = *deb | nmask;
1026 *deb = *deb & pmask;
1032 else if ( BitsAllocated == 32 )
1034 // pmask : to mask the 'unused bits' (may contain overlays)
1035 uint32_t pmask = 0xffffffff;
1036 pmask = pmask >> ( BitsAllocated - BitsStored );
1038 uint32_t *deb = (uint32_t*)Raw;
1042 for(int i = 0; i<l; i++)
1044 *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
1050 // smask : to check the 'sign' when BitsStored != BitsAllocated
1051 uint32_t smask = 0x00000001;
1052 smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 ));
1053 // nmask : to propagate sign bit on negative values
1054 int32_t nmask = 0x80000000;
1055 nmask = nmask >> ( BitsAllocated - BitsStored -1 );
1057 for(int i = 0; i<l; i++)
1059 *deb = *deb >> (BitsStored - HighBitPosition - 1);
1061 *deb = *deb | nmask;
1063 *deb = *deb & pmask;
1070 gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)");
1071 throw FormatError( "Weird image !?" );
1078 * \brief Convert (Red plane, Green plane, Blue plane) to RGB pixels
1079 * \warning Works on all the frames at a time
1081 void PixelReadConvert::ConvertRGBPlanesToRGBPixels()
1083 gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels");
1085 uint8_t *localRaw = Raw;
1086 uint8_t *copyRaw = new uint8_t[ RawSize ];
1087 memmove( copyRaw, localRaw, RawSize );
1089 int l = XSize * YSize * ZSize;
1091 uint8_t *a = copyRaw;
1092 uint8_t *b = copyRaw + l;
1093 uint8_t *c = copyRaw + l + l;
1095 for (int j = 0; j < l; j++)
1097 *(localRaw++) = *(a++);
1098 *(localRaw++) = *(b++);
1099 *(localRaw++) = *(c++);
1105 * \brief Convert (cY plane, cB plane, cR plane) to RGB pixels
1106 * \warning Works on all the frames at a time
1108 void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels()
1110 // Remarks for YBR newbees :
1111 // YBR_FULL works very much like RGB, i.e. three samples per pixel,
1112 // just the color space is YCbCr instead of RGB. This is particularly useful
1113 // for doppler ultrasound where most of the image is grayscale
1114 // (i.e. only populates the Y components) and Cb and Cr are mostly zero,
1115 // except for the few patches of color on the image.
1116 // On such images, RLE achieves a compression ratio that is much better
1117 // than the compression ratio on an equivalent RGB image.
1119 gdcmWarningMacro("--> ConvertYcBcRPlanesToRGBPixels");
1121 uint8_t *localRaw = Raw;
1122 uint8_t *copyRaw = new uint8_t[ RawSize ];
1123 memmove( copyRaw, localRaw, RawSize );
1125 // to see the tricks about YBR_FULL, YBR_FULL_422,
1126 // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
1127 // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
1128 // and be *very* affraid
1130 int l = XSize * YSize;
1131 int nbFrames = ZSize;
1133 uint8_t *a = copyRaw + 0;
1134 uint8_t *b = copyRaw + l;
1135 uint8_t *c = copyRaw + l+ l;
1138 /// We replaced easy to understand but time consuming floating point
1139 /// computations by the 'well known' integer computation counterpart
1141 /// http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
1142 /// for code optimisation.
1144 for ( int i = 0; i < nbFrames; i++ )
1146 for ( int j = 0; j < l; j++ )
1148 R = 38142 *(*a-16) + 52298 *(*c -128);
1149 G = 38142 *(*a-16) - 26640 *(*c -128) - 12845 *(*b -128);
1150 B = 38142 *(*a-16) + 66093 *(*b -128);
1159 if (R > 255) R = 255;
1160 if (G > 255) G = 255;
1161 if (B > 255) B = 255;
1163 *(localRaw++) = (uint8_t)R;
1164 *(localRaw++) = (uint8_t)G;
1165 *(localRaw++) = (uint8_t)B;
1174 /// \brief Deals with the color decoding i.e. handle:
1175 /// - R, G, B planes (as opposed to RGB pixels)
1176 /// - YBR (various) encodings.
1177 /// - LUT[s] (or "PALETTE COLOR").
1179 void PixelReadConvert::ConvertHandleColor()
1181 //////////////////////////////////
1182 // Deal with the color decoding i.e. handle:
1183 // - R, G, B planes (as opposed to RGB pixels)
1184 // - YBR (various) encodings.
1185 // - LUT[s] (or "PALETTE COLOR").
1187 // The classification in the color decoding schema is based on the blending
1188 // of two Dicom tags values:
1189 // * "Photometric Interpretation" for which we have the cases:
1190 // - [Photo A] MONOCHROME[1|2] pictures,
1191 // - [Photo B] RGB or YBR_FULL_422 (which acts as RGB),
1192 // - [Photo C] YBR_* (with the above exception of YBR_FULL_422)
1193 // - [Photo D] "PALETTE COLOR" which indicates the presence of LUT[s].
1194 // * "Planar Configuration" for which we have the cases:
1195 // - [Planar 0] 0 then Pixels are already RGB
1196 // - [Planar 1] 1 then we have 3 planes : R, G, B,
1197 // - [Planar 2] 2 then we have 1 gray Plane and 3 LUTs
1199 // Now in theory, one could expect some coherence when blending the above
1200 // cases. For example we should not encounter files belonging at the
1201 // time to case [Planar 0] and case [Photo D].
1202 // Alas, this was only theory ! Because in practice some odd (read ill
1203 // formated Dicom) files (e.g. gdcmData/US-PAL-8-10x-echo.dcm) we encounter:
1204 // - "Planar Configuration" = 0,
1205 // - "Photometric Interpretation" = "PALETTE COLOR".
1206 // Hence gdcm will use the folowing "heuristic" in order to be tolerant
1207 // towards Dicom-non-conformant files:
1208 // << whatever the "Planar Configuration" value might be, a
1209 // "Photometric Interpretation" set to "PALETTE COLOR" forces
1210 // a LUT intervention >>
1212 // Now we are left with the following handling of the cases:
1213 // - [Planar 0] OR [Photo A] no color decoding (since respectively
1214 // Pixels are already RGB and monochrome pictures have no color :),
1215 // - [Planar 1] AND [Photo B] handled with ConvertRGBPlanesToRGBPixels()
1216 // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels()
1217 // - [Planar 2] OR [Photo D] requires LUT intervention.
1219 gdcmWarningMacro("--> ConvertHandleColor"
1220 << "Planar Configuration " << PlanarConfiguration );
1224 // [Planar 2] OR [Photo D]: LUT intervention done outside
1225 gdcmWarningMacro("--> RawRGB : LUT intervention done outside");
1229 if ( PlanarConfiguration == 1 )
1233 // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB)
1234 gdcmWarningMacro("--> YBRFull");
1235 ConvertYcBcRPlanesToRGBPixels();
1239 // [Planar 1] AND [Photo C]
1240 gdcmWarningMacro("--> YBRFull");
1241 ConvertRGBPlanesToRGBPixels();
1246 // When planarConf is 0, and RLELossless (forbidden by Dicom norm)
1247 // pixels need to be RGB-fyied anyway
1251 gdcmWarningMacro("--> RLE Lossless");
1252 ConvertRGBPlanesToRGBPixels();
1255 // In *normal *case, when planarConf is 0, pixels are already in RGB
1258 /// Computes the Pixels Size
1259 void PixelReadConvert::ComputeRawAndRGBSizes()
1261 int bitsAllocated = BitsAllocated;
1262 // Number of "Bits Allocated" is fixed to 16 when it's 12, since
1263 // in this case we will expand the image to 16 bits (see
1264 // \ref ReadAndDecompress12BitsTo16Bits() )
1265 if ( BitsAllocated == 12 )
1270 RawSize = XSize * YSize * ZSize
1271 * ( bitsAllocated / 8 )
1275 RGBSize = 3 * RawSize; // works for 8 and 16 bits per Pixel
1283 /// Allocates room for RGB Pixels
1284 void PixelReadConvert::AllocateRGB()
1288 RGB = new uint8_t[RGBSize];
1291 /// Allocates room for RAW Pixels
1292 void PixelReadConvert::AllocateRaw()
1296 Raw = new uint8_t[RawSize];
1299 //-----------------------------------------------------------------------------
1302 * \brief Print self.
1303 * @param indent Indentation string to be prepended during printing.
1304 * @param os Stream to print to.
1306 void PixelReadConvert::Print( std::ostream &os, std::string const &indent )
1309 << "--- Pixel information -------------------------"
1312 << "Pixel Data: offset " << PixelOffset
1313 << " x(" << std::hex << PixelOffset << std::dec
1314 << ") length " << PixelDataLength
1315 << " x(" << std::hex << PixelDataLength << std::dec
1316 << ")" << std::endl;
1318 if ( IsRLELossless )
1322 RLEInfo->Print( os, indent );
1326 gdcmWarningMacro("Set as RLE file but NO RLEinfo present.");
1330 if ( IsJPEG2000 || IsJPEGLossless || IsJPEGLossy || IsJPEGLS )
1334 JPEGInfo->Print( os, indent );
1338 gdcmWarningMacro("Set as JPEG file but NO JPEGinfo present.");
1343 //-----------------------------------------------------------------------------
1344 } // end namespace gdcm
1346 // Note to developpers :
1347 // Here is a very detailled post from David Clunie, on the troubles caused
1348 // 'non standard' LUT and LUT description
1349 // We shall have to take it into accound in our code.
1354 Subject: Problem with VOI LUTs in Agfa and Fuji CR and GE DX images, was Re: VOI LUT issues
1355 Date: Sun, 06 Feb 2005 17:13:40 GMT
1356 From: David Clunie <dclunie@dclunie.com>
1357 Reply-To: dclunie@dclunie.com
1358 Newsgroups: comp.protocols.dicom
1359 References: <1107553502.040221.189550@o13g2000cwo.googlegroups.com>
1361 > THE LUT that comes with [my] image claims to be 16-bit, but none of the
1362 > values goes higher than 4095. That being said, though, none of my
1363 > original pixel values goes higher than that, either. I have read
1364 > elsewhere on this group that when that happens you are supposed to
1365 > adjust the LUT. Can someone be more specific? There was a thread from
1366 > 2002 where Marco and David were mentioning doing precisely that.
1373 You have encountered the well known "we know what the standard says but
1374 we are going to ignore it and do what we have been doing for almost
1375 a decade regardless" CR vendor bug. Agfa started this, but they are not
1376 the only vendor doing this now; GE and Fuji may have joined the club.
1378 Sadly, one needs to look at the LUT Data, figure out what the maximum
1379 value actually encoded is, and find the next highest power of 2 (e.g.
1380 212 in this case), to figure out what the range of the data is
1381 supposed to be. I have assumed that if the maximum value in the LUT
1382 data is less than a power of 2 minus 1 (e.g. 0xebc) then the intent
1383 of the vendor was not to use the maximum available grayscale range
1384 of the display (e.g. the maximum is 0xfff in this case). An alternative
1385 would be to scale to the actual maximum rather than a power of two.
1387 Very irritating, and in theory not totally reliable if one really
1388 intended the full 16 bits and only used, say 15, but that is extremely
1389 unlikely since everything would be too dark, and this heuristic
1392 There has never been anything in the standard that describes having
1393 to go through these convolutions. Since the only value in the
1394 standard that describes the bit depth of the LUT values is LUT
1395 Descriptor value 3 and that is (usually) always required to be
1396 either 8 or 16, it mystifies me how the creators' of these images
1397 imagine that the receiver is going to divine the range that is intended. Further, the standard is quite explicit that this 3rd
1398 value defines the range of LUT values, but as far as I am aware, all
1399 the vendors are ignoring the standard and indeed sending a third value
1402 This problem is not confined to CR, and is also seen with DX products.
1404 Typically I have seen:
1406 - Agfa CR, which usually (always ?) sends LUTs, values up to 0x0fff
1407 - Fuji CR, which occasionally send LUTs, values up to 0x03ff
1408 - GE DX, for presentation, which always have LUTs, up to 0x3fff
1410 Swissray, Siemens, Philips, Canon and Kodak never seem to send VOI LUTs
1411 at this point (which is a whole other problem). Note that the presence
1412 or absence of a VOI LUT as opposed to window values may be configurable
1413 on the modality in some cases, and I have just looked at what I happen
1414 to have received from a myriad of sites over whose configuration I have
1415 no control. This may be why the majority of Fuji images have no VOI LUTs,
1416 but a few do (or it may be the Siemens system that these Fuji images went
1417 through that perhaps added it). I do have some test Hologic DX images that
1418 are not from a clinical site that do actually get this right (a value
1419 of 12 for the third value and a max of 0xfff).
1421 Since almost every vendor that I have encountered that encodes LUTs
1422 makes this mistake, perhaps it is time to amend the standard to warn
1423 implementor's of receivers and/or sanction this bad behavior. We have
1424 talked about this in the past in WG 6 but so far everyone has been
1425 reluctant to write into the standard such a comment. Maybe it is time
1426 to try again, since if one is not aware of this problem, one cannot
1427 effectively implement display using VOI LUTs, and there is a vast
1428 installed base to contend with.
1430 I did not check presentation states, in which VOI LUTs could also be
1431 encountered, for the prevalence of this mistake, nor did I look at the
1432 encoding of Modality LUT's, which are unusual. Nor did I check digital
1433 mammography images. I would be interested to hear from anyone who has.
1437 PS. The following older thread in this newsgroup discusses this:
1439 "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"
1441 PPS. From a historical perspective, the following may be of interest.
1443 In the original standard in 1993, all that was said about this was a
1444 reference to the corresponding such where Modality LUTs are described
1447 "The third value specifies the number of bits for each entry in the
1448 LUT Data. It shall take the value 8 or 16. The LUT Data shall be stored
1449 in a format equivalent to 8 or 16 bits allocated and high bit equal
1452 Since the high bit hint was not apparently explicit enough, a very
1453 early CP, CP 15 (submitted by Agfa as it happens), replaced this with:
1455 "The third value conveys the range of LUT entry values. It shall take
1456 the value 8 or 16, corresponding with the LUT entry value range of
1459 Note: The third value is not required for describing the
1460 LUT data and is only included for informational usage
1461 and for maintaining compatibility with ACRNEMA 2.0.
1463 The LUT Data contains the LUT entry values."
1465 That is how it read in the 1996, 1998 and 1999 editions.
1467 By the 2000 edition, Supplement 33 that introduced presentation states
1468 extensively reworked this entire section and tried to explain this in
1471 "The output range is from 0 to 2^n-1 where n is the third value of LUT
1472 Descriptor. This range is always unsigned."
1474 and also added a note to spell out what the output range meant in the
1477 "9. The output of the Window Center/Width or VOI LUT transformation
1478 is either implicitly scaled to the full range of the display device
1479 if there is no succeeding transformation defined, or implicitly scaled
1480 to the full input range of the succeeding transformation step (such as
1481 the Presentation LUT), if present. See C.11.6.1."
1483 It still reads this way in the 2004 edition.
1485 Note that LUTs in other applications than the general VOI LUT allow for
1486 values other than 8 or 16 in the third value of LUT descriptor to permit
1487 ranges other than 0 to 255 or 65535.
1489 In addition, the DX Image Module specializes the VOI LUT
1490 attributes as follows, in PS 3.3 section C.8.11.3.1.5 (added in Sup 32):
1492 "The third value specifies the number of bits for each entry in the LUT
1493 Data (analogous to ìbits storedî). It shall be between 10-16. The LUT
1494 Data shall be stored in a format equivalent to 16 ìbits allocatedî and
1495 ìhigh bitî equal to ìbits storedî - 1. The third value conveys the range
1496 of LUT entry values. These unsigned LUT entry values shall range between
1497 0 and 2^n-1, where n is the third value of the LUT Descriptor."
1499 So in the case of the GE DX for presentation images, the third value of
1500 LUT descriptor is allowed to be and probably should be 14 rather than 16.