Back to index

wims  3.65+svn20090927
Classes | Defines | Typedefs | Functions
whirlgif.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  Transparency
struct  Global
struct  GifScreenHdr
union  GifColor
struct  GifColor::cmap
struct  GifImageHdr
struct  GifTree

Defines

#define DA_REV   3.04
#define WRIBIN   "w"
#define REATXT   "r"
#define REABIN   "r"
#define FALSE   0
#define DEFAULT_TIME   10
#define DEFAULT_LOOP   0
#define DEFAULT_USE_COLORMAP   0
#define TRANS_NONE   1
#define TRANS_RGB   2
#define TRANS_MAP   3
#define DISP_NONE   0
#define DISP_NOT   1
#define DISP_BACK   2
#define DISP_PREV   3
#define DEFAULT_DISPOSAL   DISP_NONE
#define BIGSTRING   256
#define MAXVAL   4096 /* maxval of lzw coding size */
#define MAXVALP   4096
#define TERMIN   'T'
#define LOOKUP   'L'
#define SEARCH   'S'
#define noOfArrays   20
#define LONG   int
#define ULONG   unsigned int
#define BYTE   char
#define UBYTE   unsigned char
#define SHORT   short
#define USHORT   unsigned short
#define WORD   short int
#define UWORD   unsigned short int
#define GifPutShort(i, fout)   {fputc(i&0xff, fout); fputc(i>>8, fout);}
#define GifGetShort(fin)   (Xgetc(fin) | Xgetc(fin)<<8)

Typedefs

typedef struct Transparency Transparency
typedef struct Global Global
typedef struct GifScreenHdr GifScreenHdr
typedef union GifColor GifColor
typedef struct GifImageHdr GifImageHdr
typedef struct GifTree GifTree

Functions

char * AddCodeToBuffer (int, short, char *)
void CalcTrans (char *)
void ClearTree (int, GifTree *)
void GifClearTable ()
void GifComment (FILE *, char *)
void GifDecode (FILE *, UBYTE *, GifImageHdr)
void GifEncode (FILE *, UBYTE *, int, int)
void GifLoop (FILE *, unsigned int)
void GifReadFile (FILE *, char *, int)
void GifScreenHeader (FILE *, FILE *, int)
UBYTEGifSendData (UBYTE *, int, UBYTE *)
void ReadImageHeader (FILE *)
void SetOffset (char *)
long sq (UBYTE, UBYTE)
void TheEnd ()
void TheEnd1 (char *)
void Usage ()
void WriteImageHeader (FILE *)
UBYTE Xgetc (FILE *)

Class Documentation

struct Transparency

Definition at line 98 of file whirlgif.h.

Class Members
UBYTE blue
UBYTE green
UBYTE map
UBYTE red
int type
UBYTE valid
struct Global

Definition at line 107 of file whirlgif.h.

Collaboration diagram for Global:
Class Members
unsigned short disposal
int left
unsigned int time
int top
Transparency trans
struct GifScreenHdr

Definition at line 115 of file whirlgif.h.

Class Members
UBYTE aspect
UBYTE bc
UBYTE cres
int height
UBYTE m
UBYTE pixbits
int width
union GifColor

Definition at line 125 of file whirlgif.h.

Collaboration diagram for GifColor:
Class Members
struct cmap cmap
ULONG pixel
struct GifColor::cmap

Definition at line 126 of file whirlgif.h.

Class Members
UBYTE blue
UBYTE green
UBYTE pad
UBYTE red
struct GifImageHdr

Definition at line 135 of file whirlgif.h.

Class Members
int height
UBYTE i
int left
UBYTE m
UBYTE pixbits
UBYTE reserved
int top
int width
struct GifTree

Definition at line 146 of file whirlgif.h.

Collaboration diagram for GifTree:
Class Members
struct GifTree * alt
int code
UBYTE ix
struct GifTree ** node
struct GifTree * nxt
char typ

Define Documentation

#define BIGSTRING   256

Definition at line 74 of file whirlgif.h.

#define BYTE   char

Definition at line 89 of file whirlgif.h.

#define DA_REV   3.04

Definition at line 24 of file whirlgif.h.

Definition at line 71 of file whirlgif.h.

Definition at line 58 of file whirlgif.h.

#define DEFAULT_TIME   10

Definition at line 56 of file whirlgif.h.

Definition at line 60 of file whirlgif.h.

#define DISP_BACK   2

Definition at line 69 of file whirlgif.h.

#define DISP_NONE   0

Definition at line 67 of file whirlgif.h.

#define DISP_NOT   1

Definition at line 68 of file whirlgif.h.

#define DISP_PREV   3

Definition at line 70 of file whirlgif.h.

#define FALSE   0

