// Generated by Sichem at 9/16/2024 9:09:30 AM using Misaki.HighPerformance.Image.Runtime; using System.Runtime.InteropServices; namespace Misaki.HighPerformance.Image { public unsafe partial class StbImage { public delegate void delegate0(byte* arg0, int arg1, short* arg2); public delegate void delegate1(byte* arg0, byte* arg1, byte* arg2, byte* arg3, int arg4, int arg5); public delegate byte* delegate2(byte* arg0, byte* arg1, byte* arg2, int arg3, int arg4); public static uint[] stbi__bmask = { 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535 }; public static int[] stbi__jbias = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 }; public static byte[] stbi__jpeg_dezigzag = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }; public static int stbi__jpeg_test(stbi__context s) { var r = 0; var j = new stbi__jpeg(); if (j == null) { return stbi__err("outofmem"); } j.s = s; stbi__setup_jpeg(j); r = stbi__decode_jpeg_header(j, STBI__SCAN_type); stbi__rewind(s); return r; } public static void* stbi__jpeg_load(stbi__context s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) { byte* result; var j = new stbi__jpeg(); if (j == null) { return (byte*)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0); } j.s = s; stbi__setup_jpeg(j); result = load_jpeg_image(j, x, y, comp, req_comp); return result; } public static int stbi__jpeg_info(stbi__context s, int* x, int* y, int* comp) { var result = 0; var j = new stbi__jpeg(); if (j == null) { return stbi__err("outofmem"); } j.s = s; result = stbi__jpeg_info_raw(j, x, y, comp); return result; } public static int stbi__build_huffman(stbi__huffman* h, int* count) { var i = 0; var j = 0; var k = 0; uint code = 0; for (i = 0; i < 16; ++i) { for (j = 0; j < count[i]; ++j) { h->size[k++] = (byte)(i + 1); if (k >= 257) { return stbi__err("bad size list"); } } } h->size[k] = 0; code = 0; k = 0; for (j = 1; j <= 16; ++j) { h->delta[j] = (int)(k - code); if (h->size[k] == j) { while (h->size[k] == j) { h->code[k++] = (ushort)code++; } if (code - 1 >= 1u << j) { return stbi__err("bad code lengths"); } } h->maxcode[j] = code << (16 - j); code <<= 1; } h->maxcode[j] = 0xffffffff; CRuntime.memset(h->fast, 255, (ulong)(1 << 9)); for (i = 0; i < k; ++i) { int s = h->size[i]; if (s <= 9) { var c = h->code[i] << (9 - s); var m = 1 << (9 - s); for (j = 0; j < m; ++j) { h->fast[c + j] = (byte)i; } } } return 1; } public static void stbi__build_fast_ac(short[] fast_ac, stbi__huffman* h) { var i = 0; for (i = 0; i < 1 << 9; ++i) { var fast = h->fast[i]; fast_ac[i] = 0; if (fast < 255) { int rs = h->values[fast]; var run = (rs >> 4) & 15; var magbits = rs & 15; int len = h->size[fast]; if (magbits != 0 && len + magbits <= 9) { var k = ((i << len) & ((1 << 9) - 1)) >> (9 - magbits); var m = 1 << (magbits - 1); if (k < m) { k += (int)((~0U << magbits) + 1); } if (k >= -128 && k <= 127) { fast_ac[i] = (short)(k * 256 + run * 16 + len + magbits); } } } } } public static void stbi__grow_buffer_unsafe(stbi__jpeg j) { do { var b = (uint)(j.nomore != 0 ? 0 : stbi__get8(j.s)); if (b == 0xff) { int c = stbi__get8(j.s); while (c == 0xff) { c = stbi__get8(j.s); } if (c != 0) { j.marker = (byte)c; j.nomore = 1; return; } } j.code_buffer |= b << (24 - j.code_bits); j.code_bits += 8; } while (j.code_bits <= 24); } public static int stbi__jpeg_huff_decode(stbi__jpeg j, stbi__huffman* h) { uint temp = 0; var c = 0; var k = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } c = (int)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1)); k = h->fast[c]; if (k < 255) { int s = h->size[k]; if (s > j.code_bits) { return -1; } j.code_buffer <<= s; j.code_bits -= s; return h->values[k]; } temp = j.code_buffer >> 16; for (k = 9 + 1; ; ++k) { if (temp < h->maxcode[k]) { break; } } if (k == 17) { j.code_bits -= 16; return -1; } if (k > j.code_bits) { return -1; } c = (int)(((j.code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]); if (c < 0 || c >= 256) { return -1; } j.code_bits -= k; j.code_buffer <<= k; return h->values[c]; } public static int stbi__extend_receive(stbi__jpeg j, int n) { uint k = 0; var sgn = 0; if (j.code_bits < n) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < n) { return 0; } sgn = (int)(j.code_buffer >> 31); k = CRuntime._lrotl(j.code_buffer, n); j.code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; j.code_bits -= n; return (int)(k + (stbi__jbias[n] & (sgn - 1))); } public static int stbi__jpeg_get_bits(stbi__jpeg j, int n) { uint k = 0; if (j.code_bits < n) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < n) { return 0; } k = CRuntime._lrotl(j.code_buffer, n); j.code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; j.code_bits -= n; return (int)k; } public static int stbi__jpeg_get_bit(stbi__jpeg j) { uint k = 0; if (j.code_bits < 1) { stbi__grow_buffer_unsafe(j); } if (j.code_bits < 1) { return 0; } k = j.code_buffer; j.code_buffer <<= 1; --j.code_bits; return (int)(k & 0x80000000); } public static int stbi__jpeg_decode_block(stbi__jpeg j, short* data, stbi__huffman* hdc, stbi__huffman* hac, short[] fac, int b, ushort[] dequant) { var diff = 0; var dc = 0; var k = 0; var t = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } t = stbi__jpeg_huff_decode(j, hdc); if (t < 0 || t > 15) { return stbi__err("bad huffman code"); } CRuntime.memset(data, 0, (ulong)(64 * sizeof(short))); diff = t != 0 ? stbi__extend_receive(j, t) : 0; if (stbi__addints_valid(j.img_comp[b].dc_pred, diff) == 0) { return stbi__err("bad delta"); } dc = j.img_comp[b].dc_pred + diff; j.img_comp[b].dc_pred = dc; if (stbi__mul2shorts_valid(dc, dequant[0]) == 0) { return stbi__err("can't merge dc and ac"); } data[0] = (short)(dc * dequant[0]); k = 1; do { uint zig = 0; var c = 0; var r = 0; var s = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } c = (int)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1)); r = fac[c]; if (r != 0) { k += (r >> 4) & 15; s = r & 15; if (s > j.code_bits) { return stbi__err("bad huffman code"); } j.code_buffer <<= s; j.code_bits -= s; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short)((r >> 8) * dequant[zig]); } else { var rs = stbi__jpeg_huff_decode(j, hac); if (rs < 0) { return stbi__err("bad huffman code"); } s = rs & 15; r = rs >> 4; if (s == 0) { if (rs != 0xf0) { break; } k += 16; } else { k += r; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); } } } while (k < 64); return 1; } public static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg j, short* data, stbi__huffman* hdc, int b) { var diff = 0; var dc = 0; var t = 0; if (j.spec_end != 0) { return stbi__err("can't merge dc and ac"); } if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } if (j.succ_high == 0) { CRuntime.memset(data, 0, (ulong)(64 * sizeof(short))); t = stbi__jpeg_huff_decode(j, hdc); if (t < 0 || t > 15) { return stbi__err("can't merge dc and ac"); } diff = t != 0 ? stbi__extend_receive(j, t) : 0; if (stbi__addints_valid(j.img_comp[b].dc_pred, diff) == 0) { return stbi__err("bad delta"); } dc = j.img_comp[b].dc_pred + diff; j.img_comp[b].dc_pred = dc; if (stbi__mul2shorts_valid(dc, 1 << j.succ_low) == 0) { return stbi__err("can't merge dc and ac"); } data[0] = (short)(dc * (1 << j.succ_low)); } else { if (stbi__jpeg_get_bit(j) != 0) { data[0] += (short)(1 << j.succ_low); } } return 1; } public static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg j, short* data, stbi__huffman* hac, short[] fac) { var k = 0; if (j.spec_start == 0) { return stbi__err("can't merge dc and ac"); } if (j.succ_high == 0) { var shift = j.succ_low; if (j.eob_run != 0) { --j.eob_run; return 1; } k = j.spec_start; do { uint zig = 0; var c = 0; var r = 0; var s = 0; if (j.code_bits < 16) { stbi__grow_buffer_unsafe(j); } c = (int)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1)); r = fac[c]; if (r != 0) { k += (r >> 4) & 15; s = r & 15; if (s > j.code_bits) { return stbi__err("bad huffman code"); } j.code_buffer <<= s; j.code_bits -= s; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short)((r >> 8) * (1 << shift)); } else { var rs = stbi__jpeg_huff_decode(j, hac); if (rs < 0) { return stbi__err("bad huffman code"); } s = rs & 15; r = rs >> 4; if (s == 0) { if (r < 15) { j.eob_run = 1 << r; if (r != 0) { j.eob_run += stbi__jpeg_get_bits(j, r); } --j.eob_run; break; } k += 16; } else { k += r; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); } } } while (k <= j.spec_end); } else { var bit = (short)(1 << j.succ_low); if (j.eob_run != 0) { --j.eob_run; for (k = j.spec_start; k <= j.spec_end; ++k) { var p = &data[stbi__jpeg_dezigzag[k]]; if (*p != 0) { if (stbi__jpeg_get_bit(j) != 0) { if ((*p & bit) == 0) { if (*p > 0) { *p += bit; } else { *p -= bit; } } } } } } else { k = j.spec_start; do { var r = 0; var s = 0; var rs = stbi__jpeg_huff_decode(j, hac); if (rs < 0) { return stbi__err("bad huffman code"); } s = rs & 15; r = rs >> 4; if (s == 0) { if (r < 15) { j.eob_run = (1 << r) - 1; if (r != 0) { j.eob_run += stbi__jpeg_get_bits(j, r); } r = 64; } } else { if (s != 1) { return stbi__err("bad huffman code"); } if (stbi__jpeg_get_bit(j) != 0) { s = bit; } else { s = -bit; } } while (k <= j.spec_end) { var p = &data[stbi__jpeg_dezigzag[k++]]; if (*p != 0) { if (stbi__jpeg_get_bit(j) != 0) { if ((*p & bit) == 0) { if (*p > 0) { *p += bit; } else { *p -= bit; } } } } else { if (r == 0) { *p = (short)s; break; } --r; } } } while (k <= j.spec_end); } } return 1; } public static void stbi__idct_block(byte* _out_, int out_stride, short* data) { var i = 0; var val = stackalloc int[64]; var v = val; byte* o; var d = data; for (i = 0; i < 8; ++i, ++d, ++v) { if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 && d[40] == 0 && d[48] == 0 && d[56] == 0) { var dcterm = d[0] * 4; v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; } else { var t0 = 0; var t1 = 0; var t2 = 0; var t3 = 0; var p1 = 0; var p2 = 0; var p3 = 0; var p4 = 0; var p5 = 0; var x0 = 0; var x1 = 0; var x2 = 0; var x3 = 0; p2 = d[16]; p3 = d[48]; p1 = (p2 + p3) * (int)(0.5411961f * 4096 + 0.5); t2 = p1 + p3 * (int)(-1.847759065f * 4096 + 0.5); t3 = p1 + p2 * (int)(0.765366865f * 4096 + 0.5); p2 = d[0]; p3 = d[32]; t0 = (p2 + p3) * 4096; t1 = (p2 - p3) * 4096; x0 = t0 + t3; x3 = t0 - t3; x1 = t1 + t2; x2 = t1 - t2; t0 = d[56]; t1 = d[40]; t2 = d[24]; t3 = d[8]; p3 = t0 + t2; p4 = t1 + t3; p1 = t0 + t3; p2 = t1 + t2; p5 = (p3 + p4) * (int)(1.175875602f * 4096 + 0.5); t0 = t0 * (int)(0.298631336f * 4096 + 0.5); t1 = t1 * (int)(2.053119869f * 4096 + 0.5); t2 = t2 * (int)(3.072711026f * 4096 + 0.5); t3 = t3 * (int)(1.501321110f * 4096 + 0.5); p1 = p5 + p1 * (int)(-0.899976223f * 4096 + 0.5); p2 = p5 + p2 * (int)(-2.562915447f * 4096 + 0.5); p3 = p3 * (int)(-1.961570560f * 4096 + 0.5); p4 = p4 * (int)(-0.390180644f * 4096 + 0.5); t3 += p1 + p4; t2 += p2 + p3; t1 += p2 + p4; t0 += p1 + p3; x0 += 512; x1 += 512; x2 += 512; x3 += 512; v[0] = (x0 + t3) >> 10; v[56] = (x0 - t3) >> 10; v[8] = (x1 + t2) >> 10; v[48] = (x1 - t2) >> 10; v[16] = (x2 + t1) >> 10; v[40] = (x2 - t1) >> 10; v[24] = (x3 + t0) >> 10; v[32] = (x3 - t0) >> 10; } } for (i = 0, v = val, o = _out_; i < 8; ++i, v += 8, o += out_stride) { var t0 = 0; var t1 = 0; var t2 = 0; var t3 = 0; var p1 = 0; var p2 = 0; var p3 = 0; var p4 = 0; var p5 = 0; var x0 = 0; var x1 = 0; var x2 = 0; var x3 = 0; p2 = v[2]; p3 = v[6]; p1 = (p2 + p3) * (int)(0.5411961f * 4096 + 0.5); t2 = p1 + p3 * (int)(-1.847759065f * 4096 + 0.5); t3 = p1 + p2 * (int)(0.765366865f * 4096 + 0.5); p2 = v[0]; p3 = v[4]; t0 = (p2 + p3) * 4096; t1 = (p2 - p3) * 4096; x0 = t0 + t3; x3 = t0 - t3; x1 = t1 + t2; x2 = t1 - t2; t0 = v[7]; t1 = v[5]; t2 = v[3]; t3 = v[1]; p3 = t0 + t2; p4 = t1 + t3; p1 = t0 + t3; p2 = t1 + t2; p5 = (p3 + p4) * (int)(1.175875602f * 4096 + 0.5); t0 = t0 * (int)(0.298631336f * 4096 + 0.5); t1 = t1 * (int)(2.053119869f * 4096 + 0.5); t2 = t2 * (int)(3.072711026f * 4096 + 0.5); t3 = t3 * (int)(1.501321110f * 4096 + 0.5); p1 = p5 + p1 * (int)(-0.899976223f * 4096 + 0.5); p2 = p5 + p2 * (int)(-2.562915447f * 4096 + 0.5); p3 = p3 * (int)(-1.961570560f * 4096 + 0.5); p4 = p4 * (int)(-0.390180644f * 4096 + 0.5); t3 += p1 + p4; t2 += p2 + p3; t1 += p2 + p4; t0 += p1 + p3; x0 += 65536 + (128 << 17); x1 += 65536 + (128 << 17); x2 += 65536 + (128 << 17); x3 += 65536 + (128 << 17); o[0] = stbi__clamp((x0 + t3) >> 17); o[7] = stbi__clamp((x0 - t3) >> 17); o[1] = stbi__clamp((x1 + t2) >> 17); o[6] = stbi__clamp((x1 - t2) >> 17); o[2] = stbi__clamp((x2 + t1) >> 17); o[5] = stbi__clamp((x2 - t1) >> 17); o[3] = stbi__clamp((x3 + t0) >> 17); o[4] = stbi__clamp((x3 - t0) >> 17); } } public static byte stbi__get_marker(stbi__jpeg j) { byte x = 0; if (j.marker != 0xff) { x = j.marker; j.marker = 0xff; return x; } x = stbi__get8(j.s); if (x != 0xff) { return 0xff; } while (x == 0xff) { x = stbi__get8(j.s); } return x; } public static void stbi__jpeg_reset(stbi__jpeg j) { j.code_bits = 0; j.code_buffer = 0; j.nomore = 0; j.img_comp[0].dc_pred = j.img_comp[1].dc_pred = j.img_comp[2].dc_pred = j.img_comp[3].dc_pred = 0; j.marker = 0xff; j.todo = j.restart_interval != 0 ? j.restart_interval : 0x7fffffff; j.eob_run = 0; } public static int stbi__parse_entropy_coded_data(stbi__jpeg z) { stbi__jpeg_reset(z); if (z.progressive == 0) { if (z.scan_n == 1) { var i = 0; var j = 0; var data = stackalloc short[64]; var n = z.order[0]; var w = (z.img_comp[n].x + 7) >> 3; var h = (z.img_comp[n].y + 7) >> 3; for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { var ha = z.img_comp[n].ha; fixed (stbi__huffman* dptr = &z.huff_dc[z.img_comp[n].hd]) fixed (stbi__huffman* aptr = &z.huff_ac[ha]) { if (stbi__jpeg_decode_block(z, data, dptr, aptr, z.fast_ac[ha], n, z.dequant[z.img_comp[n].tq]) == 0) { return 0; } } z.idct_block_kernel(z.img_comp[n].data + z.img_comp[n].w2 * j * 8 + i * 8, z.img_comp[n].w2, data); if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (!(z.marker >= 0xd0 && z.marker <= 0xd7)) { return 1; } stbi__jpeg_reset(z); } } } return 1; } else { var i = 0; var j = 0; var k = 0; var x = 0; var y = 0; var data = stackalloc short[64]; for (j = 0; j < z.img_mcu_y; ++j) { for (i = 0; i < z.img_mcu_x; ++i) { for (k = 0; k < z.scan_n; ++k) { var n = z.order[k]; for (y = 0; y < z.img_comp[n].v; ++y) { for (x = 0; x < z.img_comp[n].h; ++x) { var x2 = (i * z.img_comp[n].h + x) * 8; var y2 = (j * z.img_comp[n].v + y) * 8; var ha = z.img_comp[n].ha; fixed (stbi__huffman* dptr = &z.huff_dc[z.img_comp[n].hd]) fixed (stbi__huffman* aptr = &z.huff_ac[ha]) { if (stbi__jpeg_decode_block(z, data, dptr, aptr, z.fast_ac[ha], n, z.dequant[z.img_comp[n].tq]) == 0) { return 0; } } z.idct_block_kernel(z.img_comp[n].data + z.img_comp[n].w2 * y2 + x2, z.img_comp[n].w2, data); } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (!(z.marker >= 0xd0 && z.marker <= 0xd7)) { return 1; } stbi__jpeg_reset(z); } } } return 1; } } if (z.scan_n == 1) { var i = 0; var j = 0; var n = z.order[0]; var w = (z.img_comp[n].x + 7) >> 3; var h = (z.img_comp[n].y + 7) >> 3; for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { var data = z.img_comp[n].coeff + 64 * (i + j * z.img_comp[n].coeff_w); if (z.spec_start == 0) { fixed (stbi__huffman* dptr = &z.huff_dc[z.img_comp[n].hd]) { if (stbi__jpeg_decode_block_prog_dc(z, data, dptr, n) == 0) { return 0; } } } else { var ha = z.img_comp[n].ha; fixed (stbi__huffman* aptr = &z.huff_ac[ha]) { if (stbi__jpeg_decode_block_prog_ac(z, data, aptr, z.fast_ac[ha]) == 0) { return 0; } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (!(z.marker >= 0xd0 && z.marker <= 0xd7)) { return 1; } stbi__jpeg_reset(z); } } } return 1; } else { var i = 0; var j = 0; var k = 0; var x = 0; var y = 0; for (j = 0; j < z.img_mcu_y; ++j) { for (i = 0; i < z.img_mcu_x; ++i) { for (k = 0; k < z.scan_n; ++k) { var n = z.order[k]; for (y = 0; y < z.img_comp[n].v; ++y) { for (x = 0; x < z.img_comp[n].h; ++x) { var x2 = i * z.img_comp[n].h + x; var y2 = j * z.img_comp[n].v + y; var data = z.img_comp[n].coeff + 64 * (x2 + y2 * z.img_comp[n].coeff_w); fixed (stbi__huffman* dptr = &z.huff_dc[z.img_comp[n].hd]) { if (stbi__jpeg_decode_block_prog_dc(z, data, dptr, n) == 0) { return 0; } } } } } if (--z.todo <= 0) { if (z.code_bits < 24) { stbi__grow_buffer_unsafe(z); } if (!(z.marker >= 0xd0 && z.marker <= 0xd7)) { return 1; } stbi__jpeg_reset(z); } } } return 1; } } public static void stbi__jpeg_dequantize(short* data, ushort[] dequant) { var i = 0; for (i = 0; i < 64; ++i) { data[i] *= (short)dequant[i]; } } public static void stbi__jpeg_finish(stbi__jpeg z) { if (z.progressive != 0) { var i = 0; var j = 0; var n = 0; for (n = 0; n < z.s.img_n; ++n) { var w = (z.img_comp[n].x + 7) >> 3; var h = (z.img_comp[n].y + 7) >> 3; for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { var data = z.img_comp[n].coeff + 64 * (i + j * z.img_comp[n].coeff_w); stbi__jpeg_dequantize(data, z.dequant[z.img_comp[n].tq]); z.idct_block_kernel(z.img_comp[n].data + z.img_comp[n].w2 * j * 8 + i * 8, z.img_comp[n].w2, data); } } } } } public static int stbi__process_marker(stbi__jpeg z, int m) { var L = 0; switch (m) { case 0xff: return stbi__err("expected marker"); case 0xDD: if (stbi__get16be(z.s) != 4) { return stbi__err("bad DRI len"); } z.restart_interval = stbi__get16be(z.s); return 1; case 0xDB: L = stbi__get16be(z.s) - 2; while (L > 0) { int q = stbi__get8(z.s); var p = q >> 4; var sixteen = p != 0 ? 1 : 0; var t = q & 15; var i = 0; if (p != 0 && p != 1) { return stbi__err("bad DQT type"); } if (t > 3) { return stbi__err("bad DQT table"); } for (i = 0; i < 64; ++i) { z.dequant[t][stbi__jpeg_dezigzag[i]] = (ushort)(sixteen != 0 ? stbi__get16be(z.s) : stbi__get8(z.s)); } L -= sixteen != 0 ? 129 : 65; } return L == 0 ? 1 : 0; case 0xC4: L = stbi__get16be(z.s) - 2; var sizes = stackalloc int[16]; while (L > 0) { var i = 0; var n = 0; int q = stbi__get8(z.s); var tc = q >> 4; var th = q & 15; if (tc > 1 || th > 3) { return stbi__err("bad DHT header"); } for (i = 0; i < 16; ++i) { sizes[i] = stbi__get8(z.s); n += sizes[i]; } if (n > 256) { return stbi__err("bad DHT header"); } L -= 17; if (tc == 0) { fixed (stbi__huffman* hptr = &z.huff_dc[th]) { if (stbi__build_huffman(hptr, sizes) == 0) { return 0; } var v = hptr->values; for (i = 0; i < n; ++i) { v[i] = stbi__get8(z.s); } } } else { fixed (stbi__huffman* aptr = &z.huff_ac[th]) { if (stbi__build_huffman(aptr, sizes) == 0) { return 0; } var v = aptr->values; for (i = 0; i < n; ++i) { v[i] = stbi__get8(z.s); } } } if (tc != 0) { fixed (stbi__huffman* aptr = &z.huff_ac[th]) { stbi__build_fast_ac(z.fast_ac[th], aptr); } } L -= n; } return L == 0 ? 1 : 0; } if (m >= 0xE0 && m <= 0xEF || m == 0xFE) { L = stbi__get16be(z.s); if (L < 2) { if (m == 0xFE) { return stbi__err("bad COM len"); } return stbi__err("bad APP len"); } L -= 2; if (m == 0xE0 && L >= 5) { var ok = 1; var i = 0; for (i = 0; i < 5; ++i) { if (stbi__get8(z.s) != stbi__process_marker_tag[i]) { ok = 0; } } L -= 5; if (ok != 0) { z.jfif = 1; } } else if (m == 0xEE && L >= 12) { var ok = 1; var i = 0; for (i = 0; i < 6; ++i) { if (stbi__get8(z.s) != stbi__process_marker_tag[i]) { ok = 0; } } L -= 6; if (ok != 0) { stbi__get8(z.s); stbi__get16be(z.s); stbi__get16be(z.s); z.app14_color_transform = stbi__get8(z.s); L -= 6; } } stbi__skip(z.s, L); return 1; } return stbi__err("unknown marker"); } public static int stbi__process_scan_header(stbi__jpeg z) { var i = 0; var Ls = stbi__get16be(z.s); z.scan_n = stbi__get8(z.s); if (z.scan_n < 1 || z.scan_n > 4 || z.scan_n > z.s.img_n) { return stbi__err("bad SOS component count"); } if (Ls != 6 + 2 * z.scan_n) { return stbi__err("bad SOS len"); } for (i = 0; i < z.scan_n; ++i) { int id = stbi__get8(z.s); var which = 0; int q = stbi__get8(z.s); for (which = 0; which < z.s.img_n; ++which) { if (z.img_comp[which].id == id) { break; } } if (which == z.s.img_n) { return 0; } z.img_comp[which].hd = q >> 4; if (z.img_comp[which].hd > 3) { return stbi__err("bad DC huff"); } z.img_comp[which].ha = q & 15; if (z.img_comp[which].ha > 3) { return stbi__err("bad AC huff"); } z.order[i] = which; } { var aa = 0; z.spec_start = stbi__get8(z.s); z.spec_end = stbi__get8(z.s); aa = stbi__get8(z.s); z.succ_high = aa >> 4; z.succ_low = aa & 15; if (z.progressive != 0) { if (z.spec_start > 63 || z.spec_end > 63 || z.spec_start > z.spec_end || z.succ_high > 13 || z.succ_low > 13) { return stbi__err("bad SOS"); } } else { if (z.spec_start != 0) { return stbi__err("bad SOS"); } if (z.succ_high != 0 || z.succ_low != 0) { return stbi__err("bad SOS"); } z.spec_end = 63; } } return 1; } public static int stbi__free_jpeg_components(stbi__jpeg z, int ncomp, int why) { var i = 0; for (i = 0; i < ncomp; ++i) { if (z.img_comp[i].raw_data != null) { CRuntime.free(z.img_comp[i].raw_data); z.img_comp[i].raw_data = null; z.img_comp[i].data = null; } if (z.img_comp[i].raw_coeff != null) { CRuntime.free(z.img_comp[i].raw_coeff); z.img_comp[i].raw_coeff = null; z.img_comp[i].coeff = null; } if (z.img_comp[i].linebuf != null) { CRuntime.free(z.img_comp[i].linebuf); z.img_comp[i].linebuf = null; } } return why; } public static int stbi__process_frame_header(stbi__jpeg z, int scan) { var s = z.s; var Lf = 0; var p = 0; var i = 0; var q = 0; var h_max = 1; var v_max = 1; var c = 0; Lf = stbi__get16be(s); if (Lf < 11) { return stbi__err("bad SOF len"); } p = stbi__get8(s); if (p != 8) { return stbi__err("only 8-bit"); } s.img_y = (uint)stbi__get16be(s); if (s.img_y == 0) { return stbi__err("no header height"); } s.img_x = (uint)stbi__get16be(s); if (s.img_x == 0) { return stbi__err("0 width"); } if (s.img_y > 1 << 24) { return stbi__err("too large"); } if (s.img_x > 1 << 24) { return stbi__err("too large"); } c = stbi__get8(s); if (c != 3 && c != 1 && c != 4) { return stbi__err("bad component count"); } s.img_n = c; for (i = 0; i < c; ++i) { z.img_comp[i].data = null; z.img_comp[i].linebuf = null; } if (Lf != 8 + 3 * s.img_n) { return stbi__err("bad SOF len"); } z.rgb = 0; for (i = 0; i < s.img_n; ++i) { z.img_comp[i].id = stbi__get8(s); if (s.img_n == 3 && z.img_comp[i].id == stbi__process_frame_header_rgb[i]) { ++z.rgb; } q = stbi__get8(s); z.img_comp[i].h = q >> 4; if (z.img_comp[i].h == 0 || z.img_comp[i].h > 4) { return stbi__err("bad H"); } z.img_comp[i].v = q & 15; if (z.img_comp[i].v == 0 || z.img_comp[i].v > 4) { return stbi__err("bad V"); } z.img_comp[i].tq = stbi__get8(s); if (z.img_comp[i].tq > 3) { return stbi__err("bad TQ"); } } if (scan != STBI__SCAN_load) { return 1; } if (stbi__mad3sizes_valid((int)s.img_x, (int)s.img_y, s.img_n, 0) == 0) { return stbi__err("too large"); } for (i = 0; i < s.img_n; ++i) { if (z.img_comp[i].h > h_max) { h_max = z.img_comp[i].h; } if (z.img_comp[i].v > v_max) { v_max = z.img_comp[i].v; } } for (i = 0; i < s.img_n; ++i) { if (h_max % z.img_comp[i].h != 0) { return stbi__err("bad H"); } if (v_max % z.img_comp[i].v != 0) { return stbi__err("bad V"); } } z.img_h_max = h_max; z.img_v_max = v_max; z.img_mcu_w = h_max * 8; z.img_mcu_h = v_max * 8; z.img_mcu_x = (int)((s.img_x + z.img_mcu_w - 1) / z.img_mcu_w); z.img_mcu_y = (int)((s.img_y + z.img_mcu_h - 1) / z.img_mcu_h); for (i = 0; i < s.img_n; ++i) { z.img_comp[i].x = (int)((s.img_x * z.img_comp[i].h + h_max - 1) / h_max); z.img_comp[i].y = (int)((s.img_y * z.img_comp[i].v + v_max - 1) / v_max); z.img_comp[i].w2 = z.img_mcu_x * z.img_comp[i].h * 8; z.img_comp[i].h2 = z.img_mcu_y * z.img_comp[i].v * 8; z.img_comp[i].coeff = null; z.img_comp[i].raw_coeff = null; z.img_comp[i].linebuf = null; z.img_comp[i].raw_data = stbi__malloc_mad2(z.img_comp[i].w2, z.img_comp[i].h2, 15); if (z.img_comp[i].raw_data == null) { return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem")); } z.img_comp[i].data = (byte*)(((long)z.img_comp[i].raw_data + 15) & ~15); if (z.progressive != 0) { z.img_comp[i].coeff_w = z.img_comp[i].w2 / 8; z.img_comp[i].coeff_h = z.img_comp[i].h2 / 8; z.img_comp[i].raw_coeff = stbi__malloc_mad3(z.img_comp[i].w2, z.img_comp[i].h2, sizeof(short), 15); if (z.img_comp[i].raw_coeff == null) { return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem")); } z.img_comp[i].coeff = (short*)(((long)z.img_comp[i].raw_coeff + 15) & ~15); } } return 1; } public static int stbi__decode_jpeg_header(stbi__jpeg z, int scan) { var m = 0; z.jfif = 0; z.app14_color_transform = -1; z.marker = 0xff; m = stbi__get_marker(z); if (!(m == 0xd8)) { return stbi__err("no SOI"); } if (scan == STBI__SCAN_type) { return 1; } m = stbi__get_marker(z); while (!(m == 0xc0 || m == 0xc1 || m == 0xc2)) { if (stbi__process_marker(z, m) == 0) { return 0; } m = stbi__get_marker(z); while (m == 0xff) { if (stbi__at_eof(z.s) != 0) { return stbi__err("no SOF"); } m = stbi__get_marker(z); } } z.progressive = m == 0xc2 ? 1 : 0; if (stbi__process_frame_header(z, scan) == 0) { return 0; } return 1; } public static byte stbi__skip_jpeg_junk_at_end(stbi__jpeg j) { while (stbi__at_eof(j.s) == 0) { var x = stbi__get8(j.s); while (x == 0xff) { if (stbi__at_eof(j.s) != 0) { return 0xff; } x = stbi__get8(j.s); if (x != 0x00 && x != 0xff) { return x; } } } return 0xff; } public static int stbi__decode_jpeg_image(stbi__jpeg j) { var m = 0; for (m = 0; m < 4; m++) { j.img_comp[m].raw_data = null; j.img_comp[m].raw_coeff = null; } j.restart_interval = 0; if (stbi__decode_jpeg_header(j, STBI__SCAN_load) == 0) { return 0; } m = stbi__get_marker(j); while (!(m == 0xd9)) { if (m == 0xda) { if (stbi__process_scan_header(j) == 0) { return 0; } if (stbi__parse_entropy_coded_data(j) == 0) { return 0; } if (j.marker == 0xff) { j.marker = stbi__skip_jpeg_junk_at_end(j); } m = stbi__get_marker(j); if (m >= 0xd0 && m <= 0xd7) { m = stbi__get_marker(j); } } else if (m == 0xdc) { var Ld = stbi__get16be(j.s); var NL = (uint)stbi__get16be(j.s); if (Ld != 4) { return stbi__err("bad DNL len"); } if (NL != j.s.img_y) { return stbi__err("bad DNL height"); } m = stbi__get_marker(j); } else { if (stbi__process_marker(j, m) == 0) { return 1; } m = stbi__get_marker(j); } } if (j.progressive != 0) { stbi__jpeg_finish(j); } return 1; } public static byte* resample_row_1(byte* _out_, byte* in_near, byte* in_far, int w, int hs) { return in_near; } public static byte* stbi__resample_row_v_2(byte* _out_, byte* in_near, byte* in_far, int w, int hs) { var i = 0; for (i = 0; i < w; ++i) { _out_[i] = (byte)((3 * in_near[i] + in_far[i] + 2) >> 2); } return _out_; } public static byte* stbi__resample_row_h_2(byte* _out_, byte* in_near, byte* in_far, int w, int hs) { var i = 0; var input = in_near; if (w == 1) { _out_[0] = _out_[1] = input[0]; return _out_; } _out_[0] = input[0]; _out_[1] = (byte)((input[0] * 3 + input[1] + 2) >> 2); for (i = 1; i < w - 1; ++i) { var n = 3 * input[i] + 2; _out_[i * 2 + 0] = (byte)((n + input[i - 1]) >> 2); _out_[i * 2 + 1] = (byte)((n + input[i + 1]) >> 2); } _out_[i * 2 + 0] = (byte)((input[w - 2] * 3 + input[w - 1] + 2) >> 2); _out_[i * 2 + 1] = input[w - 1]; return _out_; } public static byte* stbi__resample_row_hv_2(byte* _out_, byte* in_near, byte* in_far, int w, int hs) { var i = 0; var t0 = 0; var t1 = 0; if (w == 1) { _out_[0] = _out_[1] = (byte)((3 * in_near[0] + in_far[0] + 2) >> 2); return _out_; } t1 = 3 * in_near[0] + in_far[0]; _out_[0] = (byte)((t1 + 2) >> 2); for (i = 1; i < w; ++i) { t0 = t1; t1 = 3 * in_near[i] + in_far[i]; _out_[i * 2 - 1] = (byte)((3 * t0 + t1 + 8) >> 4); _out_[i * 2] = (byte)((3 * t1 + t0 + 8) >> 4); } _out_[w * 2 - 1] = (byte)((t1 + 2) >> 2); return _out_; } public static byte* stbi__resample_row_generic(byte* _out_, byte* in_near, byte* in_far, int w, int hs) { var i = 0; var j = 0; for (i = 0; i < w; ++i) { for (j = 0; j < hs; ++j) { _out_[i * hs + j] = in_near[i]; } } return _out_; } public static void stbi__YCbCr_to_RGB_row(byte* _out_, byte* y, byte* pcb, byte* pcr, int count, int step) { var i = 0; for (i = 0; i < count; ++i) { var y_fixed = (y[i] << 20) + (1 << 19); var r = 0; var g = 0; var b = 0; var cr = pcr[i] - 128; var cb = pcb[i] - 128; r = y_fixed + cr * ((int)(1.40200f * 4096.0f + 0.5f) << 8); g = (int)(y_fixed + cr * -((int)(0.71414f * 4096.0f + 0.5f) << 8) + ((cb * -((int)(0.34414f * 4096.0f + 0.5f) << 8)) & 0xffff0000)); b = y_fixed + cb * ((int)(1.77200f * 4096.0f + 0.5f) << 8); r >>= 20; g >>= 20; b >>= 20; if ((uint)r > 255) { if (r < 0) { r = 0; } else { r = 255; } } if ((uint)g > 255) { if (g < 0) { g = 0; } else { g = 255; } } if ((uint)b > 255) { if (b < 0) { b = 0; } else { b = 255; } } _out_[0] = (byte)r; _out_[1] = (byte)g; _out_[2] = (byte)b; _out_[3] = 255; _out_ += step; } } public static void stbi__setup_jpeg(stbi__jpeg j) { j.idct_block_kernel = stbi__idct_block; j.YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; j.resample_row_hv_2_kernel = stbi__resample_row_hv_2; } public static void stbi__cleanup_jpeg(stbi__jpeg j) { stbi__free_jpeg_components(j, j.s.img_n, 0); } public static byte* load_jpeg_image(stbi__jpeg z, int* out_x, int* out_y, int* comp, int req_comp) { var n = 0; var decode_n = 0; var is_rgb = 0; z.s.img_n = 0; if (req_comp < 0 || req_comp > 4) { return (byte*)(ulong)(stbi__err("bad req_comp") != 0 ? 0 : 0); } if (stbi__decode_jpeg_image(z) == 0) { stbi__cleanup_jpeg(z); return null; } n = req_comp != 0 ? req_comp : z.s.img_n >= 3 ? 3 : 1; is_rgb = z.s.img_n == 3 && (z.rgb == 3 || (z.app14_color_transform == 0 && z.jfif == 0)) ? 1 : 0; if (z.s.img_n == 3 && n < 3 && is_rgb == 0) { decode_n = 1; } else { decode_n = z.s.img_n; } if (decode_n <= 0) { stbi__cleanup_jpeg(z); return null; } { var k = 0; uint i = 0; uint j = 0; byte* output; var coutput = stackalloc byte*[] { null, null, null, null }; var res_comp = new stbi__resample[4]; res_comp[0] = new stbi__resample(); res_comp[1] = new stbi__resample(); res_comp[2] = new stbi__resample(); res_comp[3] = new stbi__resample(); for (k = 0; k < decode_n; ++k) { var r = res_comp[k]; z.img_comp[k].linebuf = (byte*)stbi__malloc(z.s.img_x + 3); if (z.img_comp[k].linebuf == null) { stbi__cleanup_jpeg(z); return (byte*)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0); } r.hs = z.img_h_max / z.img_comp[k].h; r.vs = z.img_v_max / z.img_comp[k].v; r.ystep = r.vs >> 1; r.w_lores = (int)((z.s.img_x + r.hs - 1) / r.hs); r.ypos = 0; r.line0 = r.line1 = z.img_comp[k].data; if (r.hs == 1 && r.vs == 1) { r.resample = resample_row_1; } else if (r.hs == 1 && r.vs == 2) { r.resample = stbi__resample_row_v_2; } else if (r.hs == 2 && r.vs == 1) { r.resample = stbi__resample_row_h_2; } else if (r.hs == 2 && r.vs == 2) { r.resample = z.resample_row_hv_2_kernel; } else { r.resample = stbi__resample_row_generic; } } output = (byte*)stbi__malloc_mad3(n, (int)z.s.img_x, (int)z.s.img_y, 1); if (output == null) { stbi__cleanup_jpeg(z); return (byte*)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0); } for (j = 0; j < z.s.img_y; ++j) { var _out_ = output + n * z.s.img_x * j; for (k = 0; k < decode_n; ++k) { var r = res_comp[k]; var y_bot = r.ystep >= r.vs >> 1 ? 1 : 0; coutput[k] = r.resample(z.img_comp[k].linebuf, y_bot != 0 ? r.line1 : r.line0, y_bot != 0 ? r.line0 : r.line1, r.w_lores, r.hs); if (++r.ystep >= r.vs) { r.ystep = 0; r.line0 = r.line1; if (++r.ypos < z.img_comp[k].y) { r.line1 += z.img_comp[k].w2; } } } if (n >= 3) { var y = coutput[0]; if (z.s.img_n == 3) { if (is_rgb != 0) { for (i = 0; i < z.s.img_x; ++i) { _out_[0] = y[i]; _out_[1] = coutput[1][i]; _out_[2] = coutput[2][i]; _out_[3] = 255; _out_ += n; } } else { z.YCbCr_to_RGB_kernel(_out_, y, coutput[1], coutput[2], (int)z.s.img_x, n); } } else if (z.s.img_n == 4) { if (z.app14_color_transform == 0) { for (i = 0; i < z.s.img_x; ++i) { var m = coutput[3][i]; _out_[0] = stbi__blinn_8x8(coutput[0][i], m); _out_[1] = stbi__blinn_8x8(coutput[1][i], m); _out_[2] = stbi__blinn_8x8(coutput[2][i], m); _out_[3] = 255; _out_ += n; } } else if (z.app14_color_transform == 2) { z.YCbCr_to_RGB_kernel(_out_, y, coutput[1], coutput[2], (int)z.s.img_x, n); for (i = 0; i < z.s.img_x; ++i) { var m = coutput[3][i]; _out_[0] = stbi__blinn_8x8((byte)(255 - _out_[0]), m); _out_[1] = stbi__blinn_8x8((byte)(255 - _out_[1]), m); _out_[2] = stbi__blinn_8x8((byte)(255 - _out_[2]), m); _out_ += n; } } else { z.YCbCr_to_RGB_kernel(_out_, y, coutput[1], coutput[2], (int)z.s.img_x, n); } } else { for (i = 0; i < z.s.img_x; ++i) { _out_[0] = _out_[1] = _out_[2] = y[i]; _out_[3] = 255; _out_ += n; } } } else { if (is_rgb != 0) { if (n == 1) { for (i = 0; i < z.s.img_x; ++i) { *_out_++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); } } else { for (i = 0; i < z.s.img_x; ++i, _out_ += 2) { _out_[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); _out_[1] = 255; } } } else if (z.s.img_n == 4 && z.app14_color_transform == 0) { for (i = 0; i < z.s.img_x; ++i) { var m = coutput[3][i]; var r = stbi__blinn_8x8(coutput[0][i], m); var g = stbi__blinn_8x8(coutput[1][i], m); var b = stbi__blinn_8x8(coutput[2][i], m); _out_[0] = stbi__compute_y(r, g, b); _out_[1] = 255; _out_ += n; } } else if (z.s.img_n == 4 && z.app14_color_transform == 2) { for (i = 0; i < z.s.img_x; ++i) { _out_[0] = stbi__blinn_8x8((byte)(255 - coutput[0][i]), coutput[3][i]); _out_[1] = 255; _out_ += n; } } else { var y = coutput[0]; if (n == 1) { for (i = 0; i < z.s.img_x; ++i) { _out_[i] = y[i]; } } else { for (i = 0; i < z.s.img_x; ++i) { *_out_++ = y[i]; *_out_++ = 255; } } } } } stbi__cleanup_jpeg(z); *out_x = (int)z.s.img_x; *out_y = (int)z.s.img_y; if (comp != null) { *comp = z.s.img_n >= 3 ? 3 : 1; } return output; } } public static int stbi__jpeg_info_raw(stbi__jpeg j, int* x, int* y, int* comp) { if (stbi__decode_jpeg_header(j, STBI__SCAN_header) == 0) { stbi__rewind(j.s); return 0; } if (x != null) { *x = (int)j.s.img_x; } if (y != null) { *y = (int)j.s.img_y; } if (comp != null) { *comp = j.s.img_n >= 3 ? 3 : 1; } return 1; } [StructLayout(LayoutKind.Sequential)] public struct stbi__huffman { public fixed byte fast[512]; public fixed ushort code[256]; public fixed byte values[256]; public fixed byte size[257]; public fixed uint maxcode[18]; public fixed int delta[17]; } public class stbi__jpeg { public int app14_color_transform; public int code_bits; public uint code_buffer; public ushort[][] dequant = Utility.CreateArray(4, 64); public int eob_run; public short[][] fast_ac = Utility.CreateArray(4, 512); public stbi__huffman[] huff_ac = new stbi__huffman[4]; public stbi__huffman[] huff_dc = new stbi__huffman[4]; public delegate0 idct_block_kernel; public unnamed1[] img_comp = new unnamed1[4]; public int img_h_max; public int img_mcu_h; public int img_mcu_w; public int img_mcu_x; public int img_mcu_y; public int img_v_max; public int jfif; public byte marker; public int nomore; public int[] order = new int[4]; public int progressive; public delegate2 resample_row_hv_2_kernel; public int restart_interval; public int rgb; public stbi__context s; public int scan_n; public int spec_end; public int spec_start; public int succ_high; public int succ_low; public int todo; public delegate1 YCbCr_to_RGB_kernel; [StructLayout(LayoutKind.Sequential)] public struct unnamed1 { public int id; public int h; public int v; public int tq; public int hd; public int ha; public int dc_pred; public int x; public int y; public int w2; public int h2; public byte* data; public void* raw_data; public void* raw_coeff; public byte* linebuf; public short* coeff; public int coeff_w; public int coeff_h; } } public class stbi__resample { public int hs; public byte* line0; public byte* line1; public delegate2 resample; public int vs; public int w_lores; public int ypos; public int ystep; } } }