/* encode.c - Don Yang (uguu.org) Encode text to variable length data. Assume each line starts with at least one space. 11/28/01 */ /*@ -shiftsigned -type @*/ #include #define BITS_PER_GROUP 2 #define BASE64_OFFSET '0' static void FlushCode(int byte, FILE *outfile); static void WriteCode(int code, int *byte, int *bit, int *size, FILE *outfile); /******************************************************************** main */ int main(int argc, char **argv) { FILE *infile, *outfile; int i, c, len, bit, byte, size; infile = stdin; outfile = stdout; if( argc > 1 ) { if( (infile = fopen(argv[1], "rb")) == 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]); } } } c = EOF; len = bit = byte = size = 0; (void)fputc('\"', outfile); do { i = fgetc(infile); if( i != c ) { if( i == '\n' ) { if( len > 0 && c != EOF ) WriteCode(len, &byte, &bit, &size, outfile); WriteCode(0, &byte, &bit, &size, outfile); c = EOF; len = 0; } else { if( len > 0 && c != EOF ) WriteCode(len, &byte, &bit, &size, outfile); c = i; len = 1; } } else { len++; } } while( i != EOF ); if( bit > 0 ) FlushCode(byte, outfile); fprintf(outfile, "\"\n/* %d bits */\n", size); (void)fclose(infile); (void)fclose(outfile); return 0; } /* main() */ /*************************************************************** FlushCode */ static void FlushCode(int byte, FILE *outfile) { if( (byte += BASE64_OFFSET) == '\\' ) (void)fputc('\\', outfile); (void)fputc(byte, outfile); } /* FlushCode() */ /*************************************************************** WriteCode */ static void WriteCode(int code, int *byte, int *bit, int *size, FILE *outfile) { int i; do { for(i = 0; i < BITS_PER_GROUP; i++) { *byte |= ((code & (1 << i)) == 0 ? 0 : 1) << (*bit)++; if( *bit > 5 ) { FlushCode(*byte, outfile); *bit = *byte = 0; } } *byte |= (code >= (1 << BITS_PER_GROUP) ? 1 : 0) << (*bit)++; if( *bit > 5 ) { FlushCode(*byte, outfile); *bit = *byte = 0; } code >>= BITS_PER_GROUP; *size += BITS_PER_GROUP + 1; } while( code > 0 ); } /* WriteCode() */