/*========================================================================= Program: gdcm Module: $RCSfile: gdcmRLEFramesInfo.cxx,v $ Language: C++ Date: $Date: 2007/05/23 14:18:11 $ Version: $Revision: 1.22 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "gdcmRLEFramesInfo.h" #include "gdcmDebug.h" #include "gdcmUtil.h" #if defined(__BORLANDC__) #include // for memset #endif namespace GDCM_NAME_SPACE { //------------------------------------------------------------------------- // Constructor / Destructor RLEFramesInfo::~RLEFramesInfo() { for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it) { delete (*it); } Frames.clear(); } //----------------------------------------------------------------------------- // Public void RLEFramesInfo::AddFrame(RLEFrame *frame) { Frames.push_back(frame); } RLEFrame *RLEFramesInfo::GetFirstFrame() { ItFrames = Frames.begin(); if (ItFrames != Frames.end()) return *ItFrames; return NULL; } RLEFrame *RLEFramesInfo::GetNextFrame() { gdcmAssertMacro (ItFrames != Frames.end()); ++ItFrames; if (ItFrames != Frames.end()) return *ItFrames; return NULL; } /** * \brief Reads from disk the Pixel Data of 'Run Length Encoded' * Dicom encapsulated file and decompress it. * @param fp already open File Pointer * from which the pixel data should be read * @param raw raw * @param xSize x Size * @param ySize y Size * @param zSize z Size * @param tSize t Size * @param bitsAllocated Bits allocated * @return Boolean */ bool RLEFramesInfo::DecompressRLEFile( std::ifstream *fp , uint8_t *raw, int xSize, int ySize, int zSize, int tSize, int bitsAllocated ) { uint8_t *subRaw = raw; long rawSegmentSize = xSize * ySize * tSize; // Loop on the frame[s] for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it) { subRaw = (*it)->ReadAndDecompressRLEFrame( subRaw, rawSegmentSize, fp); } if ( bitsAllocated == 16 ) { // Try to deal with RLE 16 Bits ConvertRLE16BitsFromRLE8Bits( raw, xSize, ySize, zSize, tSize ); } return true; } /** * \brief We assume Raw contains the decoded RLE pixels but as * 8 bits per pixel. We convert those pixels to 16 bits * per pixel. * @param raw raw * @param xSize x Size * @param ySize y Size * @param tSize t Size * @param numberOfFrames number of frames * @return Boolean always true */ bool RLEFramesInfo::ConvertRLE16BitsFromRLE8Bits(uint8_t *raw, int xSize, int ySize, int tSize, int numberOfFrames) { size_t pixelNumber = xSize * ySize * tSize; size_t rawSize = pixelNumber * numberOfFrames * 2; // We assumed Raw contains the decoded RLE pixels but as // 8 bits per pixel. In order to convert those pixels to 16 bits // per pixel we cannot work in place within Raw and hence // we copy it in a safe place, say copyRaw. uint8_t *copyRaw = new uint8_t[rawSize]; memmove( copyRaw, raw, rawSize ); uint8_t *x = raw; uint8_t *a; uint8_t *b; // Warning : unckecked patch to see the behaviour on Big Endian Processors if ( !Util::IsCurrentProcessorBigEndian() ) { a = copyRaw; // beginning of 'low bytes' b = a + pixelNumber; // beginning of 'hight bytes' } else { b = copyRaw; // beginning of 'low bytes' a = b + pixelNumber; // beginning of 'hight bytes' } // Re order bytes for ( int i = 0; i < numberOfFrames; i++ ) { for ( unsigned int j = 0; j < pixelNumber; j++ ) { *(x++) = *(b++); *(x++) = *(a++); } } delete[] copyRaw; return true; } //----------------------------------------------------------------------------- // Protected //----------------------------------------------------------------------------- // Private //----------------------------------------------------------------------------- // Print /** * \brief Print self. * @param indent Indentation string to be prepended during printing. * @param os Stream to print to. */ void RLEFramesInfo::Print( std::ostream &os, std::string indent ) { os << std::endl; os << indent << "----------------- RLE frames --------------------------------" << std::endl; os << indent << "Total number of Frames : " << Frames.size() << std::endl; int frameNumber = 0; /// \todo : find an example, to know haow 3rd and 4th dimension /// works together for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it) { os << indent << " frame number :" << frameNumber++ << std::endl; (*it)->Print( os, indent + " " ); } } //----------------------------------------------------------------------------- } // end namespace gdcm