home *** CD-ROM | disk | FTP | other *** search
- /*
- pcpmapio.c
-
- % Routines for PC pixel map i/o interface
-
- 7/05/89 by Ted.
-
- OWL 1.1
- Copyright (c) 1989 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 02/23/88 ted: Added copy case.
- */
-
- #include "pcpriv.h"
- #include "pmlsreq.h"
- #include "pcxdecl.h"
-
- #define MAXPLANES 24 /* max number of planes supported in image format */
-
- OSTATIC pcxunpack_func(pc_unpackpcx);
- OSTATIC pcxpack_func(pc_packpcx);
- OSTATIC void DIGPRIV setobuf(_arg3(pmap_type pmap, byte *obuf[], byte nplanes));
- OSTATIC boolean DIGPRIV pixnot0(_arg6(pmap_type pmap, byte **obuf, byte nplanes, opcoord x, opcoord y, byte bmask));
- /* -------------------------------------------------------------------------- */
-
- int pc_PmapIoReq(msg, indata, outdata)
- dig_pcmsg msg;
- VOID *indata;
- VOID *outdata;
- {
- pmaplsreq_struct *pmlsr;
- pmap_type pmap;
- bmap_type bmap;
-
- switch (msg) {
- case PC_LOADPMAP:
- {
- ocolmap_type cmap = NULL;
-
- pmlsr = (pmaplsreq_struct *)indata;
-
- dig_loadpcx(&pmlsr->frw, &pmlsr->pmap, &cmap, pc_unpackpcx);
- pc_squeezecmap(pmlsr->pmap, cmap, pmlsr->crange);
-
- ocolmap_Close(cmap);
- break;
- }
- case PC_SAVEPMAP:
-
- pmlsr = (pmaplsreq_struct *)indata;
-
- *((boolean *) outdata) =
- dig_savepcx(&pmlsr->frw, pmlsr->pmap, pmlsr->crange, pc_packpcx);
- break;
-
- case PC_BMAPTOPMAP:
- {
- /* Copy / translate an image from the bit map passed in indata */
- /* into the pixel map passed in outdata. */
- }
- break;
- case PC_PMAPTOBMAP:
- {
- /* Copy / translate an image from the pixel map passed in indata */
- /* into the bit map passed in outdata. */
- byte bmask;
- unsigned bmbyte;
- odim x, y;
- byte *obuf[MAXPLANES];
- odim bwidth;
- byte nplanes;
- byte iplane;
-
- pmap = (pmap_type) indata;
- bmap = (bmap_type) outdata;
-
- if (pmap == NULL || bmap == NULL) {
- return(FALSE);
- }
- bwidth = pcpmap_bytewidth(pmap);
- nplanes = pcpmap_nplanes(pmap);
- setobuf(pmap, obuf, nplanes);
-
- bmbyte = 0;
- for (y = 0; y < bmap->height; y++) {
- bmask = 0x80;
- for (x = 0; ; x++) {
- if (pixnot0(pmap, obuf, nplanes, x, y, bmask)) {
- bmap->array[bmbyte] |= bmask;
- }
- else {
- bmap->array[bmbyte] &= ~bmask;
- }
- if (x >= bmap->width) {
- break;
- }
- if ((bmask >>= 1) == 0) {
- bmask = 0x80;
- bmbyte++;
- }
- }
- for (iplane = 0; iplane < nplanes; iplane++) {
- obuf[iplane] += bwidth;
- }
- bmbyte++;
- }
- break;
- }
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV pc_unpackpcx(frw, pcxhdr, pmap)
- struct frw_struct *frw;
- pcxhdr_struct *pcxhdr;
- pmap_type pmap;
- {
- byte *obuf[MAXPLANES];
- unsigned height;
- unsigned linebytes, pclinebytes;
- int iline, iplane;
- byte **planes;
- int nplanes;
- int pcnplanes;
- unsigned ocount;
-
- nplanes = pcxhdr->nplanes;
- pcnplanes = pcpmap_nplanes(pmap);
- height = pmap_GetHeight(pmap);
- linebytes = pclinebytes = pcpmap_bytewidth(pmap);
- /* Don't read more bytes per line than the file has. */
- if (linebytes > pcxhdr->linebytes) {
- linebytes = pcxhdr->linebytes;
- }
- /* Initialize the obuf array of image plane buffers pointers */
- if (pcnplanes == 1) {
- /* Set all planes to point to same buffer so it will get overwritten */
- /* by the pcx file planes, to suck all the bytes out of the file */
- for (iplane = 0; iplane < nplanes; iplane++) {
- obuf[iplane] = pcpmap_pixbuf(pmap);
- }
- }
- else {
- planes = pcpmap_planes(pmap);
- for (iplane = 0; iplane < nplanes && iplane < pcnplanes; iplane++) {
- obuf[iplane] = planes[iplane];
- }
- /* If pcxhdr has fewer planes than pmap, clear extra pmap planes to 0 */
- for ( ; iplane < pcnplanes; iplane++) {
- memset(planes[iplane], 0, (unsigned)pcpmap_GetPlaneSize(pmap));
- }
- }
- /* Decode the image */
- for (iline = 0 ; iline < height; iline++) { /* For every line */
- /* For each plane within a line */
- ocount = 0;
- for (iplane = 0; iplane < nplanes; iplane++) {
- /* Load a line of the plane buffer for the current plane */
- if (!pcx_readline(frw, obuf[iplane], linebytes, &ocount)) {
- return(FALSE);
- }
- obuf[iplane] += pclinebytes;
- } /* end of plane loop */
- } /* end of lines loop */
-
- /* Take care of cases where the linebytes counts don't match */
- if (pclinebytes > pcxhdr->linebytes) {
- /* Pmap wider - fill with 0's */
- for (iplane = 0; iplane < pcnplanes; iplane++) {
- obuf[iplane] -= pclinebytes * height - linebytes; /* Rewind obuf's */
- }
- /* Blank out leftover bytes on every plane on every line */
- linebytes = pclinebytes - linebytes; /* # of extra bytes per line */
- for (iline = 0 ; iline < height; iline++) { /* For every line */
- for (iplane = 0; iplane < pcnplanes; iplane++) {
- memset(obuf[iplane], 0, linebytes);
- obuf[iplane] += pclinebytes;
- }
- }
- }
- else if (pclinebytes < pcxhdr->linebytes) {
- /* File wider - suck up extra bytes */
- /* Round linebytes up to even #; pcx_readline did. */
- linebytes += linebytes&1;
- ocount = (pcxhdr->linebytes - linebytes) * height;
- for ( ; ocount > 0; ocount--) {
- if (frw_readb(frw) & 0xFF00) return(FALSE);
- }
- }
- /* Take care of case where the pcx file has leftover lines */
- if (height < pcxhdr->ylines) {
- unsigned long lcount;
-
- lcount = (unsigned long) pcxhdr->linebytes *
- (unsigned long)(pcxhdr->ylines - height);
- for ( ; lcount > 0; lcount--) {
- if (frw_readb(frw) & 0xFF00) return(FALSE);
- }
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV pc_packpcx(frw, pmap)
- struct frw_struct *frw;
- pmap_type pmap;
- {
- unsigned height;
- unsigned linebytes;
- int iline, iplane;
- byte nplanes;
- byte *obuf[MAXPLANES];
-
- nplanes = disp_GetInfo()->nplanes;
- height = pmap_GetHeight(pmap);
-
- /* Note: pmap linebytes must equal pcxhdr->linebytes or pcxhdr->linebytes-1 */
- linebytes = pcpmap_bytewidth(pmap);
-
- /* Initialize the obuf array of image plane buffers pointers */
- setobuf(pmap, obuf, nplanes);
-
- /* Encode the image */
- for (iline = 0 ; iline < height; iline++) { /* For every line */
-
- /* For each plane within a line */
- for (iplane = 0; iplane < nplanes; iplane++) {
- /* Save a line of the plane buffer for the current plane */
- if (!pcx_writeline(frw, obuf[iplane], linebytes)) {
- return(FALSE);
- }
- obuf[iplane] += linebytes;
- } /* end of plane loop */
- } /* end of lines loop */
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV pixnot0(pmap, obuf, nplanes, x, y, bmask)
- pmap_type pmap;
- byte **obuf;
- byte nplanes;
- opcoord x;
- opcoord y;
- byte bmask;
- {
- int iplane;
- unsigned planebyte;
-
- if (y < pmap_GetHeight(pmap) && x < pmap_GetWidth(pmap)) {
-
- if (pcpmap_pixbits(pmap) == 8) {
- bmask = 0xFF;
- planebyte = x;
- }
- else planebyte = x >> 3;
- for (iplane = 0; iplane < nplanes; iplane++) {
- if ((obuf[iplane][planebyte] & bmask) != 0) {
- return(TRUE);
- }
- }
- }
- return(FALSE);
- }
- /* -------------------------------------------------------------------------- */
-
- static void DIGPRIV setobuf(pmap, obuf, nplanes)
- pmap_type pmap;
- byte *obuf[];
- byte nplanes;
- {
- byte **planes;
- int iplane;
-
- if (nplanes <= 1) {
- obuf[0] = pcpmap_pixbuf(pmap);
- }
- else {
- planes = pcpmap_planes(pmap);
- for (iplane = 0; iplane < nplanes; iplane++) {
- obuf[iplane] = planes[iplane];
- }
- }
- }
- /* -------------------------------------------------------------------------- */
-
-