Definition at line 51 of file whirlgif.h.

#define GifGetShort (   fin)    (Xgetc(fin) | Xgetc(fin)<<8)

Definition at line 155 of file whirlgif.h.

#define GifPutShort (   i,
  fout 
)    {fputc(i&0xff, fout); fputc(i>>8, fout);}

Definition at line 154 of file whirlgif.h.

#define LONG   int

Definition at line 87 of file whirlgif.h.

#define LOOKUP   'L'

Definition at line 78 of file whirlgif.h.

#define MAXVAL   4096 /* maxval of lzw coding size */

Definition at line 75 of file whirlgif.h.

#define MAXVALP   4096

Definition at line 76 of file whirlgif.h.

#define noOfArrays   20

Definition at line 80 of file whirlgif.h.

#define REABIN   "r"

Definition at line 44 of file whirlgif.h.

#define REATXT   "r"

Definition at line 43 of file whirlgif.h.

#define SEARCH   'S'

Definition at line 79 of file whirlgif.h.

#define SHORT   short

Definition at line 91 of file whirlgif.h.

#define TERMIN   'T'

Definition at line 77 of file whirlgif.h.

#define TRANS_MAP   3

Definition at line 65 of file whirlgif.h.

#define TRANS_NONE   1

Definition at line 63 of file whirlgif.h.

#define TRANS_RGB   2

Definition at line 64 of file whirlgif.h.

#define UBYTE   unsigned char

Definition at line 90 of file whirlgif.h.

#define ULONG   unsigned int

Definition at line 88 of file whirlgif.h.

#define USHORT   unsigned short

Definition at line 92 of file whirlgif.h.

#define UWORD   unsigned short int

Definition at line 94 of file whirlgif.h.

#define WORD   short int

Definition at line 93 of file whirlgif.h.

#define WRIBIN   "w"

Definition at line 42 of file whirlgif.h.


Typedef Documentation

typedef union GifColor GifColor
typedef struct GifImageHdr GifImageHdr
typedef struct GifScreenHdr GifScreenHdr
typedef struct GifTree GifTree
typedef struct Global Global
typedef struct Transparency Transparency

Function Documentation

char* AddCodeToBuffer ( int  ,
short  ,
char *   
)

Definition at line 266 of file gifencod.c.

{
  int    mask;

  if(n<0) {
    if(need<8) {
      buf++;
      *buf = 0x0;
    }
    need = 8;
    return buf;
  }

  while(n>=need) {
    mask = (1<<need)-1;
    *buf += (mask&code)<<(8-need);
    buf++;
    *buf = 0x0;
    code = code>>need;
    n -= need;
    need = 8;
  }
  if(n) {
    mask = (1<<n)-1;
    *buf += (mask&code)<<(8-need);
    need -= n;
  }
  return buf;
}

Here is the caller graph for this function:

void CalcTrans ( char *  )

Definition at line 681 of file whirlgif.c.

{
  if(string[0] != '#') {
    global.trans.type = TRANS_MAP;
    global.trans.map = atoi(string);
    global.trans.valid = 1;
  }
  else {
    /* it's an RGB value */
    int r, g, b;
    string++;
    if (debugFlag > 1) fprintf(stderr, "String is %s\n", string);
    if(3 == sscanf(string, "%2x%2x%2x", &r, &g, &b)) {
      global.trans.red = r;
      global.trans.green = g;
      global.trans.blue = b;
      global.trans.type = TRANS_RGB;
      global.trans.valid = 0;
      if(debugFlag > 1)
       fprintf(stderr, "Transparent RGB=(%x,%x,%x) = (%d,%d,%d)\n",
           r, g, b, r, g, b);
    }
  }
  if(debugFlag > 1)
       fprintf(stderr, "DEBUG:CalcTrans is %d\n", global.trans.type);
}

Here is the caller graph for this function:

void ClearTree ( int  ,
GifTree  
)

Definition at line 238 of file gifencod.c.

{
  int i;
  GifTree *newNode, **xx;

  if (debugFlag>1) fprintf(stderr, "Clear Tree  cc= %d\n", cc);
  if (debugFlag>1) fprintf(stderr, "nodeCount = %d lookup nodes = %d\n", nodecount, lookuptypes);
  maxchainlen=0; lookuptypes = 1;
  nodecount = 0;
  nodeArray = root->node;
  xx= nodeArray;
  for (i = 0; i < noOfArrays; i++ ) {
    memmove (xx, empty, 256*sizeof(GifTree **));
    xx += 256;
  }
  topNode = baseNode;
  for(i=0; i<cc; i++) {
    root->node[i] = newNode = ++topNode;
    newNode->nxt = NULL;
    newNode->alt = NULL;
    newNode->code = i;
    newNode->ix = i;
    newNode->typ = TERMIN;
    newNode->node = empty;
    nodecount++;
  }
}

