X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmPixelReadConvert.cxx;h=9b97cbb171e525e98fc0ea176a36a55d2e208ddc;hb=eeb624df6a1661e969566c200505f3dac84f4cd6;hp=264f30bc7343543efd45a93140b556eb6f4dc4e0;hpb=06c8a65724fa7d53ee2c97b72f8ac9de5f375a18;p=gdcm.git diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index 264f30bc..9b97cbb1 100644 --- a/src/gdcmPixelReadConvert.cxx +++ b/src/gdcmPixelReadConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.cxx,v $ Language: C++ - Date: $Date: 2005/06/17 12:35:00 $ - Version: $Revision: 1.67 $ + Date: $Date: 2005/07/01 11:25:51 $ + Version: $Revision: 1.74 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -50,6 +50,8 @@ PixelReadConvert::PixelReadConvert() LutRedData = 0; LutGreenData = 0; LutBlueData = 0; + RLEInfo = 0; + JPEGInfo = 0; } /// Canonical Destructor @@ -167,7 +169,7 @@ void PixelReadConvert::GrabInformationsFromFile( File *file ) LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 ); if ( ! LutRedData ) { - gdcmWarningMacro( "Unable to read Red LUT data" ); + gdcmWarningMacro( "Unable to read Red Palette Color Lookup Table data" ); } // //// Green round: @@ -175,7 +177,7 @@ void PixelReadConvert::GrabInformationsFromFile( File *file ) LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 ); if ( ! LutGreenData) { - gdcmWarningMacro( "Unable to read Green LUT data" ); + gdcmWarningMacro( "Unable to read Green Palette Color Lookup Table data" ); } // //// Blue round: @@ -183,7 +185,7 @@ void PixelReadConvert::GrabInformationsFromFile( File *file ) LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 ); if ( ! LutBlueData ) { - gdcmWarningMacro( "Unable to read Blue LUT data" ); + gdcmWarningMacro( "Unable to read Blue Palette Color Lookup Table data" ); } } @@ -207,7 +209,7 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) } fp->seekg( PixelOffset, std::ios::beg ); - if( fp->fail() || fp->eof()) + if ( fp->fail() || fp->eof() ) { gdcmWarningMacro( "Unable to find PixelOffset in file." ); return false; @@ -216,7 +218,7 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) AllocateRaw(); ////////////////////////////////////////////////// - //// Second stage: read from disk dans decompress. + //// Second stage: read from disk and decompress. if ( BitsAllocated == 12 ) { ReadAndDecompress12BitsTo16Bits( fp); @@ -227,12 +229,12 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) // 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) + if ( PixelDataLength != RawSize ) { gdcmWarningMacro( "Mismatch between PixelReadConvert : " << PixelDataLength << " and RawSize : " << RawSize ); } - if( PixelDataLength > RawSize) + if ( PixelDataLength > RawSize ) { fp->read( (char*)Raw, RawSize); } @@ -321,12 +323,14 @@ bool PixelReadConvert::BuildRGBImage() // The job can't be done return false; } + + gdcmWarningMacro( "--> BuildRGBImage" ); // Build RGB Pixels AllocateRGB(); int j; - if( BitsAllocated <= 8) + if ( BitsAllocated <= 8 ) { uint8_t *localRGB = RGB; for (size_t i = 0; i < RawSize; ++i ) @@ -420,7 +424,7 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) assert( !IsJPEGLossless || !IsJPEGLossy || !IsJPEGLS ); // FIXME this is really ugly but it seems I have to load the complete // jpeg2000 stream to use jasper: - // I don't think we'll ever be able to deal with multiple fragments properly + // I don't think we'll ever be able to deal with multiple fragments properly unsigned long inputlength = 0; JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment(); @@ -555,7 +559,7 @@ void PixelReadConvert::BuildLUTRGBA() nbRead = sscanf( LutRedDescriptor.c_str(), "%d\\%d\\%d", &lengthR, &debR, &nbitsR ); - if( nbRead != 3 ) + if ( nbRead != 3 ) { gdcmWarningMacro( "Wrong Red LUT descriptor" ); } @@ -566,7 +570,7 @@ void PixelReadConvert::BuildLUTRGBA() nbRead = sscanf( LutGreenDescriptor.c_str(), "%d\\%d\\%d", &lengthG, &debG, &nbitsG ); - if( nbRead != 3 ) + if ( nbRead != 3 ) { gdcmWarningMacro( "Wrong Green LUT descriptor" ); } @@ -577,7 +581,7 @@ void PixelReadConvert::BuildLUTRGBA() nbRead = sscanf( LutRedDescriptor.c_str(), "%d\\%d\\%d", &lengthB, &debB, &nbitsB ); - if( nbRead != 3 ) + if ( nbRead != 3 ) { gdcmWarningMacro( "Wrong Blue LUT descriptor" ); } @@ -591,7 +595,7 @@ void PixelReadConvert::BuildLUTRGBA() if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143 lengthR=65536; - if( !lengthG ) // if = 2^16, this shall be 0 + if ( !lengthG ) // if = 2^16, this shall be 0 lengthG=65536; if ( !lengthB ) // if = 2^16, this shall be 0 lengthB=65536; @@ -606,7 +610,7 @@ void PixelReadConvert::BuildLUTRGBA() // ------------------------------------------------------------- - if ( BitsAllocated <= 8) + if ( BitsAllocated <= 8 ) { // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha) @@ -640,10 +644,14 @@ void PixelReadConvert::BuildLUTRGBA() //take "Subscript of the first Lut Value" (debR,debG,debB) into account! + //FIXME : +1 : to get 'low value' byte + // Trouble expected on Big Endian Processors ? + // 16 BIts Per Pixel Palette Color to be swapped? + a = LutRGBA + 0 + debR; for( i=0; i < lengthR; ++i ) { - *a = LutRedData[i*mult+1]; + *a = LutRedData[i*mult+1]; a += 4; } @@ -660,7 +668,7 @@ void PixelReadConvert::BuildLUTRGBA() *a = LutBlueData[i*mult+1]; a += 4; } - + a = LutRGBA + 3 ; for(i=0; i < 256; ++i) { @@ -719,7 +727,8 @@ void PixelReadConvert::BuildLUTRGBA() *a16 = 1; // Alpha component a16 += 4; } -/* +/* Just to 'see' the LUT, at debug time + a16=(uint16_t*)LutRGBA; for (int j=0;j<65536;j++) { @@ -738,7 +747,7 @@ void PixelReadConvert::ConvertSwapZone() { unsigned int i; - if( BitsAllocated == 16 ) + if ( BitsAllocated == 16 ) { uint16_t *im16 = (uint16_t*)Raw; switch( SwapCode ) @@ -757,7 +766,7 @@ void PixelReadConvert::ConvertSwapZone() gdcmWarningMacro("SwapCode value (16 bits) not allowed."); } } - else if( BitsAllocated == 32 ) + else if ( BitsAllocated == 32 ) { uint32_t s32; uint16_t high; @@ -823,7 +832,7 @@ void PixelReadConvert::ConvertReorderEndianity() uint16_t *deb = (uint16_t *)Raw; for(int i = 0; i> ( BitsAllocated - BitsStored ); + // pmask : to mask the 'unused bits' (may contain overlays) + uint16_t pmask = 0xffff; + pmask = pmask >> ( BitsAllocated - BitsStored ); + uint16_t *deb = (uint16_t*)Raw; - for(int i = 0; i> (BitsStored - HighBitPosition - 1)) & mask; - deb++; + for(int i = 0; i> (BitsStored - HighBitPosition - 1)) & pmask; + deb++; + } + } + else // Pixels are signed + { + // smask : to check the 'sign' when BitsStored != BitsAllocated + uint16_t smask = 0x0001; + smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) ); + // nmask : to propagate sign bit on negative values + int16_t nmask = (int16_t)0x8000; + nmask = nmask >> ( BitsAllocated - BitsStored - 1 ); +/* +std::cout << "BitsStored " << BitsStored + << " BitsAllocated " << BitsAllocated + << std::endl; +std::cout << std::hex << "pmask " << pmask + << " smask " << smask + << " nmask " << nmask + << std::endl; +*/ + for(int i = 0; i> (BitsStored - HighBitPosition - 1); + if ( *deb & smask ) + { + *deb = *deb | nmask; + } + else + { + *deb = *deb & pmask; + } + deb++; + } } } else if ( BitsAllocated == 32 ) { - uint32_t mask = 0xffffffff; - mask = mask >> ( BitsAllocated - BitsStored ); + // pmask : to mask the 'unused bits' (may contain overlays) + uint32_t pmask = 0xffffffff; + pmask = pmask >> ( BitsAllocated - BitsStored ); + uint32_t *deb = (uint32_t*)Raw; - for(int i = 0; i> (BitsStored - HighBitPosition - 1)) & mask; - deb++; + for(int i = 0; i> (BitsStored - HighBitPosition - 1)) & pmask; + deb++; + } + } + else + { + // smask : to check the 'sign' when BitsStored != BitsAllocated + uint32_t smask = 0x00000001; + smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 )); + // nmask : to propagate sign bit on negative values + int32_t nmask = 0x80000000; + nmask = nmask >> ( BitsAllocated - BitsStored -1 ); + + for(int i = 0; i> (BitsStored - HighBitPosition - 1); + if ( *deb & smask ) + *deb = *deb | nmask; + else + *deb = *deb & pmask; + deb++; + } } } else { - gdcmWarningMacro("Weird image"); + gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)"); throw FormatError( "Weird image !?" ); } } @@ -947,6 +1019,8 @@ bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError ) */ void PixelReadConvert::ConvertRGBPlanesToRGBPixels() { + gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels"); + uint8_t *localRaw = Raw; uint8_t *copyRaw = new uint8_t[ RawSize ]; memmove( copyRaw, localRaw, RawSize ); @@ -977,10 +1051,12 @@ void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels() // just the color space is YCbCr instead of RGB. This is particularly useful // for doppler ultrasound where most of the image is grayscale // (i.e. only populates the Y components) and Cb and Cr are mostly zero, - // except for the few patches of color on the image. // + // except for the few patches of color on the image. // On such images, RLE achieves a compression ratio that is much better // than the compression ratio on an equivalent RGB image. - + + gdcmWarningMacro("--> ConvertYcBcRPlanesToRGBPixels"); + uint8_t *localRaw = Raw; uint8_t *copyRaw = new uint8_t[ RawSize ]; memmove( copyRaw, localRaw, RawSize ); @@ -1079,9 +1155,13 @@ void PixelReadConvert::ConvertHandleColor() // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels() // - [Planar 2] OR [Photo D] requires LUT intervention. + gdcmWarningMacro("--> ConvertHandleColor" + << "Planar Configuration " << PlanarConfiguration ); + if ( ! IsRawRGB() ) { // [Planar 2] OR [Photo D]: LUT intervention done outside + gdcmWarningMacro("--> RawRGB : LUT intervention done outside"); return; } @@ -1090,22 +1170,27 @@ void PixelReadConvert::ConvertHandleColor() if ( IsYBRFull ) { // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB) + gdcmWarningMacro("--> YBRFull"); ConvertYcBcRPlanesToRGBPixels(); } else { // [Planar 1] AND [Photo C] + gdcmWarningMacro("--> YBRFull"); ConvertRGBPlanesToRGBPixels(); } return; } // When planarConf is 0, and RLELossless (forbidden by Dicom norm) - // pixels need to be RGB-fied anyway + // pixels need to be RGB-fyied anyway + if (IsRLELossless) - { + { + gdcmWarningMacro("--> RLE Lossless"); ConvertRGBPlanesToRGBPixels(); } + // In *normal *case, when planarConf is 0, pixels are already in RGB }