1 /*=========================================================================
4 Module: $RCSfile: gdcmRLE.cxx,v $
6 Date: $Date: 2004/06/26 04:09:33 $
7 Version: $Revision: 1.20 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.htm for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
21 #include <ctype.h> // For isprint()
23 #define str2num(str, typeNum) *((typeNum *)(str))
25 //-----------------------------------------------------------------------------
28 * \brief Reads a 'Run Length Encoded' Dicom encapsulated file
29 * @param fp already open File Pointer
30 * @param image_buffer destination Address (in caller's memory space)
31 * at which the pixel data should be copied
34 bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
35 long fragmentBegining; // for ftell, fseek
36 char * im = (char *)image_buffer;
38 long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
40 guint32 nbRleSegments;
41 guint32 RleSegmentOffsetTable[15];
42 guint16 ItemTagGr,ItemTagEl;
43 uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize();
45 // Basic Offset Table with Item Value
47 fread(&ItemTagGr,2,1,fp); // Reading (fffe):Basic Offset Table Item Tag Gr
48 fread(&ItemTagEl,2,1,fp); // Reading (e000):Basic Offset Table Item Tag El
49 if(Header->GetSwapCode()) {
50 ItemTagGr=Header->SwapShort(ItemTagGr);
51 ItemTagEl=Header->SwapShort(ItemTagEl);
56 if(Header->GetSwapCode())
57 ln=Header->SwapLong(ln); // Basic Offset Table Item Lentgh
59 // What is it used for ??
60 char * BasicOffsetTableItemValue= new char[ln+1];
61 fread(BasicOffsetTableItemValue,ln,1,fp);
63 for (int i=0;i<ln;i+=4){
64 a=str2num(&BasicOffsetTableItemValue[i],guint32);
69 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
70 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
71 if(Header->GetSwapCode()) {
72 ItemTagGr=Header->SwapShort(ItemTagGr);
73 ItemTagEl=Header->SwapShort(ItemTagEl);
76 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
77 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
78 // Parse fragments of the current Fragment (Frame)
80 fread(&fragmentLength,4,1,fp);
81 if(Header->GetSwapCode())
82 fragmentLength=Header->SwapLong(fragmentLength); // length
84 //------------------ scanning (not reading) fragment pixels
86 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
87 if(Header->GetSwapCode())
88 nbRleSegments=Header->SwapLong(nbRleSegments);
90 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
92 fread(&RleSegmentOffsetTable[k],4,1,fp);
93 if(Header->GetSwapCode())
94 RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
97 if (nbRleSegments>1) {
98 for(unsigned int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
99 RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
101 fragmentBegining=ftell(fp);
102 gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
103 fseek(fp,fragmentBegining,SEEK_SET);
104 fseek(fp,RleSegmentLength[k],SEEK_CUR);
107 RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
109 fragmentBegining=ftell(fp);
110 gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
111 fseek(fp,fragmentBegining,SEEK_SET);
112 fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);
114 // end of scanning fragment pixels
117 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
118 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
119 if(Header->GetSwapCode()) {
120 ItemTagGr=Header->SwapShort(ItemTagGr);
121 ItemTagEl=Header->SwapShort(ItemTagEl);
125 if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits
127 im = (char *)image_buffer;
128 // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
130 int l = Header->GetXSize()*Header->GetYSize();
131 int nbFrames = Header->GetZSize();
133 char * newDest = new char[l*nbFrames*2];
135 char * a = (char *)image_buffer;
138 for (int i=0;i<nbFrames;i++) {
139 for (int j=0;j<l; j++) {
144 memmove(image_buffer,newDest,ImageDataSize);
152 // ----------------------------------------------------------------------------
153 // RLE LossLess Fragment
154 int gdcmFile::gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode,
155 long uncompressedSegmentSize, FILE *fp) {
156 (void)lengthToDecode; //FIXME
159 long numberOfOutputBytes=0;
163 while(numberOfOutputBytes<uncompressedSegmentSize) {
165 fread(&n,sizeof(char),1,fp);
167 if (count >= 0 && count <= 127) {
168 fread(*areaToRead,(count+1)*sizeof(char),1,fp);
169 *areaToRead+=count+1;
170 numberOfOutputBytes+=count+1;
172 if (count <= -1 && count >= -127) {
173 fread(&car,sizeof(char),1,fp);
174 for(int i=0; i<-count+1; i++) {
175 (*areaToRead)[i]=car;
177 *areaToRead+=(-count+1);
178 numberOfOutputBytes+=(-count+1);
181 // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
186 // ----------------------------------------------------------------------------