| 5076 | #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) |
| 5077 | |
| 5078 | static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) |
| 5079 | { |
| 5080 | stbi_uc palette[1024], pal_img_n=0; |
| 5081 | stbi_uc has_trans=0, tc[3]={0}; |
| 5082 | stbi__uint16 tc16[3]; |
| 5083 | stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; |
| 5084 | int first=1,k,interlace=0, color=0, is_iphone=0; |
| 5085 | stbi__context *s = z->s; |
| 5086 | |
| 5087 | z->expanded = NULL; |
| 5088 | z->idata = NULL; |
| 5089 | z->out = NULL; |
| 5090 | |
| 5091 | if (!stbi__check_png_header(s)) return 0; |
| 5092 | |
| 5093 | if (scan == STBI__SCAN_type) return 1; |
| 5094 | |
| 5095 | for (;;) { |
| 5096 | stbi__pngchunk c = stbi__get_chunk_header(s); |
| 5097 | switch (c.type) { |
| 5098 | case STBI__PNG_TYPE('C','g','B','I'): |
| 5099 | is_iphone = 1; |
| 5100 | stbi__skip(s, c.length); |
| 5101 | break; |
| 5102 | case STBI__PNG_TYPE('I','H','D','R'): { |
| 5103 | int comp,filter; |
| 5104 | if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); |
| 5105 | first = 0; |
| 5106 | if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); |
| 5107 | s->img_x = stbi__get32be(s); |
| 5108 | s->img_y = stbi__get32be(s); |
| 5109 | if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); |
| 5110 | if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); |
| 5111 | z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); |
| 5112 | color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); |
| 5113 | if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); |
| 5114 | if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); |
| 5115 | comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); |
| 5116 | filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); |
| 5117 | interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); |
| 5118 | if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); |
| 5119 | if (!pal_img_n) { |
| 5120 | s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); |
| 5121 | if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); |
| 5122 | } else { |
| 5123 | // if paletted, then pal_n is our final components, and |
| 5124 | // img_n is # components to decompress/filter. |
| 5125 | s->img_n = 1; |
| 5126 | if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); |
| 5127 | } |
| 5128 | // even with SCAN_header, have to scan to see if we have a tRNS |
| 5129 | break; |
| 5130 | } |
| 5131 | |
| 5132 | case STBI__PNG_TYPE('P','L','T','E'): { |
| 5133 | if (first) return stbi__err("first not IHDR", "Corrupt PNG"); |
| 5134 | if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); |
| 5135 | pal_len = c.length / 3; |
no test coverage detected