Back to index

wims  3.65+svn20090927
Defines | Functions | Variables
gifencod.c File Reference
#include "whirlgif.h"

Go to the source code of this file.

Defines

#define BLOKLEN   255
#define BUFLEN   1000

Functions

void GifEncode (FILE *fout, UBYTE *pixels, int depth, int siz)
void ClearTree (int cc, GifTree *root)
char * AddCodeToBuffer (int code, short n, char *buf)

Variables

int chainlen = 0
int maxchainlen = 0
int nodecount = 0
int lookuptypes = 0
int nbits
short need = 8
GifTreeempty [256]
GifTree GifRoot = {LOOKUP, 0, 0, empty, NULL, NULL}
GifTreetopNode
GifTreebaseNode
GifTree ** nodeArray
GifTree ** lastArray
unsigned int debugFlag
unsigned int verbose
int count

Define Documentation

#define BLOKLEN   255

Definition at line 57 of file gifencod.c.

#define BUFLEN   1000

Definition at line 58 of file gifencod.c.


Function Documentation

char* AddCodeToBuffer ( int  code,
short  n,
char *  buf 
)

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 ClearTree ( int  cc,
GifTree root 
)

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 GifEncode ( FILE *  fout,
UBYTE pixels,
int  depth,
int  siz 
)

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:


Variable Documentation

Definition at line 63 of file gifencod.c.

int chainlen = 0

Definition at line 61 of file gifencod.c.

int count

Definition at line 36 of file modstat.c.

unsigned int debugFlag

Definition at line 71 of file whirlgif.c.

GifTree* empty[256]

Definition at line 63 of file gifencod.c.

Definition at line 63 of file gifencod.c.

Definition at line 63 of file gifencod.c.

int lookuptypes = 0

Definition at line 61 of file gifencod.c.

int maxchainlen = 0

Definition at line 61 of file gifencod.c.

int nbits

Definition at line 61 of file gifencod.c.

short need = 8

Definition at line 62 of file gifencod.c.

Definition at line 63 of file gifencod.c.

int nodecount = 0

Definition at line 61 of file gifencod.c.

Definition at line 63 of file gifencod.c.

unsigned int verbose