home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / PCXLOAD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-06  |  5.2 KB  |  207 lines

  1. /*
  2.     pcxload.c
  3.  
  4.     % Load a Z-soft pcx format image file into a pixel map structure.
  5.  
  6.     5/02/89 By Ted.
  7.  
  8.     OWL 1.1
  9.     Copyright (c) 1989 by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14. */
  15.  
  16. #include "oakhead.h"
  17. #include "disppriv.h"
  18. #include "frwdecl.h"
  19. #include "pcxdecl.h"
  20. #include "digutil.h"
  21.  
  22. OSTATIC boolean DIGPRIV pcx_loadhdr(_arg2(frw_type frw, pcxhdr_struct *pcxhdr));
  23. OSTATIC boolean DIGPRIV pcx_loadcolmap(_arg3(frw_type frw, pcxhdr_struct *pcxhdr, ocolmap_type *cmapp));
  24.  
  25. #define FRWBUFSIZE        1024
  26. /* -------------------------------------------------------------------------- */
  27.  
  28. void DIGPRIV dig_loadpcx(frw, pmapp, cmapp, unpackpcx)
  29.     frw_type frw;
  30.     pmap_type *pmapp;
  31.     ocolmap_type *cmapp;
  32.     pcxunpack_fptr unpackpcx;
  33. {
  34.     pcxhdr_struct pcxhdr;
  35.  
  36.     /* Load pcx file header */
  37.     if (!pcx_loadhdr(frw, &pcxhdr)) {
  38.         return;
  39.     }
  40.     /* Allocate Pixmap */
  41.     *pmapp = pmap_Open(pcxhdr.xmax - pcxhdr.xmin + 1,
  42.                         pcxhdr.ymax - pcxhdr.ymin + 1);
  43.     if (*pmapp == NULL) {
  44.         return;
  45.     }
  46.     /* Allocate Buffer */
  47.     if (!frw_openbuf(frw, FRWBUFSIZE, FRW_READMODE)) {
  48.         pmap_Close(*pmapp);
  49.         *pmapp = NULL;
  50.         return;
  51.     }
  52.     /* Read in image */
  53.     (*unpackpcx)(frw, &pcxhdr, *pmapp);
  54.  
  55.     /* Extract colormap */
  56.     pcx_loadcolmap(frw, &pcxhdr, cmapp);
  57.  
  58.     frw_closebuf(frw);
  59.     return;
  60. }
  61. /* -------------------------------------------------------------------------- */
  62.  
  63. OSTATIC boolean DIGPRIV pcx_loadhdr(frw, pcxhdr)
  64.     frw_type frw;
  65.     pcxhdr_struct *pcxhdr;
  66. {
  67.     /* Read in header */
  68.     if (frw_read(frw, (VOID *)pcxhdr, sizeof(pcxhdr_struct)) < sizeof(pcxhdr_struct)) {
  69.         return(FALSE);
  70.     }
  71.     pcx_hdrflip(pcxhdr);    /* Flip bytes in shorts if needed */
  72.  
  73.     /* Cursory check of header */
  74.     if (pcxhdr->mfgr != 10 ||
  75.         pcxhdr->encoding != 1 ||
  76.         !(pcxhdr->version == 0 || pcxhdr->version == 2 ||
  77.           pcxhdr->version == 3 || pcxhdr->version == 5)) {
  78.         return(FALSE);
  79.     }
  80.     return(TRUE);
  81. }
  82. /* -------------------------------------------------------------------------- */
  83.  
  84. OSTATIC boolean DIGPRIV pcx_loadcolmap(frw, pcxhdr, cmapp)
  85.     frw_type frw;
  86.     pcxhdr_struct *pcxhdr;
  87.     ocolmap_type *cmapp;
  88. {
  89.     opixval ncols;
  90.  
  91.     ncols = (opixval) dig_powof2(pcxhdr->pixbits * pcxhdr->nplanes);
  92.  
  93.     if (ncols == 256 && pcxhdr->version == 5) {
  94.         /* 256 color map at end of image */
  95.         if (frw_readb(frw) == 12) {
  96.             *cmapp = ocolmap_Open(0, 256);
  97.             if (*cmapp != NULL) {
  98.                 if(frw_read(frw, (VOID *) ocolmap_entry(*cmapp, 0), 256*3) == 256*3) {
  99.                     return(TRUE);
  100.                 }
  101.             }
  102.         }
  103.     }
  104.     else {    /* 16 color color map in header */
  105.         if (ncols <= 16 && pcxhdr->version != 3) {
  106.             *cmapp = ocolmap_Open(0, ncols);
  107.             if (*cmapp != NULL) {
  108.                 memmove((VOID *) ocolmap_entry(*cmapp, 0), (VOID *) pcxhdr->rgb,
  109.                         (SIZE_T)((*cmapp)->nentries * 3));
  110.                 return(TRUE);
  111.             }
  112.         }
  113.     }
  114.     return(FALSE);
  115. }
  116. /* -------------------------------------------------------------------------- */
  117.  
  118. boolean DIGPRIV pcx_readline(frw, obuf, linebytes, ocountp)
  119.     frw_type frw;
  120.     byte *obuf;
  121.     unsigned linebytes;
  122.     unsigned *ocountp;
  123. {
  124.     unsigned ibyte;
  125.     unsigned cbyte;    /* note: hi byte used for error flag */
  126.     byte count, xcount;
  127.  
  128.     ibyte = 0;
  129.     count = (byte) *ocountp;
  130.     if (count != 0) cbyte = *ocountp >> 8;
  131.  
  132.     /* For each code within a plane-line */
  133.     for (;;) {
  134.  
  135.         if (ibyte >= linebytes) break;
  136.  
  137.         if (count == 0) {
  138.             cbyte = frw_readb(frw);
  139.             if (cbyte & 0xFF00) return(FALSE);
  140.  
  141.             if (((byte)cbyte & 0xC0) != 0xC0) {    /* No repeat - stash & go. */
  142.                 *obuf++ = (byte) cbyte;
  143.                 if (++ibyte >= linebytes) {
  144.                     break;    /* break out of line loop to next plane */
  145.                 }
  146.                 continue;    /* continue line loop */
  147.             }
  148.             else {    /* Got a loop count */
  149.                 count = (byte)cbyte & ~0xC0;
  150.  
  151.                 cbyte = frw_readb(frw);
  152.                 if (cbyte & 0xFF00) return(FALSE);
  153.             }
  154.         }
  155.         /* If count hangs over the end of this plane line, truncate it */
  156.         /*  and save the remainder for the next plane */
  157.         if (linebytes - ibyte < (unsigned) count) {
  158.             xcount = count - (byte)(linebytes - ibyte);
  159.             count = (byte)(linebytes - ibyte);
  160.         }
  161.         else  xcount = 0;
  162.  
  163.         ibyte += (unsigned) count;
  164.         for ( ; count > 0; count--) *obuf++ = (byte) cbyte;
  165.  
  166.     }    /* end of line loop */
  167.  
  168.     /* Suck out extra byte in case of odd number of bytes in line */
  169.     if (linebytes & 1) {
  170.         if (xcount == 0) {
  171.             cbyte = frw_readb(frw);
  172.             if (cbyte & 0xFF00) return(FALSE);
  173.  
  174.             if (((byte)cbyte & 0xC0) == 0xC0) {        /* repeat... */
  175.                 xcount = (byte)cbyte & ~0xC0 - 1;
  176.  
  177.                 cbyte = frw_readb(frw);
  178.                 if (cbyte & 0xFF00) return(FALSE);
  179.             }
  180.         }
  181.         else xcount--;
  182.     }
  183.     *ocountp = xcount | (cbyte << 8);
  184.     return(TRUE);
  185. }
  186. /* -------------------------------------------------------------------------- */
  187.  
  188. void DIGPRIV pcx_hdrflip(pcxhdr)
  189.     pcxhdr_struct *pcxhdr;
  190. /*
  191.     Flip bytes in shorts if needed
  192. */
  193. {
  194.     if (disp_GetByteOrder() != BO_LSBYTFIRST) {
  195.         dig_flipshort(&pcxhdr->xmin);
  196.         dig_flipshort(&pcxhdr->xmax);
  197.         dig_flipshort(&pcxhdr->ymin);
  198.         dig_flipshort(&pcxhdr->ymax);
  199.         dig_flipshort(&pcxhdr->hres);
  200.         dig_flipshort(&pcxhdr->vres);
  201.         dig_flipshort(&pcxhdr->linebytes);
  202.         dig_flipshort(&pcxhdr->paltype);
  203.     }
  204. }
  205. /* -------------------------------------------------------------------------- */
  206.  
  207.