home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / 3DENGINE.ZIP / Pcx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-17  |  3.5 KB  |  135 lines

  1.  
  2. // PCX.CPP
  3. //  A set of functions for loading and compressing PCX images.
  4. //
  5. // Written August 7, 1993 by Christopher Lampton
  6. // for GARDENS OF IMAGINATION (Waite Group Press)
  7.  
  8. #include    <stdio.h>
  9. #include    <dos.h>
  10. #include  <io.h>
  11. #include    <fcntl.h>
  12. #include    <mem.h>
  13.  
  14. #ifndef __PCX__
  15.      #include "pcx.h"
  16. #endif
  17.  
  18. const int  MINIMUM_RUN=4;
  19.  
  20. int load_image(int pcxfile,pcx_struct *pcx);
  21. void load_palette(int pcxfile,pcx_struct *pcx);
  22.  
  23. static int infile;
  24.  
  25. int loadPCX(char far *filename,pcx_struct *pcx)
  26. {
  27.   if ((infile=open(filename,O_BINARY))==-1) return(-1);
  28.   lseek(infile,0L,SEEK_SET);
  29.   read(infile,&(pcx->header),sizeof(pcx_header));
  30.   if (pcx->header.xmax - pcx->header.xmin+1 > 320) return(-1);
  31.   if (pcx->header.ymax - pcx->header.ymin+1 > 200) return(-1);
  32.   if (pcx->header.version != 5) return(-1);
  33.   if (load_image(infile,pcx)) return(-1);
  34.   load_palette(infile,pcx);
  35.   close(infile);
  36.   return(0);
  37. }
  38.  
  39. int load_image(int pcxfile,pcx_struct *pcx)
  40. {
  41.   const int BYTEMODE=0, RUNMODE=1,BUFLEN=5*1024;
  42.   int mode=BYTEMODE,readlen;
  43.   static unsigned char outbyte,bytecount;
  44.   static unsigned char buffer[BUFLEN];
  45.  
  46.   int image_width=pcx->header.xmax - pcx->header.xmin + 1;
  47.   int image_height=pcx->header.ymax - pcx->header.ymin + 1;
  48.   long image_size=(long)image_width * image_height;
  49.   if ((pcx->image=new unsigned char[image_size])==NULL)
  50.        return(-1);
  51.   int bufptr=0;
  52.   readlen=0;
  53.   unsigned char *image_ptr=pcx->image;
  54.   for (long i=0; i<image_size; i++) {
  55.     if (mode==BYTEMODE) {
  56.       if (bufptr>=readlen) {
  57.         bufptr=0;
  58.         if ((readlen=read(pcxfile,buffer,BUFLEN))==0) break;
  59.       }
  60.       outbyte=buffer[bufptr++];
  61.       if (outbyte>0xbf) {
  62.         bytecount = (int)((int)outbyte & 0x3f);
  63.         if (bufptr>=readlen) {
  64.           bufptr=0;
  65.           if ((readlen=read(pcxfile,buffer,BUFLEN))==0) break;
  66.         }
  67.         outbyte=buffer[bufptr++];
  68.         if (--bytecount > 0) mode = RUNMODE;
  69.       }
  70.     }
  71.     else if (--bytecount == 0) mode=BYTEMODE;
  72.     *image_ptr++=outbyte;
  73.   }
  74.   return 0;
  75. }
  76.  
  77. void load_palette(int pcxfile,pcx_struct *pcx)
  78. {
  79.   lseek(pcxfile,-768L,SEEK_END);
  80.   read(pcxfile,pcx->palette,3*256);
  81.   for (int i=0; i<256; i++)
  82.     for (int j=0; j<3; j++)
  83.       pcx->palette[i*3+j]=pcx->palette[i*3+j]>>2;
  84. }
  85.  
  86. int compress(pcx_struct *pcx)
  87. {
  88.   int value,runlength,runptr;
  89.  
  90.   int image_width=pcx->header.xmax - pcx->header.xmin + 1;
  91.   int image_height=pcx->header.ymax - pcx->header.ymin + 1;
  92.   long image_size=(long)image_width * image_height;
  93.   long ptr=0;
  94.   long cptr=0;
  95.   unsigned char *cbuffer=new unsigned char[65530];
  96.   while (ptr<image_size) {
  97.     if (pcx->image[ptr]==0) {
  98.       runlength=0;
  99.       value=pcx->image[ptr];
  100.       while (pcx->image[ptr]==0) {
  101.         ptr++;
  102.         runlength++;
  103.         if (runlength>=127) break;
  104.         if (ptr >= image_size) break;
  105.             }
  106.             cbuffer[cptr] = (unsigned char) (runlength + 128);
  107.             cptr++;
  108.             cbuffer[cptr] = (unsigned char) value;
  109.             cptr++;
  110.         }
  111.         else {
  112.             runlength=0;
  113.             runptr=cptr++;
  114.             while (pcx->image[ptr]!=0) {
  115.                 cbuffer[cptr]=pcx->image[ptr];
  116.                 cptr++;
  117.                 ptr++;
  118.                 runlength++;
  119.                 if (runlength>=127) break;
  120.                 if (ptr >= image_size) break;
  121.             }
  122.             cbuffer[runptr]=runlength;
  123.         }
  124.     }
  125.     if ((pcx->cimage=new unsigned char[cptr]) != NULL)
  126.         {
  127.         memcpy(pcx->cimage,cbuffer,cptr);
  128.         delete cbuffer;
  129.         pcx->clength = cptr;
  130.         }
  131.     else
  132.         cptr = 0;
  133.     return(cptr);
  134. }
  135.