📄 compress.c
字号:
/* ********************************************************************** * * <copyright> * * BBN Technologies, a Verizon Company * 10 Moulton Street * Cambridge, MA 02138 * (617) 873-8000 * * Copyright (C) BBNT Solutions LLC. All rights reserved. * * </copyright> * ********************************************************************** * * $Source: /cvs/distapps/openmap/src/cserver/toolLib/src/compress.c,v $ * $RCSfile: compress.c,v $ * $Revision: 1.2 $ * $Date: 2004/01/26 19:07:10 $ * $Author: dietrick $ * * ********************************************************************** *//* * compress.c * * File compression code derived from compress 4.0, the public * domain file compression utility. Modified to strip out variants * we will not need, use Diamond style and throw exceptions * instead of exiting on error. */#include <stdio.h>#include <ctype.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include "style.h"#include "error_hand.h"extern int errno;/* #define MAC_OS_X */#ifdef MAC_OS_X extern __const int sys_nerr; /* perror(3) external variables */ extern __const char *__const sys_errlist[];#else extern char *sys_errlist[]; extern int sys_nerr;#endif#ifndef min#define min(a,b) ((a>b) ? b : a)#endif/* * Various defines taken from the sources to compress version 4.0; since * we don't have to run on all the machines compress does, we have stripped * all of the options that aren't required for our purposes. */#define BITS 16#define HSIZE 69001#define INIT_BITS 9 /* initial number of bits/code */#define MAXCODE(bits) ((1 << (bits)) - 1)#define MAXMAXCODE (1L << BITS) /* should NEVER generate this */#define BIT_MASK 0x1f#define BLOCK_MASK 0x80#define CHECK_GAP 10000 /* ratio check interval */typedef long code_t;/* * the next two codes should not be changed lightly, as they must not * lie within the contiguous general code space. */#define FIRST 257 /* first free entry */#define CLEAR 256 /* table clear output code *//* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type * as the codetab. The tab_suffix table needs 2**BITS characters. We * get this from the beginning of htab. The output stack uses the rest * of htab, and contains characters. There is plenty of room for any * possible stack (stack used to be 8000 characters). */#define htabof(i) htab[i]#define codetabof(i) codetab[i]#define tab_prefixof(i) codetabof(i)#define tab_suffixof(i) ((u_char *)(htab))[i]#define de_stack ((u_char *)&tab_suffixof(1<<BITS))static u_char g_magic[] = {"\037\235"}; /* 1F 9D */static int n_bits; /* number of bits/code */static code_t maxcode; /* maximum code, given n_bits */static long htab[HSIZE];static u_short codetab[HSIZE];static code_t free_ent; /* first unused entry */static int offset;static long in_count; /* length of input */static long bytes_out; /* length of compressed output *//* * block compression parameters -- after all codes are used up, * and compression rate changes, start over. */static int clear_flg;static long ratio;static long checkpoint;static FILE *in_fp;static FILE *out_fp;static code_t getcode();#ifdef DO_COMPRESSstatic void output();static void clear_hash();static void clear_block();#endif/****************************************************************************** * decompress(): decompress input file pointer to output file pointer * * May throw EX_FAILURE if bad input is supplied, or EX_WRITE * if write errors occur on output. * * Lifted from the public domain Compress 4.0 * */int decompress(in, out, out_ptr, out_bytes)FILE *in;FILE *out;unsigned char *out_ptr;int out_bytes;{ register u_char *stackp; register int finchar; register code_t code, oldcode, incode; int usebits; int bytes_written = 0; int c; /* * Make sure input is compressed. */ in_fp = in; out_fp = out; if (((c = getc(in_fp)) != (g_magic[0] & 0xFF)) || (getc(in_fp) != (g_magic[1] & 0xFF))) { if (c == EOF) WARNING_MESSAGE("Truncated file passed to decompress."); else WARNING_MESSAGE("Input to decompress not in compressed format."); return -1; } usebits = getc(in_fp) & BIT_MASK; if (usebits != BITS) { sprintf(msgBuf, "Expected input with %d bit compression, but got %d bit instead.", BITS, usebits); WARNING_MESSAGE(msgBuf); } /* * As above, initialize the first 256 entries in the table. */ maxcode = MAXCODE(n_bits = INIT_BITS); for (code = 255; code >= 0; code--) { tab_prefixof(code) = 0; tab_suffixof(code) = (u_char) code; } clear_flg = 0; free_ent = FIRST; finchar = oldcode = getcode(); if (oldcode == -1) /* EOF already? */ return(0); /* Get out of here */ bytes_written++; if (out_fp != NULL) { putc((char)finchar, out_fp); /* first code must be 8 bits = char */ /* t_ferror(out_fp); */ } else if (bytes_written < out_bytes) { *out_ptr++ = (unsigned char)finchar; } else { WARNING_MESSAGE("No more room to decompress into buffer, finchar."); return -1; } stackp = de_stack; while ((code = getcode()) > -1) { if ((code == CLEAR) && BLOCK_MASK) { for (code = 255; code >= 0; code--) tab_prefixof(code) = 0; clear_flg = 1; free_ent = FIRST - 1; if ((code = getcode()) == -1) /* O, untimely death! */ break; } incode = code; /* * Special case for KwKwK string. */ if (code >= free_ent) { *stackp++ = finchar; code = oldcode; } /* * Generate output characters in reverse order */ while (code >= 256) { *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = finchar = tab_suffixof(code); /* * And put them out in forward order */ if (out_fp != NULL) { do { putc(*--stackp, out_fp); bytes_written++; } while (stackp > de_stack); } else { do { if (++bytes_written > out_bytes) { WARNING_MESSAGE( "No more room to decompress into buffer, stackp."); } *out_ptr++ = *--stackp; } while (stackp > de_stack); } /* * Generate the new entry. */ if ((code = free_ent) < MAXMAXCODE) { tab_prefixof(code) = (u_short) oldcode; tab_suffixof(code) = finchar; free_ent = code + 1; } /* * Remember previous code. */ oldcode = incode; } if (out_fp != NULL) fflush(out_fp); /* Flush */ return (bytes_written);}/****************************************************************************** * getcode(): Read one code from input file pointer. If EOF, return -1. */static char buf[BITS];#ifndef vaxu_char lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};u_char rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};#endif /* vax */static code_t getcode(){ /* * On the VAX, it is important to have the register declarations in * exactly the order given, or the asm will break. */ register code_t code; static int gc_offset = 0, size = 0; static u_char gc_buf[BITS]; register int r_off, bits; register u_char *bp = gc_buf; if (clear_flg > 0 || gc_offset >= size || free_ent > maxcode) { /* * If the next entry will be too big for the current code size, then * we must increase the size. This implies reading a new buffer * full, too. */ if (free_ent > maxcode) { n_bits++; if (n_bits == BITS) maxcode = MAXMAXCODE; /* won't get any bigger now */ else maxcode = MAXCODE(n_bits); } if (clear_flg > 0) { maxcode = MAXCODE(n_bits = INIT_BITS); clear_flg = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -