// Generated by Sichem at 12/24/2021 8:28:15 PM

using System;
using Hebron.Runtime;

namespace StbImageBeef
{
	extension StbImage
	{
		public static uint8[?] stbi__zdefault_distance =
			.(5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);

		public static uint8[?] stbi__zdefault_length =
		.(
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
			9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8
		);

		public static int32[?] stbi__zdist_base =
		.(
			1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097,
			6145, 8193, 12289, 16385, 24577, 0, 0
		);

		public static int32[?] stbi__zdist_extra =
			.(0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0);

		public static int32[?] stbi__zlength_base =
		.(
			3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195,
			227, 258, 0, 0
		);

		public static int32[?] stbi__zlength_extra =
			.(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0);

		public static int32 stbi__compute_huffman_codes(stbi__zbuf* a)
		{
			var z_codelength = scope stbi__zhuffman();
			uint8[455] lencodes = ?;
			uint8[19] codelength_sizes = ?;
			int32 i = 0;
			int32 n = 0;
			var hlit = (int32)(stbi__zreceive(a, 5) + 257);
			var hdist = (int32)(stbi__zreceive(a, 5) + 1);
			var hclen = (int32)(stbi__zreceive(a, 4) + 4);
			var ntot = hlit + hdist;
			CRuntime.memset(&codelength_sizes[0], 0, (uint64)(19 * sizeof(uint8)));
			for (i = 0; i < hclen; ++i)
			{
				var s = (int32)stbi__zreceive(a, 3);
				codelength_sizes[stbi__compute_huffman_codes_length_dezigzag[i]] = (uint8)s;
			}

			if (stbi__zbuild_huffman(&z_codelength[0], &codelength_sizes[0], 19) == 0)
				return 0;
			n = 0;
			while (n < ntot)
			{
				var c = stbi__zhuffman_decode(a, &z_codelength[0]);
				if (c < 0 || c >= 19)
					return stbi__err("bad codelengths");
				if (c < 16)
				{
					lencodes[n++] = (uint8)c;
				}
				else
				{
					uint8 fill = 0;
					if (c == 16)
					{
						c = (int32)(stbi__zreceive(a, 2) + 3);
						if (n == 0)
							return stbi__err("bad codelengths");
						fill = lencodes[n - 1];
					}
					else if (c == 17)
					{
						c = (int32)(stbi__zreceive(a, 3) + 3);
					}
					else if (c == 18)
					{
						c = (int32)(stbi__zreceive(a, 7) + 11);
					}
					else
					{
						return stbi__err("bad codelengths");
					}

					if (ntot - n < c)
						return stbi__err("bad codelengths");
					CRuntime.memset(&lencodes[n], fill, (uint64)c);
					n += c;
				}
			}

			if (n != ntot)
				return stbi__err("bad codelengths");
			if (stbi__zbuild_huffman(&a.z_length, &lencodes[0], hlit) == 0)
				return 0;
			if (stbi__zbuild_huffman(&a.z_distance, &lencodes[hlit], hdist) == 0)
				return 0;
			return 1;
		}

		public static int32 stbi__do_zlib(stbi__zbuf* a, int8* obuf, int32 olen, int32 exp, int32 parse_header)
		{
			a.zout_start = obuf;
			a.zout = obuf;
			a.zout_end = obuf + olen;
			a.z_expandable = exp;
			return stbi__parse_zlib(a, parse_header);
		}

		public static void stbi__fill_bits(stbi__zbuf* z)
		{
			repeat
			{
				if (z.code_buffer >= 1U << z.num_bits)
				{
					z.zbuffer = z.zbuffer_end;
					return;
				}

				z.code_buffer |= (uint32)stbi__zget8(z) << z.num_bits;
				z.num_bits += 8;
			} while (z.num_bits <= 24);
		}

