// Generated by Sichem at 12/24/2021 8:28:15 PM using Misaki.HighPerformance.Image.Runtime; using System.Runtime.InteropServices; namespace Misaki.HighPerformance.Image { public unsafe partial class StbImage { public static int stbi__gif_test(stbi__context s) { var r = stbi__gif_test_raw(s); stbi__rewind(s); return r; } public static void* stbi__gif_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { byte* u = null; var g = new stbi__gif(); u = stbi__gif_load_next(s, g, comp, req_comp, null); if (u != null) { *x = g.w; *y = g.h; if (req_comp != 0 && req_comp != 4) { u = stbi__convert_format(u, 4, req_comp, (uint)g.w, (uint)g.h); } } else if (g._out_ != null) { CRuntime.free(g._out_); } CRuntime.free(g.history); CRuntime.free(g.background); return u; } 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__gif_info(stbi__context s, int* x, int* y, int* comp) { return stbi__gif_info_raw(s, x, y, comp); } public static int stbi__gif_test_raw(stbi__context s) { var sz = 0; if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56) { return 0; } sz = stbi__get8(s); if (sz != 57 && sz != 55) { return 0; } if (stbi__get8(s) != 97) { return 0; } return 1; } public static void stbi__gif_parse_colortable(stbi__context s, byte[][] pal, int num_entries, int transp) { var i = 0; for (i = 0; i < num_entries; ++i) { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); pal[i][3] = (byte)(transp == i ? 0 : 255); } } public static int stbi__gif_header(stbi__context s, stbi__gif g, int* comp, int is_info) { byte version = 0; if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56) { return stbi__err("not GIF"); } version = stbi__get8(s); if (version != 55 && version != 57) { return stbi__err("not GIF"); } if (stbi__get8(s) != 97) { return stbi__err("not GIF"); } stbi__g_failure_reason = ""; g.w = stbi__get16le(s); g.h = stbi__get16le(s); g.flags = stbi__get8(s); g.bgindex = stbi__get8(s); g.ratio = stbi__get8(s); g.transparent = -1; if (g.w > 1 << 24) { return stbi__err("too large"); } if (g.h > 1 << 24) { return stbi__err("too large"); } if (comp != null) { *comp = 4; } if (is_info != 0) { return 1; } if ((g.flags & 0x80) != 0) { stbi__gif_parse_colortable(s, g.pal, 2 << (g.flags & 7), -1); } return 1; } public static int stbi__gif_info_raw(stbi__context s, int* x, int* y, int* comp) { var g = new stbi__gif(); if (g == null) { return stbi__err("outofmem"); } if (stbi__gif_header(s, g, comp, 1) == 0) { stbi__rewind(s); return 0; } if (x != null) { *x = g.w; } if (y != null) { *y = g.h; } return 1; } public static void stbi__out_gif_code(stbi__gif g, ushort code) { byte* p; var idx = 0; if (g.codes[code].prefix >= 0) { stbi__out_gif_code(g, (ushort)g.codes[code].prefix); } if (g.cur_y >= g.max_y) { return; } idx = g.cur_x + g.cur_y; p = &g._out_[idx]; g.history[idx / 4] = 1; var c = g.color_table[g.codes[code].suffix]; if (c[3] > 128) { p[0] = c[2]; p[1] = c[1]; p[2] = c[0]; p[3] = c[3]; } g.cur_x += 4; if (g.cur_x >= g.max_x) { g.cur_x = g.start_x; g.cur_y += g.step; while (g.cur_y >= g.max_y && g.parse > 0) { g.step = (1 << g.parse) * g.line_size; g.cur_y = g.start_y + (g.step >> 1); --g.parse; } } } public static byte* stbi__process_gif_raster(stbi__context s, stbi__gif g) { byte lzw_cs = 0; var len = 0; var init_code = 0; uint first = 0; var codesize = 0; var codemask = 0; var avail = 0; var oldcode = 0; var bits = 0; var valid_bits = 0; var clear = 0; stbi__gif_lzw* p; lzw_cs = stbi__get8(s); if (lzw_cs > 12) { return null; } clear = 1 << lzw_cs; first = 1; codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; bits = 0; valid_bits = 0; for (init_code = 0; init_code < clear; init_code++) { g.codes[init_code].prefix = -1; g.codes[init_code].first = (byte)init_code; g.codes[init_code].suffix = (byte)init_code; } avail = clear + 2; oldcode = -1; len = 0; for (; ; ) { if (valid_bits < codesize) { if (len == 0) { len = stbi__get8(s); if (len == 0) { return g._out_; } } --len; bits |= stbi__get8(s) << valid_bits; valid_bits += 8; } else { var code = bits & codemask; bits >>= codesize; valid_bits -= codesize; if (code == clear) { codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; avail = clear + 2; oldcode = -1; first = 0; } else if (code == clear + 1) { stbi__skip(s, len); while ((len = stbi__get8(s)) > 0) { stbi__skip(s, len); } return g._out_; } else if (code <= avail) { if (first != 0) { return (byte*)(ulong)(stbi__err("no clear code") != 0 ? 0 : 0); } if (oldcode >= 0) { fixed (stbi__gif_lzw* p2 = &g.codes[avail++]) { p = p2; if (avail > 8192) { return (byte*)(ulong)(stbi__err("too many codes") != 0 ? 0 : 0); } p->prefix = (short)oldcode; p->first = g.codes[oldcode].first; p->suffix = code == avail ? p->first : g.codes[code].first; } } else if (code == avail) { return (byte*)(ulong)(stbi__err("illegal code in raster") != 0 ? 0 : 0); } stbi__out_gif_code(g, (ushort)code); if ((avail & codemask) == 0 && avail <= 0x0FFF) { codesize++; codemask = (1 << codesize) - 1; } oldcode = code; } else { return (byte*)(ulong)(stbi__err("illegal code in raster") != 0 ? 0 : 0); } } } } public static byte* stbi__gif_load_next(stbi__context s, stbi__gif g, int* comp, int req_comp, byte* two_back) { var dispose = 0; var first_frame = 0; var pi = 0; var pcount = 0; first_frame = 0; if (g._out_ == null) { if (stbi__gif_header(s, g, comp, 0) == 0) { return null; } if (stbi__mad3sizes_valid(4, g.w, g.h, 0) == 0) { return (byte*)(ulong)(stbi__err("too large") != 0 ? 0 : 0); } pcount = g.w * g.h; g._out_ = (byte*)stbi__malloc((ulong)(4 * pcount)); g.background = (byte*)stbi__malloc((ulong)(4 * pcount)); g.history = (byte*)stbi__malloc((ulong)pcount); if (g._out_ == null || g.background == null || g.history == null) { return (byte*)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0); } CRuntime.memset(g._out_, 0x00, (ulong)(4 * pcount)); CRuntime.memset(g.background, 0x00, (ulong)(4 * pcount)); CRuntime.memset(g.history, 0x00, (ulong)pcount); first_frame = 1; } else { dispose = (g.eflags & 0x1C) >> 2; pcount = g.w * g.h; if (dispose == 3 && two_back == null) { dispose = 2; } if (dispose == 3) { for (pi = 0; pi < pcount; ++pi) { if (g.history[pi] != 0) { CRuntime.memcpy(&g._out_[pi * 4], &two_back[pi * 4], (ulong)4); } } } else if (dispose == 2) { for (pi = 0; pi < pcount; ++pi) { if (g.history[pi] != 0) { CRuntime.memcpy(&g._out_[pi * 4], &g.background[pi * 4], (ulong)4); } } } CRuntime.memcpy(g.background, g._out_, (ulong)(4 * g.w * g.h)); } CRuntime.memset(g.history, 0x00, (ulong)(g.w * g.h)); for (; ; ) { int tag = stbi__get8(s); switch (tag) { case 0x2C: { var x = 0; var y = 0; var w = 0; var h = 0; byte* o; x = stbi__get16le(s); y = stbi__get16le(s); w = stbi__get16le(s); h = stbi__get16le(s); if (x + w > g.w || y + h > g.h) { return (byte*)(ulong)(stbi__err("bad Image Descriptor") != 0 ? 0 : 0); } g.line_size = g.w * 4; g.start_x = x * 4; g.start_y = y * g.line_size; g.max_x = g.start_x + w * 4; g.max_y = g.start_y + h * g.line_size; g.cur_x = g.start_x; g.cur_y = g.start_y; if (w == 0) { g.cur_y = g.max_y; } g.lflags = stbi__get8(s); if ((g.lflags & 0x40) != 0) { g.step = 8 * g.line_size; g.parse = 3; } else { g.step = g.line_size; g.parse = 0; } if ((g.lflags & 0x80) != 0) { stbi__gif_parse_colortable(s, g.lpal, 2 << (g.lflags & 7), (g.eflags & 0x01) != 0 ? g.transparent : -1); g.color_table = g.lpal; } else if ((g.flags & 0x80) != 0) { g.color_table = g.pal; } else { return (byte*)(ulong)(stbi__err("missing color table") != 0 ? 0 : 0); } o = stbi__process_gif_raster(s, g); if (o == null) { return null; } pcount = g.w * g.h; if (first_frame != 0 && g.bgindex > 0) { for (pi = 0; pi < pcount; ++pi) { if (g.history[pi] == 0) { g.pal[g.bgindex][3] = 255; fixed (byte* ptr = &g.pal[g.bgindex][0]) { CRuntime.memcpy(&g._out_[pi * 4], ptr, (ulong)4); } } } } return o; } case 0x21: { var len = 0; int ext = stbi__get8(s); if (ext == 0xF9) { len = stbi__get8(s); if (len == 4) { g.eflags = stbi__get8(s); g.delay = 10 * stbi__get16le(s); if (g.transparent >= 0) { g.pal[g.transparent][3] = 255; } if ((g.eflags & 0x01) != 0) { g.transparent = stbi__get8(s); if (g.transparent >= 0) { g.pal[g.transparent][3] = 0; } } else { stbi__skip(s, 1); g.transparent = -1; } } else { stbi__skip(s, len); break; } } while ((len = stbi__get8(s)) != 0) { stbi__skip(s, len); } break; } case 0x3B: return null; default: return (byte*)(ulong)(stbi__err("unknown code") != 0 ? 0 : 0); } } } public static void* stbi__load_gif_main_outofmem(stbi__gif g, byte* _out_, int** delays) { CRuntime.free(g._out_); CRuntime.free(g.history); CRuntime.free(g.background); if (_out_ != null) { CRuntime.free(_out_); } if (delays != null && *delays != null) { CRuntime.free(*delays); } return (byte*)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0); } public class stbi__gif { public byte* _out_; public byte* background; public int bgindex; public stbi__gif_lzw[] codes = new stbi__gif_lzw[8192]; public byte[][] color_table; public int cur_x; public int cur_y; public int delay; public int eflags; public int flags; public int h; public byte* history; public int lflags; public int line_size; public byte[][] lpal = Utility.CreateArray(256, 4); public int max_x; public int max_y; public byte[][] pal = Utility.CreateArray(256, 4); public int parse; public int ratio; public int start_x; public int start_y; public int step; public int transparent; public int w; } [StructLayout(LayoutKind.Sequential)] public struct stbi__gif_lzw { public short prefix; public byte first; public byte suffix; } } }