home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / graphics / acksrc.zip / MIFF.C < prev    next >
Text File  |  1993-06-20  |  5KB  |  175 lines

  1. // Sample IFF File Reader
  2. //
  3. // This function will return a pointer to a buffer that holds the raw image.
  4. // just free the pointer to delete this buffer. After returning, the array
  5. // colordat will hold the adjusted palette of this pic.
  6. //
  7. // Also, this has been modified to only read in form PBM brushes. form ILBM's
  8. // (the "old" type) are not supported. use the "new" deluxe paint .lbm type
  9. // and do not choose "old".
  10.  
  11. #include <stdio.h>
  12. #include <conio.h>
  13. #include <process.h>
  14. #include <bios.h>
  15. #include <fcntl.h>
  16. #include <malloc.h>
  17. #include <mem.h>
  18. #include "iff.h"
  19. #include "ack3d.h"
  20.  
  21.     extern        int        ErrorCode;
  22.  
  23. unsigned char far  colordat[768];  /* maximum it can be...256 colors    */
  24.  
  25. unsigned char far  cplanes[8][80]; /* setting max at 640 pixels width    */
  26.                    /* thats 8 pixels per byte per plane */
  27. unsigned char far  *pplanes= (char far *) &cplanes[0][0];  /* for a form pbm        */
  28.  
  29. unsigned char far * Readiff(char *picname)
  30.    {
  31.    FILE *pic;
  32.    form_chunk   fchunk;
  33.    ChunkHeader  chunk;
  34.    BitMapHeader bmhd;
  35.    long length;
  36.    char value;       // must remain signed, no matter what. ignore any warnings.
  37.    int sofar;
  38.    int width,height,planes;
  39.    int pixw;
  40.    unsigned char far *destx, *savedestx;
  41.  
  42.    if ((pic = fopen(picname,"r+b"))== NULL)
  43.     {
  44.     ErrorCode = ERR_BADFILE;
  45.     return(0L);
  46.     }
  47.  
  48.    fread(&fchunk,1,sizeof(form_chunk),pic); /* read in the first 12 bytes*/
  49.  
  50.    if (fchunk.type != FORM)
  51.       {
  52.       fclose(pic);
  53.       return(0L);
  54.       }
  55.  
  56.    if (fchunk.subtype != ID_PBM)
  57.       {
  58.       printf("Error: Not form PBM!");
  59.       fclose(pic);
  60.       return(0L);
  61.       }
  62.    // now lets loop...Because the Chunks can be in any order!
  63.    while(1)
  64.       {
  65.       fread(&chunk,1,sizeof(ChunkHeader),pic);
  66.       ByteFlipLong(&(long)(chunk.ckSize));
  67.       if (chunk.ckSize & 1) chunk.ckSize ++;    // must be word aligned
  68.       if(chunk.ckID == ID_BMHD)
  69.           {
  70.       fread(&bmhd,1,sizeof(BitMapHeader),pic);
  71.           bmhd.w=swab(bmhd.w);                  // the only things we need.
  72.           bmhd.h=swab(bmhd.h);
  73.           destx = (unsigned char far *)farmalloc((bmhd.w * bmhd.h)+4);
  74.           if ( !destx ) return(0L);
  75.           savedestx = destx;
  76.  
  77.           destx[0] = bmhd.w%256;
  78.           destx[1] = bmhd.w/256;
  79.           destx[2] = bmhd.h%256;
  80.           destx[3] = bmhd.h/256;
  81.           destx += 4;
  82.           continue;
  83.           }
  84.       if(chunk.ckID == ID_CMAP)
  85.           {
  86.           int i;
  87.           unsigned char r,g;
  88.  
  89.           fread(colordat,1,chunk.ckSize,pic);
  90.           for (i=0;i<768;i++)
  91.               {
  92.                r = colordat[i];   // r,g do not stand for red and green
  93.               g = r >> 2;
  94.           colordat[i] = g;
  95.               }
  96.           continue;
  97.           }
  98.       if(chunk.ckID == ID_BODY)
  99.           {
  100.           for(height = 0; height<bmhd.h; height ++)
  101.              {
  102.              unsigned char *dest;
  103.          dest = (unsigned char *)&(pplanes[0]); /* point at first char  */
  104.              sofar = bmhd.w;                        /* number of bytes = 8  */
  105.              if (sofar&1) sofar++;
  106.              while (sofar)
  107.                 {
  108.                 if (bmhd.compression)
  109.                    {
  110.                    value=fgetc(pic);      /* get the next byte    */
  111.                    // if (value == 128) continue; /* NOP..just get another*/
  112.                    if (value > 0)
  113.                       {
  114.                       int len;
  115.                       len = value +1;
  116.                       sofar -= len;
  117.                       if(!(fread(dest,len,1,pic)))
  118.               {
  119.                           fclose(pic);
  120.                           return(0L);
  121.                           }
  122.                       dest +=len;
  123.                       }
  124.                    else
  125.                       {
  126.                       int count;
  127.                       count = -value; /* get amount to dup */
  128.                       count ++;
  129.                       sofar -= count;
  130.                       value=fgetc(pic);
  131.                       while (--count >= 0) *dest++ = value;
  132.                       }
  133.                    }
  134.                 else
  135.                    {
  136.                    fread(dest,sofar,1,pic); /* just throw on plane */
  137.                    sofar = 0;
  138.                    }
  139.                 }
  140.              if (sofar < 0)
  141.                 {
  142.         fclose(pic);
  143.         }
  144.          _fmemcpy(destx,pplanes,bmhd.w);
  145.          destx += bmhd.w;
  146.          }
  147.       break; /* leave if we've unpacked the BODY*/
  148.       }
  149.       fseek(pic,chunk.ckSize,SEEK_CUR);
  150.       }
  151.  
  152.    fclose(pic);
  153.    return((char far *)savedestx);
  154.    }
  155.  
  156. void ByteFlipLong(long *NUMBER)
  157.    {
  158.    // Hey, I didn;t write this function!!!
  159.    long int Y, T;
  160.    int I;
  161.  
  162.    T = *NUMBER;
  163.    Y=0;for (I=0;I<4;I++){Y = Y | (T & 0xFF);if (I<3) {Y = Y << 8;T = T >> 8;}}
  164.    *NUMBER = Y;
  165.    }
  166.  
  167. int swab(unsigned short number)
  168.    {
  169.    unsigned int xx1,xx2;
  170.    unsigned int result;
  171.  
  172.    xx1 = number <<8; xx2 = number >>8; result = xx1|xx2;
  173.    return(result);
  174.    }
  175.