		public static int32 stbi__parse_huffman_block(stbi__zbuf* a)
		{
			var zout = a.zout;
			for (; ; )
			{
				var z = stbi__zhuffman_decode(a, &a.z_length);
				if (z < 256)
				{
					if (z < 0)
						return stbi__err("bad huffman code");
					if (zout >= a.zout_end)
					{
						if (stbi__zexpand(a, zout, 1) == 0)
							return 0;
						zout = a.zout;
					}

					*zout++ = (int8)z;
				}
				else
				{
					uint8* p;
					int32 len = 0;
					int32 dist = 0;
					if (z == 256)
					{
						a.zout = zout;
						return 1;
					}

					z -= 257;
					len = stbi__zlength_base[z];
					if (stbi__zlength_extra[z] != 0)
						len += (int32)stbi__zreceive(a, stbi__zlength_extra[z]);
					z = stbi__zhuffman_decode(a, &a.z_distance);
					if (z < 0)
						return stbi__err("bad huffman code");
					dist = stbi__zdist_base[z];
					if (stbi__zdist_extra[z] != 0)
						dist += (int32)stbi__zreceive(a, stbi__zdist_extra[z]);
					if (zout - a.zout_start < dist)
						return stbi__err("bad dist");
					if (zout + len > a.zout_end)
					{
						if (stbi__zexpand(a, zout, len) == 0)
							return 0;
						zout = a.zout;
					}

					p = (uint8*)(zout - dist);
					if (dist == 1)
					{
						var v = *p;
						if (len != 0)
						{
							repeat
							{
								*zout++ = (int8)v;
							} while (--len != 0);
						}
					}
					else
					{
						if (len != 0)
						{
							repeat
							{
								*zout++ = (int8)*p++;
							} while (--len != 0);
						}
					}
				}
			}
		}

		public static int32 stbi__parse_uncompressed_block(stbi__zbuf* a)
		{
			uint8[4] header = ?;
			int32 len = 0;
			int32 nlen = 0;
			int32 k = 0;
			if ((a.num_bits & 7) != 0)
				stbi__zreceive(a, a.num_bits & 7);
			k = 0;
			while (a.num_bits > 0)
			{
				header[k++] = (uint8)(a.code_buffer & 255);
				a.code_buffer >>= 8;
				a.num_bits -= 8;
			}

			if (a.num_bits < 0)
				return stbi__err("zlib corrupt");
			while (k < 4) header[k++] = stbi__zget8(a);

			len = (int32)(header[1] * 256 + header[0]);
			nlen = (int32)(header[3] * 256 + header[2]);
			if (nlen != (len ^ 0xffff))
				return stbi__err("zlib corrupt");
			if (a.zbuffer + len > a.zbuffer_end)
				return stbi__err("read past buffer");
			if (a.zout + len > a.zout_end)
				if (stbi__zexpand(a, a.zout, len) == 0)
					return 0;
			CRuntime.memcpy(a.zout, a.zbuffer, (uint64)len);
			a.zbuffer += len;
			a.zout += len;
			return 1;
		}

		public static int32 stbi__parse_zlib(stbi__zbuf* a, int32 parse_header)
		{
			int32 final = 0;
			int32 type = 0;
			if (parse_header != 0)
				if (stbi__parse_zlib_header(a) == 0)
					return 0;
			a.num_bits = 0;
			a.code_buffer = 0;
			repeat
			{
				final = (int32)stbi__zreceive(a, 1);
				type = (int32)stbi__zreceive(a, 2);
				if (type == 0)
				{
					if (stbi__parse_uncompressed_block(a) == 0)
						return 0;
				}
				else if (type == 3)
				{
					return 0;
				}
				else
				{
					if (type == 1)
					{
						if (stbi__zbuild_huffman(&a.z_length, &stbi__zdefault_length[0], 288) == 0)
							return 0;

						if (stbi__zbuild_huffman(&a.z_distance, &stbi__zdefault_distance[0], 32) == 0)
							return 0;
					}
					else
					{
						if (stbi__compute_huffman_codes(a) == 0)
							return 0;
					}

					if (stbi__parse_huffman_block(a) == 0)
						return 0;
				}
			} while (final == 0);

			return 1;
		}

		public static int32 stbi__parse_zlib_header(stbi__zbuf* a)
		{
			int32 cmf = stbi__zget8(a);
			var cm = cmf & 15;
			int32 flg = stbi__zget8(a);
			if (stbi__zeof(a) != 0)
				return stbi__err("bad zlib header");
			if ((cmf * 256 + flg) % 31 != 0)
				return stbi__err("bad zlib header");
			if ((flg & 32) != 0)
				return stbi__err("no preset dict");
			if (cm != 8)
				return stbi__err("bad compression");
			return 1;
		}

