From 52931fd54824e6a467357340011768d78b62c5e4 Mon Sep 17 00:00:00 2001 From: Jyrki Alakuijala Date: Mon, 29 Jun 2015 13:25:42 +0000 Subject: [PATCH] lossless: combine the Huffman code with extra bits gives 2 % speedup 24.9 -> 25.5 MP/s for a photo with -q 0 -m 0 Change-Id: If9ae04683a86dd7b1fced2183cf79b9349a24a9e --- src/enc/vp8l.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/enc/vp8l.c b/src/enc/vp8l.c index 1e0b0b1b..e3e9f704 100644 --- a/src/enc/vp8l.c +++ b/src/enc/vp8l.c @@ -663,7 +663,7 @@ static void StoreHuffmanCode(VP8LBitWriter* const bw, } } -static void WriteHuffmanCode(VP8LBitWriter* const bw, +static WEBP_INLINE void WriteHuffmanCode(VP8LBitWriter* const bw, const HuffmanTreeCode* const code, int code_index) { const int depth = code->code_lengths[code_index]; @@ -671,6 +671,17 @@ static void WriteHuffmanCode(VP8LBitWriter* const bw, VP8LPutBits(bw, symbol, depth); } +static WEBP_INLINE void WriteHuffmanCodeWithExtraBits( + VP8LBitWriter* const bw, + const HuffmanTreeCode* const code, + int code_index, + int bits, + int n_bits) { + const int depth = code->code_lengths[code_index]; + const int symbol = code->codes[code_index]; + VP8LPutBits(bw, (bits << depth) | symbol, depth + n_bits); +} + static WebPEncodingError StoreImageToBitMask( VP8LBitWriter* const bw, int width, int histo_bits, VP8LBackwardRefs* const refs, @@ -695,26 +706,29 @@ static WebPEncodingError StoreImageToBitMask( (x >> histo_bits)]; codes = huffman_codes + 5 * histogram_ix; } - if (PixOrCopyIsCacheIdx(v)) { - const int code = PixOrCopyCacheIdx(v); - const int literal_ix = 256 + NUM_LENGTH_CODES + code; - WriteHuffmanCode(bw, codes, literal_ix); - } else if (PixOrCopyIsLiteral(v)) { + if (PixOrCopyIsLiteral(v)) { static const int order[] = { 1, 2, 0, 3 }; int k; for (k = 0; k < 4; ++k) { const int code = PixOrCopyLiteral(v, order[k]); WriteHuffmanCode(bw, codes + k, code); } + } else if (PixOrCopyIsCacheIdx(v)) { + const int code = PixOrCopyCacheIdx(v); + const int literal_ix = 256 + NUM_LENGTH_CODES + code; + WriteHuffmanCode(bw, codes, literal_ix); } else { int bits, n_bits; - int code, distance; + int code; + const int distance = PixOrCopyDistance(v); VP8LPrefixEncode(v->len, &code, &n_bits, &bits); - WriteHuffmanCode(bw, codes, 256 + code); - VP8LPutBits(bw, bits, n_bits); + WriteHuffmanCodeWithExtraBits(bw, codes, 256 + code, bits, n_bits); - distance = PixOrCopyDistance(v); + // Don't write the distance with the extra bits code since + // the distance can be up to 18 bits of extra bits, and the prefix + // 15 bits, totaling to 33, and our PutBits only supports up to 32 bits. + // TODO(jyrki): optimize this further. VP8LPrefixEncode(distance, &code, &n_bits, &bits); WriteHuffmanCode(bw, codes + 4, code); VP8LPutBits(bw, bits, n_bits);