Algorithm 版 (精华区)

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



/* LZWUNC - FILE UNCOMPRESSOR UTILITY                                   */
#include "stdio.h"
#include "fcntl.h"
#include "sgtty.h"
#include "debug.h"
#define FALSE    0
#define TRUE     !FALSE
#define TABSIZE  4096
#define STACKSIZE TABSIZE
#define NO_PRED  0xFFFF
#define EMPTY    0xF000
#define NOT_FND  0xFFFF
#define NO_UPDATE FALSE
#define UEOF ((unsigned)EOF)
struct entry {
  char used;
  unsigned int next;        /* hi bit is 'used' flag                        */
  unsigned int predecessor; /* 12 bit code                  */
  unsigned char follower;
} string_tab[TABSIZE];
char is_a_con = FALSE;  /* suppresses printing dots during operation if
                           outfd is the console                         */
/*   routines common to compress and decompress, contained in CommLZW.c */
unsigned hash();
unsigned unhash();
unsigned getcode();
putcode();
init_tab();
upd_tab();
main(argc,argv)
int argc; char *argv[];
{
  register unsigned int c, tempc, code, oldcode, incode, finchar,lastchar;
  char unknown = FALSE;
  int code_count = TABSIZE - 256;
  int infd, outfd;
  register struct entry *ep;
  _fmode = O_BINARY;
  if (3 != argc) {
    fprintf(stderr,"Usage : lzwunc squeezefilename newfilename\n");
    exit(0);
  }
  if ( -1 == (infd = open( *++argv, O_RDONLY )) ) {
    fprintf(stderr,"Cant open %s\n", *argv);
    exit(0);
  }
  if ( -1 == (outfd = creat(*++argv,0666)) ) {
    fprintf(stderr,"Cant create %s\n",*argv);
    exit(0);
  }
  is_a_con = isatty(outfd);             /* suppress dots if it is        */
  init_tab();                           /* set up atomic code definitions*/
  code = oldcode = getcode(infd);
  c = string_tab[code].follower;        /* first code always known      */
  writec(outfd,c);
  DEBUGGER(\
           putc(c,stderr);\
           fprintf(stderr,"\n%x\n",code);\
  )
  finchar = c;
  while ( UEOF != (code = incode = getcode(infd)) ) {
        DEBUGGER(fprintf(stderr,"\n%x\n",code);)
    ep = &string_tab[code];             /* initialize pointer           */
    if ( !ep->used )
        {                  /* if code isn't known          */
          lastchar = finchar;
          code = oldcode;
          unknown = TRUE;
      ep = &string_tab[code];           /* re-initialize pointer        */
    }
    while (NO_PRED != ep->predecessor)
        {
      push( ep->follower);              /* decode string backwards into */
                                        /* stack                        */
      code = ep->predecessor;
      ep = &string_tab[code];
    }
    finchar = ep->follower;
    /* above loop terminates, one way or another, with                  */
    /* string_tab[code].follower = first char in string                 */
    writec(outfd, finchar);
    DEBUGGER(fputc(finchar,stderr);)
    /* pop anything stacked during code parsing                         */
    while ( EMPTY != (tempc = pop()) )
        {
      writec(outfd,tempc);
          DEBUGGER(\
        putc(tempc,stderr);\
          )
    }
    if ( unknown ) {                  /* if code isn't known          */
      writec(outfd,finchar = lastchar); /* the follower char of last    */
          unknown = FALSE;
          DEBUGGER(\
                putc(lastchar,stderr);\
                fprintf(stderr,"\nunknown code\n");\
          )
        }
    if ( code_count )
        {
      upd_tab(oldcode,finchar);
      --code_count;
          DEBUGGER(fprintf(stderr,"\nAdding %x,%c = %x\n",\
                                oldcode,finchar,unhash(oldcode,finchar));)
    }
    oldcode = incode;
  }
  flushout(outfd);      /* write out fractional buffer, if any          */
  exit(0);              /* close all files and quit                     */
}
char stack[STACKSIZE];  /* stack for pushing and popping characters     */
int sp = 0;             /* current stack pointer                        */
push(c)
int c;
{
  stack[sp] = ((char) c);/* coerce passed integer into a character      */
  ++sp;
  if (sp >= STACKSIZE) {
    fprintf(stderr,"Stack overflow, aborting\n");
    exit(1);            /* non-0 exit parameter terminates batch job    */
  }
}
pop()
{
  if (sp > 0)
  {
    --sp;               /* push leaves sp pointing to next empty slot   */
    return ( (int) stack[sp] ); /* make sure pop returns char           */
  }
  else
    return EMPTY;
}


--
████████████████████████
█                                            █   http://inf.home.chinaren.net
█ HAPPY NEW MILLENNIUM! █   http://jtlab.163.net
█                                 Yours,     █
█                                     Anya   █   inf@chinaren.com
████████████████████████
※ 修改:.haojs 于 Sep  3 16:04:55 修改本文.[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:49 修改本文·[FROM: 202.118.226.15]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:4.090毫秒