home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * flpcx.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
- *
- * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
- * use this file in whole or in part provided that you do not sell it
- * for profit and that this copyright notice is retained unchanged.
- *
- * flpcx.c:
- *
- * CONTENTS
- * write_pcx (image, stream)
- * read_pcx (image, stream, mstr, mlen)
- *
- * EDITLOG
- * LastEditDate = Tue Mar 7 19:57:24 1989 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/flpcx.c
- *
- * HISTORY
- * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Beta release (version 0.9) mlm@cs.cmu.edu
- *
- * 12-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Created.
- *****************************************************************/
-
- # include <stdio.h>
- # include <math.h>
- # include <ctype.h>
- # include "fbm.h"
-
- /****************************************************************
- * pcx.h: Paintbrush file format header, as per "ZSoft Technical
- * Reference Manual for Publisher's Paintbrush, PC Paintbrush Plus,
- * PC Paintbrush and Frieze Graphics.", 1988, ZSoft corporation,
- *
- * 450 Franklin Rd. Suite 100 / Marietta, GA 30067 / 404-428-0008
- *
- * HISTORY
- * {1} 1-Sep-87 Michael L. Mauldin (mlm) at cognac
- * Created.
- *
- ****************************************************************/
-
- # define UBYTE unsigned char /* 8 bits unsigned */
- # define WORD short /* 16 bits signed */
-
- typedef struct pcxstruct {
- UBYTE Manufacturer; /* 10 == ZSoft PCX */
- UBYTE Version; /* Version Information */
- /* 0 == ver 2.5 */
- /* 2 == ver 2.8 w/pallete */
- /* 3 == 2.8 w/o pallete */
- /* 5 == ver 3.0 w/pallete */
- UBYTE Encoding; /* 01 == PCX run-length encoding */
- UBYTE BitsPerPixel; /* 8/number of pixels per byte */
- WORD Window[4]; /* xmin, ymin, xmax, ymax */
- WORD Hres; /* Horizontal resolution */
- WORD Vres; /* Vertical resolution */
- UBYTE Colormap[16][3]; /* Color Pallete, RGB in 0..255 */
- UBYTE Reserved; /* Reserved */
- UBYTE NPlanes; /* Number of Color Planes */
- WORD BytesPerLine; /* Number of bytes per scan line */
- WORD Palette; /* 1 = color/BW, 2 = grayscale */
- UBYTE Filler[58]; /* Pad header to 128 bytes */
- } PCXHDR;
-
- # define XMIN 0
- # define YMIN 1
- # define XMAX 2
- # define YMAX 3
-
- # define CNTMSK 0xc0
- # define MAXCNT 0x3f
-
- # define swapword(X) ((((X)&0xff) << 8) | (((X) & 0xff00) >> 8))
-
- /****************************************************************
- * write_pcx: Write PC Paintbrush format
- ****************************************************************/
-
- #ifndef lint
- static char *fbmid =
- "$FBM flpcx.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
- #endif
-
- write_pcx (image, stream)
- FBM *image;
- FILE *stream;
- {
- fprintf (stderr, "PCX support not yet available\n");
-
- return (0);
- }
-
- /****************************************************************
- * read_pcx: Read PC Paintbrush format
- ****************************************************************/
-
- read_pcx (image, rfile, mstr, mlen)
- FBM *image;
- FILE *rfile;
- char *mstr;
- int mlen;
- { PCXHDR phdr;
- char *hp;
- register unsigned char *bmp, *scan;
- register int k, r, c, bit, byte, mask, width, height, rowlen;
- int depth, ptype, color, enc, clrlen, totalbytes;
- unsigned char *buf, *tail;
-
- /* Read PCX file header */
- hp = (char *) &phdr;
-
- if (mlen > 0) strncpy (hp, mstr, mlen);
-
- if (! fread (hp+mlen, sizeof (phdr) - mlen, 1, rfile))
- { perror ("read_fbm (header)"); return (0); }
-
- if (phdr.Manufacturer != PCX_MAGIC)
- { fprintf (stderr,
- "Error, file is not a PCX file, magic %02x is not 0a\n",
- phdr.Manufacturer);
- return (0);
- }
-
- /* PCX uses Little Indian byte order, swap on SUNS, RTs, ... */
- if (machine_byte_order () == BIG)
- { phdr.Window[0] = swapword (phdr.Window[0]);
- phdr.Window[1] = swapword (phdr.Window[1]);
- phdr.Window[2] = swapword (phdr.Window[2]);
- phdr.Window[3] = swapword (phdr.Window[3]);
- phdr.Hres = swapword (phdr.Hres);
- phdr.Vres = swapword (phdr.Vres);
- phdr.BytesPerLine = swapword (phdr.BytesPerLine);
- phdr.Palette = swapword (phdr.Palette);
- }
-
- # ifdef DEBUG
- fprintf (stderr, "Manufacturer %d\n", phdr.Manufacturer);
- fprintf (stderr, "Version %d\n", phdr.Version);
- fprintf (stderr, "Encoding %d\n", phdr.Encoding);
- fprintf (stderr, "BitsPerPixel %d\n", phdr.BitsPerPixel);
- fprintf (stderr, "Window0 %d\n", phdr.Window[0]);
- fprintf (stderr, "Window1 %d\n", phdr.Window[1]);
- fprintf (stderr, "Window2 %d\n", phdr.Window[2]);
- fprintf (stderr, "Window3 %d\n", phdr.Window[3]);
- fprintf (stderr, "Hres %d\n", phdr.Hres);
- fprintf (stderr, "Vres %d\n", phdr.Vres);
- fprintf (stderr, "Reserved %d\n", phdr.Reserved);
- fprintf (stderr, "NPlanes %d\n", phdr.NPlanes);
- fprintf (stderr, "BytesPerLine %d\n", phdr.BytesPerLine);
- fprintf (stderr, "Palette %d\n", phdr.Palette);
- # endif
-
- /* Now extract relevant features of PCX file header */
- width = phdr.Window[XMAX] - phdr.Window[XMIN] + 1;
- height = phdr.Window[YMAX] - phdr.Window[YMIN] + 1;
- depth = phdr.NPlanes;
- ptype = phdr.Version;
- color = (ptype == 2) || (ptype == 5);
- enc = phdr.Encoding;
-
- if (phdr.BitsPerPixel != 1)
- { fprintf (stderr, "%s %d bits per pixel with %d planes\n",
- "Error in PCX file, can't handle",
- phdr.BitsPerPixel, depth);
- return (0);
- }
-
- /* Initialize image header */
- image->hdr.cols = width;
- image->hdr.rows = height;
- image->hdr.planes = 1;
- image->hdr.bits = (color || depth > 1) ? 8 : 1;
- image->hdr.physbits = 8;
- image->hdr.rowlen = rowlen = 16 * ((width + 15) / 16);
- image->hdr.plnlen = rowlen * height;
- image->hdr.clrlen = clrlen = color ? (16 * 3) : 0;
- image->hdr.aspect = 1.0;
- image->hdr.title[0] = '\0';
- image->hdr.credits[0] = '\0';
-
- /* Describe what we are doing */
- fprintf (stderr, "Reading PCX file [%dx%d]", width, height);
- if (phdr.BitsPerPixel > 1)
- fprintf (stderr, ", %d bits per pixel", phdr.BitsPerPixel);
- if (depth > 1)
- fprintf (stderr, ", %d planes", depth);
- if (clrlen > 0)
- fprintf (stderr, ", %d colors", clrlen/3);
- fprintf (stderr, "\n");
-
- /* Allocate space */
- alloc_fbm (image);
-
- /* Read colormap if need be */
- if (clrlen > 0)
- { for (c=0; c<16; c++)
- { image->cm[c] = phdr.Colormap[c][0];
- image->cm[c+16] = phdr.Colormap[c][1];
- image->cm[c+32] = phdr.Colormap[c][2];
- }
- }
-
- /* Zero out the bits */
- bmp = image->bm;
- tail = bmp + image->hdr.plnlen;
-
- while (bmp < tail) { *bmp++ = 0; }
-
- /* Bytes per scan line */
- totalbytes = depth * phdr.BytesPerLine;
- buf = (unsigned char *) malloc (totalbytes);
-
- /* Now read bits */
- for (r=0; r<height; r++)
- { bmp = &(image->bm[r * rowlen]);
-
- /* Read a scan line */
- if (pcxline_read (enc, buf, totalbytes, rfile) == 0)
- { fprintf (stderr, "Premature EOF in row %d, totalbytes %d\n",
- r, totalbytes);
- # ifdef REAL
- free_fbm (image);
- return (0);
- # else
- return (1);
- # endif
- }
-
- /* Decode scan line into row of image */
- if (depth == 1)
- { bmp = &(image->bm[r * rowlen]);
- scan = buf;
-
- for (c=0; c<width; c++)
- { byte = c>>3;
- mask = 0x80 >> (c&7);
- *bmp++ = (buf[byte] & mask) ? WHITE : BLACK;
- }
- }
- else
- { for (k=0; k<depth; k++)
- { bmp = &(image->bm[r * rowlen]);
- scan = &buf[k * phdr.BytesPerLine];
- bit = 1 << k;
-
- for (c=0; c<width; c++)
- { byte = c>>3;
- mask = 0x80 >> (c&7);
-
- *bmp++ |= (buf[byte] & mask) ? bit : 0;
- }
- }
- }
- }
-
- if (depth > 1)
- { fprintf (stderr, "Read %d planes successfully\n", depth);
- }
-
- return (1);
- }
-
- /****************************************************************
- * encget (pbyt, pcnt, fid) Page 10 of ZSoft Manual
- ****************************************************************/
-
- encget (pbyt, pcnt, fid)
- int *pbyt; /* Where to place data */
- int *pcnt; /* Where to place count */
- FILE *fid; /* Image file stream */
- { register int i;
-
- *pcnt = 1; /* Safety play */
- if (EOF == (i = getc (fid))) return (EOF);
- if (CNTMSK == (CNTMSK & i))
- { *pcnt = MAXCNT & i;
- if (EOF == (i = getc (fid))) return (EOF);
- }
- *pbyt = i;
- return (0);
- }
-
- /****************************************************************
- * pcxline_read
- ****************************************************************/
- pcxline_read (enc, buf, total, fid)
- unsigned char *buf; /* Output buffer */
- int total; /* Bytes in one scan line */
- FILE *fid; /* Input stream */
- { int data, count, len=0;
-
- if (enc != 1)
- { return (fread (buf, 1, total, fid)); }
-
- while (len < total)
- { if (EOF == encget (&data, &count, fid))
- return (len);
- while (count > 0) { *buf++ = data; len++; count--; }
- }
-
- if (count > 0)
- { fprintf (stderr, "%s, after %d bytes, lost %d bytes of %02x\n",
- "Error in reading scan lines", total, count, data);
- }
-
- return (len);
- }
-