public static void *stbi__load_main(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *ri, int bpc) { ri->bits_per_channel = 8; ri->channel_order = STBI_ORDER_RGB; ri->num_channels = 0; if (stbi__jpeg_test(s) != 0) { return(stbi__jpeg_load(s, x, y, comp, reqComp, ri)); } if (stbi__png_test(s) != 0) { return(stbi__png_load(s, x, y, comp, reqComp, ri)); } if (stbi__bmp_test(s) != 0) { return(stbi__bmp_load(s, x, y, comp, reqComp, ri)); } if (stbi__gif_test(s) != 0) { return(stbi__gif_load(s, x, y, comp, reqComp, ri)); } if (stbi__tga_test(s) != 0) { return(stbi__tga_load(s, x, y, comp, reqComp, ri)); } return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? (byte *)null : null)); }
public static void *stbi__gif_load(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *ri) { byte *u = null; var g = new StbiGif(); u = stbi__gif_load_next(s, g, comp, reqComp, null); if (u != null) { *x = g.W; *y = g.H; if (reqComp != 0 && reqComp != 4) { u = stbi__convert_format(u, 4, reqComp, (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__png_load(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *ri) { var p = new StbiPng(); p.S = s; return(stbi__do_png(p, x, y, comp, reqComp, ri)); }
public static void *stbi__do_png(StbiPng p, int *x, int *y, int *n, int reqComp, StbiResultInfo *ri) { void *result = null; if (reqComp < 0 || reqComp > 4) { return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? (byte *)null : null)); } if (stbi__parse_png_file(p, STBI_SCAN_LOAD, reqComp) != 0) { if (p.Depth < 8) { ri->bits_per_channel = 8; } else { ri->bits_per_channel = p.Depth; } result = p.Out; p.Out = null; if (reqComp != 0 && reqComp != p.S.ImgOutN) { if (ri->bits_per_channel == 8) { result = stbi__convert_format((byte *)result, p.S.ImgOutN, reqComp, p.S.ImgX, p.S.ImgY); } else { result = stbi__convert_format16((ushort *)result, p.S.ImgOutN, reqComp, p.S.ImgX, p.S.ImgY); } p.S.ImgOutN = reqComp; if (result == null) { return(result); } } *x = (int)p.S.ImgX; *y = (int)p.S.ImgY; if (n != null) { *n = p.S.ImgN; } } 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__bmp_load(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *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 StbiBmpData(); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == null) { return(null); } flip_vertically = (int)s.ImgY > 0 ? 1 : 0; s.ImgY = (uint)CRuntime.Abs((int)s.ImgY); 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.ImgN = ma != 0 ? 4 : 3; if (reqComp != 0 && reqComp >= 3) { target = reqComp; } else { target = s.ImgN; } if (stbi__mad3sizes_valid(target, (int)s.ImgX, (int)s.ImgY, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null)); } out_ = (byte *)stbi__malloc_mad3(target, (int)s.ImgX, (int)s.ImgY, 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.ImgX + 7) >> 3); } else if (info.bpp == 4) { width = (int)((s.ImgX + 1) >> 1); } else if (info.bpp == 8) { width = (int)s.ImgX; } 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.ImgY; ++j) { var bit_offset = 7; var v = (int)stbi__get8(s); for (i = 0; i < (int)s.ImgX; ++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.ImgX) { break; } if (--bit_offset < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j = 0; j < (int)s.ImgY; ++j) { for (i = 0; i < (int)s.ImgX; 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.ImgX) { 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.ImgX); } else if (info.bpp == 16) { width = (int)(2 * s.ImgX); } 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.ImgY; ++j) { if (easy != 0) { for (i = 0; i < (int)s.ImgX; ++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.ImgX; ++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.ImgX * s.ImgY - 1); i >= 0; i -= 4) { out_[i] = 255; } } if (flip_vertically != 0) { byte t = 0; for (j = 0; j < (int)s.ImgY >> 1; ++j) { var p1 = out_ + j * s.ImgX * target; var p2 = out_ + (s.ImgY - 1 - j) * s.ImgX * target; for (i = 0; i < (int)s.ImgX * target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (reqComp != 0 && reqComp != target) { out_ = stbi__convert_format(out_, target, reqComp, s.ImgX, s.ImgY); if (out_ == null) { return(out_); } } *x = (int)s.ImgX; *y = (int)s.ImgY; if (comp != null) { *comp = s.ImgN; } return(out_); }
public static void *stbi__tga_load(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *ri) { var tga_offset = (int)stbi__get8(s); var tga_indexed = (int)stbi__get8(s); var tga_image_type = (int)stbi__get8(s); var tga_is_rle = 0; var tga_palette_start = stbi__get16le(s); var tga_palette_len = stbi__get16le(s); var tga_palette_bits = (int)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); var tga_bits_per_pixel = (int)stbi__get8(s); var tga_comp = 0; var tga_rgb16 = 0; var tga_inverted = (int)stbi__get8(s); byte *tga_data; byte *tga_palette = null; var i = 0; var j = 0; var raw_data = stackalloc byte[4]; raw_data[0] = 0; var rle_count = 0; var rle_repeating = 0; var read_next_pixel = 1; 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 ? (byte *)null : null)); } *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 ? (byte *)null : null)); } tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (tga_data == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } 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) { 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 ? (byte *)null : null)); } 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 ? (byte *)null : null)); } } for (i = 0; i < tga_width * tga_height; ++i) { if (tga_is_rle != 0) { if (rle_count == 0) { var rle_cmd = (int)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 (reqComp != 0 && reqComp != tga_comp) { tga_data = stbi__convert_format(tga_data, tga_comp, reqComp, (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); }