/* * SRLE - Simple RLE * * Copyright (C) 2007, rozsnyo electronics and software * * Written by Daniel Rozsnyo * * Usage * ./srle -c -w X -t Y compressed * ./srle -d -w X -t Y decompressed * ./srle -h * * Options * -c compress * -d decompress * -h help * -w width of data in bytes * -t width of time in bytes (max. 3) * * Compressed (encoded) format: * * FILE = ( TIME DATA )* * * TIME = nTime bytes, MSB first * * DATA = nData bytes * */ /* libraries */ #include #include #include /* defaults */ #define DEFAULT_DATA_WIDTH 1 #define DEFAULT_TIME_WIDTH 1 #define DATA_WIDTH_MAX 8192 #define TIME_WIDTH_MAX 3 /* byte widths */ int nData = DEFAULT_DATA_WIDTH; int nTime = DEFAULT_TIME_WIDTH; /* input routines */ int read_time( FILE *stream, int *time ) { int c; int n = nTime; int o = 0; while(n--) { if ((c=fgetc(stream))==EOF) return 0; o = (o << 8) + c; } *time = o; return 1; } int read_data( FILE *stream, unsigned char *data ) { /* int c; int n = nData; while(n--) { if ((c=fgetc(stream))==EOF) return 0; *(data++) = c; } return 1; */ return (fread( data, 1, nData, stream )==nData); } /* output routines */ void write_time( FILE *stream, int i ) { int n = nTime; while(n--) { fputc( (i >> (8*(nTime-1))) & 0xFF, stream ); i = i << 8; } } void write_data( FILE *stream, unsigned char *data ) { /* int n = nData; while(n--) fputc( *(data++), stream ); */ fwrite( data, 1, nData, stream ); } /* misc */ int feof_fetch( FILE *stream ) { int c; if ((c=fgetc(stream))==EOF) return 1; ungetc(c,stream); return 0; } /* encoding DATA -> TIME+DATA */ int srle_encode( FILE *in, FILE *out ) { int time = 0; int max = (1<<(8*nTime))-1; unsigned char *data; unsigned char *buff; int retval = 0; if ((data=malloc(nData))==NULL) { fprintf(stderr,"Not enough memory to allocate data buffer (1)\n"); return -1; } if ((buff=malloc(nData))==NULL) { fprintf(stderr,"Not enough memory to allocate data buffer (2)\n"); return -1; } while(1) { if (feof_fetch(in)) break; if (!read_data(in,data)) { fprintf(stderr,"Premature end of input!\n"); retval = -1; break; } if (time) { /* already counted at least once */ if (memcmp(data,buff,nData)==0) { time++; /* forced flush because of time conter reached its max value */ if (time==max) { write_time(out,time); write_data(out,buff); time=0; } } else { /* differs .. flush */ write_time(out,time); write_data(out,buff); /* reinitialize */ time = 1; memcpy(buff,data,nData); } } else { /* initialize buffer */ memcpy(buff,data,nData); time = 1; } } /* last value flush */ if (time) { write_time(out,time); write_data(out,buff); } free(data); free(buff); return retval; } /* decoding TIME+DATA -> DATA */ int srle_decode( FILE *in, FILE *out ) { int time; unsigned char *data; int retval = 0; if ((data=malloc(nData))==NULL) { fprintf(stderr,"Not enough memory to allocate data buffer\n"); return -1; } while(1) { if (feof_fetch(in)) break; if (read_time(in,&time) && read_data(in,data)) { /* repeat the data time times */ while(time-->0) write_data(out,data); } else { fprintf(stderr,"Premature end of input!\n"); retval=-1; break; } } free(data); return retval; } void print_help() { printf("\n"); printf("srle - simple rle encoder/decoder\n"); printf("\n"); printf("Usage\n"); printf(" ./srle -c -w X -t Y compressed\n"); printf(" ./srle -d -w X -t Y decompressed\n"); printf(" ./srle -h\n"); printf("\n"); printf("Options\n"); printf(" -c compress\n"); printf(" -d decompress\n"); printf(" -h help\n"); printf(" -w width of data in bytes (max. %d)\n",DATA_WIDTH_MAX); printf(" -t width of time in bytes (max. %d)\n",TIME_WIDTH_MAX); printf("\n"); } int main( int argc, char* argv[] ) { int i; int doHelp = 0; int doEncode = 0; int doDecode = 0; /* if no parameters, show the help */ if (argc==1) { doHelp = 1; } else { /* parse parameters */ for(i=1;iDATA_WIDTH_MAX) { fprintf(stderr,"Data width can not be > %d !\n",DATA_WIDTH_MAX); return -1; } } else { fprintf(stderr,"Expected a value for -w\n"); return -1; } } else if (strcmp(argv[i],"-t")==0) { if ((++i)TIME_WIDTH_MAX) { fprintf(stderr,"Time width can not be > %d !\n",TIME_WIDTH_MAX); return -1; } } else { fprintf(stderr,"Expected a value for -t\n"); return -1; } } else { fprintf(stderr,"Unknown option: %s\n",argv[i]); return -1; } } } if (doHelp) { print_help(); } else { if (doEncode) { if (doDecode) { fprintf(stderr,"Can not do both encoding/decoding!\n"); return -1; } else { return srle_encode(stdin,stdout); } } else { if (doDecode) { return srle_decode(stdin,stdout); } else { fprintf(stderr,"No mode specified (use -c for encoding or -d for decoding)\n"); return -1; } } } return 0; }