]> Creatis software - gdcm.git/blob - src/gdcmRLE.cxx
ostream replaced by std::ostream
[gdcm.git] / src / gdcmRLE.cxx
1 //This is needed when compiling in debug mode
2 #ifdef _MSC_VER
3 // 'identifier' : class 'type' needs to have dll-interface to be used by
4 // clients of class 'type2'
5 #pragma warning ( disable : 4251 )
6 // 'identifier' : identifier was truncated to 'number' characters in the
7 // debug information
8 #pragma warning ( disable : 4786 )
9 #endif //_MSC_VER
10
11 #include <stdio.h>
12 #include "gdcmFile.h"
13 #include <ctype.h>              /* to declare isprint() */
14
15 #define str2num(str, typeNum) *((typeNum *)(str))
16
17 static int _gdcm_read_RLE_fragment (char ** image_buffer, 
18                                     long lengthToDecode,
19                                     long uncompressedSegmentSize, 
20                                     FILE* fp);
21 // static because nothing but gdcm_read_RLE_file may call it
22
23 // ----------------------------------------------------------------------------
24 /**
25  * \ingroup   gdcmFile
26  * \brief     Reads a 'Run Length Encoded' Dicom encapsulated file
27  * @param     image_buffer destination Address (in caller's memory space) 
28  *            at which the
29  *            pixel data should be copied
30  * @return    int acts as a Boolean 
31  */
32
33 // This is a debug version.
34 // Forget the printf as they will be removed
35 // as soon as the last Heuristics are checked
36
37 int
38 gdcmFile::gdcm_read_RLE_file (void * image_buffer) {
39    char * im = (char *)image_buffer;
40    cout << "RLE image" << std::endl;
41
42    long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
43    long ftellRes, ln;
44    guint32 nbRleSegments;
45    guint32 RleSegmentOffsetTable[15];
46    guint16 ItemTagGr,ItemTagEl;
47    uncompressedSegmentSize=GetXSize()*GetYSize();
48    printf("uncompressedSegmentSize %d\n",uncompressedSegmentSize);
49    ftellRes=ftell(fp);
50    // Basic Offset Table with Item Value
51       // Item Tag
52    fread(&ItemTagGr,2,1,fp);  // Reading (fffe):Basic Offset Table Item Tag Gr
53    fread(&ItemTagEl,2,1,fp);  // Reading (e000):Basic Offset Table Item Tag El
54    if(GetSwapCode()) {
55       ItemTagGr=SwapShort(ItemTagGr); 
56       ItemTagEl=SwapShort(ItemTagEl);      
57    }
58    printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
59           ftellRes,ItemTagGr,ItemTagEl );
60       // Item Length
61    ftellRes=ftell(fp);
62    fread(&ln,4,1,fp); 
63    if(GetSwapCode()) 
64       ln=SwapLong(ln);    // Basic Offset Table Item Lentgh
65    printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
66          ftellRes,ln,ln);
67    if (ln != 0) {
68       // What is it used for ??
69       char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
70       fread(BasicOffsetTableItemValue,ln,1,fp); 
71       guint32 a;
72       for (int i=0;i<ln;i+=4){
73          a=str2num(&BasicOffsetTableItemValue[i],guint32);
74          printf("      x(%08x)  %d\n",a,a);
75       }        
76    }
77
78    ftellRes=ftell(fp);
79    fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
80    fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
81    if(GetSwapCode()) {
82       ItemTagGr=SwapShort(ItemTagGr); 
83       ItemTagEl=SwapShort(ItemTagEl);      
84    }  
85    printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
86          ftellRes,ItemTagGr,ItemTagEl );
87
88    // while 'Sequence Delimiter Item' (fffe,e0dd) not found
89    while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
90    // Parse fragments of the current Fragment (Frame)    
91       ftellRes=ftell(fp);
92       fread(&fragmentLength,4,1,fp); 
93       if(GetSwapCode()) 
94          fragmentLength=SwapLong(fragmentLength);    // length
95       printf("      at %x : fragment length %d x(%08x)\n",
96              ftellRes, fragmentLength,fragmentLength);
97
98        // scanning fragment pixels
99  
100       fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments        
101       if(GetSwapCode()) 
102          nbRleSegments=SwapLong(nbRleSegments);
103          printf("         Nb of RLE Segments : %d\n",nbRleSegments);
104  
105       for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
106          ftellRes=ftell(fp);
107          fread(&RleSegmentOffsetTable[k],4,1,fp);
108          if(GetSwapCode())
109             RleSegmentOffsetTable[k]=SwapLong(RleSegmentOffsetTable[k]);
110          printf("        at : %x Offset Segment %d : %d (%x)\n",
111                    ftellRes,k,RleSegmentOffsetTable[k],RleSegmentOffsetTable[k]);
112       }
113
114        if (nbRleSegments>1) { 
115           for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
116              RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
117                 ftellRes=ftell(fp);
118                 printf ("        Segment %d : Length = %d Start at %x\n",
119                                  k,RleSegmentLength[k], ftellRes);    
120              _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
121               //fseek(fp,RleSegmentLength[k],SEEK_CUR);    
122      
123           }
124        }
125        RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments]; // + 4;
126             // 4 : bytes for number of RLE Segments (WHY ???);
127                                            // TODO : Check the value
128           ftellRes=ftell(fp);
129           printf ("        Segment %d : Length = %d Start at %x\n",
130                            nbRleSegments,RleSegmentLength[nbRleSegments],ftellRes);
131        _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
132         //fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);    
133   
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       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    printf ("Fragment begin : %x lengthToDecode %d\n",ftellRes,lengthToDecode);
171
172    while(numberOfOutputBytes<uncompressedSegmentSize) {
173
174       ftellRes =ftell(fp);
175       fread(&n,sizeof(char),1,fp);
176       count=n;
177      //printf ("   Piece begin : %x count : %d x(%x)\n",ftellRes, count, count);
178       if (count >= 0 && count <= 127) {
179          fread(*areaToRead,(count+1)*sizeof(char),1,fp);
180          *areaToRead+=count+1;
181          numberOfOutputBytes+=count+1;
182       } else {
183          if (count <= -1 && count >= -127) {
184             fread(&car,sizeof(char),1,fp);
185             for(int i=0; i<-count+1; i++) {
186                (*areaToRead)[i]=car;  
187             }
188             *areaToRead+=(-count+1);
189             numberOfOutputBytes+=(-count+1); 
190          }
191       } 
192       // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
193    } 
194    return 1;
195 }