@@ -262,11 +262,11 @@ static int ReadHuffmanCodeLengths(
262262 int symbol ;
263263 int max_symbol ;
264264 int prev_code_len = DEFAULT_CODE_LENGTH ;
265- HuffmanCode table [ 1 << LENGTHS_TABLE_BITS ] ;
265+ HuffmanTables tables ;
266266
267- if (!VP8LBuildHuffmanTable ( table , LENGTHS_TABLE_BITS ,
268- code_length_code_lengths ,
269- NUM_CODE_LENGTH_CODES )) {
267+ if (!VP8LHuffmanTablesAllocate ( 1 << LENGTHS_TABLE_BITS , & tables ) ||
268+ ! VP8LBuildHuffmanTable ( & tables , LENGTHS_TABLE_BITS ,
269+ code_length_code_lengths , NUM_CODE_LENGTH_CODES )) {
270270 goto End ;
271271 }
272272
@@ -286,7 +286,7 @@ static int ReadHuffmanCodeLengths(
286286 int code_len ;
287287 if (max_symbol -- == 0 ) break ;
288288 VP8LFillBitWindow (br );
289- p = & table [VP8LPrefetchBits (br ) & LENGTHS_TABLE_MASK ];
289+ p = & tables . curr_segment -> start [VP8LPrefetchBits (br ) & LENGTHS_TABLE_MASK ];
290290 VP8LSetBitPos (br , br -> bit_pos_ + p -> bits );
291291 code_len = p -> value ;
292292 if (code_len < kCodeLengthLiterals ) {
@@ -309,14 +309,16 @@ static int ReadHuffmanCodeLengths(
309309 ok = 1 ;
310310
311311 End :
312+ VP8LHuffmanTablesDeallocate (& tables );
312313 if (!ok ) return VP8LSetError (dec , VP8_STATUS_BITSTREAM_ERROR );
313314 return ok ;
314315}
315316
316317// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
317318// tree.
318319static int ReadHuffmanCode (int alphabet_size , VP8LDecoder * const dec ,
319- int * const code_lengths , HuffmanCode * const table ) {
320+ int * const code_lengths ,
321+ HuffmanTables * const table ) {
320322 int ok = 0 ;
321323 int size = 0 ;
322324 VP8LBitReader * const br = & dec -> br_ ;
@@ -367,8 +369,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
367369 VP8LMetadata * const hdr = & dec -> hdr_ ;
368370 uint32_t * huffman_image = NULL ;
369371 HTreeGroup * htree_groups = NULL ;
370- HuffmanCode * huffman_tables = NULL ;
371- HuffmanCode * huffman_table = NULL ;
372+ HuffmanTables * huffman_tables = & hdr -> huffman_tables_ ;
372373 int num_htree_groups = 1 ;
373374 int num_htree_groups_max = 1 ;
374375 const int max_alphabet_size =
@@ -378,6 +379,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
378379 int * mapping = NULL ;
379380 int ok = 0 ;
380381
382+ // Check the table has been 0 initialized (through InitMetadata).
383+ assert (huffman_tables -> root .start == NULL );
384+ assert (huffman_tables -> curr_segment == NULL );
385+
381386 if (allow_recursion && VP8LReadBits (br , 1 )) {
382387 // use meta Huffman codes.
383388 const int huffman_precision = VP8LReadBits (br , 3 ) + 2 ;
@@ -429,16 +434,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
429434
430435 code_lengths = (int * )WebPSafeCalloc ((uint64_t )max_alphabet_size ,
431436 sizeof (* code_lengths ));
432- huffman_tables = (HuffmanCode * )WebPSafeMalloc (num_htree_groups * table_size ,
433- sizeof (* huffman_tables ));
434437 htree_groups = VP8LHtreeGroupsNew (num_htree_groups );
435438
436- if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL ) {
439+ if (htree_groups == NULL || code_lengths == NULL ||
440+ !VP8LHuffmanTablesAllocate (num_htree_groups * table_size ,
441+ huffman_tables )) {
437442 VP8LSetError (dec , VP8_STATUS_OUT_OF_MEMORY );
438443 goto Error ;
439444 }
440445
441- huffman_table = huffman_tables ;
442446 for (i = 0 ; i < num_htree_groups_max ; ++ i ) {
443447 // If the index "i" is unused in the Huffman image, just make sure the
444448 // coefficients are valid but do not store them.
@@ -463,19 +467,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
463467 int max_bits = 0 ;
464468 for (j = 0 ; j < HUFFMAN_CODES_PER_META_CODE ; ++ j ) {
465469 int alphabet_size = kAlphabetSize [j ];
466- htrees [j ] = huffman_table ;
467470 if (j == 0 && color_cache_bits > 0 ) {
468471 alphabet_size += (1 << color_cache_bits );
469472 }
470- size = ReadHuffmanCode (alphabet_size , dec , code_lengths , huffman_table );
473+ size =
474+ ReadHuffmanCode (alphabet_size , dec , code_lengths , huffman_tables );
475+ htrees [j ] = huffman_tables -> curr_segment -> curr_table ;
471476 if (size == 0 ) {
472477 goto Error ;
473478 }
474479 if (is_trivial_literal && kLiteralMap [j ] == 1 ) {
475- is_trivial_literal = (huffman_table -> bits == 0 );
480+ is_trivial_literal = (htrees [ j ] -> bits == 0 );
476481 }
477- total_size += huffman_table -> bits ;
478- huffman_table += size ;
482+ total_size += htrees [ j ] -> bits ;
483+ huffman_tables -> curr_segment -> curr_table += size ;
479484 if (j <= ALPHA ) {
480485 int local_max_bits = code_lengths [0 ];
481486 int k ;
@@ -510,14 +515,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
510515 hdr -> huffman_image_ = huffman_image ;
511516 hdr -> num_htree_groups_ = num_htree_groups ;
512517 hdr -> htree_groups_ = htree_groups ;
513- hdr -> huffman_tables_ = huffman_tables ;
514518
515519 Error :
516520 WebPSafeFree (code_lengths );
517521 WebPSafeFree (mapping );
518522 if (!ok ) {
519523 WebPSafeFree (huffman_image );
520- WebPSafeFree (huffman_tables );
524+ VP8LHuffmanTablesDeallocate (huffman_tables );
521525 VP8LHtreeGroupsFree (htree_groups );
522526 }
523527 return ok ;
@@ -1352,7 +1356,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
13521356 assert (hdr != NULL );
13531357
13541358 WebPSafeFree (hdr -> huffman_image_ );
1355- WebPSafeFree ( hdr -> huffman_tables_ );
1359+ VP8LHuffmanTablesDeallocate ( & hdr -> huffman_tables_ );
13561360 VP8LHtreeGroupsFree (hdr -> htree_groups_ );
13571361 VP8LColorCacheClear (& hdr -> color_cache_ );
13581362 VP8LColorCacheClear (& hdr -> saved_color_cache_ );
@@ -1666,7 +1670,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
16661670
16671671 if (dec == NULL ) return 0 ;
16681672
1669- assert (dec -> hdr_ .huffman_tables_ != NULL );
1673+ assert (dec -> hdr_ .huffman_tables_ . root . start != NULL );
16701674 assert (dec -> hdr_ .htree_groups_ != NULL );
16711675 assert (dec -> hdr_ .num_htree_groups_ > 0 );
16721676
0 commit comments