X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmRLEFrame.cxx;h=d22e21fd9af237285574dbcb5b470406d5e1d241;hb=6278320cc85da00d2d56ffbf07806e84966892c3;hp=8ebb8f61d4619a69604b9da3705bfb30f0ac7c92;hpb=e8caac199c2683cb0f118c42c61dc6aec85b1eec;p=gdcm.git diff --git a/src/gdcmRLEFrame.cxx b/src/gdcmRLEFrame.cxx index 8ebb8f61..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/16 04:50:42 $ - Version: $Revision: 1.2 $ + 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 @@ -17,21 +17,136 @@ =========================================================================*/ #include "gdcmRLEFrame.h" +#include "gdcmDebug.h" -namespace gdcm +namespace GDCM_NAME_SPACE { +//------------------------------------------------------------------------- +// Constructor / Destructor +//----------------------------------------------------------------------------- +// Public +void RLEFrame::SetOffset(unsigned int id,long offset) +{ + gdcmAssertMacro(id<15); + Offset[id] = offset; +} + +long RLEFrame::GetOffset(unsigned int id) +{ + gdcmAssertMacro(id<15); + return Offset[id]; +} + +void RLEFrame::SetLength(unsigned int id,long length) +{ + gdcmAssertMacro(id<15); + Length[id] = length; +} + +long RLEFrame::GetLength(unsigned int id) +{ + gdcmAssertMacro(id<15); + 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 indent ) +void RLEFrame::Print( std::ostream &os, std::string const &indent ) { os << indent << "--- fragments" << std::endl; - for ( unsigned int i = 0; i < NumberFragments; i++ ) + for ( unsigned int i = 0; i < NumberOfFragments; i++ ) { os << indent << " offset : " << Offset[i] @@ -40,5 +155,6 @@ void RLEFrame::Print( std::ostream &os, std::string indent ) } } +//----------------------------------------------------------------------------- } // end namespace gdcm