+ LutBlueData = 0;
+}
+
+/// Canonical Destructor
+PixelReadConvert::~PixelReadConvert()
+{
+ Squeeze();
+}
+
+//-----------------------------------------------------------------------------
+// Public
+/**
+ * \brief Predicate to know whether the image[s] (once Raw) is RGB.
+ * \note See comments of \ref ConvertHandleColor
+ */
+bool PixelReadConvert::IsRawRGB()
+{
+ if ( IsMonochrome
+ || PlanarConfiguration == 2
+ || IsPaletteColor )
+ {
+ return false;
+ }
+ return true;
+}
+/**
+ * \brief Gets various usefull informations from the file header
+ * @param file gdcm::File pointer
+ */
+void PixelReadConvert::GrabInformationsFromFile( File *file )
+{
+ // Number of Bits Allocated for storing a Pixel is defaulted to 16
+ // when absent from the file.
+ BitsAllocated = file->GetBitsAllocated();
+ if ( BitsAllocated == 0 )
+ {
+ BitsAllocated = 16;
+ }
+
+ // Number of "Bits Stored", defaulted to number of "Bits Allocated"
+ // when absent from the file.
+ BitsStored = file->GetBitsStored();
+ if ( BitsStored == 0 )
+ {
+ BitsStored = BitsAllocated;
+ }
+
+ // High Bit Position, defaulted to "Bits Allocated" - 1
+ HighBitPosition = file->GetHighBitPosition();
+ if ( HighBitPosition == 0 )
+ {
+ HighBitPosition = BitsAllocated - 1;
+ }
+
+ XSize = file->GetXSize();
+ YSize = file->GetYSize();
+ ZSize = file->GetZSize();
+ SamplesPerPixel = file->GetSamplesPerPixel();
+ PixelSize = file->GetPixelSize();
+ PixelSign = file->IsSignedPixelData();
+ SwapCode = file->GetSwapCode();
+ std::string ts = file->GetTransferSyntax();
+ IsRaw =
+ ( ! file->IsDicomV3() )
+ || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian
+ || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndianDLXGE
+ || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian
+ || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian
+ || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian;
+
+ IsMPEG = Global::GetTS()->IsMPEG(ts);
+ IsJPEG2000 = Global::GetTS()->IsJPEG2000(ts);
+ IsJPEGLS = Global::GetTS()->IsJPEGLS(ts);
+ IsJPEGLossy = Global::GetTS()->IsJPEGLossy(ts);
+ IsJPEGLossless = Global::GetTS()->IsJPEGLossless(ts);
+ IsRLELossless = Global::GetTS()->IsRLELossless(ts);
+
+ PixelOffset = file->GetPixelOffset();
+ PixelDataLength = file->GetPixelAreaLength();
+ RLEInfo = file->GetRLEInfo();
+ JPEGInfo = file->GetJPEGInfo();
+
+ IsMonochrome = file->IsMonochrome();
+ IsMonochrome1 = file->IsMonochrome1();
+ IsPaletteColor = file->IsPaletteColor();
+ IsYBRFull = file->IsYBRFull();
+
+ PlanarConfiguration = file->GetPlanarConfiguration();
+
+ /////////////////////////////////////////////////////////////////
+ // LUT section:
+ HasLUT = file->HasLUT();
+ if ( HasLUT )
+ {
+ // Just in case some access to a File element requires disk access.
+ LutRedDescriptor = file->GetEntryValue( 0x0028, 0x1101 );
+ LutGreenDescriptor = file->GetEntryValue( 0x0028, 0x1102 );
+ LutBlueDescriptor = file->GetEntryValue( 0x0028, 0x1103 );
+
+ // 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. BinEntry::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 LUT data" );
+ }
+
+ // //// Green round:
+ file->LoadEntryBinArea(0x0028, 0x1202);
+ LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
+ if ( ! LutGreenData)
+ {
+ gdcmWarningMacro( "Unable to read Green LUT data" );
+ }
+
+ // //// Blue round:
+ file->LoadEntryBinArea(0x0028, 0x1203);
+ LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
+ if ( ! LutBlueData )
+ {
+ gdcmWarningMacro( "Unable to read Blue LUT data" );
+ }
+ }
+
+ ComputeRawAndRGBSizes();
+}
+
+/// \brief Reads from disk and decompresses Pixels
+bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
+{
+ // ComputeRawAndRGBSizes is already made by
+ // ::GrabInformationsFromfile. So, the structure sizes are
+ // correct
+ Squeeze();
+
+ //////////////////////////////////////////////////
+ //// First stage: get our hands on the Pixel Data.
+ if ( !fp )
+ {
+ gdcmWarningMacro( "Unavailable file pointer." );
+ return false;
+ }
+
+ fp->seekg( PixelOffset, std::ios::beg );
+ if( fp->fail() || fp->eof())
+ {
+ gdcmWarningMacro( "Unable to find PixelOffset in file." );
+ return false;
+ }
+
+ AllocateRaw();
+
+ //////////////////////////////////////////////////
+ //// Second stage: read from disk dans decompress.
+ if ( BitsAllocated == 12 )
+ {
+ ReadAndDecompress12BitsTo16Bits( fp);
+ }
+ else if ( IsRaw )
+ {
+ // This problem can be found when some obvious informations are found
+ // after the field containing the image data. In this case, these
+ // bad data are added to the size of the image (in the PixelDataLength
+ // variable). But RawSize is the right size of the image !
+ if( PixelDataLength != RawSize)
+ {
+ gdcmWarningMacro( "Mismatch between PixelReadConvert : "
+ << PixelDataLength << " and RawSize : " << RawSize );
+ }
+ if( PixelDataLength > RawSize)
+ {
+ fp->read( (char*)Raw, RawSize);
+ }
+ else
+ {
+ fp->read( (char*)Raw, PixelDataLength);
+ }
+
+ if ( fp->fail() || fp->eof())
+ {
+ gdcmWarningMacro( "Reading of Raw pixel data failed." );
+ return false;
+ }
+ }
+ else if ( IsRLELossless )
+ {
+ if ( ! RLEInfo->DecompressRLEFile( fp, Raw, XSize, YSize, ZSize, BitsAllocated ) )
+ {
+ gdcmWarningMacro( "RLE decompressor failed." );
+ return false;
+ }
+ }
+ else if ( IsMPEG )
+ {
+ gdcmWarningMacro( "Sorry, MPEG not yet taken into account" );
+ return false;
+ }
+ else
+ {
+ // Default case concerns JPEG family
+ if ( ! ReadAndDecompressJPEGFile( fp ) )
+ {
+ gdcmWarningMacro( "JPEG decompressor failed." );
+ return false;
+ }
+ }
+
+ ////////////////////////////////////////////
+ //// Third stage: twigle the bytes and bits.
+ ConvertReorderEndianity();
+ ConvertReArrangeBits();
+ ConvertFixGreyLevels();
+ ConvertHandleColor();
+
+ return true;