Main Page | File List | Related Pages

gdcmRLE.cxx

00001 // gdcmRLE.cxx
00002 //-----------------------------------------------------------------------------
00003 #include <stdio.h>
00004 #include "gdcmFile.h"
00005 #include <ctype.h>              /* to declare isprint() */
00006 
00007 #define str2num(str, typeNum) *((typeNum *)(str))
00008 
00009 //-----------------------------------------------------------------------------
00019 bool gdcmFile::gdcm_read_RLE_file (FILE *fp,void * image_buffer) {
00020    long fragmentBegining; // for ftell, fseek
00021    char * im = (char *)image_buffer;
00022 
00023    long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
00024    long ftellRes, ln;
00025    guint32 nbRleSegments;
00026    guint32 RleSegmentOffsetTable[15];
00027    guint16 ItemTagGr,ItemTagEl;
00028    uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize();
00029    ftellRes=ftell(fp);
00030    // Basic Offset Table with Item Value
00031       // Item Tag
00032    fread(&ItemTagGr,2,1,fp);  // Reading (fffe):Basic Offset Table Item Tag Gr
00033    fread(&ItemTagEl,2,1,fp);  // Reading (e000):Basic Offset Table Item Tag El
00034    if(Header->GetSwapCode()) {
00035       ItemTagGr=Header->SwapShort(ItemTagGr); 
00036       ItemTagEl=Header->SwapShort(ItemTagEl);      
00037    }
00038       // Item Length
00039    ftellRes=ftell(fp);
00040    fread(&ln,4,1,fp); 
00041    if(Header->GetSwapCode()) 
00042       ln=Header->SwapLong(ln);    // Basic Offset Table Item Lentgh
00043    if (ln != 0) {
00044       // What is it used for ??
00045       char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
00046       fread(BasicOffsetTableItemValue,ln,1,fp); 
00047       guint32 a;
00048       for (int i=0;i<ln;i+=4){
00049          a=str2num(&BasicOffsetTableItemValue[i],guint32);
00050       }        
00051    }
00052 
00053    ftellRes=ftell(fp);
00054    fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
00055    fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
00056    if(Header->GetSwapCode()) {
00057       ItemTagGr=Header->SwapShort(ItemTagGr); 
00058       ItemTagEl=Header->SwapShort(ItemTagEl);      
00059    }  
00060 
00061    // while 'Sequence Delimiter Item' (fffe,e0dd) not found
00062    while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
00063    // Parse fragments of the current Fragment (Frame)    
00064       ftellRes=ftell(fp);
00065       fread(&fragmentLength,4,1,fp); 
00066       if(Header->GetSwapCode()) 
00067          fragmentLength=Header->SwapLong(fragmentLength);    // length
00068 
00069           //------------------ scanning (not reading) fragment pixels
00070  
00071       fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments        
00072       if(Header->GetSwapCode()) 
00073          nbRleSegments=Header->SwapLong(nbRleSegments);
00074  
00075       for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
00076          ftellRes=ftell(fp);
00077          fread(&RleSegmentOffsetTable[k],4,1,fp);
00078          if(Header->GetSwapCode())
00079             RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
00080       }
00081 
00082       if (nbRleSegments>1) { 
00083          for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
00084             RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
00085             ftellRes=ftell(fp);
00086             fragmentBegining=ftell(fp);   
00087             gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
00088             fseek(fp,fragmentBegining,SEEK_SET);  
00089             fseek(fp,RleSegmentLength[k],SEEK_CUR);        
00090          }
00091       }
00092       RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
00093       ftellRes=ftell(fp);
00094       fragmentBegining=ftell(fp);
00095       gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
00096       fseek(fp,fragmentBegining,SEEK_SET);  
00097       fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);    
00098       
00099       // end of scanning fragment pixels       
00100    
00101       ftellRes=ftell(fp);
00102       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
00103       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
00104       if(Header->GetSwapCode()) {
00105          ItemTagGr=Header->SwapShort(ItemTagGr); 
00106          ItemTagEl=Header->SwapShort(ItemTagEl);      
00107       }
00108    } 
00109    
00110    if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits
00111    
00112       im = (char *)image_buffer;
00113          //  need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
00114 
00115       int l = Header->GetXSize()*Header->GetYSize();
00116       int nbFrames = Header->GetZSize();
00117 
00118       char * newDest = (char*) malloc(l*nbFrames*2);
00119       char *x  = newDest;
00120       char * a = (char *)image_buffer;
00121       char * b = a + l;
00122 
00123       for (int i=0;i<nbFrames;i++) {
00124          for (int j=0;j<l; j++) {
00125             *(x++) = *(a++);
00126             *(x++) = *(b++);
00127          }
00128       }
00129       memmove(image_buffer,newDest,lgrTotale);
00130       free(newDest);   
00131    }
00132       
00133    return(true);
00134 }
00135 
00136 
00137 // ----------------------------------------------------------------------------
00138 // RLE LossLess Fragment
00139 int gdcmFile::gdcm_read_RLE_fragment(char **areaToRead, long lengthToDecode, 
00140                                      long uncompressedSegmentSize, FILE *fp) {
00141    long ftellRes;
00142    int count;
00143    long numberOfOutputBytes=0;
00144    char n, car;
00145    ftellRes =ftell(fp);
00146 
00147    while(numberOfOutputBytes<uncompressedSegmentSize) {
00148       ftellRes =ftell(fp);
00149       fread(&n,sizeof(char),1,fp);
00150       count=n;
00151       if (count >= 0 && count <= 127) {
00152          fread(*areaToRead,(count+1)*sizeof(char),1,fp);
00153          *areaToRead+=count+1;
00154          numberOfOutputBytes+=count+1;
00155       } else {
00156          if (count <= -1 && count >= -127) {
00157             fread(&car,sizeof(char),1,fp);
00158             for(int i=0; i<-count+1; i++) {
00159                (*areaToRead)[i]=car;  
00160             }
00161             *areaToRead+=(-count+1);
00162             numberOfOutputBytes+=(-count+1); 
00163          }
00164       } 
00165       // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
00166    } 
00167    return 1;
00168 }
00169 
00170 // ----------------------------------------------------------------------------

Generated on Mon Feb 14 16:13:44 2005 for gdcm by doxygen 1.3.6