public static int stbi__create_png_image(stbi__png a, byte *image_data, uint image_data_len, int out_n, int depth, int color, int interlaced) { var bytes = depth == 16 ? 2 : 1; var out_bytes = out_n * bytes; byte *final; var p = 0; if (interlaced == 0) { return(stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a.s.img_x, a.s.img_y, depth, color)); } final = (byte *)stbi__malloc_mad3((int)a.s.img_x, (int)a.s.img_y, out_bytes, 0); if (final == null) { return(stbi__err("outofmem")); } for (p = 0; p < 7; ++p) { var xorig = stackalloc int[] { 0, 4, 0, 2, 0, 1, 0 }; var yorig = stackalloc int[] { 0, 0, 4, 0, 2, 0, 1 }; var xspc = stackalloc int[] { 8, 8, 4, 4, 2, 2, 1 }; var yspc = stackalloc int[] { 8, 8, 8, 4, 4, 2, 2 }; var i = 0; var j = 0; var x = 0; var y = 0; x = (int)((a.s.img_x - xorig[p] + xspc[p] - 1) / xspc[p]); y = (int)((a.s.img_y - yorig[p] + yspc[p] - 1) / yspc[p]); if (x != 0 && y != 0) { var img_len = (uint)((((a.s.img_n * x * depth + 7) >> 3) + 1) * y); if (stbi__create_png_image_raw(a, image_data, image_data_len, out_n, (uint)x, (uint)y, depth, color) == 0) { CRuntime.free(final); return(0); } for (j = 0; j < y; ++j) { for (i = 0; i < x; ++i) { var out_y = j * yspc[p] + yorig[p]; var out_x = i * xspc[p] + xorig[p]; CRuntime.memcpy(final + out_y * a.s.img_x * out_bytes + out_x * out_bytes, a._out_ + (j * x + i) * out_bytes, (ulong)out_bytes); } } CRuntime.free(a._out_); image_data += img_len; image_data_len -= img_len; } } a._out_ = final; return(1); }
protected unsafe virtual void Dispose(bool disposing) { if (disposing) { if (_gif != null) { if (_gif._out_ != null) { CRuntime.free(_gif._out_); _gif._out_ = null; } if (_gif.history != null) { CRuntime.free(_gif.history); _gif.history = null; } if (_gif.background != null) { CRuntime.free(_gif.background); _gif.background = null; } _gif = null; } } }
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__do_png(stbi__png p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { void *result = null; if (req_comp < 0 || req_comp > 4) { return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? 0 : 0)); } if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp) != 0) { if (p.depth <= 8) { ri->bits_per_channel = 8; } else if (p.depth == 16) { ri->bits_per_channel = 16; } else { return((byte *)(ulong)(stbi__err("bad bits_per_channel") != 0 ? 0 : 0)); } result = p._out_; p._out_ = null; if (req_comp != 0 && req_comp != p.s.img_out_n) { if (ri->bits_per_channel == 8) { result = stbi__convert_format((byte *)result, p.s.img_out_n, req_comp, p.s.img_x, p.s.img_y); } else { result = stbi__convert_format16((ushort *)result, p.s.img_out_n, req_comp, p.s.img_x, p.s.img_y); } p.s.img_out_n = req_comp; if (result == null) { return(result); } } *x = (int)p.s.img_x; *y = (int)p.s.img_y; if (n != null) { *n = p.s.img_n; } } CRuntime.free(p._out_); p._out_ = null; CRuntime.free(p.expanded); p.expanded = null; CRuntime.free(p.idata); p.idata = null; return(result); }
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 static float *stbi__ldr_to_hdr(byte *data, int x, int y, int comp) { var i = 0; var k = 0; var n = 0; float *output; if (data == null) { return(null); } output = (float *)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); if (output == null) { CRuntime.free(data); return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } if ((comp & 1) != 0) { n = comp; } else { n = comp - 1; } for (i = 0; i < x * y; ++i) { for (k = 0; k < n; ++k) { output[i * comp + k] = (float)(CRuntime.pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); } } if (n < comp) { for (i = 0; i < x * y; ++i) { output[i * comp + n] = data[i * comp + n] / 255.0f; } } CRuntime.free(data); return(output); }
public static ushort *stbi__convert_8_to_16(byte *orig, int w, int h, int channels) { var i = 0; var img_len = w * h * channels; ushort *enlarged; enlarged = (ushort *)stbi__malloc((ulong)(img_len * 2)); if (enlarged == null) { return((ushort *)(byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (i = 0; i < img_len; ++i) { enlarged[i] = (ushort)((orig[i] << 8) + orig[i]); } CRuntime.free(orig); return(enlarged); }
public static byte *stbi__convert_16_to_8(ushort *orig, int w, int h, int channels) { var i = 0; var img_len = w * h * channels; byte *reduced; reduced = (byte *)stbi__malloc((ulong)img_len); if (reduced == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (i = 0; i < img_len; ++i) { reduced[i] = (byte)((orig[i] >> 8) & 0xFF); } CRuntime.free(orig); return(reduced); }
public static int stbi__expand_png_palette(stbi__png a, byte *palette, int len, int pal_img_n) { uint i = 0; var pixel_count = a.s.img_x * a.s.img_y; byte *p; byte *temp_out; var orig = a._out_; p = (byte *)stbi__malloc_mad2((int)pixel_count, pal_img_n, 0); if (p == null) { return(stbi__err("outofmem")); } temp_out = p; if (pal_img_n == 3) { for (i = (uint)0; i < pixel_count; ++i) { var n = orig[i] * 4; p[0] = palette[n]; p[1] = palette[n + 1]; p[2] = palette[n + 2]; p += 3; } } else { for (i = (uint)0; i < pixel_count; ++i) { var n = orig[i] * 4; p[0] = palette[n]; p[1] = palette[n + 1]; p[2] = palette[n + 2]; p[3] = palette[n + 3]; p += 4; } } CRuntime.free(a._out_); a._out_ = temp_out; return(1); }
public void Dispose() { if (pal != null) { CRuntime.free(pal); pal = null; } if (lpal != null) { CRuntime.free(lpal); lpal = null; } if (codes != null) { CRuntime.free(codes); codes = null; } }
public static unsafe ImageResultFloat FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { float *result = null; try { int x, y, comp; var context = new StbImage.stbi__context(stream); result = StbImage.stbi__loadf_main(context, &x, &y, &comp, (int)requiredComponents); return(FromResult(result, x, y, (ColorComponents)comp, requiredComponents)); } finally { if (result != null) { CRuntime.free(result); } } }
public static unsafe ImageResult FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { byte *result = null; try { int x, y, comp; var context = new stbi__context(stream); result = stbi__load_and_postprocess_8bit(context, &x, &y, &comp, (int)requiredComponents); return(FromResult(result, x, y, (ColorComponents)comp, requiredComponents)); } finally { if (result != null) { CRuntime.free(result); } } }
public static sbyte *stbi_zlib_decode_noheader_malloc(sbyte *buffer, int len, int *outlen) { var a = new stbi__zbuf(); var p = (sbyte *)stbi__malloc((ulong)16384); if (p == null) { return(null); } a.zbuffer = (byte *)buffer; a.zbuffer_end = (byte *)buffer + len; if (stbi__do_zlib(&a, p, 16384, 1, 0) != 0) { if (outlen != null) { *outlen = (int)(a.zout - a.zout_start); } return(a.zout_start); } CRuntime.free(a.zout_start); return(null); }
public static sbyte *stbi_zlib_decode_malloc_guesssize(sbyte *buffer, int len, int initial_size, int *outlen) { var a = new stbi__zbuf(); var p = (sbyte *)stbi__malloc((ulong)initial_size); if (p == null) { return(null); } a.zbuffer = (byte *)buffer; a.zbuffer_end = (byte *)buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, 1) != 0) { if (outlen != null) { *outlen = (int)(a.zout - a.zout_start); } return(a.zout_start); } CRuntime.free(a.zout_start); return(null); }
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 byte *stbi__hdr_to_ldr(float *data, int x, int y, int comp) { var i = 0; var k = 0; var n = 0; byte *output; if (data == null) { return(null); } output = (byte *)stbi__malloc_mad3(x, y, comp, 0); if (output == null) { CRuntime.free(data); return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } if ((comp & 1) != 0) { n = comp; } else { n = comp - 1; } for (i = 0; i < x * y; ++i) { for (k = 0; k < n; ++k) { var z = (float)CRuntime.pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; if (z < 0) { z = 0; } if (z > 255) { z = 255; } output[i * comp + k] = (byte)(int)z; } if (k < comp) { var z = data[i * comp + k] * 255 + 0.5f; if (z < 0) { z = 0; } if (z > 255) { z = 255; } output[i * comp + k] = (byte)(int)z; } } CRuntime.free(data); return(output); }
public static float *stbi__hdr_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { var buffer = stackalloc sbyte[1024]; sbyte *token; var valid = 0; var width = 0; var height = 0; byte * scanline; float *hdr_data; var len = 0; byte count = 0; byte value = 0; var i = 0; var j = 0; var k = 0; var c1 = 0; var c2 = 0; var z = 0; sbyte *headerToken; headerToken = stbi__hdr_gettoken(s, buffer); if (CRuntime.strcmp(headerToken, "#?RADIANCE") != 0 && CRuntime.strcmp(headerToken, "#?RGBE") != 0) { return((float *)(ulong)(stbi__err("not HDR") != 0 ? 0 : 0)); } for (; ;) { token = stbi__hdr_gettoken(s, buffer); if (token[0] == 0) { break; } if (CRuntime.strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) { valid = 1; } } if (valid == 0) { return((float *)(ulong)(stbi__err("unsupported format") != 0 ? 0 : 0)); } token = stbi__hdr_gettoken(s, buffer); if (CRuntime.strncmp(token, "-Y ", 3) != 0) { return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0)); } token += 3; height = (int)CRuntime.strtol(token, &token, 10); while (*token == 32) { ++token; } if (CRuntime.strncmp(token, "+X ", 3) != 0) { return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0)); } token += 3; width = (int)CRuntime.strtol(token, null, 10); if (height > 1 << 24) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (width > 1 << 24) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } *x = width; *y = height; if (comp != null) { *comp = 3; } if (req_comp == 0) { req_comp = 3; } if (stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0) == 0) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); if (hdr_data == null) { return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } main_decode_loop: var enterMainDecode = false; if (enterMainDecode) { for (; j < height; ++j) { for (; i < width; ++i) { var rgbe = stackalloc byte[4]; stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } goto finish; } if (width < 8 || width >= 32768) { i = j = 0; enterMainDecode = true; goto main_decode_loop; } scanline = null; for (j = 0; j < height; ++j) { c1 = stbi__get8(s); c2 = stbi__get8(s); len = stbi__get8(s); if (c1 != 2 || c2 != 2 || (len & 0x80) != 0) { var rgbe = stackalloc byte[4]; rgbe[0] = (byte)c1; rgbe[1] = (byte)c2; rgbe[2] = (byte)len; rgbe[3] = stbi__get8(s); stbi__hdr_convert(hdr_data, rgbe, req_comp); i = 1; j = 0; CRuntime.free(scanline); goto main_decode_loop; } len <<= 8; len |= stbi__get8(s); if (len != width) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("invalid decoded scanline length") != 0 ? 0 : 0)); } if (scanline == null) { scanline = (byte *)stbi__malloc_mad2(width, 4, 0); if (scanline == null) { CRuntime.free(hdr_data); return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } } for (k = 0; k < 4; ++k) { var nleft = 0; i = 0; while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { value = stbi__get8(s); count -= 128; if (count > nleft) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0)); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = value; } } else { if (count > nleft) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0)); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = stbi__get8(s); } } } } for (i = 0; i < width; ++i) { stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); } } if (scanline != null) { CRuntime.free(scanline); } finish: return(hdr_data); }
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); } }
public static void *stbi__psd_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { var pixelCount = 0; var channelCount = 0; var compression = 0; var channel = 0; var i = 0; var bitdepth = 0; var w = 0; var h = 0; byte *_out_; if (stbi__get32be(s) != 0x38425053) { return((byte *)(ulong)(stbi__err("not PSD") != 0 ? 0 : 0)); } if (stbi__get16be(s) != 1) { return((byte *)(ulong)(stbi__err("wrong version") != 0 ? 0 : 0)); } stbi__skip(s, 6); channelCount = stbi__get16be(s); if (channelCount < 0 || channelCount > 16) { return((byte *)(ulong)(stbi__err("wrong channel count") != 0 ? 0 : 0)); } h = (int)stbi__get32be(s); w = (int)stbi__get32be(s); if (h > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (w > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } bitdepth = stbi__get16be(s); if (bitdepth != 8 && bitdepth != 16) { return((byte *)(ulong)(stbi__err("unsupported bit depth") != 0 ? 0 : 0)); } if (stbi__get16be(s) != 3) { return((byte *)(ulong)(stbi__err("wrong color format") != 0 ? 0 : 0)); } stbi__skip(s, (int)stbi__get32be(s)); stbi__skip(s, (int)stbi__get32be(s)); stbi__skip(s, (int)stbi__get32be(s)); compression = stbi__get16be(s); if (compression > 1) { return((byte *)(ulong)(stbi__err("bad compression") != 0 ? 0 : 0)); } if (stbi__mad3sizes_valid(4, w, h, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (compression == 0 && bitdepth == 16 && bpc == 16) { _out_ = (byte *)stbi__malloc_mad3(8, w, h, 0); ri->bits_per_channel = 16; } else { _out_ = (byte *)stbi__malloc((ulong)(4 * w * h)); } if (_out_ == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } pixelCount = w * h; if (compression != 0) { stbi__skip(s, h * channelCount * 2); for (channel = 0; channel < 4; channel++) { byte *p; p = _out_ + channel; if (channel >= channelCount) { for (i = 0; i < pixelCount; i++, p += 4) { *p = (byte)(channel == 3 ? 255 : 0); } } else { if (stbi__psd_decode_rle(s, p, pixelCount) == 0) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0)); } } } } else { for (channel = 0; channel < 4; channel++) { if (channel >= channelCount) { if (bitdepth == 16 && bpc == 16) { var q = (ushort *)_out_ + channel; var val = (ushort)(channel == 3 ? 65535 : 0); for (i = 0; i < pixelCount; i++, q += 4) { *q = val; } } else { var p = _out_ + channel; var val = (byte)(channel == 3 ? 255 : 0); for (i = 0; i < pixelCount; i++, p += 4) { *p = val; } } } else { if (ri->bits_per_channel == 16) { var q = (ushort *)_out_ + channel; for (i = 0; i < pixelCount; i++, q += 4) { *q = (ushort)stbi__get16be(s); } } else { var p = _out_ + channel; if (bitdepth == 16) { for (i = 0; i < pixelCount; i++, p += 4) { *p = (byte)(stbi__get16be(s) >> 8); } } else { for (i = 0; i < pixelCount; i++, p += 4) { *p = stbi__get8(s); } } } } } } if (channelCount >= 4) { if (ri->bits_per_channel == 16) { for (i = 0; i < w * h; ++i) { var pixel = (ushort *)_out_ + 4 * i; if (pixel[3] != 0 && pixel[3] != 65535) { var a = pixel[3] / 65535.0f; var ra = 1.0f / a; var inv_a = 65535.0f * (1 - ra); pixel[0] = (ushort)(pixel[0] * ra + inv_a); pixel[1] = (ushort)(pixel[1] * ra + inv_a); pixel[2] = (ushort)(pixel[2] * ra + inv_a); } } } else { for (i = 0; i < w * h; ++i) { var pixel = _out_ + 4 * i; if (pixel[3] != 0 && pixel[3] != 255) { var a = pixel[3] / 255.0f; var ra = 1.0f / a; var inv_a = 255.0f * (1 - ra); pixel[0] = (byte)(pixel[0] * ra + inv_a); pixel[1] = (byte)(pixel[1] * ra + inv_a); pixel[2] = (byte)(pixel[2] * ra + inv_a); } } } } if (req_comp != 0 && req_comp != 4) { if (ri->bits_per_channel == 16) { _out_ = (byte *)stbi__convert_format16((ushort *)_out_, 4, req_comp, (uint)w, (uint)h); } else { _out_ = stbi__convert_format(_out_, 4, req_comp, (uint)w, (uint)h); } if (_out_ == null) { return(_out_); } } if (comp != null) { *comp = 4; } *y = h; *x = w; return(_out_); }
public static void *stbi__bmp_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { byte *_out_; var mr = (uint)0; var mg = (uint)0; var mb = (uint)0; var ma = (uint)0; uint all_a = 0; var pal = stackalloc byte[256 * 4]; var psize = 0; var i = 0; var j = 0; var width = 0; var flip_vertically = 0; var pad = 0; var target = 0; var info = new stbi__bmp_data(); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == null) { return(null); } flip_vertically = (int)s.img_y > 0 ? 1 : 0; s.img_y = (uint)CRuntime.abs((int)s.img_y); mr = info.mr; mg = info.mg; mb = info.mb; ma = info.ma; all_a = info.all_a; if (info.hsz == 12) { if (info.bpp < 24) { psize = (info.offset - 14 - 24) / 3; } } else { if (info.bpp < 16) { psize = (info.offset - 14 - info.hsz) >> 2; } } s.img_n = ma != 0 ? 4 : 3; if (req_comp != 0 && req_comp >= 3) { target = req_comp; } else { target = s.img_n; } if (stbi__mad3sizes_valid(target, (int)s.img_x, (int)s.img_y, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null)); } _out_ = (byte *)stbi__malloc_mad3(target, (int)s.img_x, (int)s.img_y, 0); if (_out_ == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } if (info.bpp < 16) { var z = 0; if (psize == 0 || psize > 256) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("invalid") != 0 ? (byte *)null : null)); } for (i = 0; i < psize; ++i) { pal[i * 4 + 2] = stbi__get8(s); pal[i * 4 + 1] = stbi__get8(s); pal[i * 4 + 0] = stbi__get8(s); if (info.hsz != 12) { stbi__get8(s); } pal[i * 4 + 3] = 255; } stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); if (info.bpp == 1) { width = (int)((s.img_x + 7) >> 3); } else if (info.bpp == 4) { width = (int)((s.img_x + 1) >> 1); } else if (info.bpp == 8) { width = (int)s.img_x; } else { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("bad bpp") != 0 ? (byte *)null : null)); } pad = -width & 3; if (info.bpp == 1) { for (j = 0; j < (int)s.img_y; ++j) { var bit_offset = 7; var v = (int)stbi__get8(s); for (i = 0; i < (int)s.img_x; ++i) { var color = (v >> bit_offset) & 0x1; _out_[z++] = pal[color * 4 + 0]; _out_[z++] = pal[color * 4 + 1]; _out_[z++] = pal[color * 4 + 2]; if (target == 4) { _out_[z++] = 255; } if (i + 1 == (int)s.img_x) { break; } if (--bit_offset < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j = 0; j < (int)s.img_y; ++j) { for (i = 0; i < (int)s.img_x; i += 2) { var v = (int)stbi__get8(s); var v2 = 0; if (info.bpp == 4) { v2 = v & 15; v >>= 4; } _out_[z++] = pal[v * 4 + 0]; _out_[z++] = pal[v * 4 + 1]; _out_[z++] = pal[v * 4 + 2]; if (target == 4) { _out_[z++] = 255; } if (i + 1 == (int)s.img_x) { break; } v = info.bpp == 8 ? stbi__get8(s) : v2; _out_[z++] = pal[v * 4 + 0]; _out_[z++] = pal[v * 4 + 1]; _out_[z++] = pal[v * 4 + 2]; if (target == 4) { _out_[z++] = 255; } } stbi__skip(s, pad); } } } else { var rshift = 0; var gshift = 0; var bshift = 0; var ashift = 0; var rcount = 0; var gcount = 0; var bcount = 0; var acount = 0; var z = 0; var easy = 0; stbi__skip(s, info.offset - 14 - info.hsz); if (info.bpp == 24) { width = (int)(3 * s.img_x); } else if (info.bpp == 16) { width = (int)(2 * s.img_x); } else { width = 0; } pad = -width & 3; if (info.bpp == 24) { easy = 1; } else if (info.bpp == 32) { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) { easy = 2; } } if (easy == 0) { if (mr == 0 || mg == 0 || mb == 0) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("bad masks") != 0 ? (byte *)null : null)); } rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); } for (j = 0; j < (int)s.img_y; ++j) { if (easy != 0) { for (i = 0; i < (int)s.img_x; ++i) { byte a = 0; _out_[z + 2] = stbi__get8(s); _out_[z + 1] = stbi__get8(s); _out_[z + 0] = stbi__get8(s); z += 3; a = (byte)(easy == 2 ? stbi__get8(s) : 255); all_a |= a; if (target == 4) { _out_[z++] = a; } } } else { var bpp = info.bpp; for (i = 0; i < (int)s.img_x; ++i) { var v = bpp == 16 ? (uint)stbi__get16le(s) : stbi__get32le(s); uint a = 0; _out_[z++] = (byte)(stbi__shiftsigned(v & mr, rshift, rcount) & 255); _out_[z++] = (byte)(stbi__shiftsigned(v & mg, gshift, gcount) & 255); _out_[z++] = (byte)(stbi__shiftsigned(v & mb, bshift, bcount) & 255); a = (uint)(ma != 0 ? stbi__shiftsigned(v & ma, ashift, acount) : 255); all_a |= a; if (target == 4) { _out_[z++] = (byte)(a & 255); } } } stbi__skip(s, pad); } } if (target == 4 && all_a == 0) { for (i = (int)(4 * s.img_x * s.img_y - 1); i >= 0; i -= 4) { _out_[i] = 255; } } if (flip_vertically != 0) { byte t = 0; for (j = 0; j < (int)s.img_y >> 1; ++j) { var p1 = _out_ + j * s.img_x * target; var p2 = _out_ + (s.img_y - 1 - j) * s.img_x * target; for (i = 0; i < (int)s.img_x * target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (req_comp != 0 && req_comp != target) { _out_ = stbi__convert_format(_out_, target, req_comp, s.img_x, s.img_y); if (_out_ == null) { return(_out_); } } *x = (int)s.img_x; *y = (int)s.img_y; if (comp != null) { *comp = s.img_n; } return(_out_); }
public static void *stbi__tga_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { int tga_offset = stbi__get8(s); int tga_indexed = stbi__get8(s); int tga_image_type = stbi__get8(s); var tga_is_RLE = 0; var tga_palette_start = stbi__get16le(s); var tga_palette_len = stbi__get16le(s); int tga_palette_bits = stbi__get8(s); var tga_x_origin = stbi__get16le(s); var tga_y_origin = stbi__get16le(s); var tga_width = stbi__get16le(s); var tga_height = stbi__get16le(s); int tga_bits_per_pixel = stbi__get8(s); var tga_comp = 0; var tga_rgb16 = 0; int tga_inverted = stbi__get8(s); byte *tga_data; byte *tga_palette = null; var i = 0; var j = 0; var raw_data = stackalloc byte[] { 0, 0, 0, 0 }; var RLE_count = 0; var RLE_repeating = 0; var read_next_pixel = 1; if (tga_height > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (tga_width > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (tga_image_type >= 8) { tga_image_type -= 8; tga_is_RLE = 1; } tga_inverted = 1 - ((tga_inverted >> 5) & 1); if (tga_indexed != 0) { tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); } else { tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_image_type == 3 ? 1 : 0, &tga_rgb16); } if (tga_comp == 0) { return((byte *)(ulong)(stbi__err("bad format") != 0 ? 0 : 0)); } *x = tga_width; *y = tga_height; if (comp != null) { *comp = tga_comp; } if (stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (tga_data == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } stbi__skip(s, tga_offset); if (tga_indexed == 0 && tga_is_RLE == 0 && tga_rgb16 == 0) { for (i = 0; i < tga_height; ++i) { var row = tga_inverted != 0 ? tga_height - i - 1 : i; var tga_row = tga_data + row * tga_width * tga_comp; stbi__getn(s, tga_row, tga_width * tga_comp); } } else { if (tga_indexed != 0) { if (tga_palette_len == 0) { CRuntime.free(tga_data); return((byte *)(ulong)(stbi__err("bad palette") != 0 ? 0 : 0)); } stbi__skip(s, tga_palette_start); tga_palette = (byte *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); if (tga_palette == null) { CRuntime.free(tga_data); return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } if (tga_rgb16 != 0) { var pal_entry = tga_palette; for (i = 0; i < tga_palette_len; ++i) { stbi__tga_read_rgb16(s, pal_entry); pal_entry += tga_comp; } } else if (stbi__getn(s, tga_palette, tga_palette_len * tga_comp) == 0) { CRuntime.free(tga_data); CRuntime.free(tga_palette); return((byte *)(ulong)(stbi__err("bad palette") != 0 ? 0 : 0)); } } for (i = 0; i < tga_width * tga_height; ++i) { if (tga_is_RLE != 0) { if (RLE_count == 0) { int RLE_cmd = stbi__get8(s); RLE_count = 1 + (RLE_cmd & 127); RLE_repeating = RLE_cmd >> 7; read_next_pixel = 1; } else if (RLE_repeating == 0) { read_next_pixel = 1; } } else { read_next_pixel = 1; } if (read_next_pixel != 0) { if (tga_indexed != 0) { var pal_idx = tga_bits_per_pixel == 8 ? stbi__get8(s) : stbi__get16le(s); if (pal_idx >= tga_palette_len) { pal_idx = 0; } pal_idx *= tga_comp; for (j = 0; j < tga_comp; ++j) { raw_data[j] = tga_palette[pal_idx + j]; } } else if (tga_rgb16 != 0) { stbi__tga_read_rgb16(s, raw_data); } else { for (j = 0; j < tga_comp; ++j) { raw_data[j] = stbi__get8(s); } } read_next_pixel = 0; } for (j = 0; j < tga_comp; ++j) { tga_data[i * tga_comp + j] = raw_data[j]; } --RLE_count; } if (tga_inverted != 0) { for (j = 0; j * 2 < tga_height; ++j) { var index1 = j * tga_width * tga_comp; var index2 = (tga_height - 1 - j) * tga_width * tga_comp; for (i = tga_width * tga_comp; i > 0; --i) { var temp = tga_data[index1]; tga_data[index1] = tga_data[index2]; tga_data[index2] = temp; ++index1; ++index2; } } } if (tga_palette != null) { CRuntime.free(tga_palette); } } if (tga_comp >= 3 && tga_rgb16 == 0) { var tga_pixel = tga_data; for (i = 0; i < tga_width * tga_height; ++i) { var temp = tga_pixel[0]; tga_pixel[0] = tga_pixel[2]; tga_pixel[2] = temp; tga_pixel += tga_comp; } } if (req_comp != 0 && req_comp != tga_comp) { tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, (uint)tga_width, (uint)tga_height); } tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0; return(tga_data); }
public static ushort *stbi__convert_format16(ushort *data, int img_n, int req_comp, uint x, uint y) { var i = 0; var j = 0; ushort *good; if (req_comp == img_n) { return(data); } good = (ushort *)stbi__malloc((ulong)(req_comp * x * y * 2)); if (good == null) { CRuntime.free(data); return((ushort *)(byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (j = 0; j < (int)y; ++j) { var src = data + j * x * img_n; var dest = good + j * x * req_comp; switch (img_n * 8 + req_comp) { case 1 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; case 1 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 1 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; case 2 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 1) { dest[0] = src[0]; } break; case 2 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 2 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; case 3 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; case 3 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; case 3 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; case 4 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; case 4 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; case 4 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; default: return((ushort *)(byte *)(ulong)(stbi__err("0") != 0 ? (byte *)null : null)); } } CRuntime.free(data); return(good); }
public static byte *stbi__convert_format(byte *data, int img_n, int req_comp, uint x, uint y) { var i = 0; var j = 0; byte *good; if (req_comp == img_n) { return(data); } good = (byte *)stbi__malloc_mad3(req_comp, (int)x, (int)y, 0); if (good == null) { CRuntime.free(data); return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } for (j = 0; j < (int)y; ++j) { var src = data + j * x * img_n; var dest = good + j * x * req_comp; switch (img_n * 8 + req_comp) { case 1 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 2) { dest[0] = src[0]; dest[1] = 255; } break; case 1 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 1 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; case 2 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 1) { dest[0] = src[0]; } break; case 2 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 2 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; case 3 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; case 3 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; case 3 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; case 4 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; case 4 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; case 4 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; default: ; CRuntime.free(data); CRuntime.free(good); return((byte *)(ulong)(stbi__err("unsupported") != 0 ? 0 : 0)); } } CRuntime.free(data); return(good); }