/****************************************************************************** ** huffman_encode ** -------------------------------------------------------------------------- ** Quantize and Encode a 8x8 DCT block by JPEG Huffman lossless coding. ** This function writes encoded bit-stream into bit-buffer. ** ** ARGUMENTS: ** ctx - pointer to encoder context; ** data - pointer to 8x8 DCT block; ** ** RETURN: - ******************************************************************************/ void huffman_encode(huffman_t *const ctx, const short data[], unsigned block_num) { unsigned magn, bits; unsigned zerorun, i; short diff; short dc = quantize(data[0], ctx->qtable[0]); // WARNING: in order to everything to work correctly // the get_DC_value must be called before the block_start // otherwise it returns a wrong DC value in case of megablocks // (the block_start reset the force_marker variable, which is // used by get_DC_value diff = get_DC_value(dc, block_num); block_start(block_num); bits = huffman_bits(diff); magn = huffman_magnitude(diff); add_to_block(ctx->hdcbit[magn], ctx->hdclen[magn]); add_to_block(bits, magn); for (zerorun = 0, i = 1; i < 64; i++) { const short ac = quantize(data[zig[i]], ctx->qtable[zig[i]]); if (ac) { while (zerorun >= 16) { zerorun -= 16; // ZRL add_to_block(ctx->hacbit[15][0], ctx->haclen[15][0]); } bits = huffman_bits(ac); magn = huffman_magnitude(ac); add_to_block(ctx->hacbit[zerorun][magn], ctx->haclen[zerorun][magn]); add_to_block(bits, magn); zerorun = 0; } else zerorun++; } if (zerorun) { // EOB - End Of Block add_to_block(ctx->hacbit[0][0], ctx->haclen[0][0]); } block_end(&bitbuf); }
void huffman_encode(huffman_t * const ctx, const short data[], huffman_encoding_output* current_output) { // initialize the current output block init_huffman_output(current_output); unsigned magn, bits; unsigned zerorun, i; short diff; unsigned int sum_of_bits = 0; short dc = quantize(data[0], ctx->qtable[0]); // printf("dc: %d\n", dc); // difference between old and new DC diff = dc - ctx->dc; ctx->dc = dc; // printf("diff: %i\n", diff); bits = huffman_bits(diff); magn = huffman_magnitude(diff); // writebits(&bitbuf, ctx->hdcbit[magn], ctx->hdclen[magn]); write_huffman_output(current_output, ctx->hdcbit[magn], ctx->hdclen[magn]); // printf("%x %x\n", ctx->hdcbit[magn], ctx->hdclen[magn]); // printf("%u\n", ctx->hdclen[magn]); // printf("writing %u bits\n", ctx->hdclen[magn]); sum_of_bits += ctx->hdclen[magn]; // writebits(&bitbuf, bits, magn); write_huffman_output(current_output, bits, magn); // printf("%u\n", magn); sum_of_bits += magn; for (zerorun = 0, i = 1; i < 64; i++) { const short ac = quantize(data[zig[i]], ctx->qtable[zig[i]]); // printf("data zig: %i\n", data[zig[i]]); // printf("ctx table zig: %i\n", ctx->qtable[zig[i]]); // printf("ac: %i\n", ac); if (ac) { while (zerorun >= 16) { zerorun -= 16; // ZRL // writebits(&bitbuf, ctx->hacbit[15][0], ctx->haclen[15][0]); write_huffman_output(current_output, ctx->hacbit[15][0], ctx->haclen[15][0]); // printf("%u\n", ctx->haclen[15][0]); sum_of_bits += ctx->haclen[15][0]; } bits = huffman_bits(ac); magn = huffman_magnitude(ac); // writebits(&bitbuf, ctx->hacbit[zerorun][magn], ctx->haclen[zerorun][magn]); write_huffman_output(current_output, ctx->hacbit[zerorun][magn], ctx->haclen[zerorun][magn]); // printf("%u\n", ctx->haclen[zerorun][magn]); sum_of_bits += ctx->haclen[zerorun][magn]; // writebits(&bitbuf, bits, magn); write_huffman_output(current_output, bits, magn); // printf("%u\n", magn); sum_of_bits += magn; zerorun = 0; } else zerorun++; } if (zerorun) { // EOB - End Of Block // writebits(&bitbuf, ctx->hacbit[0][0], ctx->haclen[0][0]); write_huffman_output(current_output, ctx->hacbit[0][0], ctx->haclen[0][0]); // printf("%u\n", ctx->haclen[0][0]); sum_of_bits += ctx->haclen[0][0]; } // printf("\n"); // overall_sum_of_bits += sum_of_bits; // printf("Bits written in this block: %u, overall: %u\n", current_output.bit_position, overall_sum_of_bits); // return current_output; }