X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmRLEFrame.cxx;h=d22e21fd9af237285574dbcb5b470406d5e1d241;hb=713d0f3d28a6176fab6d57e031633061dc7354a7;hp=7ed3a0a91b66f4bf1e67017a1bfce2375ba12561;hpb=a4cff04fcd2023f798a9f1ef6bc9307269abd185;p=gdcm.git diff --git a/src/gdcmRLEFrame.cxx b/src/gdcmRLEFrame.cxx index 7ed3a0a9..d22e21fd 100644 --- a/src/gdcmRLEFrame.cxx +++ b/src/gdcmRLEFrame.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmRLEFrame.cxx,v $ Language: C++ - Date: $Date: 2005/01/26 11:42:02 $ - Version: $Revision: 1.3 $ + Date: $Date: 2007/05/23 14:18:11 $ + Version: $Revision: 1.13 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -19,28 +19,13 @@ #include "gdcmRLEFrame.h" #include "gdcmDebug.h" -namespace gdcm +namespace GDCM_NAME_SPACE { +//------------------------------------------------------------------------- +// Constructor / Destructor -/** - * \brief Print self. - * @param indent Indentation string to be prepended during printing. - * @param os Stream to print to. - */ -void RLEFrame::Print( std::ostream &os, std::string indent ) -{ - os << indent - << "--- fragments" - << std::endl; - for ( unsigned int i = 0; i < NumberFragments; i++ ) - { - os << indent - << " offset : " << Offset[i] - << " length : " << Length[i] - << std::endl; - } -} - +//----------------------------------------------------------------------------- +// Public void RLEFrame::SetOffset(unsigned int id,long offset) { gdcmAssertMacro(id<15); @@ -65,5 +50,111 @@ long RLEFrame::GetLength(unsigned int id) return Length[id]; } +uint8_t *RLEFrame::ReadAndDecompressRLEFrame( uint8_t *subRaw, + long rawSegmentSize, + std::ifstream *fp ) +{ + // Loop on the fragments + for( unsigned int k = 1; k <= NumberOfFragments; k++ ) + { + // First thing need to reset file to proper position: + fp->seekg(Offset[k], std::ios::beg); + ReadAndDecompressRLEFragment(subRaw, Length[k], + rawSegmentSize, fp); + subRaw += rawSegmentSize; + } + + return subRaw; +} + +/** + * \brief Implementation of the RLE decoding algorithm for decompressing + * a RLE fragment. [refer to PS 3.5-2003, section G.3.2 p 86] + * @param subRaw Sub region where the decoded fragment should be placed. + * @param fragmentSize The length of the binary fragment as found on the disk. + * @param rawSegmentSize The expected length of the fragment ONCE Raw. + * @param fp File Pointer: on entry the position should be the one of + * the fragment to be decoded. + */ +bool RLEFrame::ReadAndDecompressRLEFragment( uint8_t *subRaw, + long fragmentSize, + long rawSegmentSize, + std::ifstream *fp ) +{ + int8_t count; + long numberOfOutputBytes = 0; + long numberOfReadBytes = 0; + + while( numberOfOutputBytes < rawSegmentSize ) + { + fp->read( (char*)&count, 1 ); + numberOfReadBytes += 1; + if ( count >= 0 ) + // Note: count <= 127 comparison is always true due to limited range + // of data type int8_t [since the maximum of an exact width + // signed integer of width N is 2^(N-1) - 1, which for int8_t + // is 127]. + { + fp->read( (char*)subRaw, count + 1); + numberOfReadBytes += count + 1; + subRaw += count + 1; + numberOfOutputBytes += count + 1; + } + else + { + if ( count <= -1 && count >= -127 ) + { + int8_t newByte; + fp->read( (char*)&newByte, 1); + numberOfReadBytes += 1; + for( int i = 0; i < -count + 1; i++ ) + { + subRaw[i] = newByte; + } + subRaw += -count + 1; + numberOfOutputBytes += -count + 1; + } + } + // if count = 128 output nothing + + if ( numberOfReadBytes > fragmentSize ) + { + gdcmWarningMacro( "Read more bytes (" << numberOfReadBytes + << " ) than the segment size. (" + << fragmentSize << ")" ); + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Protected + +//----------------------------------------------------------------------------- +// Private + +//----------------------------------------------------------------------------- +// Print +/** + * \brief Print self. + * @param indent Indentation string to be prepended during printing. + * @param os Stream to print to. + */ +void RLEFrame::Print( std::ostream &os, std::string const &indent ) +{ + os << indent + << "--- fragments" + << std::endl; + for ( unsigned int i = 0; i < NumberOfFragments; i++ ) + { + os << indent + << " offset : " << Offset[i] + << " length : " << Length[i] + << std::endl; + } +} + +//----------------------------------------------------------------------------- } // end namespace gdcm