Skip to content

Commit

Permalink
*** empty log message ***
Browse files Browse the repository at this point in the history
git-svn-id: file:///Users/martin/Documents/svnrepo/trunk/martin/compsci@763 3ab4d77f-209f-454f-af32-ffe4b78d429c
  • Loading branch information
ept committed May 28, 2005
1 parent 909e056 commit a6bc0b1
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 6 deletions.
18 changes: 12 additions & 6 deletions burrowswheeler/Makefile
@@ -1,17 +1,23 @@
all: bw bw-i mtf mtf-i
all: bw bw-i mtf mtf-i huff huff-i

clean:
rm -f *.o bw bw-i
rm -f *.o bw bw-i mtf mtf-i huff huff-i

bw: bw.o
gcc -o $@ $<
gcc -o $@ bw.o

bw-i: bw-i.o
gcc -o $@ $<
gcc -o $@ bw-i.o

mtf: mtf.o
gcc -o $@ $<
gcc -o $@ mtf.o

mtf-i: mtf-i.o
gcc -o $@ $<
gcc -o $@ mtf-i.o

huff: huff.o huff-tree.o
gcc -o $@ huff.o huff-tree.o

huff-i: huff-i.o huff-tree.o
gcc -o $@ huff-i.o huff-tree.o

35 changes: 35 additions & 0 deletions burrowswheeler/huff-i.c
@@ -0,0 +1,35 @@
#include <stdio.h>
#include "huff-tree.h"

#define BUFSIZE 100000


unsigned char buf[BUFSIZE], enctable[512], output;
int size;
Node *count[257], *root;

int main() {
int i, j;
unsigned char ch;
Node *current;
size = fread(buf, 1, BUFSIZE, stdin);
for (i=0; i<257; i++) {
count[i] = make_node();
count[i]->ch = i;
count[i]->weight = (i == 256 ? 1 : 256*buf[2*i+1] + buf[2*i]);
}
current = root = make_tree(count);
for (i=512; i<size; i++) {
for (j=0; j<8; j++) {
if (buf[i] & (1 << j)) current = (Node*) current->r; else
current = (Node*) current->l;
if (!current->l || !current->r) {
if (current->ch == 256) return 0;
ch = current->ch;
fwrite(&ch, 1, 1, stdout);
current = root;
}
}
}
return 0;
}
50 changes: 50 additions & 0 deletions burrowswheeler/huff-tree.c
@@ -0,0 +1,50 @@
#include <stdio.h>
#include "huff-tree.h"

int cmp_nodes(void *p1, void *p2) {
Node *n1 = *((Node**) p1);
Node *n2 = *((Node**) p2);
if (n1->weight > n2->weight) return +1; else
if (n1->weight < n2->weight) return -1; else return 0;
}

Node *make_node() {
Node *n = (Node*) malloc(sizeof(Node));
n->weight = 0;
n->code1 = 0;
n->code2 = 0;
n->depth = 0;
n->ch = 0;
n->l = 0;
n->r = 0;
return n;
}

void add_parent(Node *n, int bit) {
n->code2 = (n->code2 << 1) | ((n->code1 & 0x80000000) >> 31);
n->code1 = (n->code1 << 1) | bit;
n->depth++;
if (n->l) add_parent((Node*) n->l, bit);
if (n->r) add_parent((Node*) n->r, bit);
}


Node *make_tree(Node *nodes[]) {
int i;
Node *n;
for (i=257; i>1; i--) {
qsort(nodes, i, sizeof(Node*), cmp_nodes);
if (nodes[0]->weight + nodes[1]->weight == 0) {
nodes[0] = nodes[i-1];
continue;
}
n = make_node();
n->l = nodes[0]; add_parent(nodes[0], 0);
n->r = nodes[1]; add_parent(nodes[1], 1);
n->weight = nodes[0]->weight + nodes[1]->weight;
nodes[0] = n;
nodes[1] = nodes[i-1];
}
fprintf(stderr, "Huffman table built\n");
return nodes[0];
}
8 changes: 8 additions & 0 deletions burrowswheeler/huff-tree.h
@@ -0,0 +1,8 @@
typedef struct {
unsigned int weight, depth, code1, code2, ch;
void *l, *r;
} Node;

Node *make_node();
Node *make_tree(Node *nodes[]);

45 changes: 45 additions & 0 deletions burrowswheeler/huff.c
@@ -0,0 +1,45 @@
#include <stdio.h>
#include "huff-tree.h"

#define BUFSIZE 100000


unsigned char buf[BUFSIZE], enctable[512], output;
int size;
Node *count[257], *nodes[257];

int main() {
int i, j, k;
unsigned int bit;
Node *n;
size = fread(buf, 1, BUFSIZE, stdin);
for (i=0; i<257; i++) {
count[i] = make_node();
count[i]->ch = i;
}
for (i=0; i<size; i++) count[buf[i]]->weight++;
count[256]->weight = 1;
memcpy(nodes, count, 257*sizeof(Node*));
make_tree(nodes);
for (i=0; i<256; i++) {
enctable[2*i] = count[i]->weight % 256;
enctable[2*i+1] = count[i]->weight / 256;
}
fwrite(enctable, 1, 512, stdout);
j=0; output = 0;
for (i=0; i<=size; i++) {
n = (i == size ? count[256] : count[buf[i]]);
for (k=0; k < n->depth; k++) {
bit = (k > 31 ? n->code2 : n->code1) & (1 << (k % 32));
if (j > k) bit = bit << (j - k); else bit = bit >> (k - j);
output |= bit;
j++;
if (j == 8) {
fwrite(&output, 1, 1, stdout);
j = 0; output = 0;
}
}
}
if (j > 0) fwrite(&output, 1, 1, stdout);
return 0;
}

0 comments on commit a6bc0b1

Please sign in to comment.