ajcd@cs.ed.ac.uk (Angus Duggan) (05/09/91)
In article <475@fe2o3.laurel.md.us>, rusty@fe2o3.laurel.md.us (Rusty Haddock) writes: > In article <15963@helios.TAMU.EDU> jdm5548@tamsun.tamu.edu (James Darrell McCauley) writes: > |I received some source once that would speak PaintJet via Sun Raster. > |... > |It does work very well though. Particularly, if the image is 720 pixels > |... > |ppmtopj, anyone? > > ppmtopj, yes! After this semester is over, which isn't too far off > now, I want to start on it. Hopefully it won't take much more than > a weekend. If you will, bounce that code my way so I can get some > more insight into programming the PJ. I'm interested in how the > 16-color limit is handled. Thanks! Of course, if you have a PaintJet XL, you could use its internal imaging capabilities with the following program. > > -Rusty- Followups directed to alt.graphics.pixutils. a. -- Angus Duggan, Department of Computer Science, | I'm pink, therefore I'm Spam. University of Edinburgh, JCMB, | JANET: ajcd@uk.ac.ed.lfcs The King's Buildings, Mayfield Road, | VOICE: (UK) 031 650 5126 Edinburgh, EH9 3JZ, Scotland. | OR: ajcd%lfcs.ed.ac.uk@nsfnet-relay.ac.uk #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: ppmtopcl.1 ppmtopcl.c # Wrapped by ajcd@davaar on Thu May 9 10:48:39 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f ppmtopcl.1 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ppmtopcl.1\" else echo shar: Extracting \"ppmtopcl.1\" \(2191 characters\) sed "s/^X//" >ppmtopcl.1 <<'END_OF_ppmtopcl.1' X.TH PPMTOPCL 1 "14 March 1991" X.SH NAME Xppmtopcl - convert a portable pixmap into an HP PaintJet XL PCL file X.SH SYNOPSIS Xppmtopcl [-nopack] [-gamma X.I <n> X] [-presentation] [-dark] [-diffuse] [-cluster] [-dither] [-xshift X.I <s> X] [-yshift X.I <s> X] [-xshift X.I <s> X] [-yshift X.I <s> X] [-xsize|-width|-xscale X.I <s> X] [-ysize|-height|-yscale X.I <s> X] [ppmfile] X X.SH DESCRIPTION XReads a portable pixmap as input. XProduces a PCL file suitable for printing on an HP PaintJet XL printer as Xoutput. X.PP XThe generated file is not suitable for printing on a normal PrintJet printer. XThe X.B \-nopack Xoption generates a file which does not use the normal TIFF 4.0 compression Xmethod. This file might be printable on a normal PaintJet printer (not an XL). X.PP XThe X.B \-gamma Xoption sets the gamma correction for the image. The useful range for the XPaintJet XL is approximately 0.6 to 1.5. X.PP XThe rendering algorithm used for images can be altered with the X.B -dither, X.B -cluster, Xand X.B -diffuse Xoptions. These options select ordered dithering, clustered ordered dithering, Xor error diffusion respectively. XThe X.B \-dark Xoption can be used to enhance images with a dark background when they are Xreduced in size. XThe X.B \-presentation Xoption turns on presentation mode, in which two passes are made over the paper Xto increase ink density. This should be used only for images where quality is Xcritical. X X.PP XThe image can be resized by setting the X.B \-xsize Xand X.B \-ysize Xoptions. The parameter to either of these options is interpreted as the Xnumber of dots to set the width or height to, but an optional dimension of X`\fBpt\fR' (points), `\fBdp\fR' (decipoints), `\fBin\fR' (inches), or X`\fBcm\fR' (centimetres) may be appended. XIf only one dimension is specified, the other will be scaled appropriately. X XThe options X.B \-width Xand X.B \-height Xare synonyms of X.B \-xsize Xand X.B \-ysize. X XThe X.B \-xscale Xand X.B \-yscale Xoptions can alternatively be used to scale the image by a simple factor. X X.PP XThe image can be shifted on the page by using the X.B \-xshift Xand X.B \-yshift Xoptions. These move the image the specified dimensions right and down. X X.SH "SEE ALSO" Xppm(5) X.SH AUTHOR XAngus Duggan END_OF_ppmtopcl.1 if test 2191 -ne `wc -c <ppmtopcl.1`; then echo shar: \"ppmtopcl.1\" unpacked with wrong size! fi # end of overwriting check fi if test -f ppmtopcl.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ppmtopcl.c\" else echo shar: Extracting \"ppmtopcl.c\" \(12077 characters\) sed "s/^X//" >ppmtopcl.c <<'END_OF_ppmtopcl.c' X/* ppmtopcl.c - convert portable pixmap into PCL language for HP PaintJet and X * PaintJet XL colour printers X * AJCD 12/3/91 X * X * usage: X * ppmtopcl [-nopack] [-gamma <n>] [-presentation] [-dark] X * [-diffuse] [-cluster] [-dither] X * [-xshift <s>] [-yshift <s>] X * [-xshift <s>] [-yshift <s>] X * [-xsize|-width|-xscale <s>] [-ysize|-height|-yscale <s>] X * [ppmfile] X * X */ X X#include <stdio.h> X#include <ppm.h> X#include <ppmcmap.h> X X#define MAXCOLORS 1024 X Xextern double atof(); Xextern int atoi(); X Xchar *usage="[-nopack] [-gamma <n>] [-presentation] [-dark]\n\ X [-diffuse] [-cluster] [-dither]\n\ X [-xshift <s>] [-yshift <s>]\n\ X [-xshift <s>] [-yshift <s>]\n\ X [-xsize|-width|-xscale <s>] [-ysize|-height|-yscale <s>]\n\ X [ppmfile]"; X X#define PCL_MAXWIDTH 2048 X#define PCL_MAXHEIGHT 32767 X#define PCL_MAXVAL 255 X Xstatic int nopack = 0; Xstatic int dark = 0; Xstatic int diffuse = 0; Xstatic int dither = 0; Xstatic int cluster = 0; Xstatic int xsize = 0; Xstatic int ysize = 0; Xstatic int xshift = 0; Xstatic int yshift = 0; Xstatic int quality = 0; Xstatic double xscale = 0.0; Xstatic double yscale = 0.0; Xstatic double gamma = 0.0; X X/* argument types */ X#define DIM 0 X#define REAL 1 X#define BOOL 2 Xstatic struct options { X char *name; X int type; X char *value; X} options[] = { X {"gamma", REAL, (char *)&gamma }, X {"presentation", BOOL, (char *)&quality }, X {"width", DIM, (char *)&xsize }, X {"xsize", DIM, (char *)&xsize }, X {"height", DIM, (char *)&ysize }, X {"ysize", DIM, (char *)&ysize }, X {"xscale", REAL, (char *)&xscale }, X {"yscale", REAL, (char *)&yscale }, X {"xshift", DIM, (char *)&xshift }, X {"yshift", DIM, (char *)&yshift }, X {"dark", BOOL, (char *)&dark }, X {"diffuse", BOOL, (char *)&diffuse }, X {"dither", BOOL, (char *)&dither }, X {"cluster", BOOL, (char *)&cluster }, X {"nopack", BOOL, (char *)&nopack }, X}; X X#define putword(w) (putchar(((w)>>8) & 255), putchar((w) & 255)) X Xint bitsperpixel(v) X int v; X{ X int bpp = 0; X while (v > 0) { /* calculate # bits for value */ X ++bpp; X v>>=1; X } X return (bpp); X} X Xstatic char *inrow = NULL; Xstatic char *outrow = NULL; Xstatic /*signed*/ char *runcnt = NULL; X Xputbits(b, n) /* put #n bits in b out, packing into bytes; n=0 flushes bits */ X int b, n; /* n should never be > 8 */ X{ X static int out = 0; X static int cnt = 0; X static int num = 0; X static int pack = 0; X if (n) { X int xo = 0; X int xc = 0; X if (cnt+n > 8) { /* overflowing current byte? */ X xc = cnt + n - 8; X xo = (b & ~(-1 << xc)) << (8-xc); X n -= xc; X b >>= xc; X } X cnt += n; X out |= (b & ~(-1 << n)) << (8-cnt); X if (cnt >= 8) { X inrow[num++] = out; X out = xo; X cnt = xc; X } X } else { /* flush row */ X int i; X if (cnt) { X inrow[num++] = out; X out = cnt = 0; X } X for (; num > 0 && inrow[num-1] == 0; num--); /* remove trailing zeros */ X printf("\033*b"); X if (num && !nopack) { /* TIFF 4.0 packbits encoding */ X int start = 0; X int next; X runcnt[start] = 0; X for (i = 1; i < num; i++) { X if (inrow[i] == inrow[i-1]) { X if (runcnt[start] <= 0 && runcnt[start] > -127) X runcnt[start]--; X else X runcnt[start = i] = 0; X } else { X if (runcnt[start] >= 0 && runcnt[start] < 127) X runcnt[start]++; X else X runcnt[start = i] = 0; X } X } X start = 0; X for (i = 0; i < num; i = next) { X int count = runcnt[i]; X int from = i; X if (count >= 0) { /* merge two-byte runs */ X for (;;) { X next = i+1+runcnt[i]; X if(next >= num || runcnt[next] < 0 || X count+runcnt[next]+1 > 127) X break; X count += runcnt[next]+1; X i = next; X } X } X next = i + 1 + ((runcnt[i] < 0) ? -runcnt[i] : runcnt[i]); X if (next < num && count > 0 && X runcnt[next] < 0 && runcnt[next] > -127) { X count--; X next--; X runcnt[next] = runcnt[next+1]-1; X } X outrow[start++] = count; X if (count >= 0) { X while (count-- >= 0) X outrow[start++] = inrow[from++]; X } else X outrow[start++] = inrow[from]; X } X if (start < num) { X num = start; X if (!pack) { X printf("2m"); X pack = 1; X } X } else { X if (pack) { X printf("0m"); X pack = 0; X } X } X } X printf("%dW", num); X for (i = 0; i < num; i++) X putchar(pack ? outrow[i] : inrow[i]); X num = 0; /* new row */ X } X} X Xmain(argc, argv) X int argc; X char *argv[]; X{ X FILE *ifd; X register pixel **pixels, *pixrow; X register int row, col, bpp, i; X int rows, cols; X pixval maxval; X int bpr, bpg, bpb; X int render; X int colours, index; X colorhist_vector chv; X colorhash_table cht; X X pm_progname = argv[0]; X X while (argc > 1 && argv[1][0] == '-') { X char *c, *val=argv[1]+1; X for (i = 0; i < sizeof(options)/sizeof(struct options); i++) { X if (strlen(val) <= strlen(options[i].name) && X !strncmp(val, options[i].name, strlen(val))) { X switch (options[i].type) { X case DIM: X if (++argv, --argc == 1) X pm_usage(usage); X for (c = argv[1]; isdigit(*c); c++); X if (c[0] == 'p' && c[1] == 't') /* points */ X *(int *)(options[i].value) = atoi(argv[1])*10; X else if (c[0] == 'd' && c[1] == 'p') /* decipoints */ X *(int *)(options[i].value) = atoi(argv[1]); X else if (c[0] == 'i' && c[1] == 'n') /* inches */ X *(int *)(options[i].value) = atoi(argv[1])*720; X else if (c[0] == 'c' && c[1] == 'm') /* centimetres */ X *(int *)(options[i].value) = atoi(argv[1])*283.46457; X else if (!c[0]) /* dots */ X *(int *)(options[i].value) = atoi(argv[1])*4; X else X pm_error("illegal unit of measure %s", c); X break; X case REAL: X if (++argv, --argc == 1) X pm_usage(usage); X *(double *)(options[i].value) = atof(argv[1]); X break; X case BOOL: X *(int *)(options[i].value) = 1; X break; X } X break; X } X } X if (i >= sizeof(options)/sizeof(struct options)) X pm_usage(usage); X argv++; argc--; X } X if (argc > 2) X pm_usage(usage); X else if (argc == 2) X ifd = pm_openr(argv[1]); X else X ifd = stdin ; X X /* validate arguments */ X if (diffuse+cluster+dither > 1) X pm_error("only one of -diffuse, -dither and -cluster may be used"); X render = diffuse ? 4 : dither ? 3 : cluster ? 7 : 0; X X if (xsize != 0.0 && xscale != 0.0) X pm_error("only one of -xsize and -xscale may be used"); X X if (ysize != 0.0 && yscale != 0.0) X pm_error("only one of -ysize and -yscale may be used"); X X pixels = ppm_readppm( ifd, &cols, &rows, &maxval ); X pm_close( ifd ); X X /* limit checks */ X if (cols > PCL_MAXWIDTH || rows > PCL_MAXHEIGHT) X pm_error("image too large; reduce with ppmscale"); X if (maxval > PCL_MAXVAL) X pm_error("colour range too large; reduce with ppmcscale"); X X /* Figure out the colormap. */ X fprintf( stderr, "(Computing colormap..." ); fflush( stderr ); X chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colours ); X if ( chv == (colorhist_vector) 0 ) X pm_error("too many colours; reduce with ppmquant", 0,0,0,0,0 ); X fprintf( stderr, " Done. %d colors found.)\n", colours ); X X /* And make a hash table for fast lookup. */ X cht = ppm_colorhisttocolorhash( chv, colours ); X X /* work out colour downloading mode */ X index = bitsperpixel(colours); X if (index > 8) /* can't use indexed mode */ X index = 0; X else X switch (index) { /* round up to 1,2,4,8 */ X case 0: /* direct mode (no palette) */ X bpp = bitsperpixel(maxval); /* bits per pixel */ X bpg = bpp; bpb = bpp; X bpp = (bpp*3+7)>>3; /* bytes per pixel now */ X bpr = (bpp<<3)-bpg-bpb; X bpp *= cols; /* bytes per row now */ X break; X case 5: index++; X case 6: index++; X case 3: case 7: index++; X default: X bpp = 8/index; X bpp = (cols+bpp-1)/bpp; /* bytes per row */ X } X X if ((inrow = (char *)malloc((unsigned)bpp)) == NULL || X (outrow = (char *)malloc((unsigned)bpp*2)) == NULL || X (runcnt = (/*signed*/ char *)malloc((unsigned)bpp)) == NULL) X pm_error("can't allocate space for row", 0,0,0,0,0); X X /* set up image details */ X if (xscale != 0.0) X xsize = cols * xscale * 4; X if (yscale != 0.0) X ysize = rows * yscale * 4; X X#ifdef DEBUG X fprintf(stderr, "dark =%d\n", dark); X fprintf(stderr, "diffuse =%d\n", diffuse); X fprintf(stderr, "dither =%d\n", dither); X fprintf(stderr, "cluster =%d\n", cluster); X fprintf(stderr, "quality =%d\n", quality); X fprintf(stderr, "xsize =%d\n", xsize); X fprintf(stderr, "ysize =%d\n", ysize); X fprintf(stderr, "xshift =%d\n", xshift); X fprintf(stderr, "yshift =%d\n", yshift); X fprintf(stderr, "xscale =%lf\n", xscale); X fprintf(stderr, "yscale =%lf\n", yscale); X fprintf(stderr, "gamma =%lf\n", gamma); X fprintf(stderr, "index =%d\n", index); X fprintf(stderr, "nopack =%d\n", nopack); X#endif X X /* write PCL header */ X/* printf("\033&l26A"); /* paper size */ X printf("\033*r%ds%dT", cols, rows); /* source width, height */ X if (xshift != 0 || yshift != 0) X printf("\033&a%+dh%+dV", xshift, yshift); /* xshift, yshift */ X if (quality) X printf("\033*o%dQ", quality); /* print quality */ X printf("\033*t"); X if (xsize == 0 && ysize == 0) X printf("180r"); /* resolution */ X else { /* destination width, height */ X if (xsize != 0) X printf("%dh", xsize); X if (ysize != 0) X printf("%dv", ysize); X } X if (gamma != 0) X printf("%.3lfi", gamma); /* gamma correction */ X if (dark) X printf("%dk", dark); /* scaling algorithms */ X printf("%dJ", render); /* rendering algorithm */ X printf("\033*v18W"); /* configure image data */ X putchar(0); /* relative colours */ X putchar(index ? 1 : 3); /* index/direct pixel mode */ X putchar(index); /* ignored in direct pixel mode */ X if (index) { X putchar(0); X putchar(0); X putchar(0); X } else { X putchar(bpr); /* bits per red */ X putchar(bpg); /* bits per green */ X putchar(bpb); /* bits per blue */ X } X putword(maxval); /* max red reference */ X putword(maxval); /* max green reference */ X putword(maxval); /* max blue reference */ X putword(0); /* min red reference */ X putword(0); /* min green reference */ X putword(0); /* min blue reference */ X if (index) { /* set palette */ X for (i = 0; i < colours; i++) { X int r, g, b; X r = PPM_GETR( chv[i].color ); X g = PPM_GETG( chv[i].color ); X b = PPM_GETB( chv[i].color ); X if (i == 0) X printf("\033*v"); X if (r) X printf("%da", r); X if (g) X printf("%db", g); X if (b) X printf("%dc", b); X if (i == colours-1) X printf("%dI", i); /* assign colour index */ X else X printf("%di", i); /* assign colour index */ X } X } X ppm_freecolorhist( chv ); X X /* start raster graphics at CAP */ X printf("\033*r%dA", (xsize != 0 || ysize != 0) ? 3 : 1); X X for (row = 0; row < rows; row++) { X if (index) { /* indexed colour mode */ X int out, cnt; X out = cnt = 0; X for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) { X putbits(ppm_lookupcolor( cht, *pixrow ), index); X } X putbits(0, 0); /* flush row */ X } else { /* direct colour mode */ X for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) { X putbits(PPM_GETR( *pixrow ), bpr); X putbits(PPM_GETG( *pixrow ), bpg); X putbits(PPM_GETB( *pixrow ), bpb); /* don't need to flush */ X } X putbits(0, 0); /* flush row */ X } X } X printf("\033*rC"); /* end raster graphics */ X exit(0); X} END_OF_ppmtopcl.c if test 12077 -ne `wc -c <ppmtopcl.c`; then echo shar: \"ppmtopcl.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 1 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0