X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmRLE.cxx;h=72cf33403d244acd98670b8c02ad26fb964c259b;hb=d71e2e62b38383d9b960760f6d81c4d545d59fba;hp=e927c298d1e2fbacb377be608fb01131ab890f5c;hpb=eb941e8785d3742b8a6a1aac964d43dcb4cf49f0;p=gdcm.git diff --git a/src/gdcmRLE.cxx b/src/gdcmRLE.cxx index e927c298..72cf3340 100644 --- a/src/gdcmRLE.cxx +++ b/src/gdcmRLE.cxx @@ -1,51 +1,186 @@ -//This is needed when compiling in debug mode -#ifdef _MSC_VER -// 'identifier' : class 'type' needs to have dll-interface to be used by -// clients of class 'type2' -#pragma warning ( disable : 4251 ) -// 'identifier' : identifier was truncated to 'number' characters in the -// debug information -#pragma warning ( disable : 4786 ) -#endif //_MSC_VER +/*========================================================================= + + Program: gdcm + Module: $RCSfile: gdcmRLE.cxx,v $ + Language: C++ + Date: $Date: 2004/06/23 03:36:24 $ + Version: $Revision: 1.19 $ + + 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.htm 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 #include "gdcmFile.h" -#include "jpeg/libijg8/cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ -#include "jpeg/libijg8/jversion.h" /* for version message */ -#include /* to declare isprint() */ -/* Create the add-on message string table. */ - -#define JMESSAGE(code,string) string , - -static const char * const cdjpeg_message_table[] = { -#include "jpeg/libijg8/cderror.h" - NULL -}; +#include // For isprint() + +#define str2num(str, typeNum) *((typeNum *)(str)) + +//----------------------------------------------------------------------------- +/** + * \ingroup gdcmFile + * \brief Reads a 'Run Length Encoded' Dicom encapsulated file + * @param fp already open File Pointer + * @param image_buffer destination Address (in caller's memory space) + * at which the pixel data should be copied + * @return Boolean + */ +bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) { + long fragmentBegining; // for ftell, fseek + char * im = (char *)image_buffer; + + long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;; + long ftellRes, ln; + guint32 nbRleSegments; + guint32 RleSegmentOffsetTable[15]; + guint16 ItemTagGr,ItemTagEl; + uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize(); + ftellRes=ftell(fp); + // Basic Offset Table with Item Value + // Item Tag + fread(&ItemTagGr,2,1,fp); // Reading (fffe):Basic Offset Table Item Tag Gr + fread(&ItemTagEl,2,1,fp); // Reading (e000):Basic Offset Table Item Tag El + if(Header->GetSwapCode()) { + ItemTagGr=Header->SwapShort(ItemTagGr); + ItemTagEl=Header->SwapShort(ItemTagEl); + } + // Item Length + ftellRes=ftell(fp); + fread(&ln,4,1,fp); + if(Header->GetSwapCode()) + ln=Header->SwapLong(ln); // Basic Offset Table Item Lentgh + if (ln != 0) { + // What is it used for ?? + char * BasicOffsetTableItemValue= new char[ln+1]; + fread(BasicOffsetTableItemValue,ln,1,fp); + guint32 a; + for (int i=0;iGetSwapCode()) { + ItemTagGr=Header->SwapShort(ItemTagGr); + ItemTagEl=Header->SwapShort(ItemTagEl); + } + + // while 'Sequence Delimiter Item' (fffe,e0dd) not found + while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { + // Parse fragments of the current Fragment (Frame) + ftellRes=ftell(fp); + fread(&fragmentLength,4,1,fp); + if(Header->GetSwapCode()) + fragmentLength=Header->SwapLong(fragmentLength); // length + + //------------------ scanning (not reading) fragment pixels - /* -------------------------------------------------------------------- */ - // - // RLE LossLess Files - // - /* -------------------------------------------------------------------- */ - -int -gdcmFile::gdcm_read_RLE_file (void * image_buffer) { - - - - - - - - - - - - + fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments + if(Header->GetSwapCode()) + nbRleSegments=Header->SwapLong(nbRleSegments); + + for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table + ftellRes=ftell(fp); + fread(&RleSegmentOffsetTable[k],4,1,fp); + if(Header->GetSwapCode()) + RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]); + } + + if (nbRleSegments>1) { + for(unsigned int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments + RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k]; + ftellRes=ftell(fp); + fragmentBegining=ftell(fp); + gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp); + fseek(fp,fragmentBegining,SEEK_SET); + fseek(fp,RleSegmentLength[k],SEEK_CUR); + } + } + RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments]; + ftellRes=ftell(fp); + fragmentBegining=ftell(fp); + gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp); + fseek(fp,fragmentBegining,SEEK_SET); + fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR); + + // end of scanning fragment pixels + + ftellRes=ftell(fp); + fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr + fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El + if(Header->GetSwapCode()) { + ItemTagGr=Header->SwapShort(ItemTagGr); + ItemTagEl=Header->SwapShort(ItemTagEl); + } + } + + if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits + + im = (char *)image_buffer; + // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes' + + int l = Header->GetXSize()*Header->GetYSize(); + int nbFrames = Header->GetZSize(); + + char * newDest = new char[l*nbFrames*2]; + char *x = newDest; + char * a = (char *)image_buffer; + char * b = a + l; + + for (int i=0;i= 0 && count <= 127) { + fread(*areaToRead,(count+1)*sizeof(char),1,fp); + *areaToRead+=count+1; + numberOfOutputBytes+=count+1; + } else { + if (count <= -1 && count >= -127) { + fread(&car,sizeof(char),1,fp); + for(int i=0; i<-count+1; i++) { + (*areaToRead)[i]=car; + } + *areaToRead+=(-count+1); + numberOfOutputBytes+=(-count+1); + } + } + // if count = 128 output nothing (See : PS 3.5-2003 Page 86) + } + return 1; } + +// ----------------------------------------------------------------------------