public static byte[] stbi_zlib_decode_malloc_guesssize_headerflag(byte[] buffer, int len, int initial_size, out int outlen, int parse_header) { outlen = 0; var a = new ZLib(); var p = new byte[initial_size]; a.zbuffer = new FakePtr <byte>(buffer); a.zbuffer_end = new FakePtr <byte>(buffer, +len); if (a.stbi__do_zlib(p, initial_size, 1, parse_header) != 0) { outlen = a.zout.Offset; return(a.zout_start); } return(null); }
private int stbi__parse_png_file(int scan, int req_comp) { var palette = new byte[1024]; var pal_img_n = (byte)0; var has_trans = (byte)0; var tc = new byte[3]; tc[0] = 0; var tc16 = new ushort[3]; var ioff = 0; var idata_limit = 0; uint i = 0; var pal_len = (uint)0; var first = 1; var k = 0; var interlace = 0; var color = 0; var is_iphone = 0; expanded = null; idata = null; _out_ = null; if (!stbi__check_png_header(Stream)) { return(0); } if (scan == STBI__SCAN_type) { return(1); } for (; ;) { var c = stbi__get_chunk_header(); switch (c.type) { case ((uint)'C' << 24) + ((uint)'g' << 16) + ((uint)'B' << 8) + 'I': is_iphone = 1; stbi__skip((int)c.length); break; case ((uint)'I' << 24) + ((uint)'H' << 16) + ((uint)'D' << 8) + 'R': { var comp = 0; var filter = 0; if (first == 0) { stbi__err("multiple IHDR"); } first = 0; if (c.length != 13) { stbi__err("bad IHDR len"); } img_x = (int)stbi__get32be(); if (img_x > 1 << 24) { stbi__err("too large"); } img_y = (int)stbi__get32be(); if (img_y > 1 << 24) { stbi__err("too large"); } depth = stbi__get8(); if (depth != 1 && depth != 2 && depth != 4 && depth != 8 && depth != 16) { stbi__err("1/2/4/8/16-bit only"); } color = stbi__get8(); if (color > 6) { stbi__err("bad ctype"); } if (color == 3 && depth == 16) { stbi__err("bad ctype"); } if (color == 3) { pal_img_n = 3; } else if ((color & 1) != 0) { stbi__err("bad ctype"); } comp = stbi__get8(); if (comp != 0) { stbi__err("bad comp method"); } filter = stbi__get8(); if (filter != 0) { stbi__err("bad filter method"); } interlace = stbi__get8(); if (interlace > 1) { stbi__err("bad interlace method"); } if (img_x == 0 || img_y == 0) { stbi__err("0-pixel image"); } if (pal_img_n == 0) { img_n = ((color & 2) != 0 ? 3 : 1) + ((color & 4) != 0 ? 1 : 0); if ((1 << 30) / img_x / img_n < img_y) { stbi__err("too large"); } if (scan == STBI__SCAN_header) { return(1); } } else { img_n = 1; if ((1 << 30) / img_x / 4 < img_y) { stbi__err("too large"); } } break; } case ((uint)'P' << 24) + ((uint)'L' << 16) + ((uint)'T' << 8) + 'E': { if (first != 0) { stbi__err("first not IHDR"); } if (c.length > 256 * 3) { stbi__err("invalid PLTE"); } pal_len = c.length / 3; if (pal_len * 3 != c.length) { stbi__err("invalid PLTE"); } for (i = (uint)0; i < pal_len; ++i) { palette[i * 4 + 0] = stbi__get8(); palette[i * 4 + 1] = stbi__get8(); palette[i * 4 + 2] = stbi__get8(); palette[i * 4 + 3] = 255; } break; } case ((uint)'t' << 24) + ((uint)'R' << 16) + ((uint)'N' << 8) + 'S': { if (first != 0) { stbi__err("first not IHDR"); } if (idata != null) { stbi__err("tRNS after IDAT"); } if (pal_img_n != 0) { if (scan == STBI__SCAN_header) { img_n = 4; return(1); } if (pal_len == 0) { stbi__err("tRNS before PLTE"); } if (c.length > pal_len) { stbi__err("bad tRNS len"); } pal_img_n = 4; for (i = (uint)0; i < c.length; ++i) { palette[i * 4 + 3] = stbi__get8(); } } else { if ((img_n & 1) == 0) { stbi__err("tRNS with alpha"); } if (c.length != (uint)img_n * 2) { stbi__err("bad tRNS len"); } has_trans = 1; if (depth == 16) { for (k = 0; k < img_n; ++k) { tc16[k] = (ushort)stbi__get16be(); } } else { for (k = 0; k < img_n; ++k) { tc[k] = (byte)((byte)(stbi__get16be() & 255) * stbi__depth_scale_table[depth]); } } } break; } case ((uint)'I' << 24) + ((uint)'D' << 16) + ((uint)'A' << 8) + 'T': { if (first != 0) { stbi__err("first not IHDR"); } if (pal_img_n != 0 && pal_len == 0) { stbi__err("no PLTE"); } if (scan == STBI__SCAN_header) { img_n = pal_img_n; return(1); } if ((int)(ioff + c.length) < ioff) { return(0); } if (ioff + c.length > idata_limit) { var idata_limit_old = (uint)idata_limit; if (idata_limit == 0) { idata_limit = (int)(c.length > 4096 ? c.length : 4096); } while (ioff + c.length > idata_limit) { idata_limit *= 2; } Array.Resize(ref idata, idata_limit); } if (!stbi__getn(idata, ioff, (int)c.length)) { stbi__err("outofdata"); } ioff += (int)c.length; break; } case ((uint)'I' << 24) + ((uint)'E' << 16) + ((uint)'N' << 8) + 'D': { var raw_len = 0; uint bpl = 0; if (first != 0) { stbi__err("first not IHDR"); } if (scan != STBI__SCAN_load) { return(1); } if (idata == null) { stbi__err("no IDAT"); } bpl = (uint)((img_x * depth + 7) / 8); raw_len = (int)(bpl * img_y * img_n + img_y); expanded = ZLib.stbi_zlib_decode_malloc_guesssize_headerflag(idata, ioff, raw_len, out raw_len, is_iphone != 0 ? 0 : 1); if (expanded == null) { return(0); } idata = null; if (req_comp == img_n + 1 && req_comp != 3 && pal_img_n == 0 || has_trans != 0) { img_out_n = img_n + 1; } else { img_out_n = img_n; } if (stbi__create_png_image(new FakePtr <byte>(expanded), (uint)raw_len, img_out_n, depth, color, interlace) == 0) { return(0); } if (has_trans != 0) { if (depth == 16) { if (stbi__compute_transparency16(tc16, img_out_n) == 0) { return(0); } } else { if (stbi__compute_transparency(tc, img_out_n) == 0) { return(0); } } } if (is_iphone != 0 && stbi__de_iphone_flag != 0 && img_out_n > 2) { stbi__de_iphone(); } if (pal_img_n != 0) { img_n = pal_img_n; img_out_n = pal_img_n; if (req_comp >= 3) { img_out_n = req_comp; } if (stbi__expand_png_palette(palette, (int)pal_len, img_out_n) == 0) { return(0); } } else if (has_trans != 0) { ++img_n; } expanded = null; return(1); } default: if (first != 0) { stbi__err("first not IHDR"); } if ((c.type & (1 << 29)) == 0) { var invalid_chunk = c.type + " PNG chunk not known"; stbi__err(invalid_chunk); } stbi__skip((int)c.length); break; } stbi__get32be(); } }