Skip to Content.
Sympa Menu

sm-commit - [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (01c64e09815a68402c3c14065c2db76fd2952246)

sm-commit AT lists.ibiblio.org

Subject: Source Mage code commit list

List archive

Chronological Thread  
  • From: Pavel Vinogradov <scm AT sourcemage.org>
  • To: sm-commit AT lists.ibiblio.org
  • Subject: [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (01c64e09815a68402c3c14065c2db76fd2952246)
  • Date: Wed, 13 Sep 2023 22:09:08 +0000

GIT changes to master grimoire by Pavel Vinogradov <public AT sourcemage.org>:

graphics-libs/libwebp/DETAILS | 2
graphics-libs/libwebp/HISTORY | 5
graphics-libs/libwebp/PRE_BUILD | 4
graphics-libs/libwebp/patches/CVE-2023-4863.patch | 482
++++++++++++++++++++++
4 files changed, 492 insertions(+), 1 deletion(-)

New commits:
commit 01c64e09815a68402c3c14065c2db76fd2952246
Author: Pavel Vinogradov <public AT sourcemage.org>
Commit: Pavel Vinogradov <public AT sourcemage.org>

graphics-libs/libwebp: SECURITY_PATCH++, (CVE-2023-4863)

diff --git a/graphics-libs/libwebp/DETAILS b/graphics-libs/libwebp/DETAILS
index 724d365..b72ab6b 100755
--- a/graphics-libs/libwebp/DETAILS
+++ b/graphics-libs/libwebp/DETAILS
@@ -1,6 +1,6 @@
SPELL=libwebp
VERSION=1.3.1
- SECURITY_PATCH=2
+ SECURITY_PATCH=3
SOURCE=$SPELL-$VERSION.tar.gz
SOURCE_DIRECTORY=$BUILD_DIRECTORY/$SPELL-$VERSION
SOURCE_URL[0]=http://downloads.webmproject.org/releases/webp/$SOURCE
diff --git a/graphics-libs/libwebp/HISTORY b/graphics-libs/libwebp/HISTORY
index 67f09b5..4ac18f2 100644
--- a/graphics-libs/libwebp/HISTORY
+++ b/graphics-libs/libwebp/HISTORY
@@ -1,3 +1,8 @@
+2023-09-13 Pavel Vinogradov <public AT sorcemage.org>
+ * DETAILS: SECURITY_PATCH++, (CVE-2023-4863)
+ * PRE_BUILD, patches/CVE-2023-4863.patch: added slightly modified
security
+ patch from Mozilla
+
2023-07-02 Treeve Jelbert <treeve AT sourcemage.org>
* DETAILS: version 1.3.1
SECURITY_PATCH++ fixes CVE-2023-1999
diff --git a/graphics-libs/libwebp/PRE_BUILD b/graphics-libs/libwebp/PRE_BUILD
new file mode 100755
index 0000000..f80ee7d
--- /dev/null
+++ b/graphics-libs/libwebp/PRE_BUILD
@@ -0,0 +1,4 @@
+default_pre_build &&
+cd "${SOURCE_DIRECTORY}" &&
+
+apply_patch_dir patches
diff --git a/graphics-libs/libwebp/patches/CVE-2023-4863.patch
b/graphics-libs/libwebp/patches/CVE-2023-4863.patch
new file mode 100644
index 0000000..eec6270
--- /dev/null
+++ b/graphics-libs/libwebp/patches/CVE-2023-4863.patch
@@ -0,0 +1,482 @@
+
+# HG changeset patch
+# User Ryan VanderMeulen <ryanvm AT gmail.com>
+# Date 1694477965 14400
+# Node ID e245ca2125a6eb1e2d08cc9e5824f15e1e67a566
+# Parent 17519f7f45d34a47ad1472f1ce1366a9400bb3b3
+Bug 1852649 - Cherry-pick upstream libwebp fix. r=tnikkel, a=RyanVM
+
+Backport of:
+https://chromium.googlesource.com/webm/libwebp.git/+/2af26267cdfcb63a88e5c74a85927a12d6ca1d76
+
+Differential Revision: https://phabricator.services.mozilla.com/D187950
+
+diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c
+--- a/src/dec/vp8l_dec.c
++++ b/src/dec/vp8l_dec.c
+@@ -248,21 +248,21 @@ static void BuildPackedTable(HTreeGroup*
+ static int ReadHuffmanCodeLengths(
+ VP8LDecoder* const dec, const int* const code_length_code_lengths,
+ int num_symbols, int* const code_lengths) {
+ int ok = 0;
+ VP8LBitReader* const br = &dec->br_;
+ int symbol;
+ int max_symbol;
+ int prev_code_len = DEFAULT_CODE_LENGTH;
+- HuffmanCode table[1 << LENGTHS_TABLE_BITS];
++ HuffmanTables tables;
+
+- if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
+- code_length_code_lengths,
+- NUM_CODE_LENGTH_CODES)) {
++ if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
++ !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
++ code_length_code_lengths,
NUM_CODE_LENGTH_CODES)) {
+ goto End;
+ }
+
+ if (VP8LReadBits(br, 1)) { // use length
+ const int length_nbits = 2 + 2 * VP8LReadBits(br, 3);
+ max_symbol = 2 + VP8LReadBits(br, length_nbits);
+ if (max_symbol > num_symbols) {
+ goto End;
+@@ -272,17 +272,17 @@ static int ReadHuffmanCodeLengths(
+ }
+
+ symbol = 0;
+ while (symbol < num_symbols) {
+ const HuffmanCode* p;
+ int code_len;
+ if (max_symbol-- == 0) break;
+ VP8LFillBitWindow(br);
+- p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
++ p = &tables.curr_segment->start[VP8LPrefetchBits(br) &
LENGTHS_TABLE_MASK];
+ VP8LSetBitPos(br, br->bit_pos_ + p->bits);
+ code_len = p->value;
+ if (code_len < kCodeLengthLiterals) {
+ code_lengths[symbol++] = code_len;
+ if (code_len != 0) prev_code_len = code_len;
+ } else {
+ const int use_prev = (code_len == kCodeLengthRepeatCode);
+ const int slot = code_len - kCodeLengthLiterals;
+@@ -295,24 +295,26 @@ static int ReadHuffmanCodeLengths(
+ const int length = use_prev ? prev_code_len : 0;
+ while (repeat-- > 0) code_lengths[symbol++] = length;
+ }
+ }
+ }
+ ok = 1;
+
+ End:
++ VP8LHuffmanTablesDeallocate(&tables);
+ if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return ok;
+ }
+
+ // 'code_lengths' is pre-allocated temporary buffer, used for creating
Huffman
+ // tree.
+ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
+- int* const code_lengths, HuffmanCode* const
table) {
++ int* const code_lengths,
++ HuffmanTables* const table) {
+ int ok = 0;
+ int size = 0;
+ VP8LBitReader* const br = &dec->br_;
+ const int simple_code = VP8LReadBits(br, 1);
+
+ memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths));
+
+ if (simple_code) { // Read symbols, codes & code lengths directly.
+@@ -357,26 +359,29 @@ static int ReadHuffmanCode(int alphabet_
+
+ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ int color_cache_bits, int allow_recursion) {
+ int i, j;
+ VP8LBitReader* const br = &dec->br_;
+ VP8LMetadata* const hdr = &dec->hdr_;
+ uint32_t* huffman_image = NULL;
+ HTreeGroup* htree_groups = NULL;
+- HuffmanCode* huffman_tables = NULL;
+- HuffmanCode* huffman_table = NULL;
++ HuffmanTables* huffman_tables = &hdr->huffman_tables_;
+ int num_htree_groups = 1;
+ int num_htree_groups_max = 1;
+ int max_alphabet_size = 0;
+ int* code_lengths = NULL;
+ const int table_size = kTableSize[color_cache_bits];
+ int* mapping = NULL;
+ int ok = 0;
+
++ // Check the table has been 0 initialized (through InitMetadata).
++ assert(huffman_tables->root.start == NULL);
++ assert(huffman_tables->curr_segment == NULL);
++
+ if (allow_recursion && VP8LReadBits(br, 1)) {
+ // use meta Huffman codes.
+ const int huffman_precision = VP8LReadBits(br, 3) + 2;
+ const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
+ const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
+ const int huffman_pixs = huffman_xsize * huffman_ysize;
+ if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec,
+ &huffman_image)) {
+@@ -429,26 +434,25 @@ static int ReadHuffmanCodes(VP8LDecoder*
+ }
+ if (max_alphabet_size < alphabet_size) {
+ max_alphabet_size = alphabet_size;
+ }
+ }
+
+ code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
+ sizeof(*code_lengths));
+- huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups *
table_size,
+- sizeof(*huffman_tables));
+ htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
+
+- if (htree_groups == NULL || code_lengths == NULL || huffman_tables ==
NULL) {
++ if (htree_groups == NULL || code_lengths == NULL ||
++ !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
++ huffman_tables)) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ goto Error;
+ }
+
+- huffman_table = huffman_tables;
+ for (i = 0; i < num_htree_groups_max; ++i) {
+ // If the index "i" is unused in the Huffman image, just make sure the
+ // coefficients are valid but do not store them.
+ if (mapping != NULL && mapping[i] == -1) {
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+ int alphabet_size = kAlphabetSize[j];
+ if (j == 0 && color_cache_bits > 0) {
+ alphabet_size += (1 << color_cache_bits);
+@@ -463,29 +467,30 @@ static int ReadHuffmanCodes(VP8LDecoder*
+ &htree_groups[(mapping == NULL) ? i : mapping[i]];
+ HuffmanCode** const htrees = htree_group->htrees;
+ int size;
+ int total_size = 0;
+ int is_trivial_literal = 1;
+ int max_bits = 0;
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+ int alphabet_size = kAlphabetSize[j];
+- htrees[j] = huffman_table;
+ if (j == 0 && color_cache_bits > 0) {
+ alphabet_size += (1 << color_cache_bits);
+ }
+- size = ReadHuffmanCode(alphabet_size, dec, code_lengths,
huffman_table);
++ size =
++ ReadHuffmanCode(alphabet_size, dec, code_lengths,
huffman_tables);
++ htrees[j] = huffman_tables->curr_segment->curr_table;
+ if (size == 0) {
+ goto Error;
+ }
+ if (is_trivial_literal && kLiteralMap[j] == 1) {
+- is_trivial_literal = (huffman_table->bits == 0);
++ is_trivial_literal = (htrees[j]->bits == 0);
+ }
+- total_size += huffman_table->bits;
+- huffman_table += size;
++ total_size += htrees[j]->bits;
++ huffman_tables->curr_segment->curr_table += size;
+ if (j <= ALPHA) {
+ int local_max_bits = code_lengths[0];
+ int k;
+ for (k = 1; k < alphabet_size; ++k) {
+ if (code_lengths[k] > local_max_bits) {
+ local_max_bits = code_lengths[k];
+ }
+ }
+@@ -510,24 +515,23 @@ static int ReadHuffmanCodes(VP8LDecoder*
+ }
+ }
+ ok = 1;
+
+ // All OK. Finalize pointers.
+ hdr->huffman_image_ = huffman_image;
+ hdr->num_htree_groups_ = num_htree_groups;
+ hdr->htree_groups_ = htree_groups;
+- hdr->huffman_tables_ = huffman_tables;
+
+ Error:
+ WebPSafeFree(code_lengths);
+ WebPSafeFree(mapping);
+ if (!ok) {
+ WebPSafeFree(huffman_image);
+- WebPSafeFree(huffman_tables);
++ VP8LHuffmanTablesDeallocate(huffman_tables);
+ VP8LHtreeGroupsFree(htree_groups);
+ }
+ return ok;
+ }
+
+
//------------------------------------------------------------------------------
+ // Scaling.
+
+@@ -1353,17 +1357,17 @@ static void InitMetadata(VP8LMetadata* c
+ assert(hdr != NULL);
+ memset(hdr, 0, sizeof(*hdr));
+ }
+
+ static void ClearMetadata(VP8LMetadata* const hdr) {
+ assert(hdr != NULL);
+
+ WebPSafeFree(hdr->huffman_image_);
+- WebPSafeFree(hdr->huffman_tables_);
++ VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
+ VP8LHtreeGroupsFree(hdr->htree_groups_);
+ VP8LColorCacheClear(&hdr->color_cache_);
+ VP8LColorCacheClear(&hdr->saved_color_cache_);
+ InitMetadata(hdr);
+ }
+
+ //
-----------------------------------------------------------------------------
+ // VP8LDecoder
+@@ -1668,17 +1672,17 @@ int VP8LDecodeHeader(VP8LDecoder* const
+ }
+
+ int VP8LDecodeImage(VP8LDecoder* const dec) {
+ VP8Io* io = NULL;
+ WebPDecParams* params = NULL;
+
+ if (dec == NULL) return 0;
+
+- assert(dec->hdr_.huffman_tables_ != NULL);
++ assert(dec->hdr_.huffman_tables_.root.start != NULL);
+ assert(dec->hdr_.htree_groups_ != NULL);
+ assert(dec->hdr_.num_htree_groups_ > 0);
+
+ io = dec->io_;
+ assert(io != NULL);
+ params = (WebPDecParams*)io->opaque;
+ assert(params != NULL);
+
+diff --git a/src/dec/vp8li_dec.h b/src/dec/vp8li_dec.h
+--- a/src/dec/vp8li_dec.h
++++ b/src/dec/vp8li_dec.h
+@@ -46,17 +46,17 @@ typedef struct {
+ VP8LColorCache saved_color_cache_; // for incremental
+
+ int huffman_mask_;
+ int huffman_subsample_bits_;
+ int huffman_xsize_;
+ uint32_t* huffman_image_;
+ int num_htree_groups_;
+ HTreeGroup* htree_groups_;
+- HuffmanCode* huffman_tables_;
++ HuffmanTables huffman_tables_;
+ } VP8LMetadata;
+
+ typedef struct VP8LDecoder VP8LDecoder;
+ struct VP8LDecoder {
+ VP8StatusCode status_;
+ VP8LDecodeState state_;
+ VP8Io* io_;
+
+diff --git a/src/utils/huffman_utils.c b/src/utils/huffman_utils.c
+--- a/src/utils/huffman_utils.c
++++ b/src/utils/huffman_utils.c
+@@ -172,31 +172,34 @@ static int BuildHuffmanTable(HuffmanCode
+ for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH;
+ ++len, step <<= 1) {
+ num_open <<= 1;
+ num_nodes += num_open;
+ num_open -= count[len];
+ if (num_open < 0) {
+ return 0;
+ }
+- if (root_table == NULL) continue;
+ for (; count[len] > 0; --count[len]) {
+ HuffmanCode code;
+ if ((key & mask) != low) {
+- table += table_size;
++ if (root_table != NULL) table += table_size;
+ table_bits = NextTableBitSize(count, len, root_bits);
+ table_size = 1 << table_bits;
+ total_size += table_size;
+ low = key & mask;
+- root_table[low].bits = (uint8_t)(table_bits + root_bits);
+- root_table[low].value = (uint16_t)((table - root_table) - low);
++ if (root_table != NULL) {
++ root_table[low].bits = (uint8_t)(table_bits + root_bits);
++ root_table[low].value = (uint16_t)((table - root_table) - low);
++ }
+ }
+- code.bits = (uint8_t)(len - root_bits);
+- code.value = (uint16_t)sorted[symbol++];
+- ReplicateValue(&table[key >> root_bits], step, table_size, code);
++ if (root_table != NULL) {
++ code.bits = (uint8_t)(len - root_bits);
++ code.value = (uint16_t)sorted[symbol++];
++ ReplicateValue(&table[key >> root_bits], step, table_size, code);
++ }
+ key = GetNextKey(key, len);
+ }
+ }
+
+ // Check if tree is full.
+ if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) {
+ return 0;
+ }
+@@ -206,30 +209,88 @@ static int BuildHuffmanTable(HuffmanCode
+ }
+
+ // Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits).
+ // More commonly, the value is around ~280.
+ #define MAX_CODE_LENGTHS_SIZE \
+ ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
+ // Cut-off value for switching between heap and stack allocation.
+ #define SORTED_SIZE_CUTOFF 512
+-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
++int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size) {
+- int total_size;
++ const int total_size =
++ BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size,
NULL);
+ assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
+- if (root_table == NULL) {
+- total_size = BuildHuffmanTable(NULL, root_bits,
+- code_lengths, code_lengths_size, NULL);
+- } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
++ if (total_size == 0 || root_table == NULL) return total_size;
++
++ if (root_table->curr_segment->curr_table + total_size >=
++ root_table->curr_segment->start + root_table->curr_segment->size) {
++ // If 'root_table' does not have enough memory, allocate a new segment.
++ // The available part of root_table->curr_segment is left unused
because we
++ // need a contiguous buffer.
++ const int segment_size = root_table->curr_segment->size;
++ struct HuffmanTablesSegment* next =
++ (HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
++ if (next == NULL) return 0;
++ // Fill the new segment.
++ // We need at least 'total_size' but if that value is small, it is
better to
++ // allocate a big chunk to prevent more allocations later.
'segment_size' is
++ // therefore chosen (any other arbitrary value could be chosen).
++ next->size = total_size > segment_size ? total_size : segment_size;
++ next->start =
++ (HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
++ if (next->start == NULL) {
++ WebPSafeFree(next);
++ return 0;
++ }
++ next->curr_table = next->start;
++ next->next = NULL;
++ // Point to the new segment.
++ root_table->curr_segment->next = next;
++ root_table->curr_segment = next;
++ }
++ if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+ // use local stack-allocated array.
+ uint16_t sorted[SORTED_SIZE_CUTOFF];
+- total_size = BuildHuffmanTable(root_table, root_bits,
+- code_lengths, code_lengths_size, sorted);
+- } else { // rare case. Use heap allocation.
++ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
++ code_lengths, code_lengths_size, sorted);
++ } else { // rare case. Use heap allocation.
+ uint16_t* const sorted =
+ (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
+ if (sorted == NULL) return 0;
+- total_size = BuildHuffmanTable(root_table, root_bits,
+- code_lengths, code_lengths_size, sorted);
++ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
++ code_lengths, code_lengths_size, sorted);
+ WebPSafeFree(sorted);
+ }
+ return total_size;
+ }
++
++int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
++ // Have 'segment' point to the first segment for now, 'root'.
++ HuffmanTablesSegment* const root = &huffman_tables->root;
++ huffman_tables->curr_segment = root;
++ // Allocate root.
++ root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
++ if (root->start == NULL) return 0;
++ root->curr_table = root->start;
++ root->next = NULL;
++ root->size = size;
++ return 1;
++}
++
++void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
++ HuffmanTablesSegment *current, *next;
++ if (huffman_tables == NULL) return;
++ // Free the root node.
++ current = &huffman_tables->root;
++ next = current->next;
++ WebPSafeFree(current->start);
++ current->start = NULL;
++ current->next = NULL;
++ current = next;
++ // Free the following nodes.
++ while (current != NULL) {
++ next = current->next;
++ WebPSafeFree(current->start);
++ WebPSafeFree(current);
++ current = next;
++ }
++}
+diff --git a/src/utils/huffman_utils.h b/src/utils/huffman_utils.h
+--- a/src/utils/huffman_utils.h
++++ b/src/utils/huffman_utils.h
+@@ -38,16 +38,39 @@ typedef struct {
+ // long version for holding 32b values
+ typedef struct {
+ int bits; // number of bits used for this symbol,
+ // or an impossible value if not a literal code.
+ uint32_t value; // 32b packed ARGB value if literal,
+ // or non-literal symbol otherwise
+ } HuffmanCode32;
+
++// Contiguous memory segment of HuffmanCodes.
++typedef struct HuffmanTablesSegment {
++ HuffmanCode* start;
++ // Pointer to where we are writing into the segment. Starts at 'start' and
++ // cannot go beyond 'start' + 'size'.
++ HuffmanCode* curr_table;
++ // Pointer to the next segment in the chain.
++ struct HuffmanTablesSegment* next;
++ int size;
++} HuffmanTablesSegment;
++
++// Chained memory segments of HuffmanCodes.
++typedef struct HuffmanTables {
++ HuffmanTablesSegment root;
++ // Currently processed segment. At first, this is 'root'.
++ HuffmanTablesSegment* curr_segment;
++} HuffmanTables;
++
++// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0
on
++// memory allocation error, 1 otherwise.
++int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
++void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
++
+ #define HUFFMAN_PACKED_BITS 6
+ #define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
+
+ // Huffman table group.
+ // Includes special handling for the following cases:
+ // - is_trivial_literal: one common literal base for RED/BLUE/ALPHA (not
GREEN)
+ // - is_trivial_code: only 1 code (no bit is read from bitstream)
+ // - use_packed_table: few enough literal symbols, so all the bit codes
+@@ -73,18 +96,16 @@ HTreeGroup* VP8LHtreeGroupsNew(int num_h
+ // Releases the memory allocated for HTreeGroup.
+ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
+
+ // Builds Huffman lookup table assuming code lengths are in symbol order.
+ // The 'code_lengths' is pre-allocated temporary memory buffer used for
creating
+ // the huffman table.
+ // Returns built table size or 0 in case of error (invalid tree or
+ // memory error).
+-// If root_table is NULL, it returns 0 if a lookup cannot be built,
something
+-// > 0 otherwise (but not the table size).
+-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
++int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size);
+
+ #ifdef __cplusplus
+ } // extern "C"
+ #endif
+
+ #endif // WEBP_UTILS_HUFFMAN_UTILS_H_
+



  • [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (01c64e09815a68402c3c14065c2db76fd2952246), Pavel Vinogradov, 09/13/2023

Archive powered by MHonArc 2.6.24.

Top of Page