/* rle.c -- compress files, using run length encoding algorithm */ /* $Id$ */ /* Carlos Duarte , 980910/990319 */ #include #include #include static int do_args(int first, int ac, char *av[]); #define ARG() \ s[1] ? (t=s+1, s+=strlen(s)-1, t) : ++i map into 0 .. 127 */ putc((1<<7)|(*len - 1), wf); while ((*len)--) putc(*lit++, wf); *len = 0; } static int comp(FILE *rd_f, FILE *wr_f) { unsigned char lit[128+MIN_NR_REP-1]; int lit_len = 0; unsigned char c[MIN_NR_REP]; int i; int count; count=0; for (;;) { int cc; while (count < MIN_NR_REP) { cc = getc(rd_f); c[count++] = cc; if (cc == EOF) goto out; } for (i=1; i= 127+MIN_NR_REP) { putc(127, wr_f); putc(c[0], wr_f); count -= 127+MIN_NR_REP; } if (count >= MIN_NR_REP) { putc(count-MIN_NR_REP, wr_f); putc(c[0], wr_f); count = 0; } c[count++] = cc; if (cc == EOF) goto out; skip: lit[lit_len++] = c[0]; if (lit_len == 128) out_lit(wr_f, lit, &lit_len); count--; for (i=0; i128) { n = 128; out_lit(wr_f, lit, &n); n = lit_len-128; out_lit(wr_f, lit+128, &n); } else out_lit(wr_f, lit, &lit_len); } return 0; } static int do_args(int ix, int argc, char *argv[]) { FILE *outf = stdout; FILE *inf = stdin; if (ix != argc) USAGE(); if (opts.ifile) { inf = fopen(opts.ifile, "r"); if (!inf) { perror(opts.ifile); exit(1); } } if (opts.ofile) { outf = fopen(opts.ofile, "w"); if (!outf) { fclose(inf); perror(opts.ofile); exit(1); } } if (opts.comp) comp(inf, outf); else decomp(inf, outf); if (inf != stdin) fclose(inf); if (outf != stdout) fclose(outf); return 0; }