| 4456 | } |
| 4457 | |
| 4458 | static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) { |
| 4459 | int i, k = 0; |
| 4460 | int code, next_code[16], sizes[17]; |
| 4461 | |
| 4462 | // DEFLATE spec for generating codes |
| 4463 | memset(sizes, 0, sizeof(sizes)); |
| 4464 | memset(z->fast, 0, sizeof(z->fast)); |
| 4465 | for (i = 0; i < num; ++i) |
| 4466 | ++sizes[sizelist[i]]; |
| 4467 | sizes[0] = 0; |
| 4468 | for (i = 1; i < 16; ++i) |
| 4469 | if (sizes[i] > (1 << i)) |
| 4470 | return stbi__err("bad sizes", "Corrupt PNG"); |
| 4471 | code = 0; |
| 4472 | for (i = 1; i < 16; ++i) { |
| 4473 | next_code[i] = code; |
| 4474 | z->firstcode[i] = (stbi__uint16)code; |
| 4475 | z->firstsymbol[i] = (stbi__uint16)k; |
| 4476 | code = (code + sizes[i]); |
| 4477 | if (sizes[i]) |
| 4478 | if (code - 1 >= (1 << i)) |
| 4479 | return stbi__err("bad codelengths", "Corrupt PNG"); |
| 4480 | z->maxcode[i] = code << (16 - i); // preshift for inner loop |
| 4481 | code <<= 1; |
| 4482 | k += sizes[i]; |
| 4483 | } |
| 4484 | z->maxcode[16] = 0x10000; // sentinel |
| 4485 | for (i = 0; i < num; ++i) { |
| 4486 | int s = sizelist[i]; |
| 4487 | if (s) { |
| 4488 | int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; |
| 4489 | stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); |
| 4490 | z->size[c] = (stbi_uc)s; |
| 4491 | z->value[c] = (stbi__uint16)i; |
| 4492 | if (s <= STBI__ZFAST_BITS) { |
| 4493 | int j = stbi__bit_reverse(next_code[s], s); |
| 4494 | while (j < (1 << STBI__ZFAST_BITS)) { |
| 4495 | z->fast[j] = fastv; |
| 4496 | j += (1 << s); |
| 4497 | } |
| 4498 | } |
| 4499 | ++next_code[s]; |
| 4500 | } |
| 4501 | } |
| 4502 | return 1; |
| 4503 | } |
| 4504 | |
| 4505 | // zlib-from-memory implementation for PNG reading |
| 4506 | // because PNG allows splitting the zlib stream arbitrarily, |
no test coverage detected