DOS SC2 .ani (frame-pack) unpacker; first version

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1542 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-02-17 01:26:11 +00:00
parent 866b2159f4
commit 7dcdc701bc
7 changed files with 2314 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
########################################################################
# This is a GNU makefile - tested on CYGWIN and Linux
#
# You may need to compile or install libpng and/or zlib before
# compiling this.
#
TARGET = undani
# These flags are needed to get it to compile with libpngX.dll on CYGWIN
CYGWINFLAGS = -DPNG_USE_DLL
#CYGWINFLAGS =
PNGFLAGS = -I.
CC = gcc
CFLAGS = -W -Wall -O0 # -g
LIBS = -L/usr/local/lib -lpng -lm
LDFLAGS=
BINS = $(TARGET) $(TARGET).exe
SRCS = undani.c lzhuf.c
OBJS = undani.o lzhuf.o
.SUFFIXES: .c .o
.c.o:
$(CC) -c $(CFLAGS) -o $@ $*.c $(PNGFLAGS) $(CYGWINFLAGS)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) -o $(TARGET) $(OBJS) $(LIBS) $(LDFLAGS)
clean:
rm -f $(BINS) *.o
+15
View File
@@ -0,0 +1,15 @@
/* Dummy compile-time configuration options
* Only used when compiling in MS VC++ using UQM's getopt.c
*/
#ifndef _CONFIG_H
#define _CONFIG_H
/* Define if words are stored with the most significant byte first */
#undef WORDS_BIGENDIAN
/* Defined if your system has getopt.h */
#undef HAVE_GETOPT_H
#endif /* _CONFIG_H */
+682
View File
@@ -0,0 +1,682 @@
/**************************************************************************
lzhuf.c
written by Haruyasu Yoshizaki 1988/11/20
some minor changes 1989/04/06
comments translated by Haruhiko Okumura 1989/04/07
getbit and getbyte modified 1990/03/23 by Paul Edwards
so that they would work on machines where integers are
not necessarily 16 bits (although ANSI guarantees a
minimum of 16). This program has compiled and run with
no errors under Turbo C 2.0, Power C, and SAS/C 4.5
(running on an IBM mainframe under MVS/XA 2.2). Could
people please use YYYY/MM/DD date format so that everyone
in the world can know what format the date is in?
external storage of filesize changed 1990/04/18 by Paul Edwards to
Intel's "little endian" rather than a machine-dependant style so
that files produced on one machine with lzhuf can be decoded on
any other. "little endian" style was chosen since lzhuf
originated on PC's, and therefore they should dictate the
standard.
initialization of something predicting spaces changed 1990/04/22 by
Paul Edwards so that when the compressed file is taken somewhere
else, it will decode properly, without changing ascii spaces to
ebcdic spaces. This was done by changing the ' ' (space literal)
to 0x20 (which is the far most likely character to occur, if you
don't know what environment it will be running on.
*****************************************************************************
This code was found at http://www.cs.umu.se/~isak/Snippets
with the following Copyright notice. A lot information in the notice
is quite outdated by today (at least FidoNet is pretty dead).
*****************************************************************************
Welcome to SNIPPETS!
All the code I put into SNIPPETS for distribution is Public Domain or free
to the best that I can determine. What this means is that:
1. I know or can contact the original author(s) to verify the presumed
copyright ownership, and
2. The work bears an explicit Public Domain notice, or
3. The work is copyrighted but includes a free use license, or
4. The work was published without a copyright notice prior to the effective
date of the new copyright law.
This has been occasionally annoying when I've had to pass up some useful
piece of code because it's questionable whether anyone can use it without
incurring liability (distributing someone else's property makes me an
accessory, doncha know).
Since SNIPPETS includes both public domain and free code, be sure to
carefully read each header for any free license restrictions which may
apply.
Distribution:
Starting with the December 1992 version, SNIPPETS is distributed in two
files:
SNIPmmyy.LZH is the full SNIPPETS collection.
SNPDmmyy.LZH contains only the files changes since the last release.
SNIPPETS is distributed through the FidoNet Programmer's Distribution
Network (PDN - see the file PDN.LST for a list of PDN sites and further
information. The SNIPPETS files are also available from my "home" BBS, Comm
Port One, (713) 980-9671, FidoNet address 1:106/2000 using the "magic" F'req
names of "SNIPPETS" and "SNIPDIFF". Various Internet mirror sites also carry
SNIPPETS, but I'm not sure which ones have it an any given time. One place to
try is oak.oakland.edu in /pub/msdos/c.
...Bob Stout
------------------------------- Enjoy! -----------------------------------
*****************************************************************************
made into lib-like reentrant by Alex Volkov 20050208
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "lzhuf.h"
static size_t h_read(lzhuf_session_t* sess, void* buf, size_t size, size_t count)
{
if (!sess->read)
return 0;
return sess->read(buf, size, count, sess->infile);
}
static size_t h_write(lzhuf_session_t* sess, const void* buf, size_t size, size_t count)
{
if (!sess->write)
return 0;
return sess->write(buf, size, count, sess->outfile);
}
static int h_putc(lzhuf_session_t* sess, unsigned char c)
{
return h_write(sess, &c, sizeof(c), 1) == 1 ? c : EOF;
}
static int h_getc(lzhuf_session_t* sess)
{
unsigned char c;
return h_read(sess, &c, sizeof(c), 1) == 1 ? c : EOF;
}
static int h_seek(lzhuf_session_t* sess, lzhuf_handle_t h, long ofs, int origin)
{
if (!sess->seek)
return -1;
return sess->seek(h, ofs, origin);
}
static long h_tell(lzhuf_session_t* sess, lzhuf_handle_t h)
{
if (!sess->tell)
return -1;
return sess->tell(h);
}
static void InitTree(lzhuf_session_t* sess) /* initialize trees */
{
int i;
for (i = LZHUF_N + 1; i <= LZHUF_N + 256; i++)
sess->rson[i] = LZHUF_NIL; /* root */
for (i = 0; i < LZHUF_N; i++)
sess->dad[i] = LZHUF_NIL; /* node */
}
static void InsertNode(lzhuf_session_t* sess, int r) /* insert to tree */
{
int i, p, cmp;
unsigned char *key;
unsigned c;
cmp = 1;
key = &sess->text_buf[r];
p = LZHUF_N + 1 + key[0];
sess->rson[r] = sess->lson[r] = LZHUF_NIL;
sess->match_length = 0;
for ( ; ; ) {
if (cmp >= 0) {
if (sess->rson[p] != LZHUF_NIL)
p = sess->rson[p];
else {
sess->rson[p] = r;
sess->dad[r] = p;
return;
}
} else {
if (sess->lson[p] != LZHUF_NIL)
p = sess->lson[p];
else {
sess->lson[p] = r;
sess->dad[r] = p;
return;
}
}
for (i = 1; i < LZHUF_F; i++)
if ((cmp = key[i] - sess->text_buf[p + i]) != 0)
break;
if (i > LZHUF_THRESHOLD) {
if (i > sess->match_length) {
sess->match_position = ((r - p) & (LZHUF_N - 1)) - 1;
if ((sess->match_length = i) >= LZHUF_F)
break;
}
if (i == sess->match_length) {
if ((c = ((r - p) & (LZHUF_N-1)) - 1) < (unsigned)sess->match_position) {
sess->match_position = c;
}
}
}
}
sess->dad[r] = sess->dad[p];
sess->lson[r] = sess->lson[p];
sess->rson[r] = sess->rson[p];
sess->dad[sess->lson[p]] = r;
sess->dad[sess->rson[p]] = r;
if (sess->rson[sess->dad[p]] == p)
sess->rson[sess->dad[p]] = r;
else
sess->lson[sess->dad[p]] = r;
sess->dad[p] = LZHUF_NIL; /* remove p */
}
static void DeleteNode(lzhuf_session_t* sess, int p) /* remove from tree */
{
int q;
if (sess->dad[p] == LZHUF_NIL)
return; /* not registered */
if (sess->rson[p] == LZHUF_NIL)
q = sess->lson[p];
else
if (sess->lson[p] == LZHUF_NIL)
q = sess->rson[p];
else {
q = sess->lson[p];
if (sess->rson[q] != LZHUF_NIL) {
do {
q = sess->rson[q];
} while (sess->rson[q] != LZHUF_NIL);
sess->rson[sess->dad[q]] = sess->lson[q];
sess->dad[sess->lson[q]] = sess->dad[q];
sess->lson[q] = sess->lson[p];
sess->dad[sess->lson[p]] = q;
}
sess->rson[q] = sess->rson[p];
sess->dad[sess->rson[p]] = q;
}
sess->dad[q] = sess->dad[p];
if (sess->rson[sess->dad[p]] == p)
sess->rson[sess->dad[p]] = q;
else
sess->lson[sess->dad[p]] = q;
sess->dad[p] = LZHUF_NIL;
}
/* table for encoding and decoding the upper 6 bits of position */
/* for encoding */
static const unsigned char p_len[64] = {
0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
};
static const unsigned char p_code[64] = {
0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
/* for decoding */
static const unsigned char d_code[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
};
static const unsigned char d_len[256] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
};
static int GetBit(lzhuf_session_t* sess) /* get one bit */
{
unsigned i;
while (sess->getlen <= 8) {
if ((int)(i = h_getc(sess)) < 0)
i = 0;
sess->getbuf |= i << (8 - sess->getlen);
sess->getlen += 8;
}
i = sess->getbuf;
sess->getbuf <<= 1;
sess->getlen--;
return (int)((i & 0x8000) >> 15);
}
static int GetByte(lzhuf_session_t* sess) /* get one byte */
{
unsigned i;
while (sess->getlen <= 8) {
if ((int)(i = h_getc(sess)) < 0)
i = 0;
sess->getbuf |= i << (8 - sess->getlen);
sess->getlen += 8;
}
i = sess->getbuf;
sess->getbuf <<= 8;
sess->getlen -= 8;
return (int)((i & 0xff00) >> 8);
}
static int Putcode(lzhuf_session_t* sess, int l, unsigned c) /* output c bits of code */
{
sess->putbuf |= c >> sess->putlen;
if ((sess->putlen += l) >= 8) {
if (h_putc(sess, (unsigned char)(sess->putbuf >> 8)) == EOF)
return -1;
if ((sess->putlen -= 8) >= 8) {
if (h_putc(sess, (unsigned char)sess->putbuf) == EOF)
return -1;
sess->codesize += 2;
sess->putlen -= 8;
sess->putbuf = c << (l - sess->putlen);
} else {
sess->putbuf <<= 8;
sess->codesize++;
}
}
return 0;
}
/* initialization of tree */
static void StartHuff(lzhuf_session_t* sess)
{
int i, j;
for (i = 0; i < LZHUF_N_CHAR; i++) {
sess->freq[i] = 1;
sess->son[i] = i + LZHUF_T;
sess->prnt[i + LZHUF_T] = i;
}
i = 0; j = LZHUF_N_CHAR;
while (j <= LZHUF_R) {
sess->freq[j] = sess->freq[i] + sess->freq[i + 1];
sess->son[j] = i;
sess->prnt[i] = sess->prnt[i + 1] = j;
i += 2; j++;
}
sess->freq[LZHUF_T] = 0xffff;
sess->prnt[LZHUF_R] = 0;
}
/* reconstruction of tree */
static void reconst(lzhuf_session_t* sess)
{
int i, j, k;
unsigned f, l;
/* collect leaf nodes in the first half of the table */
/* and replace the freq by (freq + 1) / 2. */
j = 0;
for (i = 0; i < LZHUF_T; i++) {
if (sess->son[i] >= LZHUF_T) {
sess->freq[j] = (sess->freq[i] + 1) / 2;
sess->son[j] = sess->son[i];
j++;
}
}
/* begin constructing tree by connecting sons */
for (i = 0, j = LZHUF_N_CHAR; j < LZHUF_T; i += 2, j++) {
k = i + 1;
f = sess->freq[j] = sess->freq[i] + sess->freq[k];
for (k = j - 1; f < sess->freq[k]; k--)
;
k++;
l = j - k;
memmove(sess->freq + k + 1, sess->freq + k, l * sizeof(sess->freq[0]));
sess->freq[k] = f;
memmove(sess->son + k + 1, sess->son + k, l * sizeof(sess->son[0]));
sess->son[k] = i;
}
/* connect prnt */
for (i = 0; i < LZHUF_T; i++) {
if ((k = sess->son[i]) >= LZHUF_T) {
sess->prnt[k] = i;
} else {
sess->prnt[k] = sess->prnt[k + 1] = i;
}
}
}
/* increment frequency of given code by one, and update tree */
static void update(lzhuf_session_t* sess, int c)
{
int i, j, k, l;
if (sess->freq[LZHUF_R] == LZHUF_MAX_FREQ) {
reconst(sess);
}
c = sess->prnt[c + LZHUF_T];
do {
k = ++sess->freq[c];
/* if the order is disturbed, exchange nodes */
if ((unsigned)k > sess->freq[l = c + 1]) {
while ((unsigned)k > sess->freq[++l])
;
l--;
sess->freq[c] = sess->freq[l];
sess->freq[l] = k;
i = sess->son[c];
sess->prnt[i] = l;
if (i < LZHUF_T)
sess->prnt[i + 1] = l;
j = sess->son[l];
sess->son[l] = i;
sess->prnt[j] = c;
if (j < LZHUF_T)
sess->prnt[j + 1] = c;
sess->son[c] = j;
c = l;
}
} while ((c = sess->prnt[c]) != 0); /* repeat up to root */
}
static void EncodeChar(lzhuf_session_t* sess, unsigned c)
{
unsigned i;
int j, k;
i = 0;
j = 0;
k = sess->prnt[c + LZHUF_T];
/* travel from leaf to root */
do {
i >>= 1;
/* if node's address is odd-numbered, choose bigger brother node */
if (k & 1)
i += 0x8000;
j++;
} while ((k = sess->prnt[k]) != LZHUF_R);
Putcode(sess, j, (i & 0xffff));
update(sess, c);
}
static void EncodePosition(lzhuf_session_t* sess, unsigned c)
{
unsigned i;
/* output upper 6 bits by table lookup */
i = c >> 6;
Putcode(sess, p_len[i], (unsigned)p_code[i] << 8);
/* output lower 6 bits verbatim */
Putcode(sess, 6, (c & 0x3f) << 10);
}
static int EncodeEnd(lzhuf_session_t* sess)
{
if (sess->putlen) {
if (h_putc(sess, (unsigned char)(sess->putbuf >> 8)) == EOF)
return -1;
sess->codesize++;
}
return 0;
}
static int DecodeChar(lzhuf_session_t* sess)
{
unsigned c;
c = sess->son[LZHUF_R];
/* travel from root to leaf, */
/* choosing the smaller child node (son[]) if the read bit is 0, */
/* the bigger (son[]+1} if 1 */
while (c < LZHUF_T) {
c += GetBit(sess);
c = sess->son[c];
}
c -= LZHUF_T;
update(sess, c);
return (int)c;
}
static int DecodePosition(lzhuf_session_t* sess)
{
unsigned i, j, c;
/* recover upper 6 bits from table */
i = GetByte(sess);
c = (unsigned)d_code[i] << 6;
j = d_len[i];
/* read lower 6 bits verbatim */
j -= 2;
while (j--) {
i = (i << 1) + GetBit(sess);
}
return (int)(c | (i & 0x3f));
}
/* compression */
int lzhuf_encode(lzhuf_session_t* sess) /* compression */
{
int i, c, len, r, s, last_match_length;
unsigned long int textsize = 0;
int ret;
h_seek(sess, sess->infile, 0L, SEEK_END);
textsize = h_tell(sess, sess->infile);
if (h_putc(sess, (unsigned char)((textsize & 0xff))) == EOF ||
h_putc(sess, (unsigned char)((textsize & 0xff00) >> 8)) == EOF ||
h_putc(sess, (unsigned char)((textsize & 0xff0000L) >> 16)) == EOF ||
h_putc(sess, (unsigned char)((textsize & 0xff000000L) >> 24)) == EOF)
return -1;
if (textsize == 0)
return 0;
h_seek(sess, sess->infile, 0L, SEEK_SET);
textsize = 0; /* rewind and re-read */
StartHuff(sess);
InitTree(sess);
s = 0;
r = LZHUF_N - LZHUF_F;
for (i = s; i < r; i++)
sess->text_buf[i] = 0x20;
for (len = 0; len < LZHUF_F && (c = h_getc(sess)) != EOF; len++)
sess->text_buf[r + len] = (unsigned char)c;
textsize = len;
for (i = 1; i <= LZHUF_F; i++)
InsertNode(sess, r - i);
InsertNode(sess, r);
do {
if (sess->match_length > len)
sess->match_length = len;
if (sess->match_length <= LZHUF_THRESHOLD) {
sess->match_length = 1;
EncodeChar(sess, sess->text_buf[r]);
} else {
EncodeChar(sess, 255 - LZHUF_THRESHOLD + sess->match_length);
EncodePosition(sess, sess->match_position);
}
last_match_length = sess->match_length;
for (i = 0; i < last_match_length && (c = h_getc(sess)) != EOF; i++) {
DeleteNode(sess, s);
sess->text_buf[s] = (unsigned char)c;
if (s < LZHUF_F - 1)
sess->text_buf[s + LZHUF_N] = (unsigned char)c;
s = (s + 1) & (LZHUF_N - 1);
r = (r + 1) & (LZHUF_N - 1);
InsertNode(sess, r);
}
textsize += i;
while (i++ < last_match_length) {
DeleteNode(sess, s);
s = (s + 1) & (LZHUF_N - 1);
r = (r + 1) & (LZHUF_N - 1);
if (--len)
InsertNode(sess, r);
}
} while (len > 0);
ret = EncodeEnd(sess);
return ret;
}
int lzhuf_decode(lzhuf_session_t* sess) /* recover */
{
int i, j, k, r, c;
unsigned long int count;
unsigned long int textsize = 0;
if (EOF == (c = h_getc(sess)))
return -1;
textsize = c;
if (EOF == (c = h_getc(sess)))
return -1;
textsize |= (c << 8);
if (EOF == (c = h_getc(sess)))
return -1;
textsize |= (c << 16);
if (EOF == (c = h_getc(sess)))
return -1;
textsize |= (c << 24);
if (textsize == 0)
return 0;
StartHuff(sess);
for (i = 0; i < LZHUF_N - LZHUF_F; i++)
sess->text_buf[i] = 0x20;
r = LZHUF_N - LZHUF_F;
for (count = 0; count < textsize; ) {
c = DecodeChar(sess);
if (c < 256) {
if (h_putc(sess, (unsigned char)c) == EOF)
return -1;
sess->text_buf[r++] = (unsigned char)c;
r &= (LZHUF_N - 1);
count++;
} else {
i = (r - DecodePosition(sess) - 1) & (LZHUF_N - 1);
j = c - 255 + LZHUF_THRESHOLD;
for (k = 0; k < j; k++) {
c = sess->text_buf[(i + k) & (LZHUF_N - 1)];
if (h_putc(sess, (unsigned char)c) == EOF)
return -1;
sess->text_buf[r++] = (unsigned char)c;
r &= (LZHUF_N - 1);
count++;
}
}
}
return 0;
}
void lzhuf_startSession(lzhuf_session_t* sess)
{
memset(sess, 0, sizeof(*sess));
}
void lzhuf_endSession(lzhuf_session_t* sess)
{
// do nothing
(void)sess;
}
+72
View File
@@ -0,0 +1,72 @@
/**************************************************************
lzhuf.h
Lib-like reentrant definition of lzhuf.c
Please see lzhuf.c for authorship info
**************************************************************/
#ifndef LZHUF_H_INCL_
#define LZHUF_H_INCL_
/********** LZSS compression **********/
#define LZHUF_N 4096 /* buffer size */
#define LZHUF_F 60 /* lookahead buffer size */
#define LZHUF_THRESHOLD 2
#define LZHUF_NIL LZHUF_N /* leaf of tree */
/* Huffman coding */
#define LZHUF_N_CHAR (256 - LZHUF_THRESHOLD + LZHUF_F)
/* kinds of characters (character code = 0..LZHUF_N_CHAR-1) */
#define LZHUF_T (LZHUF_N_CHAR * 2 - 1) /* size of table */
#define LZHUF_R (LZHUF_T - 1) /* position of root */
#define LZHUF_MAX_FREQ 0x8000 /* updates tree when the */
typedef void* lzhuf_handle_t;
typedef struct
{
unsigned long int codesize;
unsigned char text_buf[LZHUF_N + LZHUF_F - 1];
int match_position;
int match_length;
int lson[LZHUF_N + 1];
int rson[LZHUF_N + 257];
int dad[LZHUF_N + 1];
unsigned freq[LZHUF_T + 1]; /* frequency table */
int prnt[LZHUF_T + LZHUF_N_CHAR]; /* pointers to parent nodes, except for the */
/* elements [LZHUF_T..LZHUF_T + LZHUF_N_CHAR - 1] which are used to get */
/* the positions of leaves corresponding to the codes. */
int son[LZHUF_T]; /* pointers to child nodes (son[], son[] + 1) */
unsigned getbuf;
unsigned char getlen;
unsigned putbuf;
unsigned char putlen;
/* user-settable data */
void* userdata;
lzhuf_handle_t infile;
lzhuf_handle_t outfile;
size_t (* read)(void*, size_t, size_t, lzhuf_handle_t);
size_t (* write)(const void*, size_t, size_t, lzhuf_handle_t);
int (* seek)(lzhuf_handle_t, long, int);
long (* tell)(lzhuf_handle_t);
} lzhuf_session_t;
void lzhuf_startSession(lzhuf_session_t *);
void lzhuf_endSession(lzhuf_session_t *);
int lzhuf_encode(lzhuf_session_t *); /* compression */
int lzhuf_decode(lzhuf_session_t *); /* recover */
#endif /* LZHUF_H_INCL_ */
+1368
View File
File diff suppressed because it is too large Load Diff
+114
View File
@@ -0,0 +1,114 @@
# Microsoft Developer Studio Project File - Name="undani" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=undani - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "undani.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "undani.mak" CFG="undani - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "undani - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "undani - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "undani - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\src\getopt" /I "." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib libpng10.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "undani - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\..\src\getopt" /I "." /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib libpng10.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "undani - Win32 Release"
# Name "undani - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\config.h
# End Source File
# Begin Source File
SOURCE=..\..\src\getopt\getopt.c
# End Source File
# Begin Source File
SOURCE=..\..\src\getopt\getopt.h
# End Source File
# Begin Source File
SOURCE=.\lzhuf.c
# End Source File
# Begin Source File
SOURCE=.\lzhuf.h
# End Source File
# Begin Source File
SOURCE=.\undani.c
# End Source File
# End Group
# End Target
# End Project
+29
View File
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "undani"=.\undani.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################