From 93900930111901d1eadf07cace8fe5834dbf7a54 Mon Sep 17 00:00:00 2001 From: Jack <jmaxfiel@caltech.edu> Date: Wed, 1 Apr 2020 21:50:49 -0400 Subject: [PATCH] Add huffman and example file --- .gitignore | 2 + Makefile | 7 +++- example.bin | 1 + huffman.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 example.bin create mode 100644 huffman.c diff --git a/.gitignore b/.gitignore index 822895d..5e7833a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ myzip0 myunzip0 +inflate +huffman \ No newline at end of file diff --git a/Makefile b/Makefile index f1e3ca9..026c9f2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ -all : myzip0 myunzip0 +all : myzip0 myunzip0 huffman myzip0 : myzip0.c cc myzip0.c -o myzip0 myunzip0 : myunzip0.c - cc myunzip0.c -o myunzip0 \ No newline at end of file + cc myunzip0.c -o myunzip0 + +huffman : huffman.c + cc huffman.c -o huffman \ No newline at end of file diff --git a/example.bin b/example.bin new file mode 100644 index 0000000..d90011e --- /dev/null +++ b/example.bin @@ -0,0 +1 @@ +"3DUfwˆ™ª»ÌÝîÿ \ No newline at end of file diff --git a/huffman.c b/huffman.c new file mode 100644 index 0000000..527f741 --- /dev/null +++ b/huffman.c @@ -0,0 +1,115 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +/* A struct for writing to files as + streams of individual bits */ + +typedef struct __bit_writer +{ + FILE *file; + uint8_t byte; + int mod; +} bit_writer; + +bit_writer *bit_writer_init(FILE *file) +{ + bit_writer *bw = malloc(sizeof(bit_writer)); + assert(bw); + bw->file = file; + bw->byte = 0; + bw->mod = 0; + return bw; +} + +void bit_writer_free(bit_writer *bw) +{ + free(bw); +} + +void bit_writer_write_bit(bit_writer *bw, bool bit) +{ + bw->byte |= (bit > 0) << (bw->mod++); + + if (bw->mod == 8) + { + fwrite(&bw->byte, 1, 1, bw->file); + bw->byte = 0; + bw->mod = 0; + } +} + +void bit_writer_flush(bit_writer *bw) +{ + while (bw->mod != 0) bit_writer_write_bit(bw, 0); +} + +void write_byte(bit_writer *bw, uint8_t byte) +{ + + if (byte <= 143) /* 8 bit encoding */ + { + uint32_t to_encode = 0x30 + (uint32_t) byte; + for (int b = 8 - 1; b >= 0; b--) + bit_writer_write_bit(bw, to_encode & (1 << b)); + } else /* 9 bit encoding */ + { + uint32_t to_encode = 0x100 + (uint32_t) byte; + for (int b = 9 - 1; b >= 0; b--) + { + // bool to_write = () != 0; + // printf("Writing %d\n", to_write); + bit_writer_write_bit(bw, to_encode & (1 << b)); + } + } +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + printf("Usage: %s <input file>\n", argv[0]); + exit(1); + } + + char *input_file_name = argv[1]; + char *output_file_name = malloc(sizeof(char) * + (strlen(input_file_name) + strlen(".deflate") + 1)); + sprintf(output_file_name, "%s.deflate", input_file_name); + + FILE *input_file = fopen(input_file_name, "r"); + FILE *output_file = fopen(output_file_name, "w"); + free(output_file_name); + bit_writer *bw = bit_writer_init(output_file); + + + + bit_writer_write_bit(bw, 1); /* BFINAL */ + + bit_writer_write_bit(bw, 1); /* BTYPE */ + bit_writer_write_bit(bw, 0); + + // write_byte(bw, 144); + + char c; + while (fread(&c, 1, 1, input_file)) + { + // printf("Writing %d\n", (int) c); + write_byte(bw, c); + } + + for (int i = 0; i < 7; i++) + bit_writer_write_bit(bw, 0); + + bit_writer_flush(bw); + bit_writer_free(bw); + fclose(output_file); + fclose(input_file); + + + + return 0; +} \ No newline at end of file -- GitLab