/* Surface
 * (C) Copyright 1995 by Ashton Mason (amason@cs.uct.ac.za)
 *
 * Permission to use, modify, copy and distribute this source code for
 * any purpose and without fee is granted, provided that this copyright
 * notice appears in all copies and supporting documentation, and that
 * credit is given where due. This source code is provided "as is" with
 * no express or implied warranty.
 */

	// code to read pixel data from GIF files.
        // based largely on code by Steven A. Bennett,
        // which was based in turn on code by Steve Wilhite.
	// converted to C++ by Ashton Mason
	// Copyright (C) 1995 Ashton Mason
	// GIF and 'Graphics Interchange Format' are trademarks (tm) of
	// Compuserve, Incorporated, an H&R Block Company.


#define MAX_CODES   4095

#define LOCAL static
#define IMPORT extern

#define FAST register

typedef short WORD;
typedef unsigned short UWORD;
typedef char TEXT;
typedef unsigned char UTINY;
typedef long LONG;
typedef unsigned long ULONG;

/* Various error codes used by decoder
 * and my own routines...   It's okay
 * for you to define whatever you want,
 * as long as it's negative...  It will be
 * returned intact up the various subroutine
 * levels...
 * Steven Bennett
 */

#define OUT_OF_MEMORY -10
#define BAD_CODE_SIZE -20
#define READ_ERROR -1
#define WRITE_ERROR -2
#define OPEN_ERROR -3
#define CREATE_ERROR -4


	// class to read data from GIF files


class gif
{
  FILE *file;

  int bad_code_count;
  int lineno;

  	// from decode.c:

  WORD curr_size;                     /* The current code size */
  WORD clear;                         /* Value for a clear code */
  WORD ending;                        /* Value for a ending code */
  WORD newcodes;                      /* First available code */
  WORD top_slot;                      /* Highest code for current size */
  WORD slot;                          /* Last read code */

  /* The following static variables are used
   * for seperating out codes
   */

  WORD navail_bytes;                  /* # bytes left in block */
  WORD nbits_left;      	      /* # bits left in current byte */
  UTINY b1;                           /* Current byte */
  UTINY byte_buff[257];               /* Current block */
  UTINY *pbytes;                      /* Pointer to next byte in block */

  UTINY pixstack[MAX_CODES + 1];         /* Stack for storing pixels */
  UTINY suffix[MAX_CODES + 1];           /* Suffix table */
  UWORD prefix[MAX_CODES + 1];           /* Prefix linked list */

  int openFile(char *name);
  int closeFile();

  int get_byte();
  WORD out_line(unsigned char *pixels, int linelen);

  WORD init_exp(WORD size);
  WORD get_next_code();

  WORD decoder(WORD linewidth);		// main decoder routine

public:

  gif(void);
  ~gif(void);

  unsigned char *data;			// storage area for pixel data
  int xsize, ysize;			// size of read image

  int readFile(char *name);		// read GIF pixel data into memory
  int destroyData();			// destroy the data in memory
};

