|
@@ -5115,14 +5115,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
|
if (!pal_img_n) {
|
|
|
s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
|
|
|
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
|
|
|
- if (scan == STBI__SCAN_header) return 1;
|
|
|
} else {
|
|
|
// if paletted, then pal_n is our final components, and
|
|
|
// img_n is # components to decompress/filter.
|
|
|
s->img_n = 1;
|
|
|
if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
|
|
|
- // if SCAN_header, have to scan to see if we have a tRNS
|
|
|
}
|
|
|
+ // even with SCAN_header, have to scan to see if we have a tRNS
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -5154,6 +5153,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
|
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
|
|
|
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
|
|
has_trans = 1;
|
|
|
+ // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
|
|
|
+ if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
|
|
|
if (z->depth == 16) {
|
|
|
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
|
|
} else {
|
|
@@ -5166,7 +5167,12 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|
|
case STBI__PNG_TYPE('I','D','A','T'): {
|
|
|
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
|
|
|
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
|
|
|
- if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
|
|
|
+ if (scan == STBI__SCAN_header) {
|
|
|
+ // header scan definitely stops at first IDAT
|
|
|
+ if (pal_img_n)
|
|
|
+ s->img_n = pal_img_n;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
|
|
|
if ((int)(ioff + c.length) < (int)ioff) return 0;
|
|
|
if (ioff + c.length > idata_limit) {
|