]> Creatis software - gdcm.git/blob - src/gdcmRLE.cxx
* FIX: CMake generate now documentation
[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
23  *            pixel data should be copied
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 int
32 gdcmFile::gdcm_read_RLE_file (void * image_buffer) {
33    long fragmentBegining; // for ftell, fseek
34    char * im = (char *)image_buffer;
35    if (DEBUG)std::cout << "RLE image" << std::endl;
36
37    long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
38    long ftellRes, ln;
39    guint32 nbRleSegments;
40    guint32 RleSegmentOffsetTable[15];
41    guint16 ItemTagGr,ItemTagEl;
42    uncompressedSegmentSize=GetXSize()*GetYSize();
43    if (DEBUG)printf("uncompressedSegmentSize %d\n",uncompressedSegmentSize);
44    ftellRes=ftell(fp);
45    // Basic Offset Table with Item Value
46       // Item Tag
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(GetSwapCode()) {
50       ItemTagGr=SwapShort(ItemTagGr); 
51       ItemTagEl=SwapShort(ItemTagEl);      
52    }
53    if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
54           ftellRes,ItemTagGr,ItemTagEl );
55       // Item Length
56    ftellRes=ftell(fp);
57    fread(&ln,4,1,fp); 
58    if(GetSwapCode()) 
59       ln=SwapLong(ln);    // Basic Offset Table Item Lentgh
60    if (DEBUG)printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
61          ftellRes,ln,ln);
62    if (ln != 0) {
63       // What is it used for ??
64       char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
65       fread(BasicOffsetTableItemValue,ln,1,fp); 
66       guint32 a;
67       for (int i=0;i<ln;i+=4){
68          a=str2num(&BasicOffsetTableItemValue[i],guint32);
69         if (DEBUG)printf("      x(%08x)  %d\n",a,a);
70       }        
71    }
72
73    ftellRes=ftell(fp);
74    fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
75    fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
76    if(GetSwapCode()) {
77       ItemTagGr=SwapShort(ItemTagGr); 
78       ItemTagEl=SwapShort(ItemTagEl);      
79    }  
80    if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
81          ftellRes,ItemTagGr,ItemTagEl );
82
83    // while 'Sequence Delimiter Item' (fffe,e0dd) not found
84    while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
85    // Parse fragments of the current Fragment (Frame)    
86       ftellRes=ftell(fp);
87       fread(&fragmentLength,4,1,fp); 
88       if(GetSwapCode()) 
89          fragmentLength=SwapLong(fragmentLength);    // length
90       if (DEBUG)printf("      at %x : fragment length %d x(%08x)\n",
91              ftellRes, fragmentLength,fragmentLength);
92
93           //------------------ scanning (not reading) fragment pixels
94  
95       fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments        
96       if(GetSwapCode()) 
97          nbRleSegments=SwapLong(nbRleSegments);
98          if (DEBUG)printf("         Nb of RLE Segments : %d\n",nbRleSegments);
99  
100       for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
101          ftellRes=ftell(fp);
102          fread(&RleSegmentOffsetTable[k],4,1,fp);
103          if(GetSwapCode())
104             RleSegmentOffsetTable[k]=SwapLong(RleSegmentOffsetTable[k]);
105          if (DEBUG)printf("        at : %x Offset Segment %d : %d (%x)\n",
106                  ftellRes,k,RleSegmentOffsetTable[k],RleSegmentOffsetTable[k]);
107       }
108
109       if (nbRleSegments>1) { 
110          for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
111             RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
112             ftellRes=ftell(fp);
113             if (DEBUG)printf ("       (in) Segment %d : Length = %d  x(%x) Start at %x\n",
114                                  k,RleSegmentLength[k],RleSegmentLength[k], ftellRes);
115             fragmentBegining=ftell(fp);   
116             _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
117             fseek(fp,fragmentBegining,SEEK_SET);  
118             fseek(fp,RleSegmentLength[k],SEEK_CUR);        
119          }
120       }
121       RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
122       ftellRes=ftell(fp);
123       if (DEBUG)printf ("        (out)Segment %d : Length = %d  x(%x) Start at %x\n",
124                        nbRleSegments,
125                        RleSegmentLength[nbRleSegments],RleSegmentLength[nbRleSegments],
126                        ftellRes);
127       fragmentBegining=ftell(fp);
128       _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
129       fseek(fp,fragmentBegining,SEEK_SET);  
130       fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);    
131       
132       // end of scanning fragment pixels       
133    
134       ftellRes=ftell(fp);
135       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
136       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
137       if(GetSwapCode()) {
138          ItemTagGr=SwapShort(ItemTagGr); 
139          ItemTagEl=SwapShort(ItemTagEl);      
140       }
141       if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
142             ftellRes,ItemTagGr,ItemTagEl );
143    } 
144    return (1);
145 }
146
147
148  /* -------------------------------------------------------------------- */
149  //
150  // RLE LossLess Fragment
151  //
152  /* -------------------------------------------------------------------- */
153
154    // static because nothing but gdcm_read_RLE_file can call it
155    // DO NOT doxygen !
156
157 static int
158 _gdcm_read_RLE_fragment (char ** areaToRead, 
159                          long lengthToDecode, 
160                          long uncompressedSegmentSize, 
161                          FILE* fp) {
162    long ftellRes;
163    int count;
164    long numberOfOutputBytes=0;
165    char n, car;
166    ftellRes =ftell(fp);
167
168    while(numberOfOutputBytes<uncompressedSegmentSize) {
169
170       ftellRes =ftell(fp);
171       fread(&n,sizeof(char),1,fp);
172       count=n;
173       if (count >= 0 && count <= 127) {
174          fread(*areaToRead,(count+1)*sizeof(char),1,fp);
175          *areaToRead+=count+1;
176          numberOfOutputBytes+=count+1;
177       } else {
178          if (count <= -1 && count >= -127) {
179             fread(&car,sizeof(char),1,fp);
180             for(int i=0; i<-count+1; i++) {
181                (*areaToRead)[i]=car;  
182             }
183             *areaToRead+=(-count+1);
184             numberOfOutputBytes+=(-count+1); 
185          }
186       } 
187       // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
188    } 
189    return 1;
190 }