public static int stbi__zexpand(stbi__zbuf *z, sbyte *zout, int n) { sbyte *q; var cur = 0; var limit = 0; var old_limit = 0; z->zout = zout; if (z->z_expandable == 0) { return(stbi__err("output buffer limit")); } cur = (int)(z->zout - z->zout_start); limit = old_limit = (int)(z->zout_end - z->zout_start); while (cur + n > limit) { limit *= 2; } q = (sbyte *)CRuntime.realloc(z->zout_start, (ulong)limit); if (q == null) { return(stbi__err("outofmem")); } z->zout_start = q; z->zout = q + cur; z->zout_end = q + limit; return(1); }
public static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) { var b = 0; var s = 0; var k = 0; k = stbi__bit_reverse((int)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]); }
public static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) { var b = 0; var 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 int stbi__do_zlib(stbi__zbuf *a, sbyte *obuf, int olen, int exp, int 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) { do { z->code_buffer |= (uint)stbi__zget8(z) << z->num_bits; z->num_bits += 8; } while (z->num_bits <= 24); }
public static byte stbi__zget8(stbi__zbuf *z) { if (z->zbuffer >= z->zbuffer_end) { return(0); } return(*z->zbuffer++); }
public static uint stbi__zreceive(stbi__zbuf *z, int n) { uint k = 0; if (z->num_bits < n) { stbi__fill_bits(z); } k = (uint)(z->code_buffer & ((1 << n) - 1)); z->code_buffer >>= n; z->num_bits -= n; return(k); }
public static int stbi__parse_uncompressed_block(stbi__zbuf *a) { var header = stackalloc byte[4]; var len = 0; var nlen = 0; var k = 0; if ((a->num_bits & 7) != 0) { stbi__zreceive(a, a->num_bits & 7); } k = 0; while (a->num_bits > 0) { header[k++] = (byte)(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 = header[1] * 256 + header[0]; nlen = 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, (ulong)len); a->zbuffer += len; a->zout += len; return(1); }
public static void stbi__fill_bits(stbi__zbuf *z) { do { if (z->code_buffer >= 1U << z->num_bits) { z->zbuffer = z->zbuffer_end; return; } z->code_buffer |= (uint)stbi__zget8(z) << z->num_bits; z->num_bits += 8; } while (z->num_bits <= 24); }
public static int stbi__parse_zlib_header(stbi__zbuf *a) { var cmf = (int)stbi__zget8(a); var cm = cmf & 15; var flg = (int)stbi__zget8(a); 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 int stbi__parse_zlib(stbi__zbuf *a, int parse_header) { var final = 0; var type = 0; if (parse_header != 0) { if (stbi__parse_zlib_header(a) == 0) { return(0); } } a->num_bits = 0; a->code_buffer = 0; do { final = (int)stbi__zreceive(a, 1); type = (int)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) { fixed(byte *b = stbi__zdefault_length) { if (stbi__zbuild_huffman(&a->z_length, b, 288) == 0) { return(0); } } fixed(byte *b = stbi__zdefault_distance) { if (stbi__zbuild_huffman(&a->z_distance, b, 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 int stbi__compute_huffman_codes(stbi__zbuf *a) { var z_codelength = new stbi__zhuffman(); var lencodes = stackalloc byte[286 + 32 + 137]; var codelength_sizes = stackalloc byte[19]; var i = 0; var n = 0; var hlit = (int)(stbi__zreceive(a, 5) + 257); var hdist = (int)(stbi__zreceive(a, 5) + 1); var hclen = (int)(stbi__zreceive(a, 4) + 4); var ntot = hlit + hdist; CRuntime.memset(codelength_sizes, 0, (ulong)(19 * sizeof(byte))); for (i = 0; i < hclen; ++i) { var s = (int)stbi__zreceive(a, 3); codelength_sizes[length_dezigzag[i]] = (byte)s; } if (stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19) == 0) { return(0); } n = 0; while (n < ntot) { var c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) { return(stbi__err("bad codelengths")); } if (c < 16) { lencodes[n++] = (byte)c; } else { var fill = (byte)0; if (c == 16) { c = (int)(stbi__zreceive(a, 2) + 3); if (n == 0) { return(stbi__err("bad codelengths")); } fill = lencodes[n - 1]; } else if (c == 17) { c = (int)(stbi__zreceive(a, 3) + 3); } else { c = (int)(stbi__zreceive(a, 7) + 11); } if (ntot - n < c) { return(stbi__err("bad codelengths")); } CRuntime.memset(lencodes + n, fill, (ulong)c); n += c; } } if (n != ntot) { return(stbi__err("bad codelengths")); } if (stbi__zbuild_huffman(&a->z_length, lencodes, hlit) == 0) { return(0); } if (stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist) == 0) { return(0); } return(1); }
public static int 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++ = (sbyte)z; } else { byte *p; var len = 0; var dist = 0; if (z == 256) { a->zout = zout; return(1); } z -= 257; len = stbi__zlength_base[z]; if (stbi__zlength_extra[z] != 0) { len += (int)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 += (int)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 = (byte *)(zout - dist); if (dist == 1) { var v = *p; if (len != 0) { do { *zout++ = (sbyte)v; } while (--len != 0); } } else { if (len != 0) { do { *zout++ = (sbyte)*p++; } while (--len != 0); } } } } }
public static byte stbi__zget8(stbi__zbuf *z) { return((byte)(stbi__zeof(z) != 0 ? 0 : *z->zbuffer++)); }
public static int stbi__zeof(stbi__zbuf *z) { return(z->zbuffer >= z->zbuffer_end ? 1 : 0); }