home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 10 / Fresh_Fish_10_2352.bin / new / gfx / conv / image2c / i2c.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  25KB  |  683 lines

  1. /****************************************************************************
  2.  *
  3.  *  I2C (Image2'C') 1.2
  4.  *  Copyright © 1994,1995 Udo Schuermann
  5.  *  All rights reserved
  6.  *
  7.  *  This program uses  iffparse.library  to load an ILBM from a FORM IFF
  8.  *  (in plain English, it loads an IFF picture) and produces output that
  9.  *  can be used directly as part of a  struct Image  in your 'C' source
  10.  *  code.
  11.  *
  12.  *  I make this code available as a demonstration of an exceedingly simple,
  13.  *  yet functional program that uses  iffparse.library  and does something
  14.  *  moderately useful with it.  Of some interest might be the fact that
  15.  *  the program extracts a number of additional properties from the file,
  16.  *  if they are present: ANNO, AUTH, (c), and FVER chunks are inserted in
  17.  *  the output file as comments.  Hopefully, none of these contain the end-
  18.  *  comment symbol... :-7
  19.  *
  20.  *  THIS PROGRAM MAY *NOT* BE DISTRIBUTED WITHOUT SOURCE CODE AND ALL
  21.  *  NOTICES INTACT.  YOU MAY NOT SELL THIS PROGRAM OR INCLUDE IT WITH
  22.  *  A COMMERCIAL PRODUCT WITHOUT EXPRESS WRITTEN PERMISSION FROM THE
  23.  *  AUTHOR.  IT IS PERMITTED TO DISTRIBUTE THIS PROGRAM BY ELECTRONIC
  24.  *  MEANS (USENET), OR AS PART OF FRED FISH'S CD-ROMS OR RELATED
  25.  *  COLLECTIONS.  YOU MAY USE IT FOR INSTRUCTIONAL PURPOSES, AND EVEN
  26.  *  GIVE IT TO FRIENDS, BUT DON'T YOU SELL IT OR YOUR NAME SHALL BE
  27.  *  FOREVER STAINED.
  28.  *
  29.  *  Commodore is dead.  Long live the Amiga!
  30.  *
  31.  *  Share and enjoy!  ;-)
  32.  *
  33.  *  ---------------------------------------------------------------------
  34.  *
  35.  *  This program uses the following CLI template (I am not using standard
  36.  *  code for that, but am parsing the command line on my own):
  37.  *
  38.  *  ILBMFILE/A,SYMPREFIX/A,NOINFO/S,NOPENS/S,NODATA/S,NOIMAGESTRUCT/S,
  39.  *    NORGB4/S,USEIFDEFS/S,NOCHIP/S
  40.  *
  41.  *  ILBMFILE/A        Must always be given.  This is the IFF ILBM input
  42.  *            file to be converted.  I2C supports images up to
  43.  *            8 bitplanes deep (actually, any bitplane oriented
  44.  *            ILBM)
  45.  *
  46.  *  SYMPREFIX/A        Must always be given.  The symbol prefix for this
  47.  *            image file.  This forms the prefix to all symbols
  48.  *            in the file.
  49.  *            Example:  A prefix of "myImage_" will generate
  50.  *            symbols such as "UWORD myImage_ImageData[]"
  51.  *
  52.  *  NOINFO/S        This switch will cause image information, such
  53.  *            such as height, width, depth, number of colors
  54.  *            to be omitted.  See also NOIMAGESTRUCT below!
  55.  *
  56.  *  NOPENS/S        This switch will cause pens (used by LoadRGB32()
  57.  *            for example) to be omitted.
  58.  *
  59.  *  NODATA/S        This switch will cause the actual image data to
  60.  *            be omitted.  See also NOIMAGESTRUCT below!
  61.  *
  62.  *  NOIMAGESTRUCT/S    This switch will cause a "struct Image ..." item
  63.  *            to be omitted.  This item requires the presence
  64.  *            of INFO and DATA items; if you specify that either
  65.  *            or both of those should not be included (NOINFO
  66.  *            and/or NODATA) but you do not also specify the
  67.  *            NOIMAGESTRUCT, then I2C will reverse your decision
  68.  *            on NOINFO and/or NODATA so that the Image struct
  69.  *            can be built.
  70.  *
  71.  *  ADDRGB4/S        This switch will cause register color values to
  72.  *            be added.  Such values are 12-bit only and are
  73.  *            probably of use only for older software.  It is
  74.  *            for this reason that this is the only switch that
  75.  *                needs to be specified to add something to the
  76.  *            code; i.e. if not specified you will NOT get the
  77.  *            information for this item.
  78.  *
  79.  *  USEIFDEFS/S        This switch encloses the INFO, PENS, DATA, IMG,
  80.  *            and RGB4 sections with #ifdef/#endif constructs
  81.  *            to allow you to build a source file with ALL
  82.  *            information, but decide at a later time which
  83.  *            portions the compiler should include or ignore.
  84.  *            Use of this switch enables an additional level
  85.  *            of flexibility, which you may or may not find
  86.  *            of use.
  87.  *
  88.  *            The following #define statements used BEFORE you
  89.  *            #include the source code generated by I2C will
  90.  *            tell the compiler which portions of the file to
  91.  *            use and which to ignore:
  92.  *
  93.  *            #define I2C_IMAGE_INFO        Accept image info
  94.  *            #define I2C_IMAGE_PENS        Accept RGB32 pens
  95.  *            #define I2C_IMAGE_RGB4        Accept 4-bit pens
  96.  *            #define I2C_IMAGE_DATA        Accept image data
  97.  *            #define I2C_IMAGE_IMG        Accept struct Image
  98.  *
  99.  *  NOCHIP/S        Omit the __chip attribute on structures.  This may
  100.  *            be desirable if you are going to remap image colors
  101.  *            anyway and won't be needing the original in chip
  102.  *            RAM.
  103.  *
  104.  *  If you are not clear on some of the points described above, you are
  105.  *  hereby STRONGLY advised to run the program on a test image and see what
  106.  *  the resulting output file contains.  Try this:
  107.  *
  108.  *    I2C  TestImage.IFF  MyTest_  USEIFDEFS
  109.  */
  110.  
  111.  
  112. #include <stdio.h>
  113. #include <stdlib.h>
  114. #include <string.h>
  115. #include <exec/types.h>
  116. #include <libraries/iffparse.h>
  117.  
  118. #include <proto/dos.h>
  119. #include <proto/iffparse.h>
  120.  
  121.  
  122. /* If we define __MYDATE__ from the commandline, then we'll use that instead of
  123.  * redefining it to the standard Amiga __AMIGADATE__ (which is broken in SAS/C
  124.  * 6.51 whenever both the month and the day require two digits.)
  125.  */
  126. #ifndef __MYDATE__
  127. #define __MYDATE__ __AMIGADATE__
  128. #endif
  129.  
  130. #define VERSION  "1.2"
  131. char const VER[] = "$VER: Image2'C' "VERSION" "__MYDATE__;
  132.  
  133. BOOL AddINFO = TRUE;
  134. BOOL AddPENS = TRUE;
  135. BOOL AddDATA = TRUE;
  136. BOOL AddRGB4 = FALSE;
  137. BOOL AddIMG  = TRUE;
  138. BOOL UseIFDEFs = FALSE;
  139. BOOL UseCHIP = TRUE;
  140. char *ILBMFILE = NULL;
  141. char *SYMPREFIX = NULL;
  142.  
  143. struct IFFHandle *OpenFileAsIFF( char *filename ) {
  144.  
  145.   struct IFFHandle *iff;
  146.  
  147.   if( iff = AllocIFF() ) {
  148.     if( iff->iff_Stream = (ULONG)Open(filename,MODE_OLDFILE) ) { /* open the file stream */
  149.       InitIFFasDOS( iff );                                       /* initialize this as a DOS stream */
  150.       if( OpenIFF( iff, IFFF_READ ) == 0 )                       /* now open it as an IFF */
  151.     return iff;                                              /* and return read-to-go IFF handle */
  152.       else
  153.     Close( iff->iff_Stream );                                /* not an IFF file; close file */
  154.     } else
  155.       fprintf(stderr,"File unavailable (%s)!\n",filename);
  156.     FreeIFF( iff );                                              /* free the iff handle */
  157.   } else
  158.     fprintf(stderr,"Out of memory opening (%s)!\n",filename);
  159.   return NULL;                                                   /* return failure */
  160. } /* OpenFileAsIFF() */
  161.  
  162.  
  163.  
  164. #define ID_ILBM  MAKE_ID('I','L','B','M')
  165. #define ID_BMHD  MAKE_ID('B','M','H','D')
  166. #define ID_CMAP  MAKE_ID('C','M','A','P')
  167. #define ID_BODY  MAKE_ID('B','O','D','Y')
  168. #define ID_AUTH  MAKE_ID('A','U','T','H')
  169. #define ID_CPRT  MAKE_ID('(','c',')',' ')
  170. #define ID_ANNO  MAKE_ID('A','N','N','O')
  171. #define ID_FVER  MAKE_ID('F','V','E','R')
  172.  
  173.  
  174. #define mskHasMask 1      /* the only mask that REALLY needs handling */
  175. #define ByteRun1   1      /* the only compression we understand */
  176. typedef UBYTE Masking;
  177. typedef UBYTE Compression;
  178. struct BitMapHeader {
  179.   UWORD       w, h;
  180.   WORD        x, y;
  181.   UBYTE       nPlanes;
  182.   Masking     masking;
  183.   Compression compression;
  184.   UBYTE       reserved1;
  185.   UWORD       transparentColor;
  186.   UBYTE       xAspect, yAspect;
  187.   WORD        pageWidth, pageHeight;
  188. };
  189.  
  190.  
  191.  
  192. /* The ByteToWordStream() function, along with a limited set of global variables,
  193.  * permits us to produce really lovely, and well-formatted output.
  194.  *
  195.  * OnNewLine is externally set to 1 whenever we have finished with a scanline so
  196.  * that the next time we call ByteToWordStream, we start nicely on a new line.
  197.  * If you never use OnNewLine, then all data is merely dumped one word after
  198.  * another.  NO FUNCTIONALITY IS LOST, it just won't look nice.  Your compiler
  199.  * doesn't care.  Lines are ALWAYS limited to 11 words per line.
  200.  *
  201.  * LineHeader, if not set to a "" string, is printed before a new line is output,
  202.  * so we can print the nice "/× Plane 2 ×/" items before the new plane actually
  203.  * begins, but still give this function the chance to clean up the previous line
  204.  * by adding a comma and newline to it, etc.
  205.  * If you never use LineHeader, you will simply be missing the human-readable
  206.  * markers for the bit planes.  No biggie.  Again, your compiler couldn't care
  207.  * less.
  208.  */
  209. #define WORDS_PER_LINE 11
  210. UBYTE OnNewLine = 0;
  211. char LineHeader[64] = "";
  212. void ByteT