diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/ppm/ppmtopict.c | |
download | netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip |
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtopict.c')
-rw-r--r-- | converter/ppm/ppmtopict.c | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c new file mode 100644 index 00000000..e2428fb6 --- /dev/null +++ b/converter/ppm/ppmtopict.c @@ -0,0 +1,481 @@ +/* +** ppmtopict.c - read a portable pixmap and produce a Macintosh PICT2 file. +** +** Copyright (C) 1990 by Ken Yap <ken@cs.rochester.edu>. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "ppm.h" + +#define HEADER_SIZE 512 + +#define RUN_THRESH 3 +#define MAX_RUN 128 /* 0xff = 2, 0xfe = 3, etc */ +#define MAX_COUNT 128 /* 0x00 = 1, 0x01 = 2, etc */ + +/* Opcodes */ +#define PICT_NOP 0x00 +#define PICT_clipRgn 0x01 +#define PICT_bkPat 0x02 +#define PICT_txFont 0x03 +#define PICT_txFace 0x04 +#define PICT_txMode 0x05 +#define PICT_spExtra 0x06 +#define PICT_pnSize 0x07 +#define PICT_pnMode 0x08 +#define PICT_pnPat 0x09 +#define PICT_thePat 0x0A +#define PICT_ovSize 0x0B +#define PICT_origin 0x0C +#define PICT_txSize 0x0D +#define PICT_fgColor 0x0E +#define PICT_bkColor 0x0F +#define PICT_txRatio 0x10 +#define PICT_picVersion 0x11 +#define PICT_blPixPat 0x12 +#define PICT_pnPixPat 0x13 +#define PICT_fillPixPat 0x14 +#define PICT_pnLocHFrac 0x15 +#define PICT_chExtra 0x16 +#define PICT_rgbFgCol 0x1A +#define PICT_rgbBkCol 0x1B +#define PICT_hiliteMode 0x1C +#define PICT_hiliteColor 0x1D +#define PICT_defHilite 0x1E +#define PICT_opColor 0x1F +#define PICT_line 0x20 +#define PICT_line_from 0x21 +#define PICT_short_line 0x22 +#define PICT_short_line_from 0x23 +#define PICT_long_text 0x28 +#define PICT_DH_text 0x29 +#define PICT_DV_text 0x2A +#define PICT_DHDV_text 0x2B +#define PICT_frameRect 0x30 +#define PICT_paintRect 0x31 +#define PICT_eraseRect 0x32 +#define PICT_invertRect 0x33 +#define PICT_fillRect 0x34 +#define PICT_frameSameRect 0x38 +#define PICT_paintSameRect 0x39 +#define PICT_eraseSameRect 0x3A +#define PICT_invertSameRect 0x3B +#define PICT_fillSameRect 0x3C +#define PICT_frameRRect 0x40 +#define PICT_paintRRect 0x41 +#define PICT_eraseRRect 0x42 +#define PICT_invertRRect 0x43 +#define PICT_fillRRect 0x44 +#define PICT_frameSameRRect 0x48 +#define PICT_paintSameRRect 0x49 +#define PICT_eraseSameRRect 0x4A +#define PICT_invertSameRRect 0x4B +#define PICT_fillSameRRect 0x4C +#define PICT_frameOval 0x50 +#define PICT_paintOval 0x51 +#define PICT_eraseOval 0x52 +#define PICT_invertOval 0x53 +#define PICT_fillOval 0x54 +#define PICT_frameSameOval 0x58 +#define PICT_paintSameOval 0x59 +#define PICT_eraseSameOval 0x5A +#define PICT_invertSameOval 0x5B +#define PICT_fillSameOval 0x5C +#define PICT_frameArc 0x60 +#define PICT_paintArc 0x61 +#define PICT_eraseArc 0x62 +#define PICT_invertArc 0x63 +#define PICT_fillArc 0x64 +#define PICT_frameSameArc 0x68 +#define PICT_paintSameArc 0x69 +#define PICT_eraseSameArc 0x6A +#define PICT_invertSameArc 0x6B +#define PICT_fillSameArc 0x6C +#define PICT_framePoly 0x70 +#define PICT_paintPoly 0x71 +#define PICT_erasePoly 0x72 +#define PICT_invertPoly 0x73 +#define PICT_fillPoly 0x74 +#define PICT_frameSamePoly 0x78 +#define PICT_paintSamePoly 0x79 +#define PICT_eraseSamePoly 0x7A +#define PICT_invertSamePoly 0x7B +#define PICT_fillSamePoly 0x7C +#define PICT_frameRgn 0x80 +#define PICT_paintRgn 0x81 +#define PICT_eraseRgn 0x82 +#define PICT_invertRgn 0x83 +#define PICT_fillRgn 0x84 +#define PICT_frameSameRgn 0x88 +#define PICT_paintSameRgn 0x89 +#define PICT_eraseSameRgn 0x8A +#define PICT_invertSameRgn 0x8B +#define PICT_fillSameRgn 0x8C +#define PICT_BitsRect 0x90 +#define PICT_BitsRgn 0x91 +#define PICT_PackBitsRect 0x98 +#define PICT_PackBitsRgn 0x99 +#define PICT_shortComment 0xA0 +#define PICT_longComment 0xA1 +#define PICT_EndOfPicture 0xFF +#define PICT_headerOp 0x0C00 + +static void putFill ARGS(( FILE *fd, int n )); +static void putShort ARGS(( FILE *fd, int i )); +static void putLong ARGS(( FILE *fd, long i )); +static void putFixed ARGS(( FILE *fd, int in, int frac )); +static void putRect ARGS(( FILE *fd, int x1, int x2, int y1, int y2 )); +static int putRow ARGS(( FILE *fd, int row, int cols, pixel *rowpixels, char *packed )); + +#define MAXCOLORS 256 +static colorhash_table cht; + +int +main(argc, argv) +int argc; +char *argv[]; +{ + FILE *ifp; + int argn, rows, cols, colors, i, row, oc; + register pixel **pixels; + char *packed; + pixval maxval; + long lmaxval, rval, gval, bval; + colorhist_vector chv; + + + ppm_init( &argc, argv ); + + argn = 1; + if (argn < argc) + { + ifp = pm_openr(argv[1]); + argn++; + } + else + ifp = stdin; + if (argn != argc) + pm_usage("[ppmfile]"); + + pixels = ppm_readppm(ifp, &cols, &rows, &maxval); + if (cols < 8) + pm_error("ppm input too narrow, must be >= 8 pixels wide" ); + lmaxval = (long)maxval; + pm_close(ifp); + + /* Figure out the colormap. */ + pm_message("computing colormap..." ); + chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); + if (chv == (colorhist_vector) 0) + pm_error("too many colors - try doing a 'pnmquant %d'", MAXCOLORS); + pm_message("%d colors found", colors ); + + /* Make a hash table for fast color lookup. */ + cht = ppm_colorhisttocolorhash(chv, colors); + + /* write the header */ + putFill(stdout, HEADER_SIZE); + + /* write picSize and picFrame */ + putShort(stdout, 0); + putRect(stdout, 0, 0, rows, cols); + + /* write version op and version */ + putShort(stdout, PICT_picVersion); + putShort(stdout, 0x02FF); + putShort(stdout, PICT_headerOp); + putLong(stdout, -1L); + putFixed(stdout, 0, 0); + putFixed(stdout, 0, 0); + putFixed(stdout, cols, 0); + putFixed(stdout, rows, 0); + putFill(stdout, 4); + + /* seems to be needed by many PICT2 programs */ + putShort(stdout, PICT_clipRgn); + putShort(stdout, 10); + putRect(stdout, 0, 0, rows, cols); + + /* write picture */ + putShort(stdout, PICT_PackBitsRect); + putShort(stdout, cols | 0x8000); + putRect(stdout, 0, 0, rows, cols); + putShort(stdout, 0); /* pmVersion */ + putShort(stdout, 0); /* packType */ + putLong(stdout, 0L); /* packSize */ + putFixed(stdout, 72, 0); /* hRes */ + putFixed(stdout, 72, 0); /* vRes */ + putShort(stdout, 0); /* pixelType */ + putShort(stdout, 8); /* pixelSize */ + putShort(stdout, 1); /* cmpCount */ + putShort(stdout, 8); /* cmpSize */ + putLong(stdout, 0L); /* planeBytes */ + putLong(stdout, 0L); /* pmTable */ + putLong(stdout, 0L); /* pmReserved */ + putLong(stdout, 0L); /* ctSeed */ + putShort(stdout, 0); /* ctFlags */ + putShort(stdout, colors-1); /* ctSize */ + + /* Write out the colormap. */ + for (i = 0; i < colors; i++) + { + putShort(stdout, i); + rval = PPM_GETR(chv[i].color); + gval = PPM_GETG(chv[i].color); + bval = PPM_GETB(chv[i].color); + if (lmaxval != 65535L) + { + rval = rval * 65535L / lmaxval; + gval = gval * 65535L / lmaxval; + bval = bval * 65535L / lmaxval; + } + putShort(stdout, (short)rval); + putShort(stdout, (short)gval); + putShort(stdout, (short)bval); + } + + putRect(stdout, 0, 0, rows, cols); /* srcRect */ + putRect(stdout, 0, 0, rows, cols); /* dstRect */ + putShort(stdout, 0); /* mode */ + + /* Finally, write out the data. */ + packed = (char*) malloc((unsigned)(cols+cols/MAX_COUNT+1)); + oc = 0; + for (row = 0; row < rows; row++) + oc += putRow(stdout, row, cols, pixels[row], packed); + + /* if we wrote an odd number of pixdata bytes, pad */ + if (oc & 1) + (void) putc(0, stdout); + putShort(stdout, PICT_EndOfPicture); + + lmaxval = ftell(stdout) - HEADER_SIZE; + if (fseek(stdout, (long)HEADER_SIZE, 0) >= 0) + putShort(stdout, (short)(lmaxval & 0xffff)); + + exit(0); +} + +static void +putFill(fd, n) +FILE *fd; +int n; +{ + register int i; + + for (i = 0; i < n; i++) + (void) putc(0, fd); +} + +static void +putShort(fd, i) +FILE *fd; +int i; +{ + (void) putc((i >> 8) & 0xff, fd); + (void) putc(i & 0xff, fd); +} + +#if __STDC__ +static void +putLong( FILE *fd, long i ) +#else /*__STDC__*/ +static void +putLong(fd, i) +FILE *fd; +long i; +#endif /*__STDC__*/ +{ + (void) putc((int)((i >> 24) & 0xff), fd); + (void) putc(((int)(i >> 16) & 0xff), fd); + (void) putc(((int)(i >> 8) & 0xff), fd); + (void) putc((int)(i & 0xff), fd); +} + +static void +putFixed(fd, in, frac) +FILE *fd; +int in, frac; +{ + putShort(fd, in); + putShort(fd, frac); +} + +static void +putRect(fd, x1, x2, y1, y2) +FILE *fd; +int x1, x2, y1, y2; +{ + putShort(fd, x1); + putShort(fd, x2); + putShort(fd, y1); + putShort(fd, y2); +} + +#define RUNLENGTH +#ifdef RUNLENGTH + +#define runtochar(c) (257-(c)) +#define counttochar(c) ((c)-1) + +static int +putRow(fd, row, cols, rowpixels, packed) +FILE *fd; +int row, cols; +pixel *rowpixels; +char *packed; +{ + register int i; + int packcols, count, run, rep, oc; + register pixel *pP; + pixel lastp; + register char *p; + + run = count = 0; + for (cols--, i = cols, pP = rowpixels + cols, p = packed, lastp = *pP; + i >= 0; i--, lastp = *pP, pP--) + { + if (PPM_EQUAL(lastp, *pP)) + run++; + else if (run < RUN_THRESH) + { + while (run > 0) + { + *p++ = ppm_lookupcolor(cht, &lastp); + run--; + count++; + if (count == MAX_COUNT) + { + *p++ = counttochar(MAX_COUNT); + count -= MAX_COUNT; + } + } + run = 1; + } + else + { + if (count > 0) + *p++ = counttochar(count); + count = 0; + while (run > 0) + { + rep = run > MAX_RUN ? MAX_RUN : run; + *p++ = ppm_lookupcolor(cht, &lastp); + *p++ = runtochar(rep); + run -= rep; + } + run = 1; + } + } + if (run < RUN_THRESH) + { + while (run > 0) + { + *p++ = ppm_lookupcolor(cht, &lastp); + run--; + count++; + if (count == MAX_COUNT) + { + *p++ = counttochar(MAX_COUNT); + count -= MAX_COUNT; + } + } + } + else + { + if (count > 0) + *p++ = counttochar(count); + count = 0; + while (run > 0) + { + rep = run > MAX_RUN ? MAX_RUN : run; + *p++ = ppm_lookupcolor(cht, &lastp); + *p++ = runtochar(rep); + run -= rep; + } + run = 1; + } + if (count > 0) + *p++ = counttochar(count); + + packcols = p - packed; /* how many did we write? */ + if (cols > 250) + { + putShort(fd, packcols); + oc = packcols + 2; + } + else + { + (void) putc(packcols, fd); + oc = packcols + 1; + } + + /* now write out the packed row */ + while(p != packed) + { + --p; + (void) putc(*p, fd); + } + + return (oc); +} + +#else /* RUNLENGTH */ + +/* real dumb putRow with no compression */ +static int +putRow(fd, row, cols, rowpixels, packed) +FILE *fd; +int row, cols; +pixel *rowpixels; +char *packed; +{ + register int i, j, bc, oc; + register pixel *pP; + +#if notdef + bzero(aux, cols); /* aux?? */ +#endif /*notdef*/ + bc = cols + (cols + MAX_COUNT - 1) / MAX_COUNT; + if (bc > 250) + { + putShort(fd, bc); + oc = bc + 2; + } + else + { + (void) putc(bc, fd); + oc = bc + 1; + } + for (i = 0, pP = rowpixels; i < cols;) + { + if (cols - i > MAX_COUNT) + { + (void) putc(MAX_COUNT - 1, fd); + for (j = 0; j < MAX_COUNT; j++) + { + (void) putc(ppm_lookupcolor(cht, pP), fd); + pP++; + } + i += MAX_COUNT; + } + else + { + (void) putc(cols - i - 1, fd); + for (j = 0; j < cols - i; j++) + { + (void) putc(ppm_lookupcolor(cht, pP), fd); + pP++; + } + i = cols; + } + } + return (oc); +} +#endif /* RUNLENGTH */ |