Here is the caller graph for this function:

void GifClearTable ( )

Definition at line 148 of file gifdecod.c.

{ int i, maxi;
  maxi = 1 << rootCodeSize;
  expected = maxi + 2;
  if (debugFlag > 1 ) fprintf(stderr, "Initing Table...");
  old = MAXVAL;
  codeSize = rootCodeSize + 1;
  mask = (1<<codeSize) - 1;

  for(i = 0; i < maxi; i++) {
    first[i] = MAXVAL;
    last[i] = i & 0xff;
  }
  topGifBuff = gifBuff;
}

Here is the caller graph for this function:

void GifComment ( FILE *  ,
char *   
)

Definition at line 642 of file whirlgif.c.

{
  int len;

  if( (len = strlen(string)) > 254 ) fprintf(stderr,
               "GifComment: String too long ; dropped\n");
  else if ( len > 0 ) {
    /* Undocumented feature:
       Empty comment string means no comment block in outfile */
    fputc(0x21, fout);
    fputc(0xFE, fout);
    fputc(len, fout);
    fputs(string, fout);
    fputc(0, fout);
  }
  return;
}

Here is the caller graph for this function:

void GifDecode ( FILE *  ,
UBYTE ,
GifImageHdr   
)

Definition at line 36 of file gifdecod.c.

