home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 145.lha / TableCloth / tc_iff.c < prev   
C/C++ Source or Header  |  1986-11-21  |  5KB  |  206 lines

  1.  
  2. #include "graphics:tc/tablecloth.h"
  3.  
  4. extern struct ChunkHeader chunk;
  5. extern BOOL plot;
  6. extern int actual_planes;
  7.  
  8. long get_chunk(fp)
  9. register FILE *fp;
  10. {
  11.     if(!fread(&chunk,(int)CHUNKHEADERSIZE,1,fp))
  12.     return(FALSE);
  13.  
  14.     switch (chunk.TYPE)
  15.     {
  16. /*
  17.  *  These are the chunks that we want to deal with:
  18.  *
  19.  */
  20.     case FORM:
  21.     case BMHD:
  22.     case CMAP:
  23.     case BODY:
  24.     case CAMG:
  25.         return((long)chunk.TYPE);    /* identify the latest IFF structure we encounter */
  26.         break;
  27. /*
  28.  *  These chunks are not dealt with but still flagged as legal chunks:
  29.  *
  30.  */
  31.     case GRAB:
  32.     case DEST:
  33.     case SPRT:
  34.     case CRNG:
  35.     case CCRT:
  36.     case DPPV:
  37.         return(-1); /* return non-zero since we still want to signal they are valid chunk types */
  38.         break;
  39. /*
  40.  *  If this part is reached, the file is garbled (ie we aren't at the
  41.  *  beginning of a new chunk):
  42.  *
  43.  */
  44.     default:
  45.         return(0L); /* returns failure on unrecognized chunk type, end-of-file, or any type of error condition */
  46.         break;
  47.     }
  48. }
  49.  
  50. BOOL good_pict(fp)
  51. register FILE *fp;
  52. {
  53.     char label[5];
  54.  
  55. /*
  56.  *  This is only a test for a valid IFF file, not for any particularly
  57.  *  suitable picture. When this is finished it will support pictures of
  58.  *  any size and number of colours so we won't be thrown by a loop by
  59.  *  anything except a mangled file.
  60.  *
  61.  */
  62.  
  63.     if (get_chunk(fp) != FORM) return(FALSE);     /* must start with this magic number */
  64.  
  65. /* NB: the "ILBM" is not a chunk and has no size field, just 4 bytes */
  66.  
  67.     fread(label,4,1,fp);
  68.     label[4] = 0;
  69.     if (strcmp(label,"ILBM")) return(FALSE);    /* must say "ILBM" immediately after the form*/
  70.  
  71.     return(TRUE);
  72. }
  73.  
  74. /*
  75.  *  Here is the main part. I didn't get a headache writing any other section.
  76.  *
  77.  *  This reads in the actual image data from an IFF file.
  78.  *
  79.  *  The bitmap-header must be already initialized when this is called.
  80.  *  I somehow doubt that many paint programs save files with their
  81.  *  chunks in the wrong order... still, if an error is encountered during
  82.  *  processing it will return with failure.
  83.  *
  84.  *  I have a feeling there must be a more elegant way to do this. If there
  85.  *  isn't I hope we can hide all the code like this away in a library
  86.  *  somewhere!
  87.  *
  88.  *  A badly garbled file will confuse this section; not every file read is
  89.  *  tested for success.
  90.  *
  91.  */
  92.  
  93. BOOL get_body(fp,header,bm) /* the last thing read was the chunk header for BODY */
  94. register FILE *fp;
  95. register struct bmhd *header;
  96. struct BitMap *bm;
  97. {
  98.     int i,n;
  99.     int plane_offset = 0;
  100.     int excess,underflow;
  101.     short bm_width = bm->BytesPerRow << 3;
  102.     register BOOL plot;  /* may want to read data but not display it */
  103.  
  104.     if (header->Compression != cmpNone && header->Compression != cmpByteRun1)
  105.     {
  106.     puts("Unknown compression.\n");
  107.     return(FALSE);
  108.     }
  109.  
  110.     if (header->nplanes < actual_planes) actual_planes = header->nplanes;
  111.  
  112.     for (i=0; i < header->h; i++)
  113.     {
  114.     debug("Beginning new line");
  115.  
  116.     if (i >= bm->Rows)
  117.         return(TRUE);   /* gone off end of screen, we quit loading now */
  118.     else
  119.         plot = TRUE;    /* must reset for each line */
  120.  
  121.     for (n=0; n < header->nplanes; n++)
  122.     {
  123.  
  124.         if (n >= actual_planes) plot = FALSE;   /* ignore these planes */
  125.  
  126.         if (!header->Compression)    /* no compression */
  127.         {
  128.         excess = (bm_width < header->w) ? (header->w - bm_width) >> 3 : 0;
  129.  
  130.         if (plot)
  131.             fread (bm->Planes[n]+plane_offset, MIN(header->w >> 3, bm_width >> 3), 1, fp);
  132.         else
  133.             fseek(fp, header->w >> 3, 1);
  134.  
  135. /* if the picture is smaller than the screen, we read in only what the file thinks is a scanline */
  136. /* if the picture is larger, we read in what the bitmap considers a scanline and skip the extra bytes in the file */
  137.  
  138.         if (excess)
  139.         {
  140.             debug("Dropping some bytes in the bit-bucket.");
  141.             fseek(fp,excess,1);
  142.         }
  143.         }
  144.         else    /* decode single compressed line */
  145.         {
  146.         register UBYTE *dest = bm->Planes[n] + plane_offset;
  147.         register char    len;
  148.         register int    so_far;
  149.  
  150.         so_far = MIN(bm->BytesPerRow,header->w >> 3);
  151.  
  152. /* same deal here; scanlines too large are truncated, those too small are left-justified */
  153.  
  154.         excess = (bm_width < header->w) ? (header->w - bm_width) >> 3 : 0;
  155.  
  156.         while (so_far > 0)
  157.         {
  158.             if ((len = getc (fp)) >= 0)     /*    Literal byte copy  */
  159.             {
  160.             so_far -= ++len;
  161.             if (plot)
  162.                 fread (dest, len, 1, fp);
  163.             else
  164.                 fseek(fp, len, 1);
  165.             dest += len;
  166.             }
  167.             else if ((UBYTE) len == 128)  /*  NOP  */
  168.             ;
  169.  
  170.             else if (len < 0)     /*  Replication count    */
  171.             {
  172.             UBYTE    byte;
  173.  
  174.             len = -len+1;
  175.             so_far -= len;
  176.             byte = getc (fp);
  177.  
  178.             while (--len >= 0)
  179.             {
  180.                 if (plot)
  181.                 *dest++ = byte;
  182.                 else
  183.                 dest++;
  184.             }
  185.             }
  186.  
  187.             if (excess)
  188.             {
  189.             debug("Dropping some bytes in the bit-bucket.");
  190.             fseek(fp,excess,1);
  191.             }
  192.         }
  193.  
  194.         if (so_far)
  195.         {
  196.             puts("Read wrong number of bytes from line");
  197.             return(FALSE);
  198.         }
  199.         }
  200.     }
  201.     plane_offset += bm->BytesPerRow;    /* drop down a scanline, even if only a partial one was read in */
  202.     }
  203.     return(TRUE);   /* made it through without a hitch */
  204. }
  205.  
  206.