RDLE is an include file which allows you to compress memory areas in the faster way (enhanced RLE algorithm).
The purpose is to be able to manipulate huge memory areas (images, video, sounds, memory files...)
It is designed for all machines (NT, Sun, Aix, HP).
Feel free to re-use the source code.
 
 
/* 
RDLE
 
this include file has 2 functions : 

rdle() : compresses a memory area 
unrdle() : uncompresses a memory area 

rdautel@geocities.com 
*/ 

#include  
#include  
#include  

#define ITS_OK         0  /* no error */ 
#define BAD_DATA       1  /* unexpected end of data */ 
#define NO_MEM         2  /* memory allocation failure */ 

/* 
rdle()

this function compresses an existing memory area 
and copies it into a compressed memory area  
which is allocated into the function, do not forget the free() 

lgi : size of the existing memory area in input 
dti : pointer to the existing memory area
lgo : contains the size of the compressed memory size in output 
dto : contains the pointer to the compressed memory area in output,  do not forget the free() 

returns the error code
*/ 

int rdle(int lgi,char *dti,int *lgo,char **dto) 
{ 
   unsigned char n=0,m=0; 
   int sblk=2+lgi/2; 

   *lgo=0; 
   if(!lgi) 
      return ITS_OK; 
   if(lgi==1) 
   { 
      *lgo=2; 
      *dto=(char *)malloc(2); 
      **dto=0; 
      *(*dto+1)=*dti; 
      return ITS_OK; 
   } 
   if(!(*dto=(char *)malloc(sblk))) 
      return NO_MEM; 
   for(--lgi;--lgi;++dti) 
   { 
      if(*lgo>=sblk) 
      { 
  if(!(*dto=(char *)realloc(*dto,sblk<<=1))) 
     return NO_MEM; 
      } 
      if(*dti!=*(dti+1)||*(dti+1)!=*(dti+2)) 
      { 
  if(n) 
  { 
     *(*dto+(*lgo)++)=n|128; 
     *(*dto+(*lgo)++)=*dti; 
     n=0; 
  } 
  else 
  { 
     *(*dto+(++*lgo))=*dti; 
     if(++m==128) 
     { 
        *(*dto+((*lgo)++-128))=127; 
        m=0; 
     } 
  } 
      } 
      else 
      { 
  if(m) 
  { 
     *(*dto+((*lgo)++-m))=m-1; 
     m=0; 
     n=1; 
  } 
  else 
  { 
     if(++n==128) 
     { 
        *(*dto+(*lgo)++)=255; 
        *(*dto+(*lgo)++)=*dti; 
        n=0; 
     } 
  } 
      } 
   } 
   if(m) 
      *(*dto+((*lgo)++-m))=m-1; 
   *(*dto+(*lgo)++)=n|128; 
   *(*dto+(*lgo)++)=*dti; 
   *(*dto+(*lgo)++)=0; 
   *(*dto+(*lgo)++)=*(dti+1); 
   *dto=(char *)realloc(*dto,*lgo); 
   return ITS_OK; 
} 

/* 
unrdle()

this function uncompresses a compressed memory area 
and copies it into an uncompressed memory area  
which is allocated into the function, do not forget the free() 

lgi : size of the compressed memory area in input 
dti : pointer to the compressed memory area
lgo : contains the size of the uncompressed memory size in output 
dto : contains the pointer to the uncompressed memory area in output,  do not forget the free() 

returns the error code
*/ 

int unrdle(int lgi,char *dti,int *lgo,char **dto) 
{ 
   unsigned char n; 
   int sblk=lgi*2; 

   if(!(*dto=(char *)malloc(128+sblk))) 
      return NO_MEM; 
   for(*lgo=0;lgi;(*lgo)+=n) 
   { 
      if(*lgo>=sblk) 
      { 
  if(!(*dto=(char *)realloc(*dto,128+(sblk<<=1)))) 
     return NO_MEM; 
      } 
      if((n=*dti)&128) 
      { 
  n^=128; 
  memset((*dto)+*lgo,*++dti,++n); 
  lgi-=2; 
  ++dti; 
      } 
      else 
      { 
  memcpy((*dto)+*lgo,++dti,++n); 
  lgi-=n+1; 
  dti+=n; 
      } 
      if(lgi<0) 
  return BAD_DATA; 
   } 
   *dto=(char *)realloc(*dto,*lgo); 
   return ITS_OK; 
} 

/* 
the main() function is just here to perform tests 
*/ 

int main(int argc,char **argv) 
{ 
   FILE *fd1,*fd2; 
   int code; 
   int lg1,lg2; 
   char *ch1,*ch2; 

   if(argc==4) 
   { 
      if(!(fd1=fopen(argv[2],"rb"))) 
      { 
  puts("error input file"); 
  return 7; 
      } 
      if(!(fd2=fopen(argv[3],"wb"))) 
      { 
  puts("error output file"); 
  fclose(fd1); 
  return 8; 
      } 
      switch(*argv[1]) 
      { 
  case 'a' : 
  case 'A' : 
     fseek(fd1,0,SEEK_END); 
     lg1=ftell(fd1); 
     rewind(fd1); 
     ch1=(char *)malloc(lg1); 
     if(!ch1) 
        exit(23); 
     lg1=fread(ch1,1,lg1,fd1); 
     code=rdle(lg1,ch1,&lg2,&ch2); 
     if(!code) 
     { 
        fwrite(ch2,1,lg2,fd2); 
        free(ch1); 
        if(lg2) 
    free(ch2); 
     } 
     break; 
  case 'x' : 
  case 'X' : 
     fseek(fd1,0,SEEK_END); 
     lg1=ftell(fd1); 
     rewind(fd1); 
     ch1=(char *)malloc(lg1); 
     if(!ch1) 
        exit(23); 
     lg1=fread(ch1,1,lg1,fd1); 
     code=unrdle(lg1,ch1,&lg2,&ch2); 
     if(!code) 
     { 
        fwrite(ch2,1,lg2,fd2); 
        free(ch1); 
        if(lg2) 
    free(ch2); 
     } 
     break; 
  default : 
     code=9; 
      } 
      fclose(fd1); 
      fclose(fd2); 
      if(code!=9) 
      { 
  if(code) 
     printf("error %d\n",code); 
  return code; 
      } 

   } 
   puts("rdle a file rlefile"); 
   puts("rdle x rlefile file"); 
   return 9; 
} 
 
 

 


This page hosted by   Get your own Free Home Page