public static int stbi__paeth(int a, int b, int c) { var p = a + b - c; var pa = CRuntime.abs(p - a); var pb = CRuntime.abs(p - b); var pc = CRuntime.abs(p - c); if ((pa <= pb) && (pa <= pc)) { return(a); } if (pb <= pc) { return(b); } return(c); }
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_); }