*** gif.c.orig	Fri May 24 13:05:42 2002
--- gif.c	Mon May 27 01:17:16 2002
***************
*** 23,28 ****
--- 23,38 ----
  /*
   * REVISION HISTORY
   *
+  * 2002/04/27 - Cameron Gregory, http://www.flamingtext.com/
+  *           Added GUI options and compile time options to compile in/out
+  *           RLE/LZW.  None, is now in always.
+  *           It's important for people to be able to compile out LWZ/RLE.
+  *
+  * 2002/04/24 - Cameron Gregory, http://www.flamingtext.com/
+  *           Added no_compress() option.
+  *			 Added rle_compress().  Should not be covered by lzw patent,
+  *           but this is not legal advice.
+  *
   * 99/04/25
   * 3.00.02 - Save the comment back onto the image as a persistent
   *           parasite if the comment was edited.
***************
*** 276,281 ****
--- 286,298 ----
  #include "libgimp/stdplugins-intl.h"
  
  
+ /* Define either of these to remove the LZW and/or RLE code.
+  * Uncompressed GIF's are always compiled in.
+  * If you define these below, they are removed from the options.
+  */
+ /* #define GIF_NO_LZW */
+ /* #define GIF_NO_RLE */
+ 
  /* uncomment the line below for a little debugging info */
  /* #define GIFDEBUG yesplease */
  
***************
*** 294,299 ****
--- 311,323 ----
    DISPOSE_REPLACE
  };
  
+ enum
+ {
+   ENCODE_LZW,
+   ENCODE_RLE,
+   ENCODE_NONE
+ };
+ 
  typedef struct
  {
    gint interlace;
***************
*** 301,306 ****
--- 325,331 ----
    gint loop;
    gint default_delay;
    gint default_dispose;
+   gint encoding;
  } GIFSaveVals;
  
  typedef struct
***************
*** 360,366 ****
    TRUE,    /* save comment                         */
    TRUE,    /* loop infinitely                      */
    100,     /* default_delay between frames (100ms) */
!   0        /* default_dispose = "don't care"       */
  };
  
  static GIFSaveInterface gsint =
--- 385,401 ----
    TRUE,    /* save comment                         */
    TRUE,    /* loop infinitely                      */
    100,     /* default_delay between frames (100ms) */
!   0,       /* default_dispose = "don't care"       */
!            /* encoding 0=LZW, 1=RLE, 2=NONE */
! #ifdef GIF_NO_LZW
! #ifdef GIF_NO_RLE
! 	ENCODE_NONE
! #else
! 	ENCODE_RLE
! #endif
! #else
! 	ENCODE_LZW
! #endif
  };
  
  static GIFSaveInterface gsint =
***************
*** 622,627 ****
--- 657,669 ----
  
  static void Putword (int, FILE *);
  static void compress (int, FILE *, ifunptr);
+ static void no_compress (int, FILE *, ifunptr);
+ #ifndef GIF_NO_RLE
+ static void rle_compress (int, FILE *, ifunptr);
+ #endif
+ #ifndef GIF_NO_LZW
+ static void lzw_compress (int, FILE *, ifunptr);
+ #endif
  static void output (code_int);
  static void cl_block (void);
  static void cl_hash (count_int);
***************
*** 1200,1205 ****
--- 1242,1248 ----
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *disposal_option_menu;
+   GtkWidget *encoding_option_menu;
    GtkWidget *com_table;
    GtkWidget *vscrollbar;
  #ifdef FACEHUGGERS
***************
*** 1249,1254 ****
--- 1292,1328 ----
    gtk_widget_show (toggle);
  
    hbox = gtk_hbox_new (FALSE, 4);
+   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+   label = gtk_label_new (_("Encoding: "));
+   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+   gtk_widget_show (label);
+   gtk_widget_show (hbox);
+ 
+   encoding_option_menu =
+     gimp_option_menu_new2 (FALSE, gimp_menu_item_update,
+ 			   &gsvals.encoding,
+ 			   (gpointer) gsvals.encoding,
+ 
+ /* REALLY: This should be "set_sensitve" false, but I don't know how :) */
+ #ifndef GIF_NO_LZW
+ 			   _("LZW"),
+ 			   (gpointer) ENCODE_LZW, NULL,
+ #endif
+ #ifndef GIF_NO_RLE
+ 			   _("RLE"),
+ 			   (gpointer) ENCODE_RLE, NULL,
+ #endif
+ 			   _("None"),
+ 			   (gpointer) ENCODE_NONE, NULL,
+ 
+ 			   NULL);
+   gtk_box_pack_start (GTK_BOX (hbox), encoding_option_menu, FALSE, FALSE, 0);
+   gtk_widget_show (encoding_option_menu);
+ 
+   gtk_widget_show (hbox);
+ 
+ 
+   hbox = gtk_hbox_new (FALSE, 4);
    gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  
    toggle = gtk_check_button_new_with_label (_("GIF Comment:"));
