home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / PCPMAPIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-10  |  9.0 KB  |  321 lines

  1. /*
  2.     pcpmapio.c
  3.  
  4.     % Routines for PC pixel map i/o interface
  5.  
  6.     7/05/89  by Ted.
  7.  
  8.     OWL-PC 1.2
  9.     Copyright (c) 1989 by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      9/20/89 ted    Tweaked handling of images mismatched with current vid mode.
  15.  
  16.     11/06/89 ted    Tweaked some more; fixed a few cases.
  17.      2/15/90 ted    Called dig_squeezecmap instead of pc_squeezecmap.
  18.      2/29/90 ted    Added OCDECL for assembly function.
  19.      3/28/90 jmd    ansi-fied
  20.      4/26/90 ted    Added ocolmap_set for non-squeezing load case.
  21.      6/19/90 ted    Removed reference to pcxhdr->ylines because it's not reliable.
  22.     10/10/90 ted    Replaced OCDECL with oasm_func for assembly functions.
  23. */
  24.  
  25. #include "pcpriv.h"
  26. #include "pmlsreq.h"
  27. #include "pcxdecl.h"
  28.  
  29. #define MAXPLANES    24    /*    max number of planes supported in image format */
  30.  
  31. OSTATIC pcxunpack_func(pc_unpackpcx);
  32. OSTATIC pcxpack_func(pc_packpcx);
  33.  
  34. OSTATIC boolean DIGPRIV pixnot0(pmap_type pmap, byte **obuf, byte nplanes, opcoord x, opcoord y, byte bmask);
  35. OSTATIC void     DIGPRIV setobuf(pmap_type pmap, byte *obuf[], byte nplanes);
  36. /* -------------------------------------------------------------------------- */
  37.  
  38. int pc_PmapIoReq(dig_pcmsg msg, VOID *indata, VOID *outdata)
  39. {
  40.     pmaplsreq_struct *pmlsr;
  41.     pmap_type pmap;
  42.     bmap_type bmap;
  43.  
  44.     switch (msg) {
  45.     case PC_LOADPMAP:
  46.     {        
  47.         ocolmap_type cmap = NULL;
  48.  
  49.         pmlsr = (pmaplsreq_struct *)indata;
  50.  
  51.         dig_loadpcx(&pmlsr->frw, &pmlsr->pmap, &cmap, pc_unpackpcx);
  52.         if (pc_pixbits() == 8 && pc_nplanes() == 1) {
  53.             dig_squeezecmap(pmlsr->pmap, cmap, pmlsr->crange, pc_pmhist, pc_pmcswap, pc_pmnearcol);
  54.         }
  55.         else {
  56.             ocolmap_set(pmlsr->crange, cmap);
  57.         }
  58.         ocolmap_Close(cmap);
  59.         break;
  60.     }
  61.     case PC_SAVEPMAP:
  62.  
  63.         pmlsr = (pmaplsreq_struct *)indata;
  64.  
  65.         *((boolean *) outdata) =
  66.             dig_savepcx(&pmlsr->frw, pmlsr->pmap, pmlsr->crange, pc_packpcx);
  67.         break;
  68.  
  69.     case PC_BMAPTOPMAP:
  70.     /*    Copy / translate an image from the bit map passed in indata
  71.         into the pixel map passed in outdata.
  72.     */
  73.     {
  74.     }
  75.     break;
  76.     case PC_PMAPTOBMAP:
  77.     /*    Copy / translate an image from the pixel map passed in indata
  78.         into the bit map passed in outdata.
  79.     */
  80.     {
  81.         byte bmask;
  82.         unsigned bmbyte;
  83.         odim x, y;
  84.         byte *obuf[MAXPLANES];
  85.         odim bwidth;
  86.         byte nplanes;
  87.         byte iplane;
  88.  
  89.         pmap = (pmap_type) indata;
  90.         bmap = (bmap_type) outdata;
  91.  
  92.         if (pmap == NULL || bmap == NULL) {
  93.             return(FALSE);
  94.         }
  95.         bwidth = pcpmap_bytewidth(pmap);
  96.         nplanes = pcpmap_nplanes(pmap);
  97.         setobuf(pmap, obuf, nplanes);
  98.  
  99.         bmbyte = 0;
  100.         for (y = 0; y < bmap->height; y++) {
  101.             bmask = 0x80;
  102.             for (x = 0; ; x++) {
  103.                 if (pixnot0(pmap, obuf, nplanes, x, y, bmask)) {
  104.                     bmap->array[bmbyte] |= bmask;
  105.                 }
  106.                 else {
  107.                     bmap->array[bmbyte] &= ~bmask;
  108.                 }
  109.                 if (x >= bmap->width) {
  110.                     break;
  111.                 }
  112.                 if ((bmask >>= 1) == 0) {
  113.                     bmask = 0x80;
  114.                     bmbyte++;
  115.                 }
  116.             }
  117.             for (iplane = 0; iplane < nplanes; iplane++) {
  118.                 obuf[iplane] += bwidth;
  119.             }
  120.             bmbyte++;
  121.         }
  122.         break;
  123.     }
  124.     }
  125.     return(TRUE);
  126. }
  127. /* -------------------------------------------------------------------------- */
  128.  
  129. static boolean DIGPRIV pc_unpackpcx(struct frw_struct *frw, pcxhdr_struct *pcxhdr, pmap_type pmap)
  130. {
  131.     byte *obuf[MAXPLANES];
  132.     unsigned height;
  133.     unsigned linebytes, pclinebytes;
  134.     int iline, iplane;
  135.     byte **planes;
  136.     int nplanes;
  137.     int pcnplanes;
  138.     unsigned ocount;
  139.  
  140.     nplanes = pcxhdr->nplanes;
  141.     pcnplanes = pcpmap_nplanes(pmap);
  142.     height = pmap_GetHeight(pmap);
  143.     linebytes = pclinebytes = pcpmap_bytewidth(pmap);
  144.     /* Don't read more bytes per line than the file has. */
  145.     if (linebytes > pcxhdr->linebytes) {
  146.         linebytes = pcxhdr->linebytes;
  147.     }
  148.     /* Initialize the obuf array of image plane buffers pointers */
  149.     if (pcnplanes == 1) {
  150.         /* Set all planes to point to same buffer so it will get overwritten */
  151.         /* by the pcx file planes, to suck all the bytes out of the file */
  152.         for (iplane = 0; iplane < nplanes; iplane++) {
  153.             obuf[iplane] = pcpmap_pixbuf(pmap);
  154.         }
  155.     }
  156.     else {    /* More than one plane */
  157.         planes = pcpmap_planes(pmap);
  158.         for (iplane = 0; iplane < pcnplanes; iplane++) {
  159.             obuf[iplane] = planes[iplane];
  160.         }
  161.         /* If pcx file has more planes than pmap, make extra buf planes point */
  162.         /*  to last pmap plane so it will get overwritten */
  163.         for ( ; iplane < nplanes; iplane++) {
  164.             obuf[iplane] = planes[pcnplanes - 1];
  165.         }
  166.     }
  167.     /* Decode the image */
  168.     for (iline = 0 ; iline < height; iline++) {        /* For every line */
  169.         /* For each plane within a line */
  170.         ocount = 0;
  171.         for (iplane = 0; iplane < nplanes; iplane++) {
  172.             /* Load a line of the plane buffer for the current plane */
  173.             if (!pcx_readline(frw, obuf[iplane], linebytes, &ocount)) {
  174.                 return(FALSE);
  175.             }
  176.             obuf[iplane] += linebytes;
  177.  
  178.             /* If the pmap is wider than the file image, pad pmap lines with 0's */
  179.             if (pclinebytes > linebytes) {
  180.                 memset(obuf[iplane], 0, pclinebytes - linebytes);
  181.                 obuf[iplane] += pclinebytes - linebytes;
  182.             }
  183.             /* If the file image is wider than the pmap, suck up extra bytes */
  184.             else if (pcxhdr->linebytes > linebytes) {
  185.                 if (!pcx_readline(frw, NULL, pcxhdr->linebytes - linebytes, &ocount)) {
  186.                     return(FALSE);
  187.                 }
  188.             }
  189.         }
  190.         /* If pcxhdr has fewer planes than pmap, dup the extra pmap planes */
  191.         for ( ; iplane < pcnplanes; iplane++) {
  192.             memmove(obuf[iplane], obuf[nplanes-1] - pclinebytes, pclinebytes);
  193.             obuf[iplane] += pclinebytes;
  194.         }
  195.     }        /* end of lines loop */
  196.  
  197.     /* Take care of case where the pcx file has leftover lines */
  198.     /* For every leftover line ... */
  199.     for (iline = height; iline < (pcxhdr->ymax - pcxhdr->ymin + 1); iline++) {
  200.         /* For each plane within a line */
  201.         ocount = 0;
  202.         for (iplane = 0; iplane < nplanes; iplane++) {
  203.             /* Load a line of the plane buffer for the current plane */
  204.             if (!pcx_readline(frw, NULL, pcxhdr->linebytes, &ocount)) {
  205.                 return(FALSE);
  206.             }
  207.         }
  208.     }
  209.     return(TRUE);
  210. }
  211. /* -------------------------------------------------------------------------- */
  212.  
  213. static boolean DIGPRIV pc_packpcx(struct frw_struct *frw, pmap_type pmap)
  214. {
  215.     unsigned height;
  216.     unsigned linebytes;
  217.     int iline, iplane;
  218.     byte nplanes;
  219.     byte *obuf[MAXPLANES];
  220.  
  221.     nplanes = disp_GetInfo()->nplanes;
  222.     height = pmap_GetHeight(pmap);
  223.  
  224.     /* Note: pmap linebytes must equal pcxhdr->linebytes or pcxhdr->linebytes-1 */
  225.     linebytes = pcpmap_bytewidth(pmap);
  226.  
  227.     /* Initialize the obuf array of image plane buffers pointers */
  228.     setobuf(pmap, obuf, nplanes);
  229.  
  230.     /* Encode the image */
  231.     for (iline = 0 ; iline < height; iline++) {        /* For every line */
  232.  
  233.         /* For each plane within a line */
  234.         for (iplane = 0; iplane < nplanes; iplane++) {
  235.             /* Save a line of the plane buffer for the current plane */
  236.             if (!pcx_writeline(frw, obuf[iplane], linebytes)) {
  237.                 return(FALSE);
  238.             }
  239.             obuf[iplane] += linebytes;
  240.         }        /* end of plane loop */
  241.     }        /* end of lines loop */
  242.     return(TRUE);
  243. }
  244. /* -------------------------------------------------------------------------- */
  245.  
  246. static boolean DIGPRIV pixnot0(pmap_type pmap, byte **obuf, byte nplanes, opcoord x, opcoord y, byte bmask)
  247. {
  248.     int iplane;
  249.     unsigned planebyte;
  250.  
  251.     if (y < pmap_GetHeight(pmap) && x < pmap_GetWidth(pmap)) {
  252.         
  253.         if (pcpmap_pixbits(pmap) == 8) {
  254.             bmask = 0xFF;
  255.             planebyte = x;
  256.         }
  257.         else planebyte = x >> 3;
  258.         for (iplane = 0; iplane < nplanes; iplane++) {
  259.             if ((obuf[iplane][planebyte] & bmask) != 0) {
  260.                 return(TRUE);
  261.             }
  262.         }
  263.     }
  264.     return(FALSE);
  265. }
  266. /* -------------------------------------------------------------------------- */
  267.  
  268. static void DIGPRIV setobuf(pmap_type pmap, byte *obuf[], byte nplanes)
  269. {
  270.     byte **planes;
  271.     int iplane;
  272.  
  273.     if (nplanes <= 1) {
  274.         obuf[0] = pcpmap_pixbuf(pmap);
  275.     }
  276.     else {
  277.         planes = pcpmap_planes(pmap);
  278.         for (iplane = 0; iplane < nplanes; iplane++) {
  279.             obuf[iplane] = planes[iplane];
  280.         }
  281.     }
  282. }
  283. /* -------------------------------------------------------------------------- */
  284. /* pcbxlat.asm */
  285. extern oasm_func(void, bxlat, (byte *bufaddr, unsigned bufsize, byte *swaptab));
  286.  
  287. /* pcneares.asm */
  288. extern oasm_func(opixval, pc_nearestcol, (orgb_struct *rgb, ocolmap_type cmap));
  289. /* -------------------------------------------------------------------------- */
  290.  
  291. void pc_pmhist(pmap_type pmap, unsigned short *histtab)
  292. /*
  293.     Histogram pmap pixval bytes into word table 'histtab'.
  294.     Table must be pre-initialized; we start incrementing without zeroing first.
  295. */
  296. {
  297.     byte *buf;
  298.     unsigned bufsize;
  299.  
  300.     buf = pcpmap_pixbuf(pmap);
  301.     bufsize = (unsigned) pcpmap_GetPlaneSize(pmap);
  302.  
  303.     for ( ; bufsize > 0; bufsize--) {
  304.         histtab[*(buf++)]++;
  305.     }
  306. }
  307. /* -------------------------------------------------------------------------- */
  308.  
  309. void pc_pmcswap(pmap_type pmap, byte *swaptab)
  310. {
  311.     bxlat(pcpmap_pixbuf(pmap), (unsigned) pcpmap_GetPlaneSize(pmap), swaptab);
  312. }
  313. /* -------------------------------------------------------------------------- */
  314.  
  315. opixval pc_pmnearcol(orgb_struct *rgb, ocolmap_type cmap)
  316. {
  317.     return(pc_nearestcol(rgb, cmap));
  318. }
  319. /* -------------------------------------------------------------------------- */
  320.  
  321.