mirror of
https://github.com/nothings/stb
synced 2024-12-15 04:22:35 +03:00
stb_image: Progressive AC decoding - fix ZRL code.
The original AC decoding logic handled ZRL (runs of 16 zeros) incorrectly. The problem is that the original flow set r=16 and skipped the final coeff write when s=0. This is not actually correct. The problem is the intervening "refinement" bits. With the original logic, even once we decrement r to 0, we keep reading more refinement bits for subsequent coefficients until we find the next currently-unsent AC in the current scan. That is, it works as if it was trying to place 17 new AC values, and only bails at the last minute from actually setting that 17th value. This is wrong. Once we've found the 16th previously-unsent AC, we need to stop reading refinement bits, otherwise we get out of sync with the bit stream (which expects us to read a huffman code next). The easiest fix is to just do what the JPEG standard implicitly assumes anyway: treat ZRL as a run of 15 zeros followed by an explicit magnitude-zero AC coeff. (That is, leave s=0 and actually write s). So this is what this fix does.
This commit is contained in:
parent
e4be8fae2c
commit
f224bc2cdb
11
stb_image.h
11
stb_image.h
@ -1852,8 +1852,8 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
if (r)
|
||||
j->eob_run += stbi__jpeg_get_bits(j, r);
|
||||
r = 64; // force end of block
|
||||
} else
|
||||
r = 16; // r=15 is the code for 16 0s
|
||||
}
|
||||
// r=15 s=0 already does the right thing (write 16 0s)
|
||||
} else {
|
||||
if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
|
||||
// sign bit
|
||||
@ -1865,7 +1865,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
|
||||
// advance by r
|
||||
while (k <= j->spec_end) {
|
||||
short *p = &data[stbi__jpeg_dezigzag[k]];
|
||||
short *p = &data[stbi__jpeg_dezigzag[k++]];
|
||||
if (*p != 0) {
|
||||
if (stbi__jpeg_get_bit(j))
|
||||
if ((*p & bit)==0) {
|
||||
@ -1874,15 +1874,12 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
else
|
||||
*p -= bit;
|
||||
}
|
||||
++k;
|
||||
} else {
|
||||
if (r == 0) {
|
||||
if (s)
|
||||
data[stbi__jpeg_dezigzag[k++]] = (short) s;
|
||||
*p = (short) s;
|
||||
break;
|
||||
}
|
||||
--r;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
} while (k <= j->spec_end);
|
||||
|
Loading…
Reference in New Issue
Block a user