home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / flgife.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  6KB  |  316 lines

  1. /*****************************************************************
  2.  * flgife.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * Modifications to GIFENCODE are Copyright (C) 1989,1990 by
  5.  * Michael Mauldin.  Permission is granted to use this file in whole
  6.  * or in part for any purpose, educational, recreational or commercial,
  7.  * provided that this copyright notice is retained unchanged.
  8.  * This software is available to all free of charge by anonymous
  9.  * FTP and in the UUNET archives.
  10.  *
  11.  * CONTENTS
  12.  *    GIFEncode( wfile, GHeight, GWidth, GInterlace, Background, 
  13.  *           BitsPerPixel, Red, Green, Blue, GetPixel )
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Mon Jun 25 00:09:49 1990 - Michael Mauldin
  17.  *    LastFileName = /usr2/mlm/src/misc/fbm/flgifc.c
  18.  *
  19.  * HISTORY
  20.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  21.  *    Package for Release 1.0
  22.  *
  23.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  24.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  25.  *
  26.  * 19-Feb-89  Michael Mauldin (mlm) at Carnegie Mellon University
  27.  *    Adapted to FBM package.  Now takes FILE pointer instead of
  28.  *    character name for output file.
  29.  *
  30.  * 13-Feb-89  David Rowley (mgardi@watdcsu.waterloo.edu)
  31.  *    Created (sent by mail on 2/13/89)
  32.  *    original name: GIFENCODE.C - GIF Image compression interface
  33.  *
  34.  *****************************************************************************/
  35.  
  36. #include <stdio.h>
  37.  
  38. /*
  39.  * Pointer to function returning an int
  40.  */
  41. typedef int (* ifunptr)();
  42.  
  43. #define TRUE 1
  44. #define FALSE 0
  45.  
  46. static int Width, Height;
  47. static int curx, cury;
  48. static long CountDown;
  49. static int Pass = 0;
  50. static int Interlace;
  51.  
  52. static Putword();
  53.  
  54. #ifndef lint
  55. static char *fbmid =
  56. "$FBM flgife.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  57. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  58. #endif
  59.  
  60.  
  61. /*
  62.  * Bump the 'curx' and 'cury' to point to the next pixel
  63.  */
  64. static
  65. BumpPixel()
  66. {
  67.     /*
  68.      * Bump the current X position
  69.      */
  70.     curx++;
  71.  
  72.     /*
  73.      * If we are at the end of a scan line, set curx back to the beginning
  74.      * If we are interlaced, bump the cury to the appropriate spot,
  75.      * otherwise, just increment it.
  76.      */
  77.     if( curx == Width ) {
  78.         curx = 0;
  79.  
  80.             if( !Interlace ) 
  81.             cury++;
  82.         else {
  83.              switch( Pass ) {
  84.          
  85.                    case 0:
  86.                       cury += 8;
  87.                       if( cury >= Height ) {
  88.                   Pass++;
  89.                 cury = 4;
  90.                 }
  91.                           break;
  92.           
  93.                    case 1:
  94.                       cury += 8;
  95.                       if( cury >= Height ) {
  96.                   Pass++;
  97.                 cury = 2;
  98.                 }
  99.               break;
  100.           
  101.                    case 2:
  102.                       cury += 4;
  103.                       if( cury >= Height ) {
  104.                          Pass++;
  105.                          cury = 1;
  106.                       }
  107.                       break;
  108.               
  109.                    case 3:
  110.                       cury += 2;
  111.                       break;
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117. /*
  118.  * Return the next pixel from the image
  119.  */
  120. GIFNextPixel( getpixel )
  121. ifunptr getpixel;
  122. {
  123.     int r;
  124.  
  125.     if( CountDown == 0 )
  126.         return EOF;
  127.  
  128.     CountDown--;
  129.  
  130.     r = ( * getpixel )( curx, cury );
  131.  
  132.     BumpPixel();
  133.  
  134.     return r;
  135. }
  136.  
  137. /* public */
  138.  
  139. GIFEncode( wfile, GWidth, GHeight, GInterlace, Background, 
  140.        BitsPerPixel, Red, Green, Blue, GetPixel )
  141.      
  142. FILE *wfile;
  143. int GWidth, GHeight;
  144. int GInterlace;
  145. int Background;
  146. int BitsPerPixel;
  147. int Red[], Green[], Blue[];
  148. ifunptr GetPixel;
  149.  
  150. {
  151.     FILE *fp;
  152.     int B;
  153.     int RWidth, RHeight;
  154.     int LeftOfs, TopOfs;
  155.     int Resolution;
  156.     int ColorMapSize;
  157.     int InitCodeSize;
  158.     int i;
  159.  
  160.     Interlace = GInterlace;
  161.     
  162.     ColorMapSize = 1 << BitsPerPixel;
  163.     
  164.     RWidth = Width = GWidth;
  165.     RHeight = Height = GHeight;
  166.     LeftOfs = TopOfs = 0;
  167.     
  168.     Resolution = BitsPerPixel;
  169.  
  170.     /*
  171.      * Calculate number of bits we are expecting
  172.      */
  173.     CountDown = (long)Width * (long)Height;
  174.  
  175.     /*
  176.      * Indicate which pass we are on (if interlace)
  177.      */
  178.     Pass = 0;
  179.  
  180.     /*
  181.      * The initial code size
  182.      */
  183.     if( BitsPerPixel <= 1 )
  184.         InitCodeSize = 2;
  185.     else
  186.         InitCodeSize = BitsPerPixel;
  187.  
  188.     /*
  189.      * Set up the current x and y position
  190.      */
  191.     curx = cury = 0;
  192.  
  193.     /*
  194.      * Open the GIF file for binary write
  195.      */
  196.     /* fp = fopen( FName, "wb" ); */
  197.  
  198.     fp = wfile;    /* Change for FBM - mlm 2/19/89 */
  199.  
  200.     if( fp == (FILE *)0 ) {
  201.         printf( "error: could not open output file\n" );
  202.         return (0);
  203.     }
  204.  
  205.     /*
  206.      * Write the Magic header
  207.      */
  208.     fwrite( "GIF87a", 1, 6, fp );
  209.  
  210.     /*
  211.      * Write out the screen width and height
  212.      */
  213.     Putword( RWidth, fp );
  214.     Putword( RHeight, fp );
  215.  
  216.     /*
  217.      * Indicate that there is a global colour map
  218.      */
  219.     B = 0x80;    /* Yes, there is a color map */
  220.  
  221.     /*
  222.      * OR in the resolution
  223.      */
  224.     B |= (Resolution - 1) << 5;
  225.  
  226.     /*
  227.      * OR in the Bits per Pixel
  228.      */
  229.     B |= (BitsPerPixel - 1);
  230.  
  231.     /*
  232.      * Write it out
  233.      */
  234.     fputc( B, fp );
  235.  
  236.     /*
  237.      * Write out the Background colour
  238.      */
  239.     fputc( Background, fp );
  240.  
  241.     /*
  242.      * Byte of 0s (future expansion)
  243.      */
  244.     fputc( 0, fp );
  245.  
  246.     /*
  247.      * Write out the Global Colour Map
  248.      */
  249.          for( i=0; i<ColorMapSize; i++ ) {
  250.         fputc( Red[i], fp );
  251.         fputc( Green[i], fp );
  252.         fputc( Blue[i], fp );
  253.     }
  254.  
  255.     /*
  256.      * Write an Image separator
  257.      */
  258.     fputc( ',', fp );
  259.  
  260.     /*
  261.      * Write the Image header
  262.      */
  263.  
  264.     Putword( LeftOfs, fp );
  265.     Putword( TopOfs, fp );
  266.     Putword( Width, fp );
  267.     Putword( Height, fp );
  268.  
  269.     /*
  270.      * Write out whether or not the image is interlaced
  271.      */
  272.     if( Interlace )
  273.         fputc( 0x40, fp );
  274.     else
  275.         fputc( 0x00, fp );
  276.  
  277.     /*
  278.      * Write out the initial code size
  279.      */
  280.     fputc( InitCodeSize, fp );
  281.  
  282.     /*
  283.      * Go and actually compress the data
  284.      */
  285.     compress( InitCodeSize+1, fp, GetPixel );
  286.  
  287.     /*
  288.      * Write out a Zero-length packet (to end the series)
  289.      */
  290.     fputc( 0, fp );
  291.  
  292.     /*
  293.      * Write the GIF file terminator
  294.      */
  295.     fputc( ';', fp );
  296.  
  297.     /*
  298.      * And close the file
  299.      */
  300.     fclose( fp );
  301.     
  302.     return (1);    /* success - mlm 2/19/89 */
  303. }
  304.  
  305. /*
  306.  * Write out a word to the GIF file
  307.  */
  308. static
  309. Putword( w, fp )
  310. int w;
  311. FILE *fp;
  312. {
  313.     fputc( w & 0xff, fp );
  314.     fputc( (w / 256) & 0xff, fp );
  315. }
  316.