void test_bitfile2(void) { struct bitfile *bf = bitfile_open("/dev/urandom", "r"); int i; u8 res; int sum = 0; for(i=0; i<1000000; i++) { bitfile_get_bit(bf, &res); sum += res; } printf("the sum of first million bits from urandom: %d\n", sum); bitfile_rewind(bf); sum = 0; for(i=0; i<1000000; i++) { bitfile_get_bit(bf, &res); sum += res; } printf("(again) the sum first million bits from urandom: %d\n", sum); bitfile_close(bf); }
void test_bitfile3(void) { u8 byte; u32 word; struct bitfile *bf = bitfile_open("/tmp/test", "r"); struct bitfile *bf2 = bitfile_open("/tmp/test.out", "w"); struct bitfile *bf3 = bitfile_open("/tmp/test.out2", "w"); struct bitfile *bf4 = bitfile_open("/tmp/test.out3", "w"); struct bitfile *bf5 = bitfile_open("/tmp/test.out4", "w"); while(bitfile_get_byte(bf, &byte) == 0) { bitfile_put_byte(bf2, byte); } bitfile_rewind(bf); while(bitfile_get_bit(bf, &byte) == 0) { bitfile_put_bit(bf3, byte); } bitfile_rewind(bf); while(bitfile_get_u32(bf, &word) == 0) { bitfile_put_u32(bf4, word); } bitfile_rewind(bf); { u8 bytes[2]; u8 bits[4]; while(bitfile_get_byte(bf, &bytes[0]) == 0 && bitfile_get_byte(bf, &bytes[1]) == 0 && bitfile_get_bit(bf, &bits[0]) == 0 && bitfile_get_bit(bf, &bits[1]) == 0 && bitfile_get_bit(bf, &bits[2]) == 0 && bitfile_get_bit(bf, &bits[3]) == 0) { u8 out = bits[0] << 7 | bits[1] << 6 | bits[2] << 5 | bits[3] << 4; u8 foo[3]; foo[0] = bytes[0]; foo[1] = bytes[1]; foo[2] = out; bitfile_put_bits(bf5, (u8 *)&foo, 20); /* bitfile_put_bit(bf5, bits[0]); */ /* bitfile_put_bit(bf5, bits[1]); */ /* bitfile_put_bit(bf5, bits[2]); */ /* bitfile_put_bit(bf5, bits[3]); */ } } bitfile_close(bf); bitfile_close(bf2); bitfile_close(bf3); bitfile_close(bf4); bitfile_close(bf5); }
int decode_symbol(file *f, huf_tree tree){ huf_node *node = tree.root; int bit = bitfile_get_bit(f); if(bit==EOF) return EOF; // read until we reach a leaf node while(node->left){ if(bit==EOF) die_format(); if(!bit) node = node->left; else node = node->right; if(node->left) bit = bitfile_get_bit(f); } return node->symbol; }
/* Build the Huffman tree recursively. */ void read_tree(file *f, huf_node *node, bool isRoot){ int bit = bitfile_get_bit(f); if(bit==EOF){ if(isRoot) return; else die_format(); } if(!bit){ // internal node huf_node *left = (huf_node *)malloc_or_die(2*sizeof(huf_node)); huf_node *right = left+1; node->left = left; node->right = right; read_tree(f, left, false); read_tree(f, right, false); }else{ // leaf node int s = bitfile_get_symbol(f, SYMBOL_LENGTH); if(s==EOF) die_format(); node->symbol = s; node->left = NULL; node->right = NULL; } }
void test_bitfile(void) { struct bitfile *bf; char buf[20] = {0,}; u8 res; u32 res32; int ret = 0; bf = bitfile_open("bitfile.test", "w"); assert (bf != NULL); bitfile_put_bytes(bf, (u8*)"HCPAK", 5); bitfile_put_byte(bf, 'a'); bitfile_put_byte(bf, 'b'); bitfile_put_byte(bf, 'c'); bitfile_put_byte(bf, 'd'); bitfile_put_bit(bf, 0); bitfile_put_bit(bf, 0); bitfile_put_bit(bf, 1); bitfile_put_bit(bf, 1); bitfile_put_byte(bf, 'e'); bitfile_put_byte(bf, 'f'); bitfile_put_u32(bf, (u32)123456); res = 0xff; bitfile_put_bits(bf, &res, 5); bitfile_put_bit(bf, 1); bitfile_put_bit(bf, 0); bitfile_put_bit(bf, 1); bitfile_put_bit(bf, 0); /* bitfile_put_byte(bf, 'f'); */ bitfile_close(bf); bf = bitfile_open("bitfile.test", "r"); assert (bf != NULL); bitfile_get_bytes(bf, (u8*)buf, 5); buf[5] = '\0'; assert(!memcmp(buf, "HCPAK", 5)); /* printf("HCPAK: '%s'\n", buf); */ ret += bitfile_get_byte(bf, &res); /* printf("a: %c\n", res); */ assert(res == 'a'); ret += bitfile_get_byte(bf, &res); /* printf("b: %c\n", res); */ assert(res == 'b'); ret += bitfile_get_byte(bf, &res); /* printf("c: %c\n", res); */ assert(res == 'c'); ret += bitfile_get_byte(bf, &res); /* printf("d: %c\n", res); */ assert(res == 'd'); ret += bitfile_get_bit(bf, &res); /* printf("0: %d\n", res); */ assert(res == 0); ret += bitfile_get_bit(bf, &res); /* printf("0: %d\n", res); */ assert(res == 0); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_byte(bf, &res); /* printf("e: %c\n", res); */ assert(res == 'e'); ret += bitfile_get_byte(bf, &res); /* printf("f: %c\n", res); */ assert(res == 'f'); ret += bitfile_get_u32(bf, &res32); assert (res32 == 123456); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("0: %d\n", res); */ assert(res == 0); ret += bitfile_get_bit(bf, &res); /* printf("1: %d\n", res); */ assert(res == 1); ret += bitfile_get_bit(bf, &res); /* printf("0: %d\n", res); */ assert(res == 0); assert(ret == 0); /* try reading past the EOF */ assert(bitfile_get_byte(bf, &res) != 0); /* try rewinding the file */ bitfile_rewind(bf); bitfile_get_bytes(bf, (u8*)buf, 5); buf[5] = '\0'; assert(!memcmp(buf, "HCPAK", 5)); /* printf("HCPAK: '%s'\n", buf); */ bitfile_close(bf); }