home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 243.lha / WipeDemo_v2.0 / wipepict.c < prev   
C/C++ Source or Header  |  1989-05-10  |  10KB  |  391 lines

  1.  
  2. /**********************************************************************
  3. *
  4. *         jiff.c   Jim Kent's iff - ilbm  reader
  5. *
  6. * This is the (sortof) short (sortof) simple no-frills IFF reader
  7. * to get something out of DPaint, Images, or the Animator.  It
  8. * works well with the Aztec C compiler.  It should work with Lattice
  9. * but you never know until you try it.  I haven't.
  10. *
  11. * I've included a simple main program.  This is just to make it
  12. * stand alone.  Since amiga screen initializations are massive, all
  13. * it does as is is read it into a BitMap, and then free up the BitMap.
  14. * Should crash it if it's gonna crash though.
  15. *
  16. * The main interface to this is through the routine read_iff(filename).
  17. * This returns a ILBM_info structure-pointer on success, and NULL on
  18. * failure.  It cleans up after itself on failure.
  19. *
  20. * I hope you will find this useful and easy to use.  Please forgive
  21. * my funky indentation style?  Well at least I'm consistent!
  22. *
  23. * To demonstrate what a nice guy I am even though I'm far from wild
  24. * about the IFF standard I'm placing this in the public domain.  When
  25. * you remove the DEBUG and PARANOID definitions the code is only
  26. * 1536 bytes long.
  27. *
  28. *      -Jim Kent  April 22, 1986
  29. ************************************************************************/
  30.  
  31. #include <stdio.h>
  32. #include <exec/types.h>
  33. #include <exec/memory.h>
  34. #include <graphics/gfx.h>
  35. #include <libraries/dos.h>
  36. #include "jiff.h"
  37.  
  38. /*this is an all too common state of software development.  Get rid
  39.   of this define as soon as it runs*/
  40. /*#define DEBUG*/
  41.  
  42. /*this is the normal state of software development.  Seriously undefine
  43.   this to make it shut up about errors and reduce code size half way
  44.   through beta testing... */
  45. /*#define PARANOID*/
  46.  
  47.  
  48. static struct ILBM_info *read_ilbm(), *read_body();
  49.  
  50. /* OK this code is almost re-entrant.  Pass this guy from above to
  51.    make it really re-entrant.  (Why do you need a reentrant ILBM
  52.    reader though??  Maybe for Dale ... ) */
  53. static struct ILBM_info root_info;  /*static so get initialized to zero*/
  54.  
  55.  
  56. #ifdef PARANOID
  57. /* a little paranoid routine that say's where we got before EOF */
  58. static void
  59. iff_truncated(where)
  60. int where;
  61. {
  62. printf("ILBM truncated %d\n", where);
  63. free_planes(&root_info.bitmap);
  64. }
  65. #endif PARANOID
  66.  
  67.  
  68. struct ILBM_info *
  69. read_iff(name, just_colors)
  70. char *name;
  71. short just_colors;
  72. {
  73. struct ILBM_info *info = &root_info;
  74. FILE *file;
  75. struct form_chunk chunk;
  76.  
  77. if ((file = fopen(name, "r") ) == 0)
  78.    {
  79. #ifdef PARANOID
  80.    printf("couldn't Open %s to read\n", name);
  81. #endif PARANOID
  82.    return(NULL);
  83.    }
  84.  
  85. if ( fread(&chunk, sizeof(struct form_chunk), 1, file) != 1)
  86.    {
  87. #ifdef PARANOID
  88.    iff_truncated(0);
  89. #endif PARANOID
  90.    fclose(file);
  91.    return(NULL);
  92.    }
  93.  
  94. if (chunk.fc_type.b4_type != FORM)
  95.    {
  96. #ifdef PARANOID
  97.    printf("not a FORM - %s\n", name);
  98. #endif PARANOID
  99.    fclose(file);
  100.    return(NULL);
  101.    }
  102.  
  103. if (chunk.fc_subtype.b4_type != ILBM)
  104.    {
  105. #ifdef PARANOID
  106.    printf("FORM not an ILBM - %s\n", name);
  107. #endif PARANOID
  108.    fclose(file);
  109.    return(NULL);
  110.    }
  111.  
  112. #ifdef DEBUG
  113. printf("FORM %ld ILBM\n", chunk.fc_length);
  114. #endif DEBUG
  115.  
  116. info = read_ilbm(file, info, chunk.fc_length - sizeof(chunk), just_colors);
  117. fclose(file);
  118. return(info);
  119. }
  120.  
  121. static
  122. struct ILBM_info *
  123. read_ilbm(file, info, length, just_colors)
  124. FILE *file;
  125. struct ILBM_info *info;
  126. long length;
  127. short just_colors;
  128. {
  129. struct iff_chunk chunk;
  130. int i;
  131. long read_in = 0;
  132. int got_header = FALSE;  /*to make sure gots the header first*/
  133. int got_cmap = FALSE;  /*make sure get cmap before "BODY" */
  134.  
  135. /*make sure the Planes are all NULL so can free up memory easily
  136.   on error abort */
  137. for (i=0; i<8; i++)
  138.    info->bitmap.Planes[i] = NULL;
  139.  
  140. while (read_in < length)
  141.    {
  142.    if (fread(&chunk, sizeof(chunk), 1, file) != 1)
  143.       {
  144. #ifdef PARANOID
  145.       iff_truncated(1);
  146. #endif PARANOID
  147.       return(NULL);
  148.       }
  149.    switch (chunk.iff_type.b4_type)
  150.       {
  151.       case BMHD:
  152. #ifdef DEBUG
  153.          printf("\tBMHD %ld\n", chunk.iff_length);
  154. #endif DEBUG
  155.          if (fread(&info->header, sizeof(info->header), 1, file) != 1)
  156.             {
  157. #ifdef PARANOID
  158.             iff_truncated(2);
  159. #endif PARANOID
  160.             return(NULL);
  161.             }
  162.          got_header = TRUE;
  163.          break;
  164.       case CMAP:
  165. #ifdef DEBUG
  166.          printf("\tCMAP %ld\n", chunk.iff_length);
  167. #endif DEBUG
  168.          if (!got_header)
  169.             {
  170. #ifdef PARANOID
  171.             printf("CMAP befor BMHD\n");
  172. #endif PARANOID
  173.             return(NULL);
  174.             }
  175.          if (chunk.iff_length <= 3*MAXCOL )
  176.             {
  177.             if (fread(info->cmap, (int)chunk.iff_length, 1, file) != 1)
  178.                {
  179. #ifdef PARANOID
  180.                iff_truncated(3);
  181. #endif PARANOID
  182.                return(NULL);
  183.                }
  184.             }
  185.          else
  186.             {
  187. #ifdef PARANOID
  188.             printf("warning, more than %d colors in ILBM CMAP\n",
  189.                MAXCOL);
  190. #endif PARANOID
  191.             if (fread(info->cmap, 3*MAXCOL, 1, file) != 1)
  192.                {
  193. #ifdef PARANOID
  194.                iff_truncated(4);
  195. #endif PARANOID
  196.                return(NULL);
  197.                }
  198.             bit_bucket(file, chunk.iff_length - sizeof(3*MAXCOL));
  199.             }
  200.          got_cmap = TRUE;
  201.          if (just_colors)
  202.             return(info);
  203.          break;
  204.       case BODY:
  205.          if (!got_cmap)
  206.             {
  207. #ifdef PARANOID
  208.             printf("BODY before CMAP\n");
  209. #endif PARANOID
  210.             return(NULL);
  211.             }
  212. #ifdef DEBUG
  213.          printf("\tBODY %ld\n", chunk.iff_length);
  214. #endif DEBUG
  215.          return( read_body(file, info, chunk.iff_length) );
  216.  
  217.       default:   /*squawk about unknown types if PARANOID */
  218. #ifdef PARANOID
  219.          printf("\t unknown type %lx of b4_type\n", chunk.iff_type.b4_type);
  220. #endif PARANOID
  221.       case GRAB:  /*ignore documented but unwanted types*/
  222.       case DEST:
  223.       case SPRT:
  224.       case CAMG:
  225.       case CRNG:
  226.       case CCRT:
  227.          bit_bucket(file, chunk.iff_length);
  228.          break;
  229.       }
  230.    read_in += chunk.iff_length + sizeof(chunk);
  231.    }
  232. #ifdef PARANOID
  233. printf("no BODY in ILBM\n");
  234. #endif PARANOID
  235. return(NULL); 
  236. }
  237.  
  238.  
  239.  
  240. static
  241. struct ILBM_info *
  242. read_body(file, info, length)
  243. FILE *file;
  244. register struct ILBM_info *info;
  245. long length;
  246. {
  247. struct ILBM_header *header;
  248. struct BitMap *bm;
  249. int i, j;
  250. int rlength;
  251. int plane_offset;
  252.  
  253. #ifdef DEBUG
  254. printf("read_body( %lx %lx %ld)\n", file, info, length);
  255. #endif DEBUG
  256.  
  257. #ifdef PARANOID
  258. /* when paranoid do a little error checking first ... fail fast! */
  259. if (info->header.nPlanes > 8)
  260.    {
  261.    printf("Whoa, woe  Dale only speaks 8 planes boy, not %d\n",
  262.       info->header.nPlanes);
  263.    return(NULL);
  264.    }
  265. #endif PARANOID
  266.  
  267. /* ok a little more error checking */
  268. if (info->header.compression != 0 && info->header.compression != 1)
  269.    {
  270. #ifdef PARANOID
  271.    printf("unrecognized compression type %d\n", info->header.compression);
  272. #endif PARANOID
  273.    return(NULL);
  274.    }
  275.  
  276. /*set up the bitmap part that doesn't involve memory allocation first -
  277.   hey this part does get done, and let's be optimistic...*/
  278. info->bitmap.BytesPerRow = line_bytes(info->header.w);
  279. info->bitmap.Rows = info->header.h;
  280. info->bitmap.Depth = info->header.nPlanes;
  281. info->bitmap.Flags = info->bitmap.pad = 0;
  282.  
  283. rlength = info->bitmap.Rows * info->bitmap.BytesPerRow;
  284.  
  285. for (i=0; i<info->header.nPlanes; i++)
  286.    {
  287.    if ((info->bitmap.Planes[i] = ralloc(rlength)) == NULL)
  288.       {
  289. #ifdef PARANOID
  290.       printf("couldn't alloc plane %d in read_body\n",i);
  291. #endif PARANOID
  292.       free_planes( &info->bitmap );
  293.       return(NULL);
  294.       }
  295.    }
  296. plane_offset = 0;
  297. for (i=0; i<info->bitmap.Rows; i++)
  298.    {
  299.    /* this test should be in the inner loop for shortest code,
  300.       in the outer loop for greatest speed, so sue me I compromised */
  301.    if (info->header.compression == 0)
  302.       {
  303.       for (j = 0; j < info->bitmap.Depth; j++)
  304.          {
  305.          if ( fread(info->bitmap.Planes[j] + plane_offset,
  306.             info->bitmap.BytesPerRow, 1, file) != 1)
  307.             {
  308. #ifdef PARANOID
  309.             iff_truncated(6);
  310. #endif PARANOID
  311.             free_planes( &info->bitmap);
  312.             return(NULL);
  313.             }
  314.          }
  315.       }
  316.    else
  317.       {
  318.       register char *dest, value;
  319.       register int so_far, count;  /*how much have unpacked so far*/
  320.  
  321.       for (j = 0; j < info->bitmap.Depth; j++)
  322.          {
  323.          so_far = info->bitmap.BytesPerRow;
  324.          dest = (char *)info->bitmap.Planes[j] + plane_offset;
  325.          while (so_far > 0)
  326.             {
  327.             if ( (value = getc(file)) == 128)
  328.                {
  329. #ifdef DEBUG
  330.                printf("NOP\n");
  331. #endif DEBUG
  332.                }
  333.             else if (value > 0)
  334.                {
  335.                count = (int)value + 1;
  336.                so_far -= count;
  337.                if ( fread(dest, count, 1, file) != 1)
  338.                   {
  339. #ifdef PARANOID
  340.                   iff_truncated(7);
  341. #endif PARANOID
  342.                   free_planes( &info->bitmap);
  343.                   return(NULL);
  344.                   }
  345.                dest += count;
  346.                }
  347.             else 
  348.                {
  349.                count = (int)-value + 1;
  350.                so_far -= count;
  351.                value = getc(file);
  352.                while (--count >= 0)  /*this is fastest loop in C */
  353.                   *dest++ = value;
  354.                }
  355.             }
  356.          if (so_far != 0)
  357.             {
  358. #ifdef PARANOID
  359.             printf("compression quite screwed up, aborting %d\n", so_far);
  360. #endif PARANOID
  361.             free_planes( &info->bitmap);
  362.             return(NULL);
  363.             }
  364.          }
  365.       }
  366.    plane_offset += info->bitmap.BytesPerRow;
  367.    }
  368. return(info);
  369. }
  370.  
  371.  
  372. void
  373. free_planes(bmap)
  374. register struct BitMap *bmap;
  375. {
  376. PLANEPTR plane;
  377. long length;
  378. short i;
  379.  
  380. length = bmap->BytesPerRow * bmap->Rows;
  381.  
  382. for (i=0; i<8; i++)
  383.    if ( (plane = bmap->Planes[i]) != NULL)
  384.       rfree(plane, length);
  385. }
  386.  
  387.  
  388.  
  389. #include "mywipe.h"
  390.  
  391.