// Generated by Sichem at 14.02.2020 1:27:28

namespace StbImageBeef
{
	extension StbImage
	{
		public struct stbi__huffman
		{
			public uint16[256] code;
			public int32[17] delta;
			public uint8[1 << 9] fast;
			public uint32[18] maxcode;
			public uint8[257] size;
			public uint8[256] values;
		}

		public static uint32[?] stbi__bmask = .(0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535);

		public static int32[?] stbi__jbias = .(0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767);

		public static uint8[?] 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 int32 stbi__build_huffman(stbi__huffman *h, int32* count)
		{
			int32 i = 0;
			int32 j = 0;
			int32 k = 0;
			int32 code = 0;
			for (i = 0; i < 16; ++i)
				for (j = 0; j < count[i]; ++j)
					h.size[k++] = (uint8)(i + 1);
			h.size[k] = 0;
			code = 0;
			k = 0;
			for (j = 1; j <= 16; ++j)
			{
				h.delta[j] = (int32)(k - code);
				if (h.size[k] == j)
				{
					while (h.size[k] == j)
						h.code[k++] = (uint16)code++;
					if (code - 1 >= 1u << j)
						return stbi__err("bad code lengths");
				}

				h.maxcode[j] = (uint32)code << (16 - j);
				code <<= 1;
			}

			h.maxcode[j] = 0xffffffff;

			CRuntime.memset(&h.fast[0], 255, 1 << 9);
			for (i = 0; i < k; ++i)
			{
				var s = (int32)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] = (uint8)i;
				}
			}

