| 6686 | } |
| 6687 | |
| 6688 | static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) |
| 6689 | { |
| 6690 | stbi_uc lzw_cs; |
| 6691 | stbi__int32 len, init_code; |
| 6692 | stbi__uint32 first; |
| 6693 | stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; |
| 6694 | stbi__gif_lzw *p; |
| 6695 | |
| 6696 | lzw_cs = stbi__get8(s); |
| 6697 | if (lzw_cs > 12) return NULL; |
| 6698 | clear = 1 << lzw_cs; |
| 6699 | first = 1; |
| 6700 | codesize = lzw_cs + 1; |
| 6701 | codemask = (1 << codesize) - 1; |
| 6702 | bits = 0; |
| 6703 | valid_bits = 0; |
| 6704 | for (init_code = 0; init_code < clear; init_code++) { |
| 6705 | g->codes[init_code].prefix = -1; |
| 6706 | g->codes[init_code].first = (stbi_uc) init_code; |
| 6707 | g->codes[init_code].suffix = (stbi_uc) init_code; |
| 6708 | } |
| 6709 | |
| 6710 | // support no starting clear code |
| 6711 | avail = clear+2; |
| 6712 | oldcode = -1; |
| 6713 | |
| 6714 | len = 0; |
| 6715 | for(;;) { |
| 6716 | if (valid_bits < codesize) { |
| 6717 | if (len == 0) { |
| 6718 | len = stbi__get8(s); // start new block |
| 6719 | if (len == 0) |
| 6720 | return g->out; |
| 6721 | } |
| 6722 | --len; |
| 6723 | bits |= (stbi__int32) stbi__get8(s) << valid_bits; |
| 6724 | valid_bits += 8; |
| 6725 | } else { |
| 6726 | stbi__int32 code = bits & codemask; |
| 6727 | bits >>= codesize; |
| 6728 | valid_bits -= codesize; |
| 6729 | // @OPTIMIZE: is there some way we can accelerate the non-clear path? |
| 6730 | if (code == clear) { // clear code |
| 6731 | codesize = lzw_cs + 1; |
| 6732 | codemask = (1 << codesize) - 1; |
| 6733 | avail = clear + 2; |
| 6734 | oldcode = -1; |
| 6735 | first = 0; |
| 6736 | } else if (code == clear + 1) { // end of stream code |
| 6737 | stbi__skip(s, len); |
| 6738 | while ((len = stbi__get8(s)) > 0) |
| 6739 | stbi__skip(s,len); |
| 6740 | return g->out; |
| 6741 | } else if (code <= avail) { |
| 6742 | if (first) { |
| 6743 | return stbi__errpuc("no clear code", "Corrupt GIF"); |
| 6744 | } |
| 6745 |
no test coverage detected