X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmPixelReadConvert.cxx;h=b75ecb9a8308707b63049a81299e0776ebcda228;hb=336bf4a855ae72cfa933510e0f4b731c42ca33cf;hp=ee0eb6cff9a46c2b42bd60fedb78dff3bb8315ed;hpb=f58d0f1e0e1680554dcd631817b7f81968fdb950;p=gdcm.git diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index ee0eb6cf..b75ecb9a 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/08/29 08:10:14 $ - Version: $Revision: 1.117 $ + Date: $Date: 2007/09/05 08:22:57 $ + Version: $Revision: 1.122 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -35,7 +35,7 @@ namespace GDCM_NAME_SPACE { -//bool ReadMPEGFile (std::ifstream *fp, char *inputdata, size_t lenght); +//bool ReadMPEGFile (std::ifstream *fp, char *inputdata, size_t lenght); bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength); //----------------------------------------------------------------------------- @@ -97,11 +97,11 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, { BitsAllocated = 16; } - - else if (BitsAllocated > 8 && BitsAllocated < 16 && BitsAllocated != 12) + else if ( BitsAllocated > 8 && BitsAllocated < 16 && BitsAllocated != 12 ) { BitsAllocated = 16; - } + } + // Number of "Bits Stored", defaulted to number of "Bits Allocated" // when absent from the file. BitsStored = file->GetBitsStored(); @@ -154,13 +154,13 @@ void PixelReadConvert::GrabInformationsFromFile( File *file, } // cache whether this is a strange GE transfer syntax (which uses // a little endian transfer syntax for the header and a big endian - // transfer syntax for the pixel data). + // transfer syntax for the pixel data). IsPrivateGETransferSyntax = ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE ); - IsMPEG = IsJPEG2000 = IsJPEGLS = IsJPEGLossy = IsJPEGLossless = IsRLELossless = false; + IsMPEG = IsJPEG2000 = IsJPEGLS = IsJPEGLossy = IsJPEGLossless = IsRLELossless = false; if (!IsRaw) - { + { while(true) { // mind the order : check the most usual first. @@ -323,7 +323,7 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp ) } if (remainingLength !=0 ) fp->read( raw, remainingLength); - + if ( fp->fail() || fp->eof()) { gdcmWarningMacro( "Reading of Raw pixel data failed." ); @@ -513,33 +513,60 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) // jpeg2000 stream to use jasper: // I don't think we'll ever be able to deal with multiple fragments properly - unsigned long inputlength = 0; - JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment(); - while( jpegfrag ) - { + if( ZSize == 1 ) + { + unsigned long inputlength = 0; + JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment(); + while( jpegfrag ) + { inputlength += jpegfrag->GetLength(); jpegfrag = JPEGInfo->GetNextFragment(); - } - gdcmAssertMacro( inputlength != 0); - uint8_t *inputdata = new uint8_t[inputlength]; - char *pinputdata = (char*)inputdata; - jpegfrag = JPEGInfo->GetFirstFragment(); - while( jpegfrag ) - { + } + gdcmAssertMacro( inputlength != 0); + uint8_t *inputdata = new uint8_t[inputlength]; + char *pinputdata = (char*)inputdata; + jpegfrag = JPEGInfo->GetFirstFragment(); + while( jpegfrag ) + { fp->seekg( jpegfrag->GetOffset(), std::ios::beg); fp->read(pinputdata, jpegfrag->GetLength()); pinputdata += jpegfrag->GetLength(); jpegfrag = JPEGInfo->GetNextFragment(); - } - // Warning the inputdata buffer is delete in the function - if ( ! gdcm_read_JPEG2000_file( Raw, - (char*)inputdata, inputlength ) ) - { + } + // Warning the inputdata buffer is deleted in the function + if ( gdcm_read_JPEG2000_file( Raw, + (char*)inputdata, inputlength ) ) + { return true; - } - // wow what happen, must be an error - gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); - return false; + } + // wow what happen, must be an error + gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); + return false; + } + else + { + if( (unsigned int)ZSize != JPEGInfo->GetFragmentCount() ) + { + gdcmErrorMacro( "Sorry GDCM does not handle this type of fragments" ); + return false; + } + // Hopefully every dicom fragment is *exactly* the j2k stream + JPEGFragment *jpegfrag = JPEGInfo->GetFirstFragment(); + char *praw = (char*)Raw; + while( jpegfrag ) + { + unsigned long inputlength = jpegfrag->GetLength(); + char *inputdata = new char[inputlength]; + fp->seekg( jpegfrag->GetOffset(), std::ios::beg); + fp->read(inputdata, jpegfrag->GetLength()); + // Warning the inputdata buffer is deleted in the function + gdcm_read_JPEG2000_file( praw, + inputdata, inputlength) ; + praw += XSize*YSize*SamplesPerPixel*(BitsAllocated/8); + jpegfrag = JPEGInfo->GetNextFragment(); + } + return true; + } } else if ( IsJPEGLS ) { @@ -594,8 +621,14 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) // Precompute the offset localRaw will be shifted with int length = XSize * YSize * ZSize * SamplesPerPixel; int numberBytes = BitsAllocated / 8; - - JPEGInfo->DecompressFromFile(fp, Raw, BitsStored, numberBytes, length ); + + // to avoid major troubles when BitsStored == 8 && BitsAllocated==16 ! + int dummy; + if (BitsStored == 8 && BitsAllocated==16) + dummy = 16; + else + dummy = BitsStored; + JPEGInfo->DecompressFromFile(fp, Raw, dummy, numberBytes, length ); return true; } } @@ -1065,27 +1098,38 @@ bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError ) { // pmask : to mask the 'unused bits' (may contain overlays) uint16_t pmask = 0xffff; - pmask = pmask >> ( BitsAllocated - BitsStored ); + + // It's up to the user to decide if he wants to ignore overlays (if any), + // not to gdcm, without asking. + // default is NOT TO LOAD, in order not to confuse ITK users (and others!). + + if ( !FH->GetKeepOverlays() ) // mask spurious bits ! (overlay are NOT loaded!) + { + pmask = pmask >> ( BitsAllocated - BitsStored ); + } + // else : it's up to the user to manage the 'pixels + overlays' he just loaded! uint16_t *deb = (uint16_t*)Raw; if ( !PixelSign ) // Pixels are unsigned { for(int i = 0; i> (BitsStored - HighBitPosition - 1)) & pmask; deb++; } } else // Pixels are signed { + // Hope there is never ACR-NEMA-like overlays within signed pixels (?!?) + // 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 ); - + for(int i = 0; i> (BitsStored - HighBitPosition - 1); @@ -1187,9 +1231,9 @@ void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels() // 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 ); @@ -1199,7 +1243,7 @@ void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels() // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf // and be *very* affraid // - + /// \todo : find an example to see how 3rd dim and 4th dim work together int l = XSize * YSize * TSize; int nbFrames = ZSize; @@ -1351,7 +1395,6 @@ void PixelReadConvert::ComputeRawAndRGBSizes() else { RGBSize = RawSize; - } RawSize += RawSize%2; RGBSize += RGBSize%2; @@ -1444,7 +1487,6 @@ void PixelReadConvert::CallEndMethod() CommandManager::ExecuteCommand(FH,CMD_ENDPROGRESS); } - //----------------------------------------------------------------------------- } // end namespace gdcm