| 313 | } |
| 314 | |
| 315 | static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, |
| 316 | int alphabet_size) |
| 317 | { |
| 318 | HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } }; |
| 319 | uint8_t *code_lengths; |
| 320 | uint8_t code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; |
| 321 | uint8_t reordered_code_length_code_lengths[NUM_CODE_LENGTH_CODES]; |
| 322 | uint16_t reordered_code_length_syms[NUM_CODE_LENGTH_CODES]; |
| 323 | uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH + 1] = { 0 }; |
| 324 | int symbol, max_symbol, prev_code_len, ret; |
| 325 | int num_codes = 4 + get_bits(&s->gb, 4); |
| 326 | |
| 327 | av_assert1(num_codes <= NUM_CODE_LENGTH_CODES); |
| 328 | |
| 329 | for (int i = 0; i < num_codes; i++) { |
| 330 | unsigned len = get_bits(&s->gb, 3); |
| 331 | code_length_code_lengths[code_length_code_order[i]] = len; |
| 332 | len_counts[len]++; |
| 333 | } |
| 334 | |
| 335 | if (get_bits1(&s->gb)) { |
| 336 | int bits = 2 + 2 * get_bits(&s->gb, 3); |
| 337 | max_symbol = 2 + get_bits(&s->gb, bits); |
| 338 | if (max_symbol > alphabet_size) { |
| 339 | av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n", |
| 340 | max_symbol, alphabet_size); |
| 341 | return AVERROR_INVALIDDATA; |
| 342 | } |
| 343 | } else { |
| 344 | max_symbol = alphabet_size; |
| 345 | } |
| 346 | |
| 347 | ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths, len_counts, |
| 348 | reordered_code_length_code_lengths, |
| 349 | reordered_code_length_syms, |
| 350 | NUM_CODE_LENGTH_CODES, s->avctx); |
| 351 | if (ret < 0) |
| 352 | return ret; |
| 353 | |
| 354 | code_lengths = av_malloc_array(alphabet_size, 2 * sizeof(uint8_t) + sizeof(uint16_t)); |
| 355 | if (!code_lengths) { |
| 356 | ret = AVERROR(ENOMEM); |
| 357 | goto finish; |
| 358 | } |
| 359 | |
| 360 | prev_code_len = 8; |
| 361 | symbol = 0; |
| 362 | memset(len_counts, 0, sizeof(len_counts)); |
| 363 | while (symbol < alphabet_size) { |
| 364 | int code_len; |
| 365 | |
| 366 | if (!max_symbol--) |
| 367 | break; |
| 368 | code_len = huff_reader_get_symbol(&code_len_hc, &s->gb); |
| 369 | if (code_len < 16U) { |
| 370 | /* Code length code [0..15] indicates literal code lengths. */ |
| 371 | code_lengths[symbol++] = code_len; |
| 372 | len_counts[code_len]++; |
no test coverage detected