This is ppmtopjxl.c in view mode; [Download] [Up]
/* ppmtopcl.c - convert portable pixmap into PCL language for HP PaintJet and * PaintJet XL colour printers * AJCD 12/3/91 * * usage: * ppmtopcl [-nopack] [-gamma <n>] [-presentation] [-dark] * [-diffuse] [-cluster] [-dither] * [-xshift <s>] [-yshift <s>] * [-xshift <s>] [-yshift <s>] * [-xsize|-width|-xscale <s>] [-ysize|-height|-yscale <s>] * [ppmfile] * */ #include <stdio.h> #include <math.h> #include "ppm.h" #include "ppmcmap.h" #define MAXCOLORS 1024 int bitsperpixel ARGS((int v)); void putbits ARGS((int b, int n)); char *usage="[-nopack] [-gamma <n>] [-presentation] [-dark]\n\ [-diffuse] [-cluster] [-dither]\n\ [-xshift <s>] [-yshift <s>]\n\ [-xshift <s>] [-yshift <s>]\n\ [-xsize|-width|-xscale <s>] [-ysize|-height|-yscale <s>]\n\ [ppmfile]"; #define PCL_MAXWIDTH 2048 #define PCL_MAXHEIGHT 32767 #define PCL_MAXVAL 255 static int nopack = 0; static int dark = 0; static int diffuse = 0; static int dither = 0; static int cluster = 0; static int xsize = 0; static int ysize = 0; static int xshift = 0; static int yshift = 0; static int quality = 0; static double xscale = 0.0; static double yscale = 0.0; static double gamma_val = 0.0; /* argument types */ #define DIM 0 #define REAL 1 #define BOOL 2 static struct options { char *name; int type; char *value; } options[] = { {"-gamma", REAL, (char *)&gamma_val }, {"-presentation", BOOL, (char *)&quality }, {"-width", DIM, (char *)&xsize }, {"-xsize", DIM, (char *)&xsize }, {"-height", DIM, (char *)&ysize }, {"-ysize", DIM, (char *)&ysize }, {"-xscale", REAL, (char *)&xscale }, {"-yscale", REAL, (char *)&yscale }, {"-xshift", DIM, (char *)&xshift }, {"-yshift", DIM, (char *)&yshift }, {"-dark", BOOL, (char *)&dark }, {"-diffuse", BOOL, (char *)&diffuse }, {"-dither", BOOL, (char *)&dither }, {"-cluster", BOOL, (char *)&cluster }, {"-nopack", BOOL, (char *)&nopack }, }; #define putword(w) (putchar(((w)>>8) & 255), putchar((w) & 255)) int bitsperpixel(v) int v; { int bpp = 0; while (v > 0) { /* calculate # bits for value */ ++bpp; v>>=1; } return (bpp); } static char *inrow = NULL; static char *outrow = NULL; static /*signed*/ char *runcnt = NULL; void putbits(b, n) /* put #n bits in b out, packing into bytes; n=0 flushes bits */ int b, n; /* n should never be > 8 */ { static int out = 0; static int cnt = 0; static int num = 0; static int pack = 0; if (n) { int xo = 0; int xc = 0; if (cnt+n > 8) { /* overflowing current byte? */ xc = cnt + n - 8; xo = (b & ~(-1 << xc)) << (8-xc); n -= xc; b >>= xc; } cnt += n; out |= (b & ~(-1 << n)) << (8-cnt); if (cnt >= 8) { inrow[num++] = out; out = xo; cnt = xc; } } else { /* flush row */ int i; if (cnt) { inrow[num++] = out; out = cnt = 0; } for (; num > 0 && inrow[num-1] == 0; num--); /* remove trailing zeros */ printf("\033*b"); if (num && !nopack) { /* TIFF 4.0 packbits encoding */ int start = 0; int next; runcnt[start] = 0; for (i = 1; i < num; i++) { if (inrow[i] == inrow[i-1]) { if (runcnt[start] <= 0 && runcnt[start] > -127) runcnt[start]--; else runcnt[start = i] = 0; } else { if (runcnt[start] >= 0 && runcnt[start] < 127) runcnt[start]++; else runcnt[start = i] = 0; } } start = 0; for (i = 0; i < num; i = next) { int count = runcnt[i]; int from = i; if (count >= 0) { /* merge two-byte runs */ for (;;) { next = i+1+runcnt[i]; if(next >= num || runcnt[next] < 0 || count+runcnt[next]+1 > 127) break; count += runcnt[next]+1; i = next; } } next = i + 1 + ((runcnt[i] < 0) ? -runcnt[i] : runcnt[i]); if (next < num && count > 0 && runcnt[next] < 0 && runcnt[next] > -127) { count--; next--; runcnt[next] = runcnt[next+1]-1; } outrow[start++] = count; if (count >= 0) { while (count-- >= 0) outrow[start++] = inrow[from++]; } else outrow[start++] = inrow[from]; } if (start < num) { num = start; if (!pack) { printf("2m"); pack = 1; } } else { if (pack) { printf("0m"); pack = 0; } } } printf("%dW", num); for (i = 0; i < num; i++) putchar(pack ? outrow[i] : inrow[i]); num = 0; /* new row */ } } int main(argc, argv) int argc; char *argv[]; { FILE *ifd; register pixel **pixels, *pixrow; register int row, col, bpp, i; int rows, cols; pixval maxval; int bpr, bpg, bpb; int render; int colours, pclindex; colorhist_vector chv; colorhash_table cht; char *pm_progname = argv[0]; ppm_init( &argc, argv ); while (argc > 1 && argv[1][0] == '-') { char *c; for (i = 0; i < sizeof(options)/sizeof(struct options); i++) { if (pm_keymatch(argv[1], options[i].name, min(strlen(argv[1]), strlen(options[i].name)))) { switch (options[i].type) { case DIM: if (++argv, --argc == 1) pm_usage(usage); for (c = argv[1]; isdigit(*c); c++); if (c[0] == 'p' && c[1] == 't') /* points */ *(int *)(options[i].value) = atoi(argv[1])*10; else if (c[0] == 'd' && c[1] == 'p') /* decipoints */ *(int *)(options[i].value) = atoi(argv[1]); else if (c[0] == 'i' && c[1] == 'n') /* inches */ *(int *)(options[i].value) = atoi(argv[1])*720; else if (c[0] == 'c' && c[1] == 'm') /* centimetres */ *(int *)(options[i].value) = atoi(argv[1])*283.46457; else if (!c[0]) /* dots */ *(int *)(options[i].value) = atoi(argv[1])*4; else pm_error("illegal unit of measure %s", c); break; case REAL: if (++argv, --argc == 1) pm_usage(usage); *(double *)(options[i].value) = atof(argv[1]); break; case BOOL: *(int *)(options[i].value) = 1; break; } break; } } if (i >= sizeof(options)/sizeof(struct options)) pm_usage(usage); argv++; argc--; } if (argc > 2) pm_usage(usage); else if (argc == 2) ifd = pm_openr(argv[1]); else ifd = stdin ; /* validate arguments */ if (diffuse+cluster+dither > 1) pm_error("only one of -diffuse, -dither and -cluster may be used"); render = diffuse ? 4 : dither ? 3 : cluster ? 7 : 0; if (xsize != 0.0 && xscale != 0.0) pm_error("only one of -xsize and -xscale may be used"); if (ysize != 0.0 && yscale != 0.0) pm_error("only one of -ysize and -yscale may be used"); pixels = ppm_readppm( ifd, &cols, &rows, &maxval ); pm_close( ifd ); /* limit checks */ if (cols > PCL_MAXWIDTH || rows > PCL_MAXHEIGHT) pm_error("image too large; reduce with ppmscale"); if (maxval > PCL_MAXVAL) pm_error("colour range too large; reduce with ppmcscale"); /* Figure out the colormap. */ fprintf( stderr, "(Computing colormap..." ); fflush( stderr ); chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colours ); if ( chv == (colorhist_vector) 0 ) pm_error("too many colours; reduce with ppmquant", 0,0,0,0,0 ); fprintf( stderr, " Done. %d colors found.)\n", colours ); /* And make a hash table for fast lookup. */ cht = ppm_colorhisttocolorhash( chv, colours ); /* work out colour downloading mode */ pclindex = bitsperpixel(colours); if (pclindex > 8) /* can't use indexed mode */ pclindex = 0; else switch (pclindex) { /* round up to 1,2,4,8 */ case 0: /* direct mode (no palette) */ bpp = bitsperpixel(maxval); /* bits per pixel */ bpg = bpp; bpb = bpp; bpp = (bpp*3+7)>>3; /* bytes per pixel now */ bpr = (bpp<<3)-bpg-bpb; bpp *= cols; /* bytes per row now */ break; case 5: pclindex++; case 6: pclindex++; case 3: case 7: pclindex++; default: bpp = 8/pclindex; bpp = (cols+bpp-1)/bpp; /* bytes per row */ } if ((inrow = (char *)malloc((unsigned)bpp)) == NULL || (outrow = (char *)malloc((unsigned)bpp*2)) == NULL || (runcnt = (/*signed*/ char *)malloc((unsigned)bpp)) == NULL) pm_error("can't allocate space for row", 0,0,0,0,0); /* set up image details */ if (xscale != 0.0) xsize = cols * xscale * 4; if (yscale != 0.0) ysize = rows * yscale * 4; #ifdef DEBUG fprintf(stderr, "dark =%d\n", dark); fprintf(stderr, "diffuse =%d\n", diffuse); fprintf(stderr, "dither =%d\n", dither); fprintf(stderr, "cluster =%d\n", cluster); fprintf(stderr, "quality =%d\n", quality); fprintf(stderr, "xsize =%d\n", xsize); fprintf(stderr, "ysize =%d\n", ysize); fprintf(stderr, "xshift =%d\n", xshift); fprintf(stderr, "yshift =%d\n", yshift); fprintf(stderr, "xscale =%lf\n", xscale); fprintf(stderr, "yscale =%lf\n", yscale); fprintf(stderr, "gamma =%lf\n", gamma_val); fprintf(stderr, "pclindex =%d\n", pclindex); fprintf(stderr, "nopack =%d\n", nopack); #endif /* write PCL header */ #if 0 printf("\033&l26A"); /* paper size */ #endif printf("\033*r%ds%dT", cols, rows); /* source width, height */ if (xshift != 0 || yshift != 0) printf("\033&a%+dh%+dV", xshift, yshift); /* xshift, yshift */ if (quality) printf("\033*o%dQ", quality); /* print quality */ printf("\033*t"); if (xsize == 0 && ysize == 0) printf("180r"); /* resolution */ else { /* destination width, height */ if (xsize != 0) printf("%dh", xsize); if (ysize != 0) printf("%dv", ysize); } if (gamma_val != 0) printf("%.3lfi", gamma_val); /* gamma correction */ if (dark) printf("%dk", dark); /* scaling algorithms */ printf("%dJ", render); /* rendering algorithm */ printf("\033*v18W"); /* configure image data */ putchar(0); /* relative colours */ putchar(pclindex ? 1 : 3); /* index/direct pixel mode */ putchar(pclindex); /* ignored in direct pixel mode */ if (pclindex) { putchar(0); putchar(0); putchar(0); } else { putchar(bpr); /* bits per red */ putchar(bpg); /* bits per green */ putchar(bpb); /* bits per blue */ } putword(maxval); /* max red reference */ putword(maxval); /* max green reference */ putword(maxval); /* max blue reference */ putword(0); /* min red reference */ putword(0); /* min green reference */ putword(0); /* min blue reference */ if (pclindex) { /* set palette */ for (i = 0; i < colours; i++) { int r, g, b; r = PPM_GETR( chv[i].color ); g = PPM_GETG( chv[i].color ); b = PPM_GETB( chv[i].color ); if (i == 0) printf("\033*v"); if (r) printf("%da", r); if (g) printf("%db", g); if (b) printf("%dc", b); if (i == colours-1) printf("%dI", i); /* assign colour index */ else printf("%di", i); /* assign colour index */ } } ppm_freecolorhist( chv ); /* start raster graphics at CAP */ printf("\033*r%dA", (xsize != 0 || ysize != 0) ? 3 : 1); for (row = 0; row < rows; row++) { if (pclindex) { /* indexed colour mode */ int out, cnt; out = cnt = 0; for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) { putbits(ppm_lookupcolor( cht, pixrow ), pclindex); } putbits(0, 0); /* flush row */ } else { /* direct colour mode */ for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) { putbits(PPM_GETR( *pixrow ), bpr); putbits(PPM_GETG( *pixrow ), bpg); putbits(PPM_GETB( *pixrow ), bpb); /* don't need to flush */ } putbits(0, 0); /* flush row */ } } printf("\033*rC"); /* end raster graphics */ exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.