]> Creatis software - gdcm.git/blob - src/gdcmRLE.cxx
8930df2118ff953b836bc65b6aee05b3144160ef
[gdcm.git] / src / gdcmRLE.cxx
1
2 #include <stdio.h>
3 #include "gdcmFile.h"
4 #include <ctype.h>              /* to declare isprint() */
5
6 #define str2num(str, typeNum) *((typeNum *)(str))
7
8 static int _gdcm_read_RLE_fragment (char ** image_buffer, 
9                                     long lengthToDecode,
10                                     long uncompressedSegmentSize, 
11                                     FILE* fp);
12 // static because nothing but gdcm_read_RLE_file may call it
13
14 #define DEBUG 0
15 // Will be removed
16
17 // ----------------------------------------------------------------------------
18 /**
19  * \ingroup   gdcmFile
20  * \brief     Reads a 'Run Length Encoded' Dicom encapsulated file
21  * @param     image_buffer destination Address (in caller's memory space) 
22  *            at which the pixel data should be copied
23  *   
24  * @return    int acts as a Boolean 
25  */
26
27 // This is a debug version.
28 // Forget the printf as they will be removed
29 // as soon as the last Heuristics are checked
30
31 // pb with RLE 16 Bits : 
32
33
34 int
35 gdcmFile::gdcm_read_RLE_file (void * image_buffer) {
36    long fragmentBegining; // for ftell, fseek
37    char * im = (char *)image_buffer;
38    if (DEBUG)std::cout << "RLE image" << std::endl;
39
40    long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
41    long ftellRes, ln;
42    guint32 nbRleSegments;
43    guint32 RleSegmentOffsetTable[15];
44    guint16 ItemTagGr,ItemTagEl;
45    uncompressedSegmentSize=GetXSize()*GetYSize();
46    if (DEBUG)printf("uncompressedSegmentSize %d\n",uncompressedSegmentSize);
47    ftellRes=ftell(fp);
48    // Basic Offset Table with Item Value
49       // Item Tag
50    fread(&ItemTagGr,2,1,fp);  // Reading (fffe):Basic Offset Table Item Tag Gr
51    fread(&ItemTagEl,2,1,fp);  // Reading (e000):Basic Offset Table Item Tag El
52    if(GetSwapCode()) {
53       ItemTagGr=SwapShort(ItemTagGr); 
54       ItemTagEl=SwapShort(ItemTagEl);      
55    }
56    if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
57           ftellRes,ItemTagGr,ItemTagEl );
58       // Item Length
59    ftellRes=ftell(fp);
60    fread(&ln,4,1,fp); 
61    if(GetSwapCode()) 
62       ln=SwapLong(ln);    // Basic Offset Table Item Lentgh
63    if (DEBUG)printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
64          ftellRes,ln,ln);
65    if (ln != 0) {
66       // What is it used for ??
67       char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
68       fread(BasicOffsetTableItemValue,ln,1,fp); 
69       guint32 a;
70       for (int i=0;i<ln;i+=4){
71          a=str2num(&BasicOffsetTableItemValue[i],guint32);
72         if (DEBUG)printf("      x(%08x)  %d\n",a,a);
73       }        
74    }
75
76    ftellRes=ftell(fp);
77    fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
78    fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
79    if(GetSwapCode()) {
80       ItemTagGr=SwapShort(ItemTagGr); 
81       ItemTagEl=SwapShort(ItemTagEl);      
82    }  
83    if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
84          ftellRes,ItemTagGr,ItemTagEl );
85
86    // while 'Sequence Delimiter Item' (fffe,e0dd) not found
87    while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
88    // Parse fragments of the current Fragment (Frame)    
89       ftellRes=ftell(fp);
90       fread(&fragmentLength,4,1,fp); 
91       if(GetSwapCode()) 
92          fragmentLength=SwapLong(fragmentLength);    // length
93       if (DEBUG)printf("      at %x : fragment length %d x(%08x)\n",
94              ftellRes, fragmentLength,fragmentLength);
95
96           //------------------ scanning (not reading) fragment pixels
97  
98       fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments        
99       if(GetSwapCode()) 
100          nbRleSegments=SwapLong(nbRleSegments);
101          if (DEBUG)printf("         Nb of RLE Segments : %d\n",nbRleSegments);
102  
103       for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
104          ftellRes=ftell(fp);
105          fread(&RleSegmentOffsetTable[k],4,1,fp);
106          if(GetSwapCode())
107             RleSegmentOffsetTable[k]=SwapLong(RleSegmentOffsetTable[k]);
108          if (DEBUG)printf("        at : %x Offset Segment %d : %d (%x)\n",
109                  ftellRes,k,RleSegmentOffsetTable[k],RleSegmentOffsetTable[k]);
110       }
111
112       if (nbRleSegments>1) { 
113          for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
114             RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
115             ftellRes=ftell(fp);
116             if (DEBUG)printf ("       (in) Segment %d : Length = %d  x(%x) Start at %x\n",
117                                  k,RleSegmentLength[k],RleSegmentLength[k], ftellRes);
118             fragmentBegining=ftell(fp);   
119             _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
120             fseek(fp,fragmentBegining,SEEK_SET);  
121             fseek(fp,RleSegmentLength[k],SEEK_CUR);        
122          }
123       }
124       RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
125       ftellRes=ftell(fp);
126       if (DEBUG)printf ("        (out)Segment %d : Length = %d  x(%x) Start at %x\n",
127                        nbRleSegments,
128                        RleSegmentLength[nbRleSegments],RleSegmentLength[nbRleSegments],
129                        ftellRes);
130       fragmentBegining=ftell(fp);
131       _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
132       fseek(fp,fragmentBegining,SEEK_SET);  
133       fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);    
134       
135       // end of scanning fragment pixels       
136    
137       ftellRes=ftell(fp);
138       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
139       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
140       if(GetSwapCode()) {
141          ItemTagGr=SwapShort(ItemTagGr); 
142          ItemTagEl=SwapShort(ItemTagEl);      
143       }
144       if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
145             ftellRes,ItemTagGr,ItemTagEl );
146    } 
147    return (1);
148 }
149
150
151  /* -------------------------------------------------------------------- */
152  //
153  // RLE LossLess Fragment
154  //
155  /* -------------------------------------------------------------------- */
156
157    // static because nothing but gdcm_read_RLE_file can call it
158    // DO NOT doxygen !
159
160 static int
161 _gdcm_read_RLE_fragment (char ** areaToRead, 
162                          long lengthToDecode, 
163                          long uncompressedSegmentSize, 
164                          FILE* fp) {
165    long ftellRes;
166    int count;
167    long numberOfOutputBytes=0;
168    char n, car;
169    ftellRes =ftell(fp);
170
171    while(numberOfOutputBytes<uncompressedSegmentSize) {
172
173       ftellRes =ftell(fp);
174       fread(&n,sizeof(char),1,fp);
175       count=n;
176       if (count >= 0 && count <= 127) {
177          fread(*areaToRead,(count+1)*sizeof(char),1,fp);
178          *areaToRead+=count+1;
179          numberOfOutputBytes+=count+1;
180       } else {
181          if (count <= -1 && count >= -127) {
182             fread(&car,sizeof(char),1,fp);
183             for(int i=0; i<-count+1; i++) {
184                (*areaToRead)[i]=car;  
185             }
186             *areaToRead+=(-count+1);
187             numberOfOutputBytes+=(-count+1); 
188          }
189       } 
190       // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
191    } 
192    return 1;
193 }