/ * * compress HP PCL-format bit image data * usage: pcl_pack input output * copyright 1990 Digital Insight */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #define MAX_RUN 128 /* max compressed run length */ char inbuf[4096]; /* image input buffer */ char pbuf[4096]; /* packed output buffer */ char esbuf[100]; /* escape sequence buffer */ char rawbuf[8192]; /* raw input buffer */ char *rawptr = rawbuf; /* current position in buffer */ int rawbytes; /* bytes left in buffer */ FILE *in_fp; FILE *out_fp; /* * Abort program with error message */ void fail(char *msg) { puts(msg); exit(1); } /* * Buffered input from in_fp. Used in place of fread() to speed things up * (depending on the stream I/O library's own buffer size) */ int bfread(char *buf, int nbytes) { int bytes_read = 0; /* bytes read so far */ register int partial; /* partial transfer count */ while (nbytes > 0) { if (rawbytes == 0) { /* buffer empty, get some more */ rawbytes = fread(rawptr=rawbuf, 1, sizeof(rawbuf), in_fp); if (rawbytes == 0) break; } partial = nbytes; /* transfer data from buffer */ if (partial > rawbytes) partial = rawbytes; memcpy(buf, rawptr, partial); bytes_read += partial; rawptr += partial; buf += partial; nbytes -= partial; rawbytes -= partial; } return bytes_read; } /* * Buffered input from in_fp. Used in place of fgetc() to speed things up * (depending on the stream I/O library's own buffer size) */ int bfgetc(void) { if (rawbytes == 0) { /* buffer empty, get some more */ rawbytes = fread(rawptr=rawbuf, 1, sizeof(rawbuf), in_fp); if (rawbytes == 0) return EOF; } rawbytes--; return *rawptr++; } /* * Copy input to output up to next escape sequence; * save sequence in esbuf[]. Return sequence length. */ int read_seq(void) { int c; char *seq = esbuf; do { /* read up to escape char */ if ((c = bfgetc()) == EOF) exit(0); /* done! */ fputc(c, out_fp); } while (c != 0x1B); do { /* read seq thru uppercase char */ *seq++ = c = bfgetc(); if (c == EOF) fail("unexpected end of input"); } while (!isupper(c)); *seq = 0; /* terminate sequence */ return seq-esbuf; } /* * Read line of image data into inbuf; return length. * Any other data (text, escape sequences) are sent directly to output. */ int read_line(void) { register int n; char *pos; for (;;) { /* look for [esc]*b...W/M */ n = read_seq(); if (n < 3 || esbuf[0] != '*' || esbuf[1] != 'b') { /* some other seq, send out */ fwrite(esbuf, 1, n, out_fp); continue; } for (pos=esbuf+2; *pos; pos++) { /* get #<func> */ n = (int)strtol(pos, &pos, 10); switch (*pos) { case 'W': /* found image data */ goto got_image; case 'm': /* compression mode */ case 'M': if (n != 0) fail("Input is already compressed"); break; default: /* some other sequence */ /* split off and output */ if (islower(*pos)) *pos = toupper(*pos); fprintf(out_fp, "*b%d%c\1xB", n, *pos++); } } } got_image: if (bfread(inbuf, n) != n) fail("Unexpected end of input"); while (n>1 && inbuf[n-1] == 0) /* remove trailing zero bytes */ n--; return n; } /* * Pack image data lines */ void pack(void) { static int first=1; /* first time? */ register char *rptr; /* repeat pointer */ register char *bptr; /* input buffer position */ char *bend; /* end of input */ char *pptr; /* pack buffer position */ int n, cnt; for (;;) { n = read_line(); /* (last output was [esc]) */ bend = inbuf+n; for (bptr=inbuf, pptr=pbuf; bptr<bend;) { /* find number of repeated bytes */ for (rptr=bptr+1; rptr<bend && *rptr==*bptr; rptr++) ; cnt = rptr - bptr; while (cnt > 1) { n = (cnt < MAX_RUN) ? cnt : MAX_RUN; *pptr++ = 1 - n; *pptr++ = *bptr; cnt -= n; bptr += n; } /* finished with repeat run? */ if (rptr >= bend) break; /* find number of non-repeated bytes */ for (rptr=bptr+1; rptr<bend && *rptr != *(rptr-1); rptr++) ; cnt = rptr - bptr - 1; if (rptr >= bend) cnt++; while (cnt > 0) { n = (cnt < MAX_RUN) ? cnt : MAX_RUN; *pptr++ = n - 1; memcpy(pptr, bptr, n); cnt -= n; bptr += n; pptr += n; } } n = pptr - pbuf; if (first) { /* set compaction mode */ first = 0; /* (note: ESC already output) */ fwrite("*b2M\x1B", 5, 1, out_fp); } /* output compressed image data */ fprintf(out_fp, "*b%dW", n); if (fwrite(pbuf, 1, n, out_fp) != n) fail("can't write output"); } } main(int argc, char **argv) { if (argc != 3) { puts("Compress HP PCL-format graphics file"); puts("(c) Copyright 1990 Digital Insight"); puts("Usage: pcl_pack <infile> <outfile>"); exit(1); } if ((in_fp = fopen(argv[1], "rb")) == NULL) { perror(argv[1]); exit(1); } if ((out_fp = fopen(argv[2], "wb")) == NULL) { perror(argv[2]); exit(1); } pack(); }
file: /Techref/language/pcl/grphcomp/pcl_pack.c, 5KB, , updated: 1990/11/8 20:44, local time: 2024/11/5 06:51,
3.15.22.202:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/Techref/language/pcl/grphcomp/pcl_pack.c"> language pcl grphcomp pcl_pack</A> |
Did you find what you needed? |