Algorithm 版 (精华区)

发信人: lofe ()感激生活(), 信区: Algorithm
标  题: LZW - COMMLZW.C
发信站: 哈工大紫丁香 (Sun Sep  3 16:07:37 2000), 转信


/* Added "_fmode=O_BINARY;" to main NEV */
/* COMMLZW - ROUTINES COMMON TO LZWCOM AND LZWUNC                       */
#include "stdio.h"
#include "debug.h"
#define FALSE    0
#define TRUE     !FALSE
#define TABSIZE  4096
#define NO_PRED  0xFFFF
#define EMPTY    0xFFFF
#define NOT_FND  0xFFFF
#define SECTSIZE 128
#define CTRLZ '\032' /* ascii end of file */
extern struct entry {
  char used;
  unsigned int next;                    /* index of next in collision list */
  unsigned int predecessor;             /* 12 bit code                  */
  unsigned char follower;
} string_tab[TABSIZE];
extern char is_a_con;
/* h uses the 'mid-square' algorithm. I.E. for a hash val of n bits     */
/* hash = middle binary digits of (key * key).  Upon collision, hash    */
/* searches down linked list of keys that hashed to that key already.   */
/* It will NOT notice if the table is full. This must be handled        */
/* elsewhere                                                            */
unsigned h(pred,foll)
/* returns the mid square of pred + foll                                */
        unsigned int pred; unsigned char foll;
{
  long temp, local;             /* 32 bit receiving field for local^2   */
  local = (pred + foll) | 0x0800;
  temp = local * local;
  local = (temp >> 6) & 0x0FFF;
  return local;                 /* middle 12 bits of result             */
}
unsigned eolist(index)
/* return last element in a collision list                              */
unsigned int index;
{
  register int temp;
  while ( 0 != (temp = string_tab[index].next) )
    index = temp;
  return index;
}
unsigned hash(pred,foll,update)
unsigned int pred; unsigned char foll; int update;
{
  register unsigned int local, tempnext;
  register struct entry *ep;
  local = h(pred,foll);
  if ( !string_tab[local].used )
    return local;
  else {
  /* if collision has occured                                           */
    local = eolist(local);
  /* search for free entry from local + 101 */
    tempnext = (local + 101) & 0x0FFF;
    ep = &string_tab[tempnext];                 /* initialize pointer   */
    while ( ep->used ) {
      ++tempnext;
      if ( tempnext == TABSIZE ) {
        tempnext = 0;           /* handle wrap to beginning of table    */
        ep = string_tab;        /* address of first element of table    */
      } else
        ++ep;                   /* point to next element in table       */
    }

    /* put new tempnext into last element in collision list             */
    if ( update )               /* if update requested                  */
      string_tab[local].next = tempnext;
    return tempnext;
  }
}
/* unhash uses the 'next' field to go down the collision tree to find   */
/* the entry corresponding to the passed key                            */
/* passed key and returns either the matching entry # or NOT_FND        */
unsigned unhash(pred,foll)
unsigned int pred; unsigned char foll;
{
  register unsigned int local, offset;
  register struct entry *ep;    /* pointer to current entry             */
  local = h(pred,foll);         /* initial hash                         */
  loop:
    ep = &string_tab[local];
    if ( (ep->predecessor == pred) && (ep->follower == foll) )
      return local;
    if ( ep->next == 0 )
      return NOT_FND;
    local = ep->next;
  goto loop;
}
init_tab() {
  register unsigned int i;
  setmem((char *)string_tab,sizeof(string_tab),0);
  for (i = 0; i <= 255; i++) {
    upd_tab(NO_PRED,i);
  }
}
#define UPDATE TRUE
upd_tab(pred,foll)
  unsigned int pred, foll;
{
  register struct entry *ep;    /* pointer to current entry     */
  /* calculate offset just once */
  ep = &string_tab[ hash(pred,foll,UPDATE) ];
  ep->used = TRUE;
  ep->next = 0;
  ep->predecessor = pred;
  ep->follower = foll;
}
unsigned int inbuf = EMPTY;
unsigned int outbuf = EMPTY;
/* getcode and putcode 'gallop' through input and output - they either  */
/* output two bytes or one depending on the contents of the buffer.     */
getcode(fd)
int fd;     {
  register unsigned int localbuf, returnval;
  if (EMPTY == inbuf) {         /* On code boundary                     */
    if (EOF == (localbuf = readc(fd)) ) {
                                /* H L1 byte - on code boundary         */
      return EOF;
    }
    localbuf &= 0xFF;
        if (EOF == (inbuf = readc(fd)) ) {  /* L0 Hnext                     */
      return EOF;       /* The file should always end on code boundary  */
    }
    inbuf &= 0xFF;
        DEBUGGER(fprintf(stderr,"%x and %x read\n",localbuf,inbuf);)
    returnval = ((localbuf << 4) & 0xFF0) + ((inbuf >> 4) & 0x00F);
    DEBUGGER(fprintf(stderr,"returnval = %x\n",returnval);)
    inbuf &= 0x000F;
  } else {                      /* buffer contains nibble H             */
    if (EOF == (localbuf = readc(fd)) )
      return EOF;
    localbuf &= 0xFF;
    DEBUGGER(fprintf(stderr,"%x read, inbuf = %x\n",localbuf,inbuf);)
    returnval = localbuf + ((inbuf << 8) & 0xF00);
    inbuf = EMPTY;
    DEBUGGER(fprintf(stderr,"returnval = %x\n",returnval);)
  }
  return returnval;
}
putcode(fd,code)
unsigned int fd,code;     {
  register int localbuf;
  if (EMPTY == outbuf) {
    writec( fd,((code >> 4) & 0xFF));    /* H L1                        */
    outbuf = code & 0x000F;     /* L0                                   */
  } else {
    writec( fd, ( ((outbuf << 4) & 0xFF0) + ((code >> 8) & 0x00F) ) );
                                /* L0prev H                             */
    writec( fd,(code & 0x00FF));        /* L1 L0                        */
    outbuf = EMPTY;
  }
}
int limit;
char insector[SECTSIZE];
int current = 0;
int sector = 0;
readc(fd)
int fd;
{
  register int returnval;
  if (current == 0)
  {
    if ( 0 == (limit = read(fd,insector,SECTSIZE)) )
        {
      return (EOF);
    } else
        {
          if (!is_a_con)
        if ( (++sector % 80) )
          putchar('.');
        else
                {
          putchar('.');
          putchar('\n');
        }
    }
  }
  returnval = (insector[current++]);
  if (current == limit) {
    current = 0;
  }
  return (returnval & 0xFF);
}
char outsector[SECTSIZE];
int outcurrent = 0;
writec(fd,c)
int fd,c;   {
  outsector[outcurrent++] = ( (char) c);
  if (outcurrent == SECTSIZE) {
    outcurrent = 0;
    write(fd,outsector,SECTSIZE);
  }
}
/* flushout makes sure fractional output buffer gets written */
flushout(fd)
int fd; {
  if (EMPTY != outbuf)  /* if there's still a byte waiting to be packed */
                                                /* stuff it in the buffer */
        outsector[outcurrent++] = (outbuf << 4) & 0xFF0;        
  DEBUGGER(fprintf(stderr,"\nflushout - writing %d bytes\n",outcurrent);)
  write(fd,outsector,outcurrent);
}

--
████████████████████████
█                                            █   http://inf.home.chinaren.net
█ HAPPY NEW MILLENNIUM! █   http://jtlab.163.net
█                                 Yours,     █
█                                     Anya   █   inf@chinaren.com
████████████████████████
※ 修改:.haojs 于 Sep  3 16:05:09 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
※ 修改:·lofe 於 09月03日16:10:50 修改本文·[FROM: 202.118.226.15]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.108毫秒