***************
*** 1372,1378 ****
  			   NULL);
    gtk_box_pack_start (GTK_BOX (hbox), disposal_option_menu, FALSE, FALSE, 0);
    gtk_widget_show (disposal_option_menu);
- 
    gtk_widget_show (hbox);
    gtk_widget_show (vbox);
  
--- 1446,1451 ----
***************
*** 2098,2108 ****
--- 2171,2428 ----
   0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
  
  
+ /* If an option isn't compiled in, it will drop down to the next level */
+ 
  static void
  compress (int      init_bits,
  	  FILE    *outfile,
  	  ifunptr  ReadValue)
  {
+ 	switch (gsvals.encoding) {
+ 		case ENCODE_LZW:
+ #ifndef GIF_NO_LZW
+ 			lzw_compress(init_bits, outfile, ReadValue);
+ 			break;
+ #endif
+ 		case ENCODE_RLE:
+ #ifndef GIF_NO_RLE
+ 			rle_compress(init_bits, outfile, ReadValue);
+ 			break;
+ #endif
+ 		case ENCODE_NONE:
+ 		default:
+ 			no_compress(init_bits, outfile, ReadValue);
+ 			break;
+ 		}
+ }
+ 
+ static void
+ no_compress (int      init_bits,
+ 	  FILE    *outfile,
+ 	  ifunptr  ReadValue)
+ {
+   register long fcode;
+   register code_int i /* = 0 */ ;
+   register int c;
+   register code_int ent;
+   register code_int hsize_reg;
+   register int hshift;
+ 
+ 
+   /*
+    * Set up the globals:  g_init_bits - initial number of bits
+    *                      g_outfile   - pointer to output file
+    */
+   g_init_bits = init_bits;
+   g_outfile = outfile;
+ 
+   cur_bits = 0;
+   cur_accum = 0;
+ 
+   /*
+    * Set up the necessary values
+    */
+   offset = 0;
+   out_count = 0;
+   clear_flg = 0;
+   in_count = 1;
+ 
+   ClearCode = (1 << (init_bits - 1));
+   EOFCode = ClearCode + 1;
+   free_ent = ClearCode + 2;
+ 
+ 
+   /* Had some problems here... should be okay now.  --Adam */
+   n_bits = g_init_bits;
+   maxcode = MAXCODE (n_bits);
+ 
+ 
+ 
+   char_init ();
+ 
+   ent = GIFNextPixel (ReadValue);
+ 
+   hshift = 0;
+   for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
+     ++hshift;
+   hshift = 8 - hshift;		/* set hash code range bound */
+ 
+   hsize_reg = hsize;
+   cl_hash ((count_int) hsize_reg);	/* clear hash table */
+ 
+   output ((code_int) ClearCode);
+ 
+ 
+ #ifdef SIGNED_COMPARE_SLOW
+   while ((c = GIFNextPixel (ReadValue)) != (unsigned) EOF)
+     {
+ #else /*SIGNED_COMPARE_SLOW */
+   while ((c = GIFNextPixel (ReadValue)) != EOF)
+     {				/* } */
+ #endif /*SIGNED_COMPARE_SLOW */
+ 
+       ++in_count;
+ 
+       fcode = (long) (((long) c << maxbits) + ent);
+       i = (((code_int) c << hshift) ^ ent);	/* xor hashing */
+ 
+       output ((code_int) ent);
+       ++out_count;
+       ent = c;
+ #ifdef SIGNED_COMPARE_SLOW
+       if ((unsigned) free_ent < (unsigned) maxmaxcode)
+ 	{
+ #else /*SIGNED_COMPARE_SLOW */
+       if (free_ent < maxmaxcode)
+ 	{			/* } */
+ #endif /*SIGNED_COMPARE_SLOW */
+ 	  CodeTabOf (i) = free_ent++;	/* code -> hashtable */
+ 	  HashTabOf (i) = fcode;
+ 	}
+       else
+ 	cl_block ();
+     }
+ 
+   /*
+    * Put out the final code.
+    */
+   output ((code_int) ent);
+   ++out_count;
+   output ((code_int) EOFCode);
+ }
+ 
+ #ifndef GIF_NO_RLE
+ 
+ static void
+ rle_compress (int      init_bits,
+ 	  FILE    *outfile,
+ 	  ifunptr  ReadValue)
+ {
+   register long fcode;
+   register code_int i /* = 0 */ ;
+   register int c, last;
+   register code_int ent;
+   register code_int disp;
+   register code_int hsize_reg;
+   register int hshift;
+ 
+ 
+   /*
+    * Set up the globals:  g_init_bits - initial number of bits
+    *                      g_outfile   - pointer to output file
+    */
+   g_init_bits = init_bits;
+   g_outfile = outfile;
+ 
+   cur_bits = 0;
+   cur_accum = 0;
+ 
+   /*
+    * Set up the necessary values
+    */
+   offset = 0;
+   out_count = 0;
+   clear_flg = 0;
+   in_count = 1;
+ 
+   ClearCode = (1 << (init_bits - 1));
+   EOFCode = ClearCode + 1;
+   free_ent = ClearCode + 2;
+ 
+ 
+   /* Had some problems here... should be okay now.  --Adam */
+   n_bits = g_init_bits;
+   maxcode = MAXCODE (n_bits);
+ 
+ 
+ 
+   char_init ();
+ 
+   last = ent = GIFNextPixel (ReadValue);
+ 
+   hshift = 0;
+   for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
+     ++hshift;
+   hshift = 8 - hshift;		/* set hash code range bound */
+ 
+   hsize_reg = hsize;
+   cl_hash ((count_int) hsize_reg);	/* clear hash table */
+ 
+   output ((code_int) ClearCode);
+ 
+ 
+ 
+ #ifdef SIGNED_COMPARE_SLOW
+   while ((c = GIFNextPixel (ReadValue)) != (unsigned) EOF)
+     {
+ #else /*SIGNED_COMPARE_SLOW */
+   while ((c = GIFNextPixel (ReadValue)) != EOF)
+     {				/* } */
+ #endif /*SIGNED_COMPARE_SLOW */
+ 
+       ++in_count;
+ 
+       fcode = (long) (((long) c << maxbits) + ent);
+       i = (((code_int) c << hshift) ^ ent);	/* xor hashing */
+ 
+ 
+       if (last == c) {
+         if (HashTabOf (i) == fcode)
+ 	  {
+ 	    ent = CodeTabOf (i);
+ 	    continue;
+ 	  }
+         else if ((long) HashTabOf (i) < 0)	/* empty slot */
+ 	  goto nomatch;
+         disp = hsize_reg - i;	/* secondary hash (after G. Knott) */
+         if (i == 0)
+ 	  disp = 1;
+       probe:
+         if ((i -= disp) < 0)
+ 	  i += hsize_reg;
+   
+         if (HashTabOf (i) == fcode)
+ 	  {
+ 	    ent = CodeTabOf (i);
+ 	    continue;
+ 	  }
+         if ((long) HashTabOf (i) > 0)
+ 	  goto probe;
+         }
+     nomatch:
+       output ((code_int) ent);
+       ++out_count;
+       last = ent = c;
+ #ifdef SIGNED_COMPARE_SLOW
+       if ((unsigned) free_ent < (unsigned) maxmaxcode)
+ 	{
+ #else /*SIGNED_COMPARE_SLOW */
+       if (free_ent < maxmaxcode)
+ 	{			/* } */
+ #endif /*SIGNED_COMPARE_SLOW */
+ 	  CodeTabOf (i) = free_ent++;	/* code -> hashtable */
+ 	  HashTabOf (i) = fcode;
+ 	}
+       else
+ 	cl_block ();
+     }
+ 
+   /*
+    * Put out the final code.
+    */
+   output ((code_int) ent);
+   ++out_count;
+   output ((code_int) EOFCode);
+ }
+ #endif
+ 
+ #ifndef GIF_NO_LZW
+ 
+ static void
+ lzw_compress (int      init_bits,
+ 	  FILE    *outfile,
+ 	  ifunptr  ReadValue)
+ {
    register long fcode;
    register code_int i /* = 0 */ ;
    register int c;
***************
*** 2156,2161 ****
--- 2476,2482 ----
    output ((code_int) ClearCode);
  
  
+ 
  #ifdef SIGNED_COMPARE_SLOW
    while ((c = GIFNextPixel (ReadValue)) != (unsigned) EOF)
      {
***************
*** 2207,2212 ****
--- 2528,2534 ----
        else
  	cl_block ();
      }
+ 
    /*
     * Put out the final code.
     */
***************
*** 2214,2219 ****
--- 2536,2544 ----
    ++out_count;
    output ((code_int) EOFCode);
  }
+ #endif
+ 
+ 
  
  /*****************************************************************
   * TAG( output )
