home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / fbm / part04 / flgife.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  5KB  |  306 lines

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