X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmPixelReadConvert.cxx;h=45aaf812dd75df17a02bc981bebf4232b6f29c06;hb=35ee8ee8af32946514713d271177df8bb2298eb2;hp=b75ecb9a8308707b63049a81299e0776ebcda228;hpb=2b0e408f3a5b86ef701f9da83d3dda0400facc67;p=gdcm.git diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index b75ecb9a..45aaf812 100644 --- a/src/gdcmPixelReadConvert.cxx +++ b/src/gdcmPixelReadConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.cxx,v $ Language: C++ - Date: $Date: 2007/09/05 08:22:57 $ - Version: $Revision: 1.122 $ + Date: $Date: 2008/05/20 09:22:03 $ + Version: $Revision: 1.128 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -24,6 +24,7 @@ #include "gdcmDocEntry.h" #include "gdcmRLEFramesInfo.h" #include "gdcmJPEGFragmentsInfo.h" +#include "gdcmSegmentedPalette.h" #include #include //for sscanf @@ -44,7 +45,7 @@ bool gdcm_read_JPEG2000_file (void* raw, //----------------------------------------------------------------------------- // Constructor / Destructor /// Constructor -PixelReadConvert::PixelReadConvert() +PixelReadConvert::PixelReadConvert() { RGB = 0; RGBSize = 0; @@ -70,7 +71,7 @@ PixelReadConvert::~PixelReadConvert() // Public /** * \brief Predicate to know whether the image[s] (once Raw) is RGB. - * \note See comments of \ref ConvertHandleColor + * \note See comments of ConvertHandleColor */ bool PixelReadConvert::IsRawRGB() { @@ -143,10 +144,10 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, while (true) // shorter to write than 'if elseif elseif elseif' ... { // mind the order : check the most usual first. - if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian) break; - if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian ) break; - if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian) break; - if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE) break; + if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian)) break; + if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian)) break; + if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian)) break; + if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE)) break; // DeflatedExplicitVRLittleEndian syntax means the whole Dataset (Header + Pixels) is compressed ! // Not dealt with ! (Parser hangs) //if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian) break; @@ -164,13 +165,14 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, while(true) { // mind the order : check the most usual first. - if( IsJPEGLossy = Global::GetTS()->IsJPEGLossy(ts) ) break; - if( IsJPEGLossless = Global::GetTS()->IsJPEGLossless(ts) ) break; - if( IsRLELossless = Global::GetTS()->IsRLELossless(ts) ) break; - if( IsJPEG2000 = Global::GetTS()->IsJPEG2000(ts) ) break; - if( IsMPEG = Global::GetTS()->IsMPEG(ts) ) break; - if( IsJPEGLS = Global::GetTS()->IsJPEGLS(ts) ) break; - // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' (we don't know yet how to process !) + if( IsJPEGLossy = (Global::GetTS()->IsJPEGLossy(ts))) break; + if( IsJPEGLossless = (Global::GetTS()->IsJPEGLossless(ts))) break; + if( IsRLELossless = (Global::GetTS()->IsRLELossless(ts))) break; + if( IsJPEG2000 = (Global::GetTS()->IsJPEG2000(ts))) break; + if( IsMPEG = (Global::GetTS()->IsMPEG(ts))) break; + if( IsJPEGLS = (Global::GetTS()->IsJPEGLS(ts))) break; + // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' + // (we don't know yet how to process !) gdcmWarningMacro("Unexpected Transfer Syntax :[" << ts << "]"); break; } @@ -194,51 +196,114 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, HasLUT = file->HasLUT(); if ( HasLUT ) { - // Just in case some access to a File element requires disk access. +/* + C.7.6.3.1.5 + The three values of Palette Color Lookup Table Descriptor (0028,1101-1103) + describe the format of the Lookup Table Data in the corresponding + Data Element (0028,1201-1203) or (0028,1221-1223). + + The first value is the number of entries in the lookup table. + When the number of table entries is equal to 2**16 then this value shall be 0. + + The second value is the first stored pixel value mapped. + This pixel value is mapped to the first entry in the Lookup Table Data. + All image pixel values less than the first entry value mapped are also + mapped to the first entry in the Lookup Table Data. + An image pixel value one greater than the first entry value mapped is + mapped to the second entry in the Lookup Table Data. + Subsequent image pixel values are mapped to the subsequent entries in + the Lookup Table Data up to an image pixel value equal to number of + entries + first entry value mapped - 1 which is mapped to the last entry + in the Lookup Table Data. + Image pixel values greater than or equal to number of entries + first entry + value mapped are also mapped to the last entry in the Lookup Table Data. + + The third value specifies the number of bits for each entry in the Lookup + Table Data. It shall take the value of 8 or 16. + The LUT Data shall be stored in a format equivalent to 8 or 16 bits + allocated where the high bit is equal to bits allocated-1. + + When the Palette Color Lookup Table Descriptor (0028,1101-1103) are used as + part of the Palette Color Lookup Table Module, the third value shall be + equal to 16. + + Note: A value of 16 indicates the Lookup Table Data will range from (0,0,0) + minimum intensity to (65535,65535,65535) maximum intensity. + +*/ + + // Just in case some access to a File element requires disk access. LutRedDescriptor = file->GetEntryString( 0x0028, 0x1101 ); LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 ); LutBlueDescriptor = file->GetEntryString( 0x0028, 0x1103 ); - - // FIXME : The following comment is probabely meaningless, since LUT are *always* - // loaded at parsing time, whatever their length is. - - // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE - // [ refer to invocation of Document::SetMaxSizeLoadEntry() in - // Document::Document() ], the loading of the value (content) of a - // [Bin|Val]Entry occurence migth have been hindered (read simply NOT - // loaded). Hence, we first try to obtain the LUTs data from the file - // and when this fails we read the LUTs data directly from disk. - // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge. - // We should NOT bypass the [Bin|Val]Entry class. Instead - // an access to an UNLOADED content of a [Bin|Val]Entry occurence - // (e.g. DataEntry::GetBinArea()) should force disk access from - // within the [Bin|Val]Entry class itself. The only problem - // is that the [Bin|Val]Entry is unaware of the FILE* is was - // parsed from. Fix that. FIXME. - - // //// Red round - file->LoadEntryBinArea(0x0028, 0x1201); - LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 ); - if ( ! LutRedData ) - { - gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data"); - } - - // //// Green round: - file->LoadEntryBinArea(0x0028, 0x1202); - LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 ); - if ( ! LutGreenData) - { - gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data"); - } - - // //// Blue round: - file->LoadEntryBinArea(0x0028, 0x1203); - LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 ); - if ( ! LutBlueData ) - { - gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data"); - } + // Is it a Segmented Palette ? Check if we find the red one: + if( file->GetDocEntry(0x0028,0x1221) ) // no need to check for blue & green + { + GDCM_NAME_SPACE::TagKey DCM_RedPaletteColorLookupTableDescriptor (0x0028, 0x1101); + GDCM_NAME_SPACE::TagKey DCM_GreenPaletteColorLookupTableDescriptor (0x0028, 0x1102); + GDCM_NAME_SPACE::TagKey DCM_BluePaletteColorLookupTableDescriptor (0x0028, 0x1103); + + GDCM_NAME_SPACE::TagKey DCM_SegmentedRedPaletteColorLookupTableData (0x0028, 0x1221); + GDCM_NAME_SPACE::TagKey DCM_SegmentedGreenPaletteColorLookupTableData (0x0028, 0x1222); + GDCM_NAME_SPACE::TagKey DCM_SegmentedBluePaletteColorLookupTableData (0x0028, 0x1223); + + + LutRedData = new uint8_t[65535*2]; // FIXME: leak + LutGreenData = new uint8_t[65535*2]; + LutBlueData = new uint8_t[65535*2]; + // TODO need to check file is indeed PALETTE COLOR: + ReadPaletteInto(file, DCM_RedPaletteColorLookupTableDescriptor, + DCM_SegmentedRedPaletteColorLookupTableData,LutRedData); + ReadPaletteInto(file, DCM_GreenPaletteColorLookupTableDescriptor, + DCM_SegmentedGreenPaletteColorLookupTableData,LutGreenData); + ReadPaletteInto(file, DCM_BluePaletteColorLookupTableDescriptor, + DCM_SegmentedBluePaletteColorLookupTableData,LutBlueData); + + } + else + { + + // FIXME : The following comment is probabely meaningless, since LUT are *always* + // loaded at parsing time, whatever their length is. + + // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE + // [ refer to invocation of Document::SetMaxSizeLoadEntry() in + // Document::Document() ], the loading of the value (content) of a + // [Bin|Val]Entry occurence migth have been hindered (read simply NOT + // loaded). Hence, we first try to obtain the LUTs data from the file + // and when this fails we read the LUTs data directly from disk. + // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge. + // We should NOT bypass the [Bin|Val]Entry class. Instead + // an access to an UNLOADED content of a [Bin|Val]Entry occurence + // (e.g. DataEntry::GetBinArea()) should force disk access from + // within the [Bin|Val]Entry class itself. The only problem + // is that the [Bin|Val]Entry is unaware of the FILE* is was + // parsed from. Fix that. FIXME. + + // //// Red round + file->LoadEntryBinArea(0x0028, 0x1201); + LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 ); + if ( ! LutRedData ) + { + gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data"); + } + + // //// Green round: + file->LoadEntryBinArea(0x0028, 0x1202); + LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 ); + if ( ! LutGreenData) + { + gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data"); + } + + // //// Blue round: + file->LoadEntryBinArea(0x0028, 0x1203); + LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 ); + if ( ! LutBlueData ) + { + gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data"); + } + } } FileInternal = file; FH = fileHelper; @@ -381,9 +446,9 @@ void PixelReadConvert::Squeeze() delete [] Raw; Raw = 0; - if ( LutRGBA ) - delete [] LutRGBA; - LutRGBA = 0; + //if ( LutRGBA ) + // delete [] LutRGBA; + //LutRGBA = 0; } /** @@ -614,7 +679,7 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) // if ( ! gdcm_read_JPEGLS_file( fp,Raw ) ) return false; } - else + else if( JPEGInfo ) { // make sure this is the right JPEG compression assert( !IsJPEGLS || !IsJPEG2000 ); @@ -631,6 +696,8 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) JPEGInfo->DecompressFromFile(fp, Raw, dummy, numberBytes, length ); return true; } + //else (not sure how get there...), must be one of those crazy DICOM file + return false; } /** @@ -856,7 +923,7 @@ void PixelReadConvert::BuildLUTRGBA() *a16 = 1; // Alpha component a16 += 4; } -/* Just to 'see' the LUT, at debug time +// Just to 'see' the LUT, at debug time // Don't remove this commented out code. a16=(uint16_t*)LutRGBA; @@ -866,12 +933,12 @@ void PixelReadConvert::BuildLUTRGBA() << *(a16+2) << " " << *(a16+3) << std::endl; a16+=4; } -*/ + } } /** - * \brief Swap the bytes, according to \ref SwapCode. + * \brief Swap the bytes, according to SwapCode. */ void PixelReadConvert::ConvertSwapZone() { @@ -1379,7 +1446,7 @@ void PixelReadConvert::ComputeRawAndRGBSizes() int bitsAllocated = BitsAllocated; // Number of "Bits Allocated" is fixed to 16 when it's 12, since // in this case we will expand the image to 16 bits (see - // \ref ReadAndDecompress12BitsTo16Bits() ) + // ReadAndDecompress12BitsTo16Bits() ) if ( BitsAllocated == 12 ) { bitsAllocated = 16;