#include #include #include #include #include #include /* 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 \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; }