{ UBYTE *chPos, firstCodeOut = 0, charBuff[256];
  ULONG CLEAR, EOI, bits = 0, code = 0, codeFeched, buffCount = 0;
  int need = 0;

  interlaced = gifimage.i;
  imgwidth = gifimage.width;
  imgheight = gifimage.height;
  imgsize = imgwidth * imgheight;
  picture = pix;
  pass = picI = 0;
  if ( debugFlag > 1 )
     fprintf(stderr, "(interlaced,imgwidth,imgheight,imgsize)=(%d,%d,%d,%d)\n",
              interlaced, imgwidth, imgheight, imgsize);

  rootCodeSize = Xgetc(fp);
  CLEAR = 1 << rootCodeSize;
  EOI = CLEAR + 1;

  GifClearTable();

  if ( (buffCount = Xgetc(fp)) == 0 ) {
    sprintf(charBuff, "End of image # %d before it began!\n", count);
    TheEnd1(charBuff);
  }

  while(buffCount > 0) {
    if ( fread(charBuff, 1, buffCount, fp) != buffCount ) { 
      sprintf(charBuff, "Premature end of file; Image # %d\n", count);
      TheEnd1(charBuff);
    }
    for(chPos = charBuff; buffCount-- > 0; chPos++) {
      need += (int) *chPos << bits;
      bits += 8;
      while (bits >= codeSize) {
       code = need & mask;
       need >>= codeSize;
       bits -= codeSize;
       if(code > expected)
          TheEnd1("Neither LZW nor RunLength (new code != expected)\n");
       if (code == EOI) {
         if (debugFlag > 1) fprintf(stderr, "Image # %d ends; buffCount=%d\n",
                     count, buffCount);
         goto skipRest;
       }

       if(code == CLEAR) {
       GifClearTable();
       continue;
       }
       if(old == MAXVAL) {  /* i.e. first code after clear table */
         pix = GifSendData(pix, 1, &last[code]);
         firstCodeOut = last[code];
         old = code;
         continue;
       }
       codeFeched = code;
       if(code == expected) {
         *topGifBuff++ = firstCodeOut;
         code = old;
       }
       while(code > CLEAR) {
         *topGifBuff++ = last[code];
         code = first[code];
       }

       *topGifBuff++ = firstCodeOut = last[code];
       first[expected] = old;
       last[expected] = firstCodeOut;
       if(expected < MAXVAL) expected++;
       if(((expected & mask) == 0) && (expected < MAXVAL)) {
         codeSize++;
         mask += expected;
       }
       old = codeFeched;
       pix = GifSendData(pix, topGifBuff - gifBuff, gifBuff);
       topGifBuff = gifBuff;

      }   /* end of extracting codes */
    }   /* end of reading a block of data */
    if ( (buffCount = Xgetc(fp)) == 0 ) {
      sprintf(charBuff, "End of image # %d without EOI\n", count);
      TheEnd1(charBuff);
    }
  }

skipRest: 
  if (debugFlag) fprintf(stderr, "Ending GifDecode, written: %d=%d\n",
         interlaced && (pix-picture == 0) ? imgsize : pix - picture, imgsize);
  return ;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GifEncode ( FILE *  ,
UBYTE ,
int  ,
int   
)

Definition at line 69 of file gifencod.c.

{
  GifTree *first = &GifRoot, *newNode, *curNode;
  UBYTE   *end;
  int     cc, eoi, next, tel=0;
  short   cLength;

  char    *pos, *buffer;

  empty[0] = NULL;
  need = 8;

  nodeArray = empty;
  memmove(++nodeArray, empty, 255*sizeof(GifTree **));
  if (( buffer = (char *)malloc((BUFLEN+1)*sizeof(char))) == NULL )
        TheEnd1("No memory for writing");
  buffer++;


  pos = buffer;
  buffer[0] = 0x0;

  cc = (depth == 1) ? 0x4 : 1<<depth;
  fputc((depth == 1) ? 2 : depth, fout);
  eoi = cc+1;
  next = cc+2;

  cLength = (depth == 1) ? 3 : depth+1;

  if (( topNode = baseNode = (GifTree *)malloc(sizeof(GifTree)*4094)) == NULL )
        TheEnd1("No memory for GIF-code tree");
  if (( nodeArray = first->node = (GifTree **)malloc(256*sizeof(GifTree *)*noOfArrays)) == NULL )
        TheEnd1("No memory for search nodes");
  lastArray = nodeArray + ( 256*noOfArrays - cc);
  ClearTree(cc, first);

  pos = AddCodeToBuffer(cc, cLength, pos);

  end = pixels+siz;
  curNode = first;
  while(pixels < end) {

    if ( curNode->node[*pixels] != NULL ) {
      curNode = curNode->node[*pixels];
      tel++;
      pixels++;
      chainlen++;
      continue;
    } else if ( curNode->typ == SEARCH ) {
      newNode = curNode->nxt;
      while ( newNode->alt != NULL ) {
       if ( newNode->ix == *pixels ) break;
       newNode = newNode->alt;
      }
      if (newNode->ix == *pixels ) {
       tel++;
       pixels++;
       chainlen++;
       curNode = newNode;
       continue;
      }
    }

/* ******************************************************
 * If there is no more thread to follow, we create a new node.  If the
 * current node is terminating, it will become a SEARCH node.  If it is
 * a SEARCH node, and if we still have room, it will be converted to a
 * LOOKUP node.
*/
  newNode = ++topNode;
  switch (curNode->typ ) {
   case LOOKUP:
     newNode->nxt = NULL;
     newNode->alt = NULL,
     curNode->node[*pixels] = newNode;
   break;
   case SEARCH:
     if ( nodeArray != lastArray ) {
       nodeArray += cc;
       curNode->node = nodeArray;
       curNode->typ = LOOKUP;
       curNode->node[*pixels] = newNode;
       curNode->node[(curNode->nxt)->ix] = curNode->nxt;
       lookuptypes++;
       newNode->nxt = NULL;
       newNode->alt = NULL,
       curNode->nxt = NULL;
       break;
     }
/*   otherwise do as we do with a TERMIN node  */
   case TERMIN:
     newNode->alt = curNode->nxt;
     newNode->nxt = NULL,
     curNode->nxt = newNode;
     curNode->typ = SEARCH;
     break;
   default:
     fprintf(stderr, "Silly node type: %d\n", curNode->typ);
  }
  newNode->code = next;
  newNode->ix = *pixels;
  newNode->typ = TERMIN;
  newNode->node = empty;
  nodecount++;
/*
* End of node creation
* ******************************************************
*/
  if (debugFlag) {
    if (curNode == newNode) fprintf(stderr, "Wrong choice of node\n");
    if ( curNode->typ == LOOKUP && curNode->node[*pixels] != newNode ) fprintf(stderr, "Wrong pixel coding\n");
    if ( curNode->typ == TERMIN ) fprintf(stderr, "Wrong Type coding; frame no = %d; pixel# = %d; nodecount = %d\n", count, tel, nodecount);
  }
    pos = AddCodeToBuffer(curNode->code, cLength, pos);
    if ( chainlen > maxchainlen ) maxchainlen = chainlen;
    chainlen = 0;
    if(pos-buffer>BLOKLEN) {
      buffer[-1] = BLOKLEN;
      fwrite(buffer-1, 1, BLOKLEN+1, fout);
      buffer[0] = buffer[BLOKLEN];
      buffer[1] = buffer[BLOKLEN+1];
      buffer[2] = buffer[BLOKLEN+2];
      buffer[3] = buffer[BLOKLEN+3];
      pos -= BLOKLEN;
    }
    curNode = first;

    if(next == (1<<cLength)) cLength++;
    next++;

    if(next == 0xfff) {
      ClearTree(cc,first);
      pos = AddCodeToBuffer(cc, cLength, pos);
      if(pos-buffer>BLOKLEN) {
       buffer[-1] = BLOKLEN;
       fwrite(buffer-1, 1, BLOKLEN+1, fout);
       buffer[0] = buffer[BLOKLEN];
       buffer[1] = buffer[BLOKLEN+1];
       buffer[2] = buffer[BLOKLEN+2];
       buffer[3] = buffer[BLOKLEN+3];
       pos -= BLOKLEN;
      }
      next = cc+2;
      cLength = (depth == 1)?3:depth+1;
    }
  }

  pos = AddCodeToBuffer(curNode->code, cLength, pos);
  if(pos-buffer>BLOKLEN-3) {
    buffer[-1] = BLOKLEN-3;
    fwrite(buffer-1, 1, BLOKLEN-2, fout);
    buffer[0] = buffer[BLOKLEN-3];
    buffer[1] = buffer[BLOKLEN-2];
    buffer[2] = buffer[BLOKLEN-1];
    buffer[3] = buffer[BLOKLEN];
    buffer[4] = buffer[BLOKLEN+1];
    pos -= BLOKLEN-3;
  }
  pos = AddCodeToBuffer(eoi, cLength, pos);
  pos = AddCodeToBuffer(0x0, -1, pos);
  buffer[-1] = pos-buffer;

  fwrite(buffer-1, pos-buffer+1, 1, fout);
  free(buffer-1); free(first->node); free(baseNode);
  if (debugFlag) fprintf(stderr, "pixel count = %d; nodeCount = %d lookup nodes = %d\n", tel, nodecount, lookuptypes);
  return;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void GifLoop ( FILE *  ,
unsigned  int 
)

Definition at line 663 of file whirlgif.c.

{

  fputc(0x21, fout);
  fputc(0xFF, fout);
  fputc(0x0B, fout);
  fputs("NETSCAPE2.0", fout);

  fputc(0x03, fout);
  fputc(0x01, fout);
  GifPutShort(repeats, fout); /* repeat count */

  fputc(0x00, fout); /* terminator */

  if(debugFlag) fprintf(stderr, "Wrote loop extension\n");
}

Here is the caller graph for this function:

void GifReadFile ( FILE *  ,
char *  ,
int   
)

Definition at line 255 of file whirlgif.c.

{
  FILE *fp;
  UBYTE *pix;
  int i, gifBlockSize;
  if ( (fp = fopen(fname, REABIN)) == 0) {
    fprintf(stderr, "Can't open %s for reading.\n", fname);
    TheEnd();
  }

  GifScreenHeader(fp, fout, firstImage);

   /* read until , separator */
  do {
    switch ( i = Xgetc(fp)) {
      case ',':
      case '\0':
       break;
      case '!':
       Xgetc(fp); /* the extension code */
       for ( i = Xgetc(fp); i > 0; i-- ) Xgetc(fp);
       while ( ( i = Xgetc(fp) ) > 0 ) {
         for ( i = i ; i > 0; i-- ) Xgetc(fp);
       }
       break;
      default:
       fclose(fp);
       if ( feof(fp) || i == ';' )
       TheEnd1("GifReadHeader: Unexpected End of File\n");
       TheEnd1("GifReadHeader: Unknown block type\n");
     }
   } while(i != ',');

  if(firstImage) {
    globscrn.m = gifscrn.m;
    globscrn.pixbits = gifscrn.pixbits;
    globscrn.bc = gifscrn.bc;
    if ( globscrn.m ) {
      for (i = gifMask[1+globscrn.pixbits]; i >= 0; i--) {
       gifGmap[i].cmap.red   = gifCmap[i].cmap.red;
       gifGmap[i].cmap.green = gifCmap[i].cmap.green;
       gifGmap[i].cmap.blue  = gifCmap[i].cmap.blue;
      }
    }
    if(loop) GifLoop(fout, loopcount);
  }

  ReadImageHeader(fp);

 /*** ACTION for IMAGE */

  if ( ( gifimage.m != 0 && globmap !=0 ) || minimize !=0 ) {
    UBYTE translator[256], *p, *po;
    int left, right, top, bot, i, j, k, l, hi, wi;
    long dsquare, dsquare1;
    hi = gifimage.height;
    wi = gifimage.width;
    if (( pix = (UBYTE *)malloc(wi * hi * sizeof(UBYTE)) ) == NULL )
        TheEnd1("No memory for image\n");
    if (debugFlag) fprintf(stderr, "  decoding picture no %d\n", count);
    GifDecode(fp, pix, gifimage);
    gifimage.i = 0;
    k = gifMask[1+globscrn.pixbits]; 
    l = gifMask[1+gifscrn.pixbits]; 
    for (j = 0; j <= l; j++) {
      dsquare = 256*256*3;
      for (i = 0; i <= k; i++) {
       dsquare1 = sq(gifGmap[i].cmap.red, gifCmap[j].cmap.red) +
                 sq(gifGmap[i].cmap.green, gifCmap[j].cmap.green) +
                 sq(gifGmap[i].cmap.blue,  gifCmap[j].cmap.blue);
       if ( dsquare1 < dsquare ) {
         dsquare = dsquare1;
         translator[j]=i;
         if ( dsquare == 0 ) break;
       }
      }
    }
    gifimage.m = 0;
    gifscrn.pixbits = globscrn.pixbits;
    if (debugFlag) fprintf(stderr, "  translating picture no %d\n", count);
    for (i = wi * hi -1; i>=0; i--)
      pix[i]=translator[pix[i]];
    if ( minimize != 0 && pixold != NULL  && hi == gifimageold.height
       && wi == gifimageold.width && gifimage.top == gifimageold.top
       && gifimage.left == gifimageold.left ) {
      gifimageold = gifimage;
/* First test from left to right, top to bottom */
      p = pix; po = pixold;
      for (i = 0; i < hi; i++ ) {
       for (j = 0; j < wi; j++ ) {
         if ( *p++ != *po++ ) {
           left = j; top=i;
           goto done;
         }
       }
      }
      if (FALSE) { 
done: /* i.e. a preliminary left and top found */ ;
      }
      else goto alike;
/* Then test from right to left, bottom to top */
      k=hi*wi-1; 
      p = &pix[k]; po = &pixold[k];
      for (i = hi-1; i >= top; i-- ) {
       for (j = wi -1; j >= 0; j-- ) {
         if ( *p-- != *po-- ) {
           right = j; bot=i;
           goto botfound;
         }
       }
      }
botfound:
/* The form of the differing area (not rectangle) may be slanted */
      if ( right < left ) {
       i = right; right = left; left = i;
      }
/* Now test between top and bottom at the left hand side */
      for (i = top+1; i <= bot; i++ ) {
       k= i * wi;
       p = &pix[k]; po = &pixold[k];
       for (j = 0; j < left; j++ ) {
         if ( *p++ != *po++ ) {
           left = j;
           break;
         }
       }
      }
/* Finally test between bottom and top at the right hand side */
      for (i = bot-1; i >= top; i-- ) {
       k= (i+1) * wi-1;
       p = &pix[k]; po = &pixold[k];
       for (j = wi-1; j > right; j-- ) {
         if ( *p-- != *po-- ) {
           right = j;
           break;
         }
       }
      }
      gifimage.left += left;
      gifimage.top += top;
      gifimage.width = right-left+1;
      gifimage.height = bot-top+1;
      WriteImageHeader(fout);
/* The rectangle containing diffs is transferred to the mem area of pixold */
      po = pixold;
      for (i = top; i <= bot; i++ ) {
       p = &pix[i * wi+left];
       for (j = left; j <= right; j++ ) {
         *po++ = *p++;
       }
      }
      GifEncode(fout, pixold, gifscrn.pixbits+1, gifimage.height * gifimage.width);
      if (debugFlag)
       fprintf(stderr, "  encoded: width= %d, height = %d, left = %d, top = %d\n",
          gifimage.width, gifimage.height, gifimage.left, gifimage.top);
    }
    else {
alike:
      WriteImageHeader(fout);
      gifimageold = gifimage;
      GifEncode(fout, pix, gifscrn.pixbits+1, gifimage.height * gifimage.width);
      if (debugFlag) fprintf(stderr, "  picture re-encoded\n");
/*   Undocumented feature:  If two subsequent images are alike, then
     send the whole image to the output stream (to keep the timing
     between frames, and not confuse the viewer with empty images) */
    }
    free(pixold);
    pixold = pix;
    fputc(0, fout);    /* block count of zero */
  }
  else {
    WriteImageHeader(fout);
    i = Xgetc(fp); fputc(i, fout); /* the LZW code size */
    while ( ( gifBlockSize = Xgetc(fp) ) > 0 ) {
      fputc(gifBlockSize, fout);
      while ( gifBlockSize-- > 0 ) fputc(Xgetc(fp),fout);
    }
    if ( gifBlockSize == 0 ) fputc(gifBlockSize, fout);
    else TheEnd1("GifPassing: Unexpected End of File\n");
  }

  fclose(fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GifScreenHeader ( FILE *  ,
FILE *  ,
int   
)

Definition at line 444 of file whirlgif.c.

{
  int temp, i;

  for(i = 0; i < 6; i++) {
    temp = Xgetc(fp);
    if(i == 4 && temp == '7') temp = '9';
    if (firstTime) fputc(temp, fout);
  }

  gifscrn.width = GifGetShort(fp);
  gifscrn.height = GifGetShort(fp);
  temp = Xgetc(fp);
  if (firstTime) {
    GifPutShort(gifscrn.width, fout);
    GifPutShort(gifscrn.height, fout);
    fputc(temp, fout);
  }
  gifscrn.m  =  temp & 0x80;
  gifscrn.cres   = (temp & 0x70) >> 4;
  gifscrn.pixbits =  temp & 0x07;

  gifscrn.bc  = Xgetc(fp);
  if (firstTime) {
    if (debugFlag) fprintf(stderr, "First Time ... ");
    if(GifBgcolor) gifscrn.bc = GifBgcolor & 0xff;
    fputc(gifscrn.bc, fout);
  }

  temp = Xgetc(fp);
  if (firstTime)  {
    fputc(temp, fout);
    if ( minimize && gifscrn.bc == 0 ) {
      /* Set a pseudo screen filled with the background color.
        This is only done for background color index == 0 because
        of Netscape and I.E.'s strange handling of backgrounds not
        covered by an image.
      */
      temp = gifscrn.width * gifscrn.height;
      if (( pixold = (UBYTE *)malloc(temp * sizeof(UBYTE)) ) == NULL )
           TheEnd1("No memory for image\n");
      if (debugFlag) fprintf(stderr, "BACKGROUND = %d\n", gifscrn.bc);
      while (temp > 0) pixold[--temp] = 0; /* gifscrn.bc; */
      gifimageold.left = gifimageold.top = 0;
      gifimageold.width = gifscrn.width;
      gifimageold.height = gifscrn.height;
      gifimageold.pixbits = gifscrn.pixbits;
    }
  }
  imagec = gifPtwo[(1+gifscrn.pixbits)];

  if (debugFlag)
    fprintf(stderr, "Screen #%d: %dx%dx%d m=%d cres=%d bkgnd=%d pix=%d\n",
      count, gifscrn.width, gifscrn.height, imagec, gifscrn.m, gifscrn.cres,
      gifscrn.bc, gifscrn.pixbits);

  if (gifscrn.m) {
    for(i = 0; i < imagec; i++) {
      gifCmap[i].cmap.red   = temp = Xgetc(fp);
      if (firstTime) fputc(temp, fout);
      gifCmap[i].cmap.green = temp = Xgetc(fp);
      if (firstTime) fputc(temp, fout);
      gifCmap[i].cmap.blue  = temp = Xgetc(fp);
      if (firstTime) fputc(temp, fout);

    if(firstTime && (global.trans.type==TRANS_RGB && global.trans.valid==0) )
      if (global.trans.red == gifCmap[i].cmap.red &&
         global.trans.green == gifCmap[i].cmap.green &&
         global.trans.blue == gifCmap[i].cmap.blue) {
       if(debugFlag > 1) fprintf(stderr, " Transparent match at %d\n", i);
       global.trans.map = i;
       global.trans.valid = 1;
      }
      else
       if(debugFlag > 1) fprintf(stderr, "No transp. RGB=(%x,%x,%x)\n",
        gifCmap[i].cmap.red, gifCmap[i].cmap.green, gifCmap[i].cmap.blue);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

UBYTE* GifSendData ( UBYTE ,
int  ,
UBYTE  
)
void ReadImageHeader ( FILE *  )

Definition at line 524 of file whirlgif.c.

{
  int tnum, i, flag;

  gifimage.left  = GifGetShort(fp);
  if(global.left) gifimage.left += global.left;

  gifimage.top   = GifGetShort(fp);
  if(global.top) gifimage.top += global.top;

  gifimage.width     = GifGetShort(fp);
  gifimage.height = GifGetShort(fp);
  flag = Xgetc(fp);

  gifimage.i       = flag & 0x40;
  gifimage.pixbits = flag & 0x07;
  gifimage.m       = flag & 0x80;

  imagex = gifimage.width;
  imagey = gifimage.height;
  tnum = gifPtwo[(1+gifimage.pixbits)];
  if (debugFlag > 1)
    fprintf(stderr, "Image: %dx%dx%d (%d,%d) m=%d i=%d pix=%d \n",
      imagex, imagey, tnum, gifimage.left, gifimage.top,
      gifimage.m, gifimage.i, gifimage.pixbits);

   /* if there is an image cmap then read it */
  if (gifimage.m) {
    if(debugFlag>1)
      fprintf(stderr, "DEBUG:Transferring colormap of %d colors\n",
       imagec);
  /*
   * note below assignment, it may make the subsequent code confusing
   */
    gifscrn.pixbits = gifimage.pixbits;

    for(i = 0; i < tnum; i++) {
      gifCmap[i].cmap.red   = Xgetc(fp);
      gifCmap[i].cmap.green = Xgetc(fp);
      gifCmap[i].cmap.blue  = Xgetc(fp);
    }
  }
  gifimage.m = 0;
  if ( globscrn.m && globscrn.pixbits == gifscrn.pixbits ) {
    for (i = gifMask[1+globscrn.pixbits]; i >= 0; i--) {
      if (gifGmap[i].cmap.red  != gifCmap[i].cmap.red ||
      gifGmap[i].cmap.green != gifCmap[i].cmap.green ||
      gifGmap[i].cmap.blue != gifCmap[i].cmap.blue ) {
       gifimage.m = 0x80;
       break;
      }
    }
  }
  else gifimage.m = 0x80;
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetOffset ( char *  )

Definition at line 708 of file whirlgif.c.

{
  int npar, offX, offY;
  char sep;
  if ( (npar = sscanf(string, "%d%c%d", &offX, &sep, &offY)) == 3 ) {
    /* set the offset */
    global.left = offX;
    global.top = offY;
    if(debugFlag > 1) fprintf(stderr, "Offset set to %d,%d\n",
    global.left, global.top);
    return;
  }
  fprintf(stderr, "Offset string: '%s'; fields = %d\n", string, npar);
  TheEnd1("Couldn't parse offset values.\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

long sq ( UBYTE  ,
UBYTE   
)

Definition at line 94 of file whirlgif.c.

{
  return((i-j)*(i-j));
}

Here is the caller graph for this function:

void TheEnd ( )

Definition at line 724 of file whirlgif.c.

{
 exit(0);
}

Here is the caller graph for this function:

void TheEnd1 ( char *  )

Definition at line 729 of file whirlgif.c.

{
 fprintf(stderr, "Image #%d: %s", count, p);
 TheEnd();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Usage ( )

Definition at line 735 of file whirlgif.c.

{
  fprintf(stderr, "\nUsage: whirlgif %s\n %s\n %s\n",
       "[-o outfile] [-loop [count]] [-time #delay]",
       "\t-disp [ none | back | prev | not ]",
       "\t[ -i listfile] file1 [ -time #delay] file2 ...");
  exit(0);
}

Here is the caller graph for this function:

void WriteImageHeader ( FILE *  )

Definition at line 581 of file whirlgif.c.

{
  int temp, i, flag;
  /* compute a Gif_GCL */

  fputc(0x21, fout);
  fputc(0xF9, fout);
  fputc(0x04, fout);

  flag = global.disposal <<2;
  if(global.time) flag |= 0x80;
  if(global.trans.type == TRANS_RGB && global.trans.valid == 0)
       gifimage.m = 0x80;

  temp = global.trans.map;
  if (gifimage.m != 0 && global.trans.type == TRANS_RGB ) {
    temp = 0; /* set a default value, in case nothing found */
    for (i = gifMask[1+gifscrn.pixbits]; i >= 0; i--) {
      if(global.trans.red == gifCmap[i].cmap.red &&
      global.trans.green == gifCmap[i].cmap.green &&
      global.trans.blue == gifCmap[i].cmap.blue) {
       if(debugFlag > 1) fprintf(stderr, " Transparent match at %d\n", i);
       temp = i;
       flag |= 0x01;
      }
    }
  }
  else if(global.trans.valid) flag |= 0x01;
  fputc(flag, fout);

  GifPutShort(global.time, fout); /* the delay speed - 0 is instantaneous */

  fputc(temp, fout); /* the transparency index */
  if(debugFlag > 1) {
    fprintf(stderr, "GCL: delay %d", global.time);
    if(flag && 0x1) fprintf(stderr, " Transparent: %d", temp);
    fputc('\n', stderr);
  }

  fputc(0, fout);
  /* end of Gif_GCL */

  fputc(',', fout); /* image separator */
  GifPutShort(gifimage.left  , fout);
  GifPutShort(gifimage.top   , fout);
  GifPutShort(gifimage.width , fout);
  GifPutShort(gifimage.height, fout);
  fputc(gifscrn.pixbits | gifimage.i | gifimage.m, fout);

  if ( gifimage.m ) {
    for(i = 0; i < imagec; i++) {
      fputc(gifCmap[i].cmap.red,   fout);
      fputc(gifCmap[i].cmap.green, fout);
      fputc(gifCmap[i].cmap.blue,  fout);
    }
    if(debugFlag) fprintf(stderr, "Local %d color map for picture #%d\n",
                        imagec, count);
  }
}

Here is the caller graph for this function:

UBYTE Xgetc ( FILE *  )

Definition at line 744 of file whirlgif.c.

{
  int i;
  if ( ( i = fgetc(fin) ) == EOF ) {
    TheEnd1("Unexpected EOF in input file\n"); 
  }
  return(i & 0xff);
}

Here is the call graph for this function:

Here is the caller graph for this function: