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