			return 1;
		}

		public static void stbi__build_fast_ac(int16[] fast_ac, stbi__huffman *h)
		{
			int32 i = 0;
			for (i = 0; i < 1 << 9; ++i)
			{
				var fast = h.fast[i];
				fast_ac[i] = 0;
				if (fast < 255)
				{
					var rs = (int32)h.values[fast];
					var run = (rs >> 4) & 15;
					var magbits = rs & 15;
					var len = (int32)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 += (int32)((~0U << magbits) + 1);
						if (k >= -128 && k <= 127)
							fast_ac[i] = (int16)(k * 256 + run * 16 + len + magbits);
					}
				}
			}
		}

		public static void stbi__grow_buffer_unsafe(stbi__jpeg j)
		{
			repeat
			{
				var b = (uint32)(j.nomore != 0 ? 0 : stbi__get8(j.s));
				if (b == 0xff)
				{
					var c = (int32)stbi__get8(j.s);
					while (c == 0xff)
						c = stbi__get8(j.s);
					if (c != 0)
					{
						j.marker = (uint8)c;
						j.nomore = 1;
						return;
					}
				}

				j.code_buffer |= b << (24 - j.code_bits);
				j.code_bits += 8;
			} while (j.code_bits <= 24);
		}

		public static int32 stbi__jpeg_huff_decode(stbi__jpeg j, stbi__huffman *h)
		{
			uint32 temp = 0;
			int32 c = 0;
			int32 k = 0;
			if (j.code_bits < 16)
				stbi__grow_buffer_unsafe(j);
			c = (int32)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1));
			k = h.fast[c];
			if (k < 255)
			{
				var s = (int32)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 = (int32)(((j.code_buffer >> (32 - k)) & stbi__bmask[k])) + h.delta[k];
			j.code_bits -= k;
			j.code_buffer <<= k;
			return h.values[c];
		}

		public static int32 stbi__extend_receive(stbi__jpeg j, int32 n)
		{
			uint32 k = 0;
			int32 sgn = 0;
			if (j.code_bits < n)
				stbi__grow_buffer_unsafe(j);
			sgn = (int32)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 (int32)((int32)k + (stbi__jbias[n] & ~sgn));
		}

		public static int32 stbi__jpeg_get_bits(stbi__jpeg j, int32 n)
		{
			uint32 k = 0;
			if (j.code_bits < n)
				stbi__grow_buffer_unsafe(j);
			k = CRuntime._lrotl(j.code_buffer, n);
			j.code_buffer = k & ~stbi__bmask[n];
			k &= stbi__bmask[n];
			j.code_bits -= n;
			return (int32)k;
		}

		public static int32 stbi__jpeg_get_bit(stbi__jpeg j)
		{
			uint32 k = 0;
			if (j.code_bits < 1)
				stbi__grow_buffer_unsafe(j);
			k = j.code_buffer;
			j.code_buffer <<= 1;
			--j.code_bits;
			return (int32)(k & 0x80000000);
		}

		public static int32 stbi__jpeg_decode_block(stbi__jpeg j, int16* data, stbi__huffman *hdc, stbi__huffman *hac,
			int16[] fac, int32 b, uint16[] dequant)
		{
			int32 diff = 0;
			int32 dc = 0;
			int32 k = 0;
			int32 t = 0;
			if (j.code_bits < 16)
				stbi__grow_buffer_unsafe(j);
			t = stbi__jpeg_huff_decode(j, hdc);
			if (t < 0)
				return stbi__err("bad huffman code");
			CRuntime.memset(data, 0, (uint64)(64 * sizeof(int16)));
			diff = t != 0 ? stbi__extend_receive(j, t) : 0;
			dc = j.img_comp[b].dc_pred + diff;
			j.img_comp[b].dc_pred = dc;
			data[0] = (int16)(dc * dequant[0]);
			k = 1;
			repeat
			{
				uint32 zig = 0;
				int32 c = 0;
				int32 r = 0;
				int32 s = 0;
				if (j.code_bits < 16)
					stbi__grow_buffer_unsafe(j);
				c = (int32)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1));
				r = fac[c];
				if (r != 0)
				{
					k += (r >> 4) & 15;
					s = r & 15;
					j.code_buffer <<= s;
					j.code_bits -= s;
					zig = stbi__jpeg_dezigzag[k++];
					data[zig] = (int16)((r >> 8) * dequant[(int32)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] = (int16)(stbi__extend_receive(j, s) * dequant[(int32)zig]);
					}
				}
			} while (k < 64);

			return 1;
		}

		public static int32 stbi__jpeg_decode_block_prog_dc(stbi__jpeg j, int16* data, stbi__huffman *hdc, int32 b)
		{
			int32 diff = 0;
			int32 dc = 0;
			int32 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, (uint64)(64 * sizeof(int16)));
				t = stbi__jpeg_huff_decode(j, hdc);
				diff = t != 0 ? stbi__extend_receive(j, t) : 0;
				dc = j.img_comp[b].dc_pred + diff;
				j.img_comp[b].dc_pred = dc;
				data[0] = (int16)(dc << j.succ_low);
			}
			else
			{
				if (stbi__jpeg_get_bit(j) != 0)
					data[0] += (int16)(1 << j.succ_low);
			}

			return 1;
		}

		public static int32 stbi__jpeg_decode_block_prog_ac(stbi__jpeg j, int16* data, stbi__huffman *hac, int16[] fac)
		{
			int32 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;
				repeat
				{
					uint32 zig = 0;
					int32 c = 0;
					int32 r = 0;
					int32 s = 0;
					if (j.code_bits < 16)
						stbi__grow_buffer_unsafe(j);
					c = (int32)((j.code_buffer >> (32 - 9)) & ((1 << 9) - 1));
					r = fac[c];
					if (r != 0)
					{
						k += (r >> 4) & 15;
						s = r & 15;
						j.code_buffer <<= s;
						j.code_bits -= s;
						zig = stbi__jpeg_dezigzag[k++];
						data[zig] = (int16)((r >> 8) << 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] = (int16)(stbi__extend_receive(j, s) << shift);
						}
					}
				} while (k <= j.spec_end);
			}
			else
			{
				var bit = (int16)(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;
					repeat
					{
						int32 r = 0;
						int32 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 = (int16)s;
									break;
								}

								--r;
							}
						}
					} while (k <= j.spec_end);
				}
			}

			return 1;
		}

		public static void stbi__idct_block(uint8* _out_, int32 out_stride, int16* data)
		{
			int32 i = 0;
			var val = scope int32[64];
			int32 *v = &val[0];
			uint8* 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
				{
					int32 t0 = 0;
					int32 t1 = 0;
					int32 t2 = 0;
					int32 t3 = 0;
					int32 p1 = 0;
					int32 p2 = 0;
					int32 p3 = 0;
					int32 p4 = 0;
					int32 p5 = 0;
					int32 x0 = 0;
					int32 x1 = 0;
					int32 x2 = 0;
					int32 x3 = 0;
					p2 = d[16];
					p3 = d[48];
					p1 = (p2 + p3) * (int32)(0.5411961f * 4096 + 0.5);
					t2 = p1 + p3 * (int32)(-1.847759065f * 4096 + 0.5);
					t3 = p1 + p2 * (int32)(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) * (int32)(1.175875602f * 4096 + 0.5);
					t0 = t0 * (int32)(0.298631336f * 4096 + 0.5);
					t1 = t1 * (int32)(2.053119869f * 4096 + 0.5);
					t2 = t2 * (int32)(3.072711026f * 4096 + 0.5);
					t3 = t3 * (int32)(1.501321110f * 4096 + 0.5);
					p1 = p5 + p1 * (int32)(-0.899976223f * 4096 + 0.5);
					p2 = p5 + p2 * (int32)(-2.562915447f * 4096 + 0.5);
					p3 = p3 * (int32)(-1.961570560f * 4096 + 0.5);
					p4 = p4 * (int32)(-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[0], o = _out_; i < 8; ++i, v += 8, o += out_stride)
			{
				int32 t0 = 0;
				int32 t1 = 0;
				int32 t2 = 0;
				int32 t3 = 0;
				int32 p1 = 0;
				int32 p2 = 0;
				int32 p3 = 0;
				int32 p4 = 0;
				int32 p5 = 0;
				int32 x0 = 0;
				int32 x1 = 0;
				int32 x2 = 0;
				int32 x3 = 0;
				p2 = v[2];
				p3 = v[6];
				p1 = (p2 + p3) * (int32)(0.5411961f * 4096 + 0.5);
				t2 = p1 + p3 * (int32)(-1.847759065f * 4096 + 0.5);
				t3 = p1 + p2 * (int32)(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) * (int32)(1.175875602f * 4096 + 0.5);
				t0 = t0 * (int32)(0.298631336f * 4096 + 0.5);
				t1 = t1 * (int32)(2.053119869f * 4096 + 0.5);
				t2 = t2 * (int32)(3.072711026f * 4096 + 0.5);
				t3 = t3 * (int32)(1.501321110f * 4096 + 0.5);
				p1 = p5 + p1 * (int32)(-0.899976223f * 4096 + 0.5);
				p2 = p5 + p2 * (int32)(-2.562915447f * 4096 + 0.5);
				p3 = p3 * (int32)(-1.961570560f * 4096 + 0.5);
				p4 = p4 * (int32)(-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 uint8 stbi__get_marker(stbi__jpeg j)
		{
			uint8 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 int32 stbi__parse_entropy_coded_data(stbi__jpeg z)
		{
			stbi__jpeg_reset(z);
			if (z.progressive == 0)
			{
				if (z.scan_n == 1)
				{
					int32 i = 0;
					int32 j = 0;
					var data = scope int16[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;
							if (stbi__jpeg_decode_block(z, &data[0], &z.huff_dc[z.img_comp[n].hd], &z.huff_ac[ha], 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[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
				{
					int32 i = 0;
					int32 j = 0;
					int32 k = 0;
					int32 x = 0;
					int32 y = 0;
					var data = scope int16[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;
										if (stbi__jpeg_decode_block(z, &data[0], &z.huff_dc[z.img_comp[n].hd], &z.huff_ac[ha],
												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[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;
				}
			}

			if (z.scan_n == 1)
			{
				int32 i = 0;
				int32 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)
						{
							if (stbi__jpeg_decode_block_prog_dc(z, data, &z.huff_dc[z.img_comp[n].hd], n) == 0)
								return 0;
						}
						else
						{
							var ha = z.img_comp[n].ha;
							if (stbi__jpeg_decode_block_prog_ac(z, data, &z.huff_ac[ha], 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
			{
				int32 i = 0;
				int32 j = 0;
				int32 k = 0;
				int32 x = 0;
				int32 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);
									if (stbi__jpeg_decode_block_prog_dc(z, data, &z.huff_dc[z.img_comp[n].hd], 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(int16* data, uint16[] dequant)
		{
			int32 i = 0;
			for (i = 0; i < 64; ++i)
				data[i] *= (int16)dequant[i];
		}

		public static void stbi__jpeg_finish(stbi__jpeg z)
		{
			if (z.progressive != 0)
			{
				int32 i = 0;
				int32 j = 0;
				int32 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 int32 stbi__process_marker(stbi__jpeg z, int32 m)
		{
			int32 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)
					{
						var q = (int32)stbi__get8(z.s);
						var p = q >> 4;
						var sixteen = p != 0 ? 1 : 0;
						var t = q & 15;
						int32 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]] =
								(uint16)(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;
					while (L > 0)
					{
						uint8* v;
						var sizes = scope int32[16];
						int32 i = 0;
						int32 n = 0;
						var q = (int32)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];
						}

						L -= 17;
						if (tc == 0)
						{
							if (stbi__build_huffman(&z.huff_dc[th], &sizes[0]) == 0)
								return 0;
							v = &z.huff_dc[th].values[0];
						}
						else
						{
							if (stbi__build_huffman(&z.huff_ac[th], &sizes[0]) == 0)
								return 0;
							v = &z.huff_ac[th].values[0];
						}

						for (i = 0; i < n; ++i)
							v[i] = stbi__get8(z.s);
						if (tc != 0)
							stbi__build_fast_ac(z.fast_ac[th], &z.huff_ac[th]);
						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 tag = scope uint8[5];
					tag[0] = (uint8)'J';
					tag[1] = (uint8)'F';
					tag[2] = (uint8)'I';
					tag[3] = (uint8)'F';
					tag[4] = (uint8)'\0';
					int32 ok = 1;
					int32 i = 0;
					for (i = 0; i < 5; ++i)
						if (stbi__get8(z.s) != tag[i])
							ok = 0;
					L -= 5;
					if (ok != 0)
						z.jfif = 1;
				}
				else if (m == 0xEE && L >= 12)
				{
					var tag = scope uint8[6];
					tag[0] = (uint8)'A';
					tag[1] = (uint8)'d';
					tag[2] = (uint8)'o';
					tag[3] = (uint8)'b';
					tag[4] = (uint8)'e';
					tag[5] = (uint8)'\0';
					int32 ok = 1;
					int32 i = 0;
					for (i = 0; i < 6; ++i)
						if (stbi__get8(z.s) != 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 int32 stbi__process_scan_header(stbi__jpeg z)
		{
			int32 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)
			{
				var id = (int32)stbi__get8(z.s);
				int32 which = 0;
				var q = (int32)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;
			}

			{
				int32 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 int32 stbi__free_jpeg_components(stbi__jpeg z, int32 ncomp, int32 why)
		{
			int32 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 int32 stbi__process_frame_header(stbi__jpeg z, int32 scan)
		{
			var s = z.s;
			int32 Lf = 0;
			int32 p = 0;
			int32 i = 0;
			int32 q = 0;
			int32 h_max = 1;
			int32 v_max = 1;
			int32 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 = stbi__get16be(s);
			if (s.img_y == 0)
				return stbi__err("no header height");
			s.img_x = stbi__get16be(s);
			if (s.img_x == 0)
				return stbi__err("0 width");
			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)
			{
				var rgb = scope uint8[3];
				rgb[0] = (uint8)'R';
				rgb[1] = (uint8)'G';
				rgb[2] = (uint8)'B';
				z.img_comp[i].id = stbi__get8(s);
				if (s.img_n == 3 && z.img_comp[i].id == 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((int32)s.img_x, (int32)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;
			}

			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 = (int32)((s.img_x + z.img_mcu_w - 1) / z.img_mcu_w);
			z.img_mcu_y = (int32)((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 = (int32)((s.img_x * z.img_comp[i].h + h_max - 1) / h_max);
				z.img_comp[i].y = (int32)((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 = (uint8 *)z.img_comp[i].raw_data;
				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(int16), 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 = (int16*)z.img_comp[i].raw_coeff;
				}
			}

			return 1;
		}

		public static int32 stbi__decode_jpeg_header(stbi__jpeg z, int32 scan)
		{
			int32 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 int32 stbi__decode_jpeg_image(stbi__jpeg j)
		{
			int32 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)
						while (stbi__at_eof(j.s) == 0)
						{
							var x = (int32)stbi__get8(j.s);
							if (x == 255)
							{
								j.marker = stbi__get8(j.s);
								break;
							}
						}
				}
				else if (m == 0xdc)
				{
					var Ld = stbi__get16be(j.s);
					var NL = (int32)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");
				}
				else
				{
					if (stbi__process_marker(j, m) == 0)
						return 0;
				}

				m = stbi__get_marker(j);
			}

			if (j.progressive != 0)
				stbi__jpeg_finish(j);
			return 1;
		}

		public static uint8* resample_row_1(uint8* _out_, uint8* in_near, uint8* in_far, int32 w, int32 hs)
		{
			return in_near;
		}

		public static uint8* stbi__resample_row_v_2(uint8* _out_, uint8* in_near, uint8* in_far, int32 w, int32 hs)
		{
			int32 i = 0;
			for (i = 0; i < w; ++i)
				_out_[i] = (uint8)((3 * in_near[i] + in_far[i] + 2) >> 2);
			return _out_;
		}

		public static uint8* stbi__resample_row_h_2(uint8* _out_, uint8* in_near, uint8* in_far, int32 w, int32 hs)
		{
			int32 i = 0;
			var input = in_near;
			if (w == 1)
			{
				_out_[0] = _out_[1] = input[0];
				return _out_;
			}

			_out_[0] = input[0];
			_out_[1] = (uint8)((input[0] * 3 + input[1] + 2) >> 2);
			for (i = 1; i < w - 1; ++i)
			{
				var n = 3 * input[i] + 2;
				_out_[i * 2 + 0] = (uint8)((n + input[i - 1]) >> 2);
				_out_[i * 2 + 1] = (uint8)((n + input[i + 1]) >> 2);
			}

			_out_[i * 2 + 0] = (uint8)((input[w - 2] * 3 + input[w - 1] + 2) >> 2);
			_out_[i * 2 + 1] = input[w - 1];
			return _out_;
		}

		public static uint8* stbi__resample_row_hv_2(uint8* _out_, uint8* in_near, uint8* in_far, int32 w, int32 hs)
		{
			int32 i = 0;
			int32 t0 = 0;
			int32 t1 = 0;
			if (w == 1)
			{
				_out_[0] = _out_[1] = (uint8)((3 * in_near[0] + in_far[0] + 2) >> 2);
				return _out_;
			}

			t1 = 3 * in_near[0] + in_far[0];
			_out_[0] = (uint8)((t1 + 2) >> 2);
			for (i = 1; i < w; ++i)
			{
				t0 = t1;
				t1 = 3 * in_near[i] + in_far[i];
				_out_[i * 2 - 1] = (uint8)((3 * t0 + t1 + 8) >> 4);
				_out_[i * 2] = (uint8)((3 * t1 + t0 + 8) >> 4);
			}

			_out_[w * 2 - 1] = (uint8)((t1 + 2) >> 2);
			return _out_;
		}

		public static uint8* stbi__resample_row_generic(uint8* _out_, uint8* in_near, uint8* in_far, int32 w, int32 hs)
		{
			int32 i = 0;
			int32 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(uint8* _out_, uint8* y, uint8* pcb, uint8* pcr, int32 count, int32 step)
		{
			uint8* outLocal = _out_;
			int32 i = 0;
			for (i = 0; i < count; ++i)
			{
				var y_fixed = ((int32)y[i] << 20) + ((int32)1 << 19);
				int32 r = 0;
				int32 g = 0;
				int32 b = 0;
				var cr = pcr[i] - 128;
				var cb = pcb[i] - 128;
				r = y_fixed + cr * ((int32)(1.40200f * 4096.0f + 0.5f) << 8);
				g = (int32)(y_fixed + cr * -((int32)(0.71414f * 4096.0f + 0.5f) << 8) +
						   ((cb * -((int32)(0.34414f * 4096.0f + 0.5f) << 8)) & 0xffff0000));
				b = y_fixed + cb * ((int32)(1.77200f * 4096.0f + 0.5f) << 8);
				r >>= 20;
				g >>= 20;
				b >>= 20;
				if ((uint32)r > 255)
				{
					if (r < 0)
						r = 0;
					else
						r = 255;
				}

				if ((uint32)g > 255)
				{
					if (g < 0)
						g = 0;
					else
						g = 255;
				}

				if ((uint32)b > 255)
				{
					if (b < 0)
						b = 0;
					else
						b = 255;
				}

				outLocal[0] = (uint8)r;
				outLocal[1] = (uint8)g;
				outLocal[2] = (uint8)b;
				outLocal[3] = 255;
				outLocal += 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 uint8* load_jpeg_image(stbi__jpeg z, int32* out_x, int32* out_y, int32* comp, int32 req_comp)
		{
			int32 n = 0;
			int32 decode_n = 0;
			int32 is_rgb = 0;
			z.s.img_n = 0;
			if (req_comp < 0 || req_comp > 4)
				return (uint8*)(stbi__err("bad req_comp") != 0 ? (uint8*)null : null);
			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;
			{
				int32 k = 0;
				int32 i = 0;
				int32 j = 0;
				uint8* output;
				var coutput = scope uint8*[4];
				coutput[0] = null;
				coutput[1] = null;
				coutput[2] = null;
				coutput[3] = null;
				var res_comp = new stbi__resample[4];
				for (int32 kkk = 0; kkk < res_comp.Count; ++kkk)
					res_comp[kkk] = new stbi__resample();
				for (k = 0; k < decode_n; ++k)
				{
					var r = res_comp[k];
					z.img_comp[k].linebuf = (uint8*)stbi__malloc(z.s.img_x + 3);
					if (z.img_comp[k].linebuf == null)
					{
						stbi__cleanup_jpeg(z);
						return (uint8*)(stbi__err("outofmem") != 0 ? (uint8*)null : null);
					}

					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 = (int32)((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 = (uint8*)stbi__malloc_mad3(n, (int32)z.s.img_x, (int32)z.s.img_y, 1);
				if (output == null)
				{
					stbi__cleanup_jpeg(z);
					return (uint8*)(stbi__err("outofmem") != 0 ? (uint8*)null : null);
				}

				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 = (uint32)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], (int32)z.s.img_x, n);
						}
						else if (z.s.img_n == 4)
						{
							if (z.app14_color_transform == 0)
							{
								for (i = (uint32)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], (int32)z.s.img_x, n);
								for (i = (uint32)0; i < z.s.img_x; ++i)
								{
									var m = coutput[3][i];
									_out_[0] = stbi__blinn_8x8((uint8)(255 - _out_[0]), m);
									_out_[1] = stbi__blinn_8x8((uint8)(255 - _out_[1]), m);
									_out_[2] = stbi__blinn_8x8((uint8)(255 - _out_[2]), m);
									_out_ += n;
								}
							}
							else
							{
								z.YCbCr_to_RGB_kernel(_out_, y, coutput[1], coutput[2], (int32)z.s.img_x, n);
							}
						}
						else
						{
							for (i = (uint32)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 = (uint32)0; i < z.s.img_x; ++i)
									*_out_++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
							else
								for (i = (uint32)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 = (uint32)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 = (uint32)0; i < z.s.img_x; ++i)
							{
								_out_[0] = stbi__blinn_8x8((uint8)(255 - coutput[0][i]), coutput[3][i]);
								_out_[1] = 255;
								_out_ += n;
							}
						}
						else
						{
							var y = coutput[0];
							if (n == 1)
								for (i = (uint32)0; i < z.s.img_x; ++i)
									_out_[i] = y[i];
							else
								for (i = (uint32)0; i < z.s.img_x; ++i)
								{
									*_out_++ = y[i];
									*_out_++ = 255;
								}
						}
					}
				}

				stbi__cleanup_jpeg(z);
				*out_x = (int32)z.s.img_x;
				*out_y = (int32)z.s.img_y;
				if (comp != null)
					*comp = z.s.img_n >= 3 ? 3 : 1;
				return output;
			}
		}

		public static void* stbi__jpeg_load(stbi__context s, int32* x, int32* y, int32* comp, int32 req_comp,
			stbi__result_info* ri)
		{
			uint8* result;
			var j = new stbi__jpeg();
			j.s = s;
			stbi__setup_jpeg(j);
			result = load_jpeg_image(j, x, y, comp, req_comp);

			return result;
		}

		public static int32 stbi__jpeg_test(stbi__context s)
		{
			int32 r = 0;
			var j = new stbi__jpeg();
			j.s = s;
			stbi__setup_jpeg(j);
			r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
			stbi__rewind(s);

			return r;
		}

		public static int32 stbi__jpeg_info_raw(stbi__jpeg j, int32* x, int32* y, int32* comp)
		{
			if (stbi__decode_jpeg_header(j, STBI__SCAN_header) == 0)
			{
				stbi__rewind(j.s);
				return 0;
			}

			if (x != null)
				*x = (int32)j.s.img_x;
			if (y != null)
				*y = (int32)j.s.img_y;
			if (comp != null)
				*comp = j.s.img_n >= 3 ? 3 : 1;
			return 1;
		}

		public static int32 stbi__jpeg_info(stbi__context s, int32* x, int32* y, int32* comp)
		{
			int32 result = 0;
			var j = new stbi__jpeg();
			j.s = s;
			result = stbi__jpeg_info_raw(j, x, y, comp);

			return result;
		}
	}
}