public static int stbi__zexpand(stbi__zbuf *z, sbyte *zout, int n) { sbyte *q; var cur = 0; var limit = 0; var old_limit = 0; z->zout = zout; if (z->z_expandable == 0) { return(stbi__err("output buffer limit")); } cur = (int)(z->zout - z->zout_start); limit = old_limit = (int)(z->zout_end - z->zout_start); while (cur + n > limit) { limit *= 2; } q = (sbyte *)CRuntime.realloc(z->zout_start, (ulong)limit); if (q == null) { return(stbi__err("outofmem")); } z->zout_start = q; z->zout = q + cur; z->zout_end = q + limit; return(1); }
public static void *stbi__load_gif_main(stbi__context s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) { if (stbi__gif_test(s) != 0) { var layers = 0; byte *u = null; byte *_out_ = null; byte *two_back = null; var g = new stbi__gif(); var stride = 0; var out_size = 0; var delays_size = 0; if (delays != null) { *delays = null; } do { u = stbi__gif_load_next(s, g, comp, req_comp, two_back); if (u != null) { *x = g.w; *y = g.h; ++layers; stride = g.w * g.h * 4; if (_out_ != null) { void *tmp = (byte *)CRuntime.realloc(_out_, (ulong)(layers * stride)); if (tmp == null) { return(stbi__load_gif_main_outofmem(g, _out_, delays)); } _out_ = (byte *)tmp; out_size = layers * stride; if (delays != null) { var new_delays = (int *)CRuntime.realloc(*delays, (ulong)(sizeof(int) * layers)); if (new_delays == null) { return(stbi__load_gif_main_outofmem(g, _out_, delays)); } *delays = new_delays; delays_size = layers * sizeof(int); } } else { _out_ = (byte *)stbi__malloc((ulong)(layers * stride)); if (_out_ == null) { return(stbi__load_gif_main_outofmem(g, _out_, delays)); } out_size = layers * stride; if (delays != null) { *delays = (int *)stbi__malloc((ulong)(layers * sizeof(int))); if (*delays == null) { return(stbi__load_gif_main_outofmem(g, _out_, delays)); } delays_size = layers * sizeof(int); } } CRuntime.memcpy(_out_ + (layers - 1) * stride, u, (ulong)stride); if (layers >= 2) { two_back = _out_ - 2 * stride; } if (delays != null) { (*delays)[layers - 1U] = g.delay; } } } while (u != null); CRuntime.free(g._out_); CRuntime.free(g.history); CRuntime.free(g.background); if (req_comp != 0 && req_comp != 4) { _out_ = stbi__convert_format(_out_, 4, req_comp, (uint)(layers * g.w), (uint)g.h); } *z = layers; return(_out_); } return((byte *)(ulong)(stbi__err("not GIF") != 0 ? 0 : 0)); }
public static int stbi__parse_png_file(stbi__png z, int scan, int req_comp) { var palette = stackalloc byte[1024]; var pal_img_n = (byte)0; var has_trans = (byte)0; var tc = stackalloc byte[3]; tc[0] = 0; var tc16 = stackalloc ushort[3]; var ioff = (uint)0; var idata_limit = (uint)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; var s = z.s; z.expanded = null; z.idata = null; z._out_ = null; if (stbi__check_png_header(s) == 0) { return(0); } if (scan == STBI__SCAN_type) { return(1); } for (; ;) { var c = stbi__get_chunk_header(s); switch (c.type) { case ((uint)'C' << 24) + ((uint)'g' << 16) + ((uint)'B' << 8) + 'I': is_iphone = 1; stbi__skip(s, (int)c.length); break; case ((uint)'I' << 24) + ((uint)'H' << 16) + ((uint)'D' << 8) + 'R': { var comp = 0; var filter = 0; if (first == 0) { return(stbi__err("multiple IHDR")); } first = 0; if (c.length != 13) { return(stbi__err("bad IHDR len")); } s.img_x = stbi__get32be(s); if (s.img_x > 1 << 24) { return(stbi__err("too large")); } s.img_y = stbi__get32be(s); if (s.img_y > 1 << 24) { return(stbi__err("too large")); } 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")); } color = stbi__get8(s); if (color > 6) { return(stbi__err("bad ctype")); } if (color == 3 && z.depth == 16) { return(stbi__err("bad ctype")); } if (color == 3) { pal_img_n = 3; } else if ((color & 1) != 0) { return(stbi__err("bad ctype")); } comp = stbi__get8(s); if (comp != 0) { return(stbi__err("bad comp method")); } filter = stbi__get8(s); if (filter != 0) { return(stbi__err("bad filter method")); } interlace = stbi__get8(s); if (interlace > 1) { return(stbi__err("bad interlace method")); } if (s.img_x == 0 || s.img_y == 0) { return(stbi__err("0-pixel image")); } if (pal_img_n == 0) { s.img_n = ((color & 2) != 0 ? 3 : 1) + ((color & 4) != 0 ? 1 : 0); if ((1 << 30) / s.img_x / s.img_n < s.img_y) { return(stbi__err("too large")); } if (scan == STBI__SCAN_header) { return(1); } } else { s.img_n = 1; if ((1 << 30) / s.img_x / 4 < s.img_y) { return(stbi__err("too large")); } } break; } case ((uint)'P' << 24) + ((uint)'L' << 16) + ((uint)'T' << 8) + 'E': { if (first != 0) { return(stbi__err("first not IHDR")); } if (c.length > 256 * 3) { return(stbi__err("invalid PLTE")); } pal_len = c.length / 3; if (pal_len * 3 != c.length) { return(stbi__err("invalid PLTE")); } for (i = (uint)0; i < pal_len; ++i) { palette[i * 4 + 0] = stbi__get8(s); palette[i * 4 + 1] = stbi__get8(s); palette[i * 4 + 2] = stbi__get8(s); palette[i * 4 + 3] = 255; } break; } case ((uint)'t' << 24) + ((uint)'R' << 16) + ((uint)'N' << 8) + 'S': { if (first != 0) { return(stbi__err("first not IHDR")); } if (z.idata != null) { return(stbi__err("tRNS after IDAT")); } if (pal_img_n != 0) { if (scan == STBI__SCAN_header) { s.img_n = 4; return(1); } if (pal_len == 0) { return(stbi__err("tRNS before PLTE")); } if (c.length > pal_len) { return(stbi__err("bad tRNS len")); } pal_img_n = 4; for (i = (uint)0; i < c.length; ++i) { palette[i * 4 + 3] = stbi__get8(s); } } else { if ((s.img_n & 1) == 0) { return(stbi__err("tRNS with alpha")); } if (c.length != (uint)s.img_n * 2) { return(stbi__err("bad tRNS len")); } has_trans = 1; if (z.depth == 16) { for (k = 0; k < s.img_n; ++k) { tc16[k] = (ushort)stbi__get16be(s); } } else { for (k = 0; k < s.img_n; ++k) { tc[k] = (byte)((byte)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z.depth]); } } } break; } case ((uint)'I' << 24) + ((uint)'D' << 16) + ((uint)'A' << 8) + 'T': { if (first != 0) { return(stbi__err("first not IHDR")); } if (pal_img_n != 0 && pal_len == 0) { return(stbi__err("no PLTE")); } if (scan == STBI__SCAN_header) { s.img_n = pal_img_n; return(1); } if ((int)(ioff + c.length) < (int)ioff) { return(0); } if (ioff + c.length > idata_limit) { var idata_limit_old = idata_limit; byte *p; if (idata_limit == 0) { idata_limit = c.length > 4096 ? c.length : 4096; } while (ioff + c.length > idata_limit) { idata_limit *= 2; } p = (byte *)CRuntime.realloc(z.idata, (ulong)idata_limit); if (p == null) { return(stbi__err("outofmem")); } z.idata = p; } if (stbi__getn(s, z.idata + ioff, (int)c.length) == 0) { return(stbi__err("outofdata")); } ioff += c.length; break; } case ((uint)'I' << 24) + ((uint)'E' << 16) + ((uint)'N' << 8) + 'D': { uint raw_len = 0; uint bpl = 0; if (first != 0) { return(stbi__err("first not IHDR")); } if (scan != STBI__SCAN_load) { return(1); } if (z.idata == null) { return(stbi__err("no IDAT")); } bpl = (uint)((s.img_x * z.depth + 7) / 8); raw_len = (uint)(bpl * s.img_y * s.img_n + s.img_y); z.expanded = (byte *)stbi_zlib_decode_malloc_guesssize_headerflag((sbyte *)z.idata, (int)ioff, (int)raw_len, (int *)&raw_len, is_iphone != 0 ? 0 : 1); if (z.expanded == null) { return(0); } CRuntime.free(z.idata); z.idata = null; if (req_comp == s.img_n + 1 && req_comp != 3 && pal_img_n == 0 || has_trans != 0) { s.img_out_n = s.img_n + 1; } else { s.img_out_n = s.img_n; } if (stbi__create_png_image(z, z.expanded, raw_len, s.img_out_n, z.depth, color, interlace) == 0) { return(0); } if (has_trans != 0) { if (z.depth == 16) { if (stbi__compute_transparency16(z, tc16, s.img_out_n) == 0) { return(0); } } else { if (stbi__compute_transparency(z, tc, s.img_out_n) == 0) { return(0); } } } if (is_iphone != 0 && stbi__de_iphone_flag != 0 && s.img_out_n > 2) { stbi__de_iphone(z); } if (pal_img_n != 0) { s.img_n = pal_img_n; s.img_out_n = pal_img_n; if (req_comp >= 3) { s.img_out_n = req_comp; } if (stbi__expand_png_palette(z, palette, (int)pal_len, s.img_out_n) == 0) { return(0); } } else if (has_trans != 0) { ++s.img_n; } CRuntime.free(z.expanded); z.expanded = null; return(1); } default: if (first != 0) { return(stbi__err("first not IHDR")); } if ((c.type & (1 << 29)) == 0) { var invalid_chunk = c.type + " PNG chunk not known"; return(stbi__err(invalid_chunk)); } stbi__skip(s, (int)c.length); break; } stbi__get32be(s); } }