4 #include <ctype.h> /* to declare isprint() */
6 #define str2num(str, typeNum) *((typeNum *)(str))
8 static int _gdcm_read_RLE_fragment (char ** image_buffer,
10 long uncompressedSegmentSize,
12 // static because nothing but gdcm_read_RLE_file may call it
17 // ----------------------------------------------------------------------------
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
24 * @return int acts as a Boolean
27 // This is a debug version.
28 // Forget the printf as they will be removed
29 // as soon as the last Heuristics are checked
31 // pb with RLE 16 Bits :
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;
40 long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
42 guint32 nbRleSegments;
43 guint32 RleSegmentOffsetTable[15];
44 guint16 ItemTagGr,ItemTagEl;
45 uncompressedSegmentSize=GetXSize()*GetYSize();
46 if (DEBUG)printf("uncompressedSegmentSize %d\n",uncompressedSegmentSize);
48 // Basic Offset Table with Item Value
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
53 ItemTagGr=SwapShort(ItemTagGr);
54 ItemTagEl=SwapShort(ItemTagEl);
56 if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
57 ftellRes,ItemTagGr,ItemTagEl );
62 ln=SwapLong(ln); // Basic Offset Table Item Lentgh
63 if (DEBUG)printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
66 // What is it used for ??
67 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
68 fread(BasicOffsetTableItemValue,ln,1,fp);
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);
77 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
78 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
80 ItemTagGr=SwapShort(ItemTagGr);
81 ItemTagEl=SwapShort(ItemTagEl);
83 if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
84 ftellRes,ItemTagGr,ItemTagEl );
86 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
87 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
88 // Parse fragments of the current Fragment (Frame)
90 fread(&fragmentLength,4,1,fp);
92 fragmentLength=SwapLong(fragmentLength); // length
93 if (DEBUG)printf(" at %x : fragment length %d x(%08x)\n",
94 ftellRes, fragmentLength,fragmentLength);
96 //------------------ scanning (not reading) fragment pixels
98 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
100 nbRleSegments=SwapLong(nbRleSegments);
101 if (DEBUG)printf(" Nb of RLE Segments : %d\n",nbRleSegments);
103 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
105 fread(&RleSegmentOffsetTable[k],4,1,fp);
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]);
112 if (nbRleSegments>1) {
113 for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
114 RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
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);
124 RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
126 if (DEBUG)printf (" (out)Segment %d : Length = %d x(%x) Start at %x\n",
128 RleSegmentLength[nbRleSegments],RleSegmentLength[nbRleSegments],
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);
135 // end of scanning fragment pixels
138 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
139 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
141 ItemTagGr=SwapShort(ItemTagGr);
142 ItemTagEl=SwapShort(ItemTagEl);
144 if (DEBUG)printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
145 ftellRes,ItemTagGr,ItemTagEl );
151 /* -------------------------------------------------------------------- */
153 // RLE LossLess Fragment
155 /* -------------------------------------------------------------------- */
157 // static because nothing but gdcm_read_RLE_file can call it
161 _gdcm_read_RLE_fragment (char ** areaToRead,
163 long uncompressedSegmentSize,
167 long numberOfOutputBytes=0;
171 while(numberOfOutputBytes<uncompressedSegmentSize) {
174 fread(&n,sizeof(char),1,fp);
176 if (count >= 0 && count <= 127) {
177 fread(*areaToRead,(count+1)*sizeof(char),1,fp);
178 *areaToRead+=count+1;
179 numberOfOutputBytes+=count+1;
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;
186 *areaToRead+=(-count+1);
187 numberOfOutputBytes+=(-count+1);
190 // if count = 128 output nothing (See : PS 3.5-2003 Page 86)