2 //-----------------------------------------------------------------------------
5 #include <ctype.h> // to declare isprint()
7 #define str2num(str, typeNum) *((typeNum *)(str))
9 //-----------------------------------------------------------------------------
12 * \brief Reads a 'Run Length Encoded' Dicom encapsulated file
13 * @param fp already open File Pointer
14 * @param image_buffer destination Address (in caller's memory space)
15 * at which the pixel data should be copied
18 bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
19 long fragmentBegining; // for ftell, fseek
20 char * im = (char *)image_buffer;
22 long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
24 guint32 nbRleSegments;
25 guint32 RleSegmentOffsetTable[15];
26 guint16 ItemTagGr,ItemTagEl;
27 uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize();
29 // Basic Offset Table with Item Value
31 fread(&ItemTagGr,2,1,fp); // Reading (fffe):Basic Offset Table Item Tag Gr
32 fread(&ItemTagEl,2,1,fp); // Reading (e000):Basic Offset Table Item Tag El
33 if(Header->GetSwapCode()) {
34 ItemTagGr=Header->SwapShort(ItemTagGr);
35 ItemTagEl=Header->SwapShort(ItemTagEl);
40 if(Header->GetSwapCode())
41 ln=Header->SwapLong(ln); // Basic Offset Table Item Lentgh
43 // What is it used for ??
44 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
45 fread(BasicOffsetTableItemValue,ln,1,fp);
47 for (int i=0;i<ln;i+=4){
48 a=str2num(&BasicOffsetTableItemValue[i],guint32);
53 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
54 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
55 if(Header->GetSwapCode()) {
56 ItemTagGr=Header->SwapShort(ItemTagGr);
57 ItemTagEl=Header->SwapShort(ItemTagEl);
60 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
61 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
62 // Parse fragments of the current Fragment (Frame)
64 fread(&fragmentLength,4,1,fp);
65 if(Header->GetSwapCode())
66 fragmentLength=Header->SwapLong(fragmentLength); // length
68 //------------------ scanning (not reading) fragment pixels
70 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
71 if(Header->GetSwapCode())
72 nbRleSegments=Header->SwapLong(nbRleSegments);
74 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
76 fread(&RleSegmentOffsetTable[k],4,1,fp);
77 if(Header->GetSwapCode())
78 RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
81 if (nbRleSegments>1) {
82 for(unsigned int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
83 RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
85 fragmentBegining=ftell(fp);
86 gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
87 fseek(fp,fragmentBegining,SEEK_SET);
88 fseek(fp,RleSegmentLength[k],SEEK_CUR);
91 RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
93 fragmentBegining=ftell(fp);
94 gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
95 fseek(fp,fragmentBegining,SEEK_SET);
96 fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);
98 // end of scanning fragment pixels
101 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
102 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
103 if(Header->GetSwapCode()) {
104 ItemTagGr=Header->SwapShort(ItemTagGr);
105 ItemTagEl=Header->SwapShort(ItemTagEl);
109 if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits
111 im = (char *)image_buffer;
112 // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
114 int l = Header->GetXSize()*Header->GetYSize();
115 int nbFrames = Header->GetZSize();
117 char * newDest = (char*) malloc(l*nbFrames*2);
119 char * a = (char *)image_buffer;
122 for (int i=0;i<nbFrames;i++) {
123 for (int j=0;j<l; j++) {
128 memmove(image_buffer,newDest,lgrTotale);
136 // ----------------------------------------------------------------------------
137 // RLE LossLess Fragment
138 int gdcmFile::gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode,
139 long uncompressedSegmentSize, FILE *fp) {
140 (void)lengthToDecode; //FIXME
143 long numberOfOutputBytes=0;
147 while(numberOfOutputBytes<uncompressedSegmentSize) {
149 fread(&n,sizeof(char),1,fp);
151 if (count >= 0 && count <= 127) {
152 fread(*areaToRead,(count+1)*sizeof(char),1,fp);
153 *areaToRead+=count+1;
154 numberOfOutputBytes+=count+1;
156 if (count <= -1 && count >= -127) {
157 fread(&car,sizeof(char),1,fp);
158 for(int i=0; i<-count+1; i++) {
159 (*areaToRead)[i]=car;
161 *areaToRead+=(-count+1);
162 numberOfOutputBytes+=(-count+1);
165 // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
170 // ----------------------------------------------------------------------------