/* encode.c - Don Yang (uguu.org) 12/01/01 */ #include #include #include static void WriteBits(int n, int b, FILE *outfile); static void WriteByte(int x, FILE *outfile); /******************************************************************** main */ int main(int argc, char **argv) { char data[8192]; FILE *infile, *outfile; int i, j, k, runlength, size; int maxduplength, maxdupoffset; infile = stdin; outfile = stdout; if( argc > 1 ) { if( (infile = fopen(argv[1], "rt")) == NULL ) return printf("Can not open %s\n", argv[1]); if( argc > 2 ) { if( (outfile = fopen(argv[2], "wt+")) == NULL ) { (void)fclose(infile); return printf("Can not create %s\n", argv[2]); } } } size = 0; memset(data, 0, 8192); while( (i = fgetc(infile)) != EOF ) data[1024 + size++] = (char)i; for(i = runlength = 0; i < size; i++) { maxduplength = 4; maxdupoffset = 0; for(j = -30; j < 0; j++) { for(k = 0; k < -j; k++) { if( data[1024 + i + k] != data[1024 + i + j + k] ) break; } if( k > maxduplength ) { maxdupoffset = j; maxduplength = k; } } if( maxduplength > 4 ) { if( runlength > 0 ) { fprintf(outfile, "%4d: Run = %d characters\n", i - runlength, runlength); WriteBits(1, 1, outfile); WriteBits(runlength, 5, outfile); for(j = 0; j < runlength; j++) WriteByte((int)data[1024 + i + j - runlength], outfile); runlength = 0; } fprintf(outfile, "%4d: Duplicate = %d characters, offset = %d\n", i, maxduplength, maxdupoffset); i += maxduplength - 1; WriteBits(0, 1, outfile); WriteBits(maxduplength, 5, outfile); WriteBits(-maxdupoffset, 5, outfile); } else { runlength++; if( runlength > 30 ) { fprintf(outfile, "%4d: Run = %d characters\n", i + 1 - runlength, runlength); WriteBits(1, 1, outfile); WriteBits(runlength, 5, outfile); for(j = 0; j < runlength; j++) WriteByte((int)data[1024 + i + 1 + j - runlength], outfile); runlength = 0; } } } if( runlength > 0 ) { fprintf(outfile, "%d: Run = %d characters\n", i - runlength, runlength); WriteBits(1, 1, outfile); WriteBits(runlength, 5, outfile); for(j = 0; j < runlength; j++) WriteByte((int)data[1024 + i + j - runlength], outfile); } (void)fclose(infile); (void)fclose(outfile); return 0; } /* main() */ /*************************************************************** WriteBits */ static void WriteBits(int n, int b, FILE *outfile) { int i; (void)fputs(" ", outfile); for(i = 0; i < b; i++) (void)fputc((n & (1 << (b - i - 1))) == 0 ? '0' : '1', outfile); (void)fputc('\n', outfile); } /* WriteBits() */ /*************************************************************** WriteByte */ static void WriteByte(int x, FILE *outfile) { static char dict[8] = ",.`':\"\nx"; int i; if( x == (int)' ' ) { WriteBits(0, 1, outfile); } else if( x == (int)'%' || x == (int)'X' ) { WriteBits(1, 1, outfile); WriteBits(0, 1, outfile); WriteBits(x == (int)'%' ? 0 : 1, 1, outfile); } else { WriteBits(1, 1, outfile); WriteBits(1, 1, outfile); for(i = 0; i < 8 && dict[i] != (char)x; i++); WriteBits(i, 3, outfile); } } /* WriteBits() */