summaryrefslogtreecommitdiff
path: root/libhuff
diff options
context:
space:
mode:
authorXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
committerXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
commit7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch)
treec28d0748652ad4b4222309e46e6cfc82c0906220 /libhuff
parenta2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff)
downloadpsxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'libhuff')
-rw-r--r--libhuff/Makefile23
-rw-r--r--libhuff/huff.c119
-rw-r--r--libhuff/huff.h19
3 files changed, 161 insertions, 0 deletions
diff --git a/libhuff/Makefile b/libhuff/Makefile
new file mode 100644
index 0000000..0016f91
--- /dev/null
+++ b/libhuff/Makefile
@@ -0,0 +1,23 @@
+# Makefile for libhuff
+
+include ../Makefile.cfg
+
+#CC = mipsel-unknown-elf-gcc
+#CFLAGS = -I../libpsx/include/ -G0 -O0 -fno-builtin -mno-gpopt -nostdlib -msoft-float -g -Wall
+
+all: libhuff.a
+
+huff.o: huff.c
+ $(CC) $(CFLAGS) -c huff.c
+
+libhuff.a: huff.o
+ rm -f libhuff.a
+ $(AR) r libhuff.a huff.o
+ $(RANLIB) libhuff.a
+
+install: all
+ cp libhuff.a $(TOOLCHAIN_PREFIX)/lib
+ cp huff.h $(TOOLCHAIN_PREFIX)/include
+
+clean:
+ rm -f *.o *.a \ No newline at end of file
diff --git a/libhuff/huff.c b/libhuff/huff.c
new file mode 100644
index 0000000..0a79603
--- /dev/null
+++ b/libhuff/huff.c
@@ -0,0 +1,119 @@
+// Huffman decompression library for PSXSDK
+
+// Huffman decompression code adapted from huff program
+// by Joe Wingbermuehle
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <psx.h>
+#include "huff.h"
+
+#define BUFFER_SIZE 1024
+
+unsigned char libhuff_inBuffer[BUFFER_SIZE];
+unsigned char libhuff_outBuffer[BUFFER_SIZE];
+
+struct CodeNode {
+ unsigned char value;
+ unsigned long code;
+ unsigned int codeSize;
+};
+
+struct CodeNode libhuff_codes[256];
+unsigned int libhuff_codesUsed;
+
+// Decompress_Mem returns size of uncompressed data if SizeLimit >= UncompressedDataSize,
+// otherwise if UncompressedDataSize > SizeLimit, 0 is returned
+
+// SizeLimit is the maximum space available for decompressed data
+
+unsigned int huff_decompress(void *dst, void *src, int sizeLimit) {
+ int x, y;
+ unsigned int dataSize;
+ unsigned long mask, maskSize;
+ unsigned char ch;
+ int offset;
+// int last;
+
+ int ib, ob;
+ int src_pos = 8;
+ int dst_pos = 0;
+ unsigned char *srcc = (unsigned char*)src;
+ unsigned char *dstc = (unsigned char*)dst;
+
+ libhuff_codesUsed = *((unsigned int*)src);
+ dataSize = *((unsigned int*)src + 1);
+
+ if(dataSize > sizeLimit)
+ return 0;
+
+ for(x = 0; x < libhuff_codesUsed; x++) {
+ libhuff_codes[x].value = srcc[src_pos++];
+ libhuff_codes[x].codeSize = srcc[src_pos++] + 1;
+ }
+
+ offset = 7;
+ ch = 0;
+ for(x = 0; x < libhuff_codesUsed; x++) {
+ libhuff_codes[x].code = 0;
+ for(y = libhuff_codes[x].codeSize - 1; y >= 0; y--) {
+ if(offset == 7) {
+ ch = srcc[src_pos++];
+ }
+ libhuff_codes[x].code |= ((ch >> offset) & 1) << y;
+ offset = (offset - 1) & 7;
+ }
+ }
+
+ maskSize = 0;
+ mask = 0;
+ offset = 7;
+ //last = 0;
+ y = 0;
+ x = 0;
+ ib = BUFFER_SIZE;
+ ob = 0;
+ for(;;) {
+ if(offset == 7) {
+ if(ib >= BUFFER_SIZE) {
+ memcpy(libhuff_inBuffer, &srcc[src_pos], BUFFER_SIZE);
+ src_pos += BUFFER_SIZE;
+
+ ib = 0;
+ }
+ ch = libhuff_inBuffer[ib++];
+ }
+ mask <<= 1;
+ mask |= (ch >> offset) & 1;
+ ++maskSize;
+ offset = (offset - 1) & 7;
+
+ while(libhuff_codes[y].codeSize < maskSize) ++y;
+ while(libhuff_codes[y].codeSize == maskSize) {
+ if(libhuff_codes[y].code == mask) {
+ if(ob >= BUFFER_SIZE) {
+ memcpy(&dstc[dst_pos], libhuff_outBuffer, BUFFER_SIZE);
+ dst_pos += BUFFER_SIZE;
+ ob = 0;
+ }
+ libhuff_outBuffer[ob++] = libhuff_codes[y].value;
+ ++x;
+ if(x >= dataSize) {
+ memcpy(&dstc[dst_pos], libhuff_outBuffer, ob);
+ dst_pos += ob;
+ return dataSize;
+ }
+ mask = 0;
+ maskSize = 0;
+ y = 0;
+ break;
+ }
+ ++y;
+ }
+ }
+
+ return dataSize;
+}
+
diff --git a/libhuff/huff.h b/libhuff/huff.h
new file mode 100644
index 0000000..28aecf1
--- /dev/null
+++ b/libhuff/huff.h
@@ -0,0 +1,19 @@
+/*
+ * huff.h
+ *
+ * Huffman decompression routines
+ *
+ * libhuff
+ */
+
+#ifndef _HUFF_H
+#define _HUFF_H
+
+// Decompress_Mem returns size of uncompressed data if SizeLimit >= UncompressedDataSize,
+// otherwise if UncompressedDataSize > SizeLimit, 0 is returned
+
+// SizeLimit is the maximum space available for decompressed data
+
+unsigned int huff_decompress(void *dst, void *src, int sizeLimit);
+
+#endif