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
14 // ----------------------------------------------------------------------------
17 * \brief Reads a 'Run Length Encoded' Dicom encapsulated file
18 * @param image_buffer destination Address (in caller's memory space)
19 * at which the pixel data should be copied
21 * @return int acts as a Boolean
24 // This is a debug version.
25 // Forget the printf as they will be removed
26 // as soon as the last Heuristics are checked
28 // pb with RLE 16 Bits :
31 bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
32 long fragmentBegining; // for ftell, fseek
33 char * im = (char *)image_buffer;
35 long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
37 guint32 nbRleSegments;
38 guint32 RleSegmentOffsetTable[15];
39 guint16 ItemTagGr,ItemTagEl;
40 uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize();
42 // Basic Offset Table with Item Value
44 fread(&ItemTagGr,2,1,fp); // Reading (fffe):Basic Offset Table Item Tag Gr
45 fread(&ItemTagEl,2,1,fp); // Reading (e000):Basic Offset Table Item Tag El
46 if(Header->GetSwapCode()) {
47 ItemTagGr=Header->SwapShort(ItemTagGr);
48 ItemTagEl=Header->SwapShort(ItemTagEl);
53 if(Header->GetSwapCode())
54 ln=Header->SwapLong(ln); // Basic Offset Table Item Lentgh
56 // What is it used for ??
57 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
58 fread(BasicOffsetTableItemValue,ln,1,fp);
60 for (int i=0;i<ln;i+=4){
61 a=str2num(&BasicOffsetTableItemValue[i],guint32);
66 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
67 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
68 if(Header->GetSwapCode()) {
69 ItemTagGr=Header->SwapShort(ItemTagGr);
70 ItemTagEl=Header->SwapShort(ItemTagEl);
73 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
74 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
75 // Parse fragments of the current Fragment (Frame)
77 fread(&fragmentLength,4,1,fp);
78 if(Header->GetSwapCode())
79 fragmentLength=Header->SwapLong(fragmentLength); // length
81 //------------------ scanning (not reading) fragment pixels
83 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
84 if(Header->GetSwapCode())
85 nbRleSegments=Header->SwapLong(nbRleSegments);
87 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
89 fread(&RleSegmentOffsetTable[k],4,1,fp);
90 if(Header->GetSwapCode())
91 RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
94 if (nbRleSegments>1) {
95 for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
96 RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
98 fragmentBegining=ftell(fp);
99 _gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
100 fseek(fp,fragmentBegining,SEEK_SET);
101 fseek(fp,RleSegmentLength[k],SEEK_CUR);
104 RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
106 fragmentBegining=ftell(fp);
107 _gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
108 fseek(fp,fragmentBegining,SEEK_SET);
109 fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);
111 // end of scanning fragment pixels
114 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
115 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
116 if(Header->GetSwapCode()) {
117 ItemTagGr=Header->SwapShort(ItemTagGr);
118 ItemTagEl=Header->SwapShort(ItemTagEl);
122 if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits
124 im = (char *)image_buffer;
125 // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
127 int l = Header->GetXSize()*Header->GetYSize();
128 int nbFrames = Header->GetZSize();
130 char * newDest = (char*) malloc(l*nbFrames*2);
132 char * a = (char *)image_buffer;
135 for (int i=0;i<nbFrames;i++) {
136 for (int j=0;j<l; j++) {
141 memmove(image_buffer,newDest,lgrTotale);
149 /* -------------------------------------------------------------------- */
151 // RLE LossLess Fragment
153 /* -------------------------------------------------------------------- */
155 // static because nothing but gdcm_read_RLE_file can call it
159 _gdcm_read_RLE_fragment (char ** areaToRead,
161 long uncompressedSegmentSize,
165 long numberOfOutputBytes=0;
169 while(numberOfOutputBytes<uncompressedSegmentSize) {
172 fread(&n,sizeof(char),1,fp);
174 if (count >= 0 && count <= 127) {
175 fread(*areaToRead,(count+1)*sizeof(char),1,fp);
176 *areaToRead+=count+1;
177 numberOfOutputBytes+=count+1;
179 if (count <= -1 && count >= -127) {
180 fread(&car,sizeof(char),1,fp);
181 for(int i=0; i<-count+1; i++) {
182 (*areaToRead)[i]=car;
184 *areaToRead+=(-count+1);
185 numberOfOutputBytes+=(-count+1);
188 // if count = 128 output nothing (See : PS 3.5-2003 Page 86)