void huffman_encode_func(huffman_encoding_output *out, smaller_block *inp1) { // huffman_encoding_output huffman_step_output; out->width = inp1->width; out->height = inp1->height; out->block_id = inp1->block_id; #ifdef VERBOSE printf("huffman_encoding block #%d\n", inp1->block_id); #endif #pragma ForSyDe begin huffman_encode_func if (inp1->is_cb == 1) { huffman_encode(HUFFMAN_CTX_Cb, (short *) inp1->content, out); // printf("Cb: Got %u bits form Huffman step\n", out->bit_position); } else if (inp1->is_cr == 1) { huffman_encode(HUFFMAN_CTX_Cr, (short *) inp1->content, out); // printf("Cr: Got %u bits form Huffman step\n", out->bit_position); } else if ((inp1->is_cr == 0) && (inp1->is_cb == 0)) { huffman_encode(HUFFMAN_CTX_Y, (short *) inp1->content, out); // printf("Y: Got %u bits form Huffman step\n", out->bit_position); } #pragma ForSyDe end // out[0] = huffman_step_output; }
END_TEST START_TEST(test_huffman_encode_longer_string) { char buf[] = "Hello World!"; /*'H' ( 72) |1100011 63 [ 7]*/ /*'e' (101) |00101 5 [ 5]*/ /*'l' (108) |101000 28 [ 6]*/ /*'l' (108) |101000 28 [ 6]*/ /*'o' (111) |00111 7 [ 5]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'W' ( 87) |1110010 72 [ 7]*/ /*'o' (111) |00111 7 [ 5]*/ /*'r' (114) |101100 2c [ 6]*/ /*'l' (108) |101000 28 [ 6]*/ /*'d' (100) |100100 24 [ 6]*/ /*'!' ( 33) |11111110|00 3f8 [10]*/ uint8_t encoded[] = { 0xC6, 0x5A, 0x28, 0x3A, 0x9C, 0x8F, 0x65, 0x12, 0x7F, 0x1F }; // padded with 1s huffman_result_t result; ck_assert(huffman_encode(buf, 12, &result)); check_encoded_val(encoded, 10, result.value, result.length); free(result.value); }
int main() { // Example taken from "Cormen, Leiserson - Introduction to Algorithms" // Chapter 16.3 // Added another g with count 0, that we want to support // As such it shouldn't change other results huffman_entity test[TESTSIZE]; test[0].data = "a"; test[0].count = 45; test[1].data = "b"; test[1].count = 13; test[2].data = "c"; test[2].count = 12; test[3].data = "d"; test[3].count = 16; test[4].data = "e"; test[4].count = 9; test[5].data = "f"; test[5].count = 5; test[6].data = "g"; test[6].count = 0; huffman_encode(test, TESTSIZE); for(int i = 0; i < TESTSIZE; i++) { printf("%s %2lu -> mask = "BYTE_TO_BINARY_PATTERN", value = " BYTE_TO_BINARY_PATTERN", bits = %d\n", (char *)test[i].data, test[i].count, BYTE_TO_BINARY(test[i].bitmask), BYTE_TO_BINARY(test[i].bitvalue), test[i].bitcount); } int error = (test[0].bitmask != 128) || (test[0].bitvalue != 0) || (test[0].bitcount != 1) || (test[1].bitmask != 224) || (test[1].bitvalue != 160) || (test[1].bitcount != 3) || (test[2].bitmask != 224) || (test[2].bitvalue != 128) || (test[2].bitcount != 3) || (test[3].bitmask != 224) || (test[3].bitvalue != 224) || (test[3].bitcount != 3) || (test[4].bitmask != 240) || (test[4].bitvalue != 208) || (test[4].bitcount != 4) || (test[5].bitmask != 240) || (test[5].bitvalue != 192) || (test[5].bitcount != 4) || (test[6].bitmask != 0) || (test[6].bitvalue != 1) || (test[6].bitcount != 0); if(error) { printf("Unexpected results!\n"); return 1; } else return 0; }
int main(int argc,char **argv) { int ret; int i=0; int total[COUNT]; int code_num = 0; huffman_tree root = NULL; HuffmanCode huffcode = NULL; memset(total,0,128*sizeof(int)); if(0 != (ret = getTotalMs(compressFile,total))) { printf("ERROR:get Total Message Failed\n"); }else if(0 != create_huffman_tree(root,total,COUNT)) { printf("ERROR:create huffman tree Failed.\n"); }else if(0 != huffman_encode(huffcode,root,COUNT,code_num)) { printf("ERROR:Generate Code Failed\n"); }else { //free(root); //free(huffcode); } printf("code Count :%d\n",code_num); for(i=0;i<code_num;i++) { printf("%d:%c code is:",i,huffcode[i].character); printf("%s\n",huffcode[i].code); } system("pause"); return 0; }
int encode(const char *infile) { char *filename, lz78_outfile[256], huffman_outfile[256]; struct stat s; off_t orig_size, compressed_size; int rc = 0; filename = basename(strdup(infile)); strcpy(lz78_outfile, "."); strcat(lz78_outfile, filename); strcat(lz78_outfile, ".lz78"); strcpy(huffman_outfile, filename); strcat(huffman_outfile, ".csz"); if (prog_opts & LZ78) { rc = lz78_encode(infile, lz78_outfile); if (!rc) { rc = huffman_encode(lz78_outfile, huffman_outfile); } unlink(lz78_outfile); } else { rc = huffman_encode(infile, huffman_outfile); } if (!rc) { stat(infile, &s); orig_size = s.st_size; stat(huffman_outfile, &s); compressed_size = s.st_size; printf("Original file size: %d bytes\n", orig_size); printf("Compressed file size: %d bytes\n", compressed_size); printf("Compression ratio: %f\n", (float) compressed_size / orig_size); } return rc; }
END_TEST START_TEST(test_huffman_encode_12bit_out) { char buf[] = { '5', '4' }; // 01101101 10101111 uint8_t encoded[] = { 0x6d, 0xaf }; // padded with 1s huffman_result_t result; ck_assert(huffman_encode(buf, 2, &result)); check_encoded_val(encoded, 2, result.value, result.length); free(result.value); }
END_TEST START_TEST(test_huffman_encode_single_8bit_char) { char buf[] = { ';' }; uint8_t encoded[] = { 0xfb }; huffman_result_t result; ck_assert(huffman_encode(buf, 1, &result)); check_encoded_val(encoded, 1, result.value, result.length); free(result.value); }
END_TEST START_TEST(test_huffman_encode_single_10bit_char) { char buf[] = { '?' }; uint8_t encoded[] = { 0xff, 0x3f }; // padded with 1s huffman_result_t result; ck_assert(huffman_encode(buf, 1, &result)); check_encoded_val(encoded, 2, result.value, result.length); free(result.value); }
int huffman_benchmark(char *code) { data *d = huffman_encode(code); int result = data_size(d); /*char *dec = huffman_decode(d); if (strncmp(dec, code, strlen(code)) != 0) { printf("[HUFFMAN ERROR]\n"); printf("Original: %s\n", code); printf("Decoded : %s\n", dec); } free(dec);*/ data_free(d); return result; }
END_TEST START_TEST(test_huffman_encode_date) { /*'W' ( 87) |1110010 72 [ 7]*/ /*'e' (101) |00101 5 [ 5]*/ /*'d' (100) |100100 24 [ 6]*/ /*',' ( 44) |11111010 fa [ 8]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'0' ( 48) |00000 0 [ 5]*/ /*'5' ( 53) |011011 1b [ 6]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'M' ( 77) |1101000 68 [ 7]*/ /*'a' ( 97) |00011 3 [ 5]*/ /*'r' (114) |101100 2c [ 6]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'2' ( 50) |00010 2 [ 5]*/ /*'0' ( 48) |00000 0 [ 5]*/ /*'1' ( 49) |00001 1 [ 5]*/ /*'4' ( 52) |011010 1a [ 6]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'0' ( 48) |00000 0 [ 5]*/ /*'9' ( 57) |011111 1f [ 6]*/ /*':' ( 58) |1011100 5c [ 7]*/ /*'2' ( 50) |00010 2 [ 5]*/ /*'0' ( 48) |00000 0 [ 5]*/ /*':' ( 58) |1011100 5c [ 7]*/ /*'5' ( 53) |011011 1b [ 6]*/ /*'8' ( 56) |011110 1e [ 6]*/ /*' ' ( 32) |010100 14 [ 6]*/ /*'G' ( 71) |1100010 62 [ 7]*/ /*'M' ( 77) |1101000 68 [ 7]*/ /*'T' ( 84) |1101111 6f [ 7]*/ char buf[] = "Wed, 05 Mar 2014 09:20:58 GMT"; uint8_t encoded[] = { 0xE4, 0x59, 0x3E, 0x94, 0x03, 0x6A, 0x68, 0x1D, 0x8A, 0x08, 0x01, 0x69, 0x40, 0x3F, 0x70, 0x40, 0xB8, 0xDB, 0xCA, 0x62, 0xD1, 0xBF }; // padded with 1s huffman_result_t result; ck_assert(huffman_encode(buf, strlen(buf), &result)); check_encoded_val(encoded, 22, result.value, result.length); free(result.value); }
int jpeg_encode(unsigned char* in_buf, unsigned char* out_buf) { unsigned char block[BLOCK_SIZE * BLOCK_SIZE]; short block_o[BLOCK_SIZE * BLOCK_SIZE]; init_buf(out_buf); huffman_start(IMAGE_HEIGHT, IMAGE_WIDTH, Y_IMAGE, quality); unsigned y, x; for (y = 0; y < IMAGE_HEIGHT; y += 8) { for (x = 0; x < IMAGE_WIDTH; x += 8) { get_block(x, y, 8, 8, in_buf, block); dct3(block, block_o); block_o[0] -= 1024; huffman_encode(HUFFMAN_CTX_Y, block_o); } } huffman_stop(); return get_size(); }
int main (int argc, char *argv[]) { CBitmap bmp; #ifdef INVERSE FILE *fileY = fopen("dump.y.bin", "wb"); FILE *fileCb = fopen("dump.cb.bin", "wb"); FILE *fileCr = fopen("dump.cr.bin", "wb"); #endif //unsigned i; if (argc < 3) { fprintf(stderr, "Usage: %s file-in.bmp file-out.jpg\n", argv[0]); return -1; } if (!bmp.Load(argv[1])) { fprintf(stderr, "Error: cannot open %s\n", argv[1]); return -1; } if (bmp.GetBitCount() != 24) { fprintf(stderr, "Error BitCount != 24\n"); return -1; } /*recalc_qtab(512, qtable_paint_lum, 0); recalc_qtab(1024, qtable_paint_lum, 1); recalc_qtab(512, qtable_paint_chrom, 0); recalc_qtab(1024, qtable_paint_chrom, 1);*/ BGR RGB16x16[16][16]; CACHE_ALIGN conv Y8x8[2][2][8][8]; // four 8x8 blocks - 16x16 CACHE_ALIGN conv Cb8x8[8][8]; CACHE_ALIGN conv Cr8x8[8][8]; //dct_fill_tab(); // for IDCT if ((file_jpg = open(argv[2], O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IWRITE)) < 0) { fprintf(stderr, "Error: cannot create %s (%s)\n", argv[2], strerror(errno)); return -1; } uint64_t tm = __rdtsc(); // Process image by 16x16 blocks, (16x16 because of chroma subsampling) // The resulting image will be truncated on the right/down side // if its width/height is not multiple of 16. // The data is written into <file_jpg> file by write_jpeg() function // which Huffman encoder uses to flush its output, so this file // should be opened before the call of huffman_start(). huffman_start(bmp.GetHeight() & -16, bmp.GetWidth() & -16); for (unsigned y = 0; y < bmp.GetHeight()-15; y += 16) { for (unsigned x = 0; x < bmp.GetWidth()-15; x += 16) { if (!bmp.GetBlock(x, y, 16, 16, (BGR*)RGB16x16)) { printf("Error: getBlock(%d,%d)\n", x, y); break; } /* // geting four 8x8 Y-blocks for (unsigned i = 0; i < 2; i++) for (unsigned j = 0; j < 2; j++) { for (unsigned r = 0; r < 8; r++) for (unsigned c = 0; c < 8; c++) { const unsigned rr = (i<<3) + r; const unsigned cc = (j<<3) + c; const color R = RGB16x16[rr][cc].Red; const color G = RGB16x16[rr][cc].Green; const color B = RGB16x16[rr][cc].Blue; // converting RGB into Y (luminance) Y8x8[i][j][r][c] = RGB2Y(R, G, B)-128; } } // getting subsampled Cb and Cr subsample(RGB16x16, Cb8x8, Cr8x8); */ // getting subsampled Cb and Cr subsample2(RGB16x16, Y8x8, Cb8x8, Cr8x8); uint64_t tmj = __rdtsc(); // 1 Y-compression dct3(Y8x8[0][0], Y8x8[0][0]); //quantization_lum(Y8x8[0][0]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[0][0]); // 2 Y-compression dct3(Y8x8[0][1], Y8x8[0][1]); //quantization_lum(Y8x8[0][1]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[0][1]); // 3 Y-compression dct3(Y8x8[1][0], Y8x8[1][0]); //quantization_lum(Y8x8[1][0]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[1][0]); // 4 Y-compression dct3(Y8x8[1][1], Y8x8[1][1]); //quantization_lum(Y8x8[1][1]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[1][1]); // Cb-compression dct3(Cb8x8, Cb8x8); //quantization_chrom(Cb8x8); huffman_encode(HUFFMAN_CTX_Cb, (conv*)Cb8x8); // Cr-compression dct3(Cr8x8, Cr8x8); //quantization_chrom(Cr8x8); huffman_encode(HUFFMAN_CTX_Cr, (conv*)Cr8x8); jpgclk += __rdtsc() - tmj; #ifdef INVERSE quantization_lum(Y8x8[0][0]); quantization_lum(Y8x8[0][1]); quantization_lum(Y8x8[1][0]); quantization_lum(Y8x8[1][1]); quantization_chrom(Cb8x8); quantization_chrom(Cr8x8); dump((conv*)Y8x8[0][0], fileY); dump((conv*)Y8x8[0][1], fileY); dump((conv*)Y8x8[1][0], fileY); dump((conv*)Y8x8[1][1], fileY); dump((conv*)Cb8x8, fileCb); dump((conv*)Cr8x8, fileCr); // inverse DCTs - getting pixels back iquantization_lum(Y8x8[0][0]); idct3(Y8x8[0][0], Y8x8[0][0]); //correct_color(Y8x8[0][0]); iquantization_lum(Y8x8[0][1]); idct3(Y8x8[0][1], Y8x8[0][1]); //correct_color(Y8x8[0][1]); iquantization_lum(Y8x8[1][0]); idct3(Y8x8[1][0], Y8x8[1][0]); //correct_color(Y8x8[1][0]); iquantization_lum(Y8x8[1][1]); idct3(Y8x8[1][1], Y8x8[1][1]); //correct_color(Y8x8[1][1]); iquantization_chrom(Cb8x8); idct3(Cb8x8, Cb8x8); //correct_color(Cb8x8); iquantization_chrom(Cr8x8); idct3(Cr8x8, Cr8x8); //correct_color(Cr8x8); for (unsigned i = 0; i < 2; i++) for (unsigned j = 0; j < 2; j++) { for (unsigned r = 0; r < 8; r += 2) for (unsigned c = 0; c < 8; c += 2) { const unsigned rr = (i<<3) + r; const unsigned cc = (j<<3) + c; // convert pixels back into RGB const conv Cb = Cb8x8[rr>>1][cc>>1] + 128; const conv Cr = Cr8x8[rr>>1][cc>>1] + 128; conv Y; Y = Y8x8[i][j][r][c] + 128; RGB16x16[rr][cc].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr][cc].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr][cc].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r][c+1] + 128; RGB16x16[rr][cc+1].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr][cc+1].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr][cc+1].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r+1][c] + 128; RGB16x16[rr+1][cc].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr+1][cc].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr+1][cc].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r+1][c+1] + 128; RGB16x16[rr+1][cc+1].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr+1][cc+1].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr+1][cc+1].Blue = YCbCr2B(Y, Cb, Cr); } } // save pixels if (!bmp.SetBlock(x, y, 16, 16, (BGR*)RGB16x16)) { printf("Error: SetBlock(%d,%d)\n", x, y); } #endif } } huffman_stop(); tm = __rdtsc() - tm; close(file_jpg); printf(" DCT MIPS:\t\t%f\n", dctclk/1.e6); printf("JPEG MIPS:\t\t%f\n", jpgclk/1.e6); printf("IDCT MIPS(SSE2):\t%f\n", idctclk/1.e6); printf(" ALL MIPS:\t\t%f\n", tm/1.e6); #ifdef INVERSE bmp.Save("testz.bmp"); fclose(fileY); fclose(fileCb); fclose(fileCr); #endif return 0; }