1*b2055c35SXin Li // Copyright 2012 Google Inc. All Rights Reserved. 2*b2055c35SXin Li // 3*b2055c35SXin Li // Use of this source code is governed by a BSD-style license 4*b2055c35SXin Li // that can be found in the COPYING file in the root of the source 5*b2055c35SXin Li // tree. An additional intellectual property rights grant can be found 6*b2055c35SXin Li // in the file PATENTS. All contributing project authors may 7*b2055c35SXin Li // be found in the AUTHORS file in the root of the source tree. 8*b2055c35SXin Li // ----------------------------------------------------------------------------- 9*b2055c35SXin Li // 10*b2055c35SXin Li // Utilities for building and looking up Huffman trees. 11*b2055c35SXin Li // 12*b2055c35SXin Li // Author: Urvang Joshi ([email protected]) 13*b2055c35SXin Li 14*b2055c35SXin Li #ifndef WEBP_UTILS_HUFFMAN_UTILS_H_ 15*b2055c35SXin Li #define WEBP_UTILS_HUFFMAN_UTILS_H_ 16*b2055c35SXin Li 17*b2055c35SXin Li #include <assert.h> 18*b2055c35SXin Li #include "src/webp/format_constants.h" 19*b2055c35SXin Li #include "src/webp/types.h" 20*b2055c35SXin Li 21*b2055c35SXin Li #ifdef __cplusplus 22*b2055c35SXin Li extern "C" { 23*b2055c35SXin Li #endif 24*b2055c35SXin Li 25*b2055c35SXin Li #define HUFFMAN_TABLE_BITS 8 26*b2055c35SXin Li #define HUFFMAN_TABLE_MASK ((1 << HUFFMAN_TABLE_BITS) - 1) 27*b2055c35SXin Li 28*b2055c35SXin Li #define LENGTHS_TABLE_BITS 7 29*b2055c35SXin Li #define LENGTHS_TABLE_MASK ((1 << LENGTHS_TABLE_BITS) - 1) 30*b2055c35SXin Li 31*b2055c35SXin Li 32*b2055c35SXin Li // Huffman lookup table entry 33*b2055c35SXin Li typedef struct { 34*b2055c35SXin Li uint8_t bits; // number of bits used for this symbol 35*b2055c35SXin Li uint16_t value; // symbol value or table offset 36*b2055c35SXin Li } HuffmanCode; 37*b2055c35SXin Li 38*b2055c35SXin Li // long version for holding 32b values 39*b2055c35SXin Li typedef struct { 40*b2055c35SXin Li int bits; // number of bits used for this symbol, 41*b2055c35SXin Li // or an impossible value if not a literal code. 42*b2055c35SXin Li uint32_t value; // 32b packed ARGB value if literal, 43*b2055c35SXin Li // or non-literal symbol otherwise 44*b2055c35SXin Li } HuffmanCode32; 45*b2055c35SXin Li 46*b2055c35SXin Li // Contiguous memory segment of HuffmanCodes. 47*b2055c35SXin Li typedef struct HuffmanTablesSegment { 48*b2055c35SXin Li HuffmanCode* start; 49*b2055c35SXin Li // Pointer to where we are writing into the segment. Starts at 'start' and 50*b2055c35SXin Li // cannot go beyond 'start' + 'size'. 51*b2055c35SXin Li HuffmanCode* curr_table; 52*b2055c35SXin Li // Pointer to the next segment in the chain. 53*b2055c35SXin Li struct HuffmanTablesSegment* next; 54*b2055c35SXin Li int size; 55*b2055c35SXin Li } HuffmanTablesSegment; 56*b2055c35SXin Li 57*b2055c35SXin Li // Chained memory segments of HuffmanCodes. 58*b2055c35SXin Li typedef struct HuffmanTables { 59*b2055c35SXin Li HuffmanTablesSegment root; 60*b2055c35SXin Li // Currently processed segment. At first, this is 'root'. 61*b2055c35SXin Li HuffmanTablesSegment* curr_segment; 62*b2055c35SXin Li } HuffmanTables; 63*b2055c35SXin Li 64*b2055c35SXin Li // Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on 65*b2055c35SXin Li // memory allocation error, 1 otherwise. 66*b2055c35SXin Li WEBP_NODISCARD int VP8LHuffmanTablesAllocate(int size, 67*b2055c35SXin Li HuffmanTables* huffman_tables); 68*b2055c35SXin Li void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables); 69*b2055c35SXin Li 70*b2055c35SXin Li #define HUFFMAN_PACKED_BITS 6 71*b2055c35SXin Li #define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS) 72*b2055c35SXin Li 73*b2055c35SXin Li // Huffman table group. 74*b2055c35SXin Li // Includes special handling for the following cases: 75*b2055c35SXin Li // - is_trivial_literal: one common literal base for RED/BLUE/ALPHA (not GREEN) 76*b2055c35SXin Li // - is_trivial_code: only 1 code (no bit is read from bitstream) 77*b2055c35SXin Li // - use_packed_table: few enough literal symbols, so all the bit codes 78*b2055c35SXin Li // can fit into a small look-up table packed_table[] 79*b2055c35SXin Li // The common literal base, if applicable, is stored in 'literal_arb'. 80*b2055c35SXin Li typedef struct HTreeGroup HTreeGroup; 81*b2055c35SXin Li struct HTreeGroup { 82*b2055c35SXin Li HuffmanCode* htrees[HUFFMAN_CODES_PER_META_CODE]; 83*b2055c35SXin Li int is_trivial_literal; // True, if huffman trees for Red, Blue & Alpha 84*b2055c35SXin Li // Symbols are trivial (have a single code). 85*b2055c35SXin Li uint32_t literal_arb; // If is_trivial_literal is true, this is the 86*b2055c35SXin Li // ARGB value of the pixel, with Green channel 87*b2055c35SXin Li // being set to zero. 88*b2055c35SXin Li int is_trivial_code; // true if is_trivial_literal with only one code 89*b2055c35SXin Li int use_packed_table; // use packed table below for short literal code 90*b2055c35SXin Li // table mapping input bits to a packed values, or escape case to literal code 91*b2055c35SXin Li HuffmanCode32 packed_table[HUFFMAN_PACKED_TABLE_SIZE]; 92*b2055c35SXin Li }; 93*b2055c35SXin Li 94*b2055c35SXin Li // Creates the instance of HTreeGroup with specified number of tree-groups. 95*b2055c35SXin Li WEBP_NODISCARD HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups); 96*b2055c35SXin Li 97*b2055c35SXin Li // Releases the memory allocated for HTreeGroup. 98*b2055c35SXin Li void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups); 99*b2055c35SXin Li 100*b2055c35SXin Li // Builds Huffman lookup table assuming code lengths are in symbol order. 101*b2055c35SXin Li // The 'code_lengths' is pre-allocated temporary memory buffer used for creating 102*b2055c35SXin Li // the huffman table. 103*b2055c35SXin Li // Returns built table size or 0 in case of error (invalid tree or 104*b2055c35SXin Li // memory error). 105*b2055c35SXin Li WEBP_NODISCARD int VP8LBuildHuffmanTable(HuffmanTables* const root_table, 106*b2055c35SXin Li int root_bits, 107*b2055c35SXin Li const int code_lengths[], 108*b2055c35SXin Li int code_lengths_size); 109*b2055c35SXin Li 110*b2055c35SXin Li #ifdef __cplusplus 111*b2055c35SXin Li } // extern "C" 112*b2055c35SXin Li #endif 113*b2055c35SXin Li 114*b2055c35SXin Li #endif // WEBP_UTILS_HUFFMAN_UTILS_H_ 115