home *** CD-ROM | disk | FTP | other *** search
- /*
- pcxload.c
-
- % Load a Z-soft pcx format image file into a pixel map structure.
-
- 5/02/89 By Ted.
-
- OWL-DIG 1.2
- Copyright (c) 1989 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 9/20/89 ted Allowed odd linebyte counts in image file.
- 11/06/89 ted Tweaked some more; fixed a few cases.
- 3/28/90 jmd ansi-fied
- */
-
- #include "oakhead.h"
- #include "disppriv.h"
- #include "frwdecl.h"
- #include "pcxdecl.h"
- #include "digutil.h"
-
- OSTATIC boolean DIGPRIV pcx_loadhdr(frw_type frw, pcxhdr_struct *pcxhdr);
- OSTATIC boolean DIGPRIV pcx_loadcolmap(frw_type frw, pcxhdr_struct *pcxhdr, ocolmap_type *cmapp);
-
- #define FRWBUFSIZE 1024
- /* -------------------------------------------------------------------------- */
-
- void DIGPRIV dig_loadpcx(frw_type frw, pmap_type *pmapp, ocolmap_type *cmapp, pcxunpack_fptr unpackpcx)
- {
- pcxhdr_struct pcxhdr;
-
- /* Load pcx file header */
- if (!pcx_loadhdr(frw, &pcxhdr)) {
- return;
- }
- /* Allocate Pixmap */
- *pmapp = pmap_Open(pcxhdr.xmax - pcxhdr.xmin + 1,
- pcxhdr.ymax - pcxhdr.ymin + 1);
- if (*pmapp == NULL) {
- return;
- }
- /* Allocate Buffer */
- if (!frw_openbuf(frw, FRWBUFSIZE, FRW_READMODE)) {
- pmap_Close(*pmapp);
- *pmapp = NULL;
- return;
- }
- /* Read in image */
- (*unpackpcx)(frw, &pcxhdr, *pmapp);
-
- /* Extract colormap */
- pcx_loadcolmap(frw, &pcxhdr, cmapp);
-
- frw_closebuf(frw);
- return;
- }
- /* -------------------------------------------------------------------------- */
-
- OSTATIC boolean DIGPRIV pcx_loadhdr(frw_type frw, pcxhdr_struct *pcxhdr)
- {
- /* Read in header */
- if (frw_read(frw, (VOID *)pcxhdr, sizeof(pcxhdr_struct)) < sizeof(pcxhdr_struct)) {
- return(FALSE);
- }
- pcx_hdrflip(pcxhdr); /* Flip bytes in shorts if needed */
-
- /* Cursory check of header */
- if (pcxhdr->mfgr != 10 ||
- pcxhdr->encoding != 1 ||
- !(pcxhdr->version == 0 || pcxhdr->version == 2 ||
- pcxhdr->version == 3 || pcxhdr->version == 5)) {
- return(FALSE);
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- OSTATIC boolean DIGPRIV pcx_loadcolmap(frw_type frw, pcxhdr_struct *pcxhdr, ocolmap_type *cmapp)
- {
- opixval ncols;
-
- ncols = (opixval) dig_powof2(pcxhdr->pixbits * pcxhdr->nplanes);
-
- if (ncols == 256 && pcxhdr->version == 5) {
- /* 256 color map at end of image */
- if (frw_readb(frw) == 12) {
- *cmapp = ocolmap_Open(0, 256);
- if (*cmapp != NULL) {
- if(frw_read(frw, (VOID *) ocolmap_entry(*cmapp, 0), 256*3) == 256*3) {
- return(TRUE);
- }
- }
- }
- }
- else { /* 16 color color map in header */
- if (ncols <= 16 && pcxhdr->version != 3) {
- *cmapp = ocolmap_Open(0, ncols);
- if (*cmapp != NULL) {
- memmove((VOID *) ocolmap_entry(*cmapp, 0), (VOID *) pcxhdr->rgb,
- (SIZE_T)((*cmapp)->nentries * 3));
- return(TRUE);
- }
- }
- }
- return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
-
- boolean DIGPRIV pcx_readline(frw_type frw, byte *obuf, unsigned linebytes, unsigned *ocountp)
- {
- unsigned ibyte;
- unsigned cbyte; /* note: hi byte used for error flag */
- byte count, xcount;
- unsigned tcount;
- boolean nullobuf;
-
- ibyte = 0;
- count = (byte) *ocountp;
- if (count != 0) cbyte = *ocountp >> 8;
-
- nullobuf = (obuf == NULL);
-
- /* For each code within a plane-line */
- for (;;) {
-
- if (ibyte >= linebytes) break;
-
- if (count == 0) {
- cbyte = frw_readb(frw);
- if (cbyte & 0xFF00) return(FALSE);
-
- if (((byte)cbyte & 0xC0) != 0xC0) { /* No repeat - stash & go. */
- if (!nullobuf) *obuf++ = (byte) cbyte;
- if (++ibyte >= linebytes) {
- break; /* break out of line loop to next plane */
- }
- continue; /* continue line loop */
- }
- else { /* Got a loop count */
- count = (byte)cbyte & ~0xC0;
-
- cbyte = frw_readb(frw);
- if (cbyte & 0xFF00) return(FALSE);
- }
- }
- /* If count hangs over the end of this plane line, truncate it */
- /* and save the remainder for the next plane */
- if ((tcount = linebytes - ibyte) < (unsigned) count) {
- xcount = count - (byte) tcount;
- count = (byte) tcount;
- }
- else xcount = 0;
-
- if (!nullobuf) {
- memset((VOID *) obuf, (byte) cbyte, (SIZE_T) count);
- obuf += (unsigned) count;
- }
- ibyte += (unsigned) count;
- count = 0;
-
- } /* end of line loop */
-
- /* Put count and repeat byte in ocountp if xcount is not 0. */
- if ((*ocountp = xcount) != 0) {
- *ocountp |= cbyte << 8;
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- void DIGPRIV pcx_hdrflip(pcxhdr_struct *pcxhdr)
- /*
- Flip bytes in shorts if needed
- */
- {
- if (disp_GetByteOrder() != BO_LSBYTFIRST) {
- dig_flipshort(&pcxhdr->xmin);
- dig_flipshort(&pcxhdr->xmax);
- dig_flipshort(&pcxhdr->ymin);
- dig_flipshort(&pcxhdr->ymax);
- dig_flipshort(&pcxhdr->hres);
- dig_flipshort(&pcxhdr->vres);
- dig_flipshort(&pcxhdr->linebytes);
- dig_flipshort(&pcxhdr->paltype);
- }
- }
- /* -------------------------------------------------------------------------- */
-
-