		public static int32 stbi__zbuild_huffman(stbi__zhuffman* z, uint8* sizelist, int32 num)
		{
			int32 i = 0;
			int32 k = 0;
			int32 code = 0;
			int32[16] next_code = ?;
			int32[17] sizes = ?;
			CRuntime.memset(&sizes[0], 0, (uint64)(17 * sizeof(int32)));
			CRuntime.memset(&z.fast[0], 0, (uint64)(512 * sizeof(uint16)));
			for (i = 0; i < num; ++i) ++sizes[sizelist[i]];

			sizes[0] = 0;
			for (i = 1; i < 16; ++i)
				if (sizes[i] > 1 << i)
					return stbi__err("bad sizes");

			code = 0;
			for (i = 1; i < 16; ++i)
			{
				next_code[i] = code;
				z.firstcode[i] = (uint16)code;
				z.firstsymbol[i] = (uint16)k;
				code = code + sizes[i];
				if (sizes[i] != 0)
					if (code - 1 >= 1 << i)
						return stbi__err("bad codelengths");
				z.maxcode[i] = code << (16 - i);
				code <<= 1;
				k += sizes[i];
			}

			z.maxcode[16] = 0x10000;
			for (i = 0; i < num; ++i)
			{
				int32 s = sizelist[i];
				if (s != 0)
				{
					var c = next_code[s] - z.firstcode[s] + z.firstsymbol[s];
					var fastv = (uint16)((s << 9) | i);
					z.size[c] = (uint8)s;
					z.value[c] = (uint16)i;
					if (s <= 9)
					{
						var j = stbi__bit_reverse(next_code[s], s);
						while (j < 1 << 9)
						{
							z.fast[j] = fastv;
							j += 1 << s;
						}
					}

					++next_code[s];
				}
			}

			return 1;
		}

		[Inline]
		public static int32 stbi__zeof(stbi__zbuf* z)
		{
			return z.zbuffer >= z.zbuffer_end ? 1 : 0;
		}

		public static int32 stbi__zexpand(stbi__zbuf* z, int8* zout, int32 n)
		{
			int8* q;
			int32 cur = 0;
			int64 limit = 0;
			int32 old_limit = 0;
			z.zout = zout;
			if (z.z_expandable == 0)
				return stbi__err("output buffer limit");
			cur = (int32)(z.zout - z.zout_start);
			limit = old_limit = (int32)(z.zout_end - z.zout_start);
			if (0xffffffff - cur < n)
				return stbi__err("outofmem");
			while (cur + n > limit)
			{
				if (limit > (0xffffffff / 2))
					return stbi__err("outofmem");
				limit *= 2;
			}

			q = (int8*)CRuntime.realloc(z.zout_start, (uint64)limit);
			if (q == null)
				return stbi__err("outofmem");
			z.zout_start = q;
			z.zout = q + cur;
			z.zout_end = q + limit;
			return 1;
		}

		[Inline]
		public static uint8 stbi__zget8(stbi__zbuf* z)
		{
			return (uint8)(stbi__zeof(z) != 0 ? 0 : *z.zbuffer++);
		}

		[Inline]
		public static int32 stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z)
		{
			int32 b = 0;
			int32 s = 0;
			if (a.num_bits < 16)
			{
				if (stbi__zeof(a) != 0) return -1;

				stbi__fill_bits(a);
			}

			b = z.fast[a.code_buffer & ((1 << 9) - 1)];
			if (b != 0)
			{
				s = b >> 9;
				a.code_buffer >>= s;
				a.num_bits -= s;
				return b & 511;
			}

			return stbi__zhuffman_decode_slowpath(a, z);
		}

		public static int32 stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z)
		{
			int32 b = 0;
			int32 s = 0;
			int32 k = 0;
			k = stbi__bit_reverse((int32)a.code_buffer, 16);
			for (s = 9 + 1; ; ++s)
				if (k < z.maxcode[s])
					break;

			if (s >= 16)
				return -1;
			b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s];
			if (b >= 288)
				return -1;
			if (z.size[b] != s)
				return -1;
			a.code_buffer >>= s;
			a.num_bits -= s;
			return z.value[b];
		}

		[Inline]
		public static uint32 stbi__zreceive(stbi__zbuf* z, int32 n)
		{
			uint32 k = 0;
			if (z.num_bits < n)
				stbi__fill_bits(z);
			k = (uint32)(z.code_buffer & ((1 << n) - 1));
			z.code_buffer >>= n;
			z.num_bits -= n;
			return k;
		}

		public static int32 stbi_zlib_decode_buffer(int8* obuffer, int32 olen, int8* ibuffer, int32 ilen)
		{
			stbi__zbuf a = default;
			a.zbuffer = (uint8*)ibuffer;
			a.zbuffer_end = (uint8*)ibuffer + ilen;
			if (stbi__do_zlib(&a, obuffer, olen, 0, 1) != 0)
				return (int32)(a.zout - a.zout_start);
			return -1;
		}

		public static int8* stbi_zlib_decode_malloc(int8* buffer, int32 len, int32* outlen)
		{
			return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
		}

		public static int8* stbi_zlib_decode_malloc_guesssize(int8* buffer, int32 len, int32 initial_size, int32* outlen)
		{
			stbi__zbuf a = default;
			var p = (int8*)stbi__malloc((uint64)initial_size);
			if (p == null)
				return null;
			a.zbuffer = (uint8*)buffer;
			a.zbuffer_end = (uint8*)buffer + len;
			if (stbi__do_zlib(&a, p, initial_size, 1, 1) != 0)
			{
				if (outlen != null)
					*outlen = (int32)(a.zout - a.zout_start);
				return a.zout_start;
			}

			CRuntime.free(a.zout_start);
			return null;
		}

		public static int8* stbi_zlib_decode_malloc_guesssize_headerflag(int8* buffer, int32 len, int32 initial_size,
			int32* outlen, int32 parse_header)
		{
			stbi__zbuf a = default;
			var p = (int8*)stbi__malloc((uint64)initial_size);
			if (p == null)
				return null;
			a.zbuffer = (uint8*)buffer;
			a.zbuffer_end = (uint8*)buffer + len;
			if (stbi__do_zlib(&a, p, initial_size, 1, parse_header) != 0)
			{
				if (outlen != null)
					*outlen = (int32)(a.zout - a.zout_start);
				return a.zout_start;
			}

			CRuntime.free(a.zout_start);
			return null;
		}

		public static int32 stbi_zlib_decode_noheader_buffer(int8* obuffer, int32 olen, int8* ibuffer, int32 ilen)
		{
			stbi__zbuf a = default;
			a.zbuffer = (uint8*)ibuffer;
			a.zbuffer_end = (uint8*)ibuffer + ilen;
			if (stbi__do_zlib(&a, obuffer, olen, 0, 0) != 0)
				return (int32)(a.zout - a.zout_start);
			return -1;
		}

		public static int8* stbi_zlib_decode_noheader_malloc(int8* buffer, int32 len, int32* outlen)
		{
			stbi__zbuf a = default;
			var p = (int8*)stbi__malloc(16384);
			if (p == null)
				return null;
			a.zbuffer = (uint8*)buffer;
			a.zbuffer_end = (uint8*)buffer + len;
			if (stbi__do_zlib(&a, p, 16384, 1, 0) != 0)
			{
				if (outlen != null)
					*outlen = (int32)(a.zout - a.zout_start);
				return a.zout_start;
			}

			CRuntime.free(a.zout_start);
			return null;
		}

		public struct stbi__zbuf
		{
			public uint8* zbuffer;
			public uint8* zbuffer_end;
			public int32 num_bits;
			public uint32 code_buffer;
			public int8* zout;
			public int8* zout_start;
			public int8* zout_end;
			public int32 z_expandable;
			public stbi__zhuffman z_length;
			public stbi__zhuffman z_distance;
		}

		public struct stbi__zhuffman
		{
			public uint16[512] fast;
			public uint16[16] firstcode;
			public int32[17] maxcode;
			public uint16[16] firstsymbol;
			public uint8[288] size;
			public uint16[288] value;
		}
	}
}