home *** CD-ROM | disk | FTP | other *** search
- /*
- pcpmapio.c
-
- % Routines for PC pixel map i/o interface
-
- 7/05/89 by Ted.
-
- OWL-PC 1.2
- Copyright (c) 1989 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 9/20/89 ted Tweaked handling of images mismatched with current vid mode.
-
- 11/06/89 ted Tweaked some more; fixed a few cases.
- 2/15/90 ted Called dig_squeezecmap instead of pc_squeezecmap.
- 2/29/90 ted Added OCDECL for assembly function.
- 3/28/90 jmd ansi-fied
- 4/26/90 ted Added ocolmap_set for non-squeezing load case.
- 6/19/90 ted Removed reference to pcxhdr->ylines because it's not reliable.
- 10/10/90 ted Replaced OCDECL with oasm_func for assembly functions.
- */
-
- #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 boolean DIGPRIV pixnot0(pmap_type pmap, byte **obuf, byte nplanes, opcoord x, opcoord y, byte bmask);
- OSTATIC void DIGPRIV setobuf(pmap_type pmap, byte *obuf[], byte nplanes);
- /* -------------------------------------------------------------------------- */
-
- int pc_PmapIoReq(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);
- if (pc_pixbits() == 8 && pc_nplanes() == 1) {
- dig_squeezecmap(pmlsr->pmap, cmap, pmlsr->crange, pc_pmhist, pc_pmcswap, pc_pmnearcol);
- }
- else {
- ocolmap_set(pmlsr->crange, cmap);
- }
- 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(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 { /* More than one plane */
- planes = pcpmap_planes(pmap);
- for (iplane = 0; iplane < pcnplanes; iplane++) {
- obuf[iplane] = planes[iplane];
- }
- /* If pcx file has more planes than pmap, make extra buf planes point */
- /* to last pmap plane so it will get overwritten */
- for ( ; iplane < nplanes; iplane++) {
- obuf[iplane] = planes[pcnplanes - 1];
- }
- }
- /* 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] += linebytes;
-
- /* If the pmap is wider than the file image, pad pmap lines with 0's */
- if (pclinebytes > linebytes) {
- memset(obuf[iplane], 0, pclinebytes - linebytes);
- obuf[iplane] += pclinebytes - linebytes;
- }
- /* If the file image is wider than the pmap, suck up extra bytes */
- else if (pcxhdr->linebytes > linebytes) {
- if (!pcx_readline(frw, NULL, pcxhdr->linebytes - linebytes, &ocount)) {
- return(FALSE);
- }
- }
- }
- /* If pcxhdr has fewer planes than pmap, dup the extra pmap planes */
- for ( ; iplane < pcnplanes; iplane++) {
- memmove(obuf[iplane], obuf[nplanes-1] - pclinebytes, pclinebytes);
- obuf[iplane] += pclinebytes;
- }
- } /* end of lines loop */
-
- /* Take care of case where the pcx file has leftover lines */
- /* For every leftover line ... */
- for (iline = height; iline < (pcxhdr->ymax - pcxhdr->ymin + 1); iline++) {
- /* 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, NULL, pcxhdr->linebytes, &ocount)) {
- return(FALSE);
- }
- }
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean DIGPRIV pc_packpcx(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_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_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];
- }
- }
- }
- /* -------------------------------------------------------------------------- */
- /* pcbxlat.asm */
- extern oasm_func(void, bxlat, (byte *bufaddr, unsigned bufsize, byte *swaptab));
-
- /* pcneares.asm */
- extern oasm_func(opixval, pc_nearestcol, (orgb_struct *rgb, ocolmap_type cmap));
- /* -------------------------------------------------------------------------- */
-
- void pc_pmhist(pmap_type pmap, unsigned short *histtab)
- /*
- Histogram pmap pixval bytes into word table 'histtab'.
- Table must be pre-initialized; we start incrementing without zeroing first.
- */
- {
- byte *buf;
- unsigned bufsize;
-
- buf = pcpmap_pixbuf(pmap);
- bufsize = (unsigned) pcpmap_GetPlaneSize(pmap);
-
- for ( ; bufsize > 0; bufsize--) {
- histtab[*(buf++)]++;
- }
- }
- /* -------------------------------------------------------------------------- */
-
- void pc_pmcswap(pmap_type pmap, byte *swaptab)
- {
- bxlat(pcpmap_pixbuf(pmap), (unsigned) pcpmap_GetPlaneSize(pmap), swaptab);
- }
- /* -------------------------------------------------------------------------- */
-
- opixval pc_pmnearcol(orgb_struct *rgb, ocolmap_type cmap)
- {
- return(pc_nearestcol(rgb, cmap));
- }
- /* -------------------------------------------------------------------------- */
-