public static sbyte *stbi_zlib_decode_noheader_malloc(sbyte *buffer, int len, int *outlen) { var a = new stbi__zbuf(); var p = (sbyte *)stbi__malloc((ulong)16384); if (p == null) { return(null); } a.zbuffer = (byte *)buffer; a.zbuffer_end = (byte *)buffer + len; if (stbi__do_zlib(&a, p, 16384, 1, 0) != 0) { if (outlen != null) { *outlen = (int)(a.zout - a.zout_start); } return(a.zout_start); } CRuntime.free(a.zout_start); return(null); }
public static unsafe ImageResult FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { byte *result = null; try { int x, y, comp; var context = new StbImage.stbi__context(stream); result = StbImage.stbi__load_and_postprocess_8bit(context, &x, &y, &comp, (int)requiredComponents); return(FromResult(result, x, y, (ColorComponents)comp, requiredComponents)); } finally { if (result != null) { CRuntime.free(result); } } }
public static sbyte *stbi_zlib_decode_malloc_guesssize(sbyte *buffer, int len, int initial_size, int *outlen) { var a = new stbi__zbuf(); var p = (sbyte *)stbi__malloc((ulong)initial_size); if (p == null) { return(null); } a.zbuffer = (byte *)buffer; a.zbuffer_end = (byte *)buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, 1) != 0) { if (outlen != null) { *outlen = (int)(a.zout - a.zout_start); } return(a.zout_start); } CRuntime.free(a.zout_start); return(null); }
public static int stbtt_PackBegin(stbtt_pack_context spc, byte *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { stbrp_context *context = (stbrp_context *)(CRuntime.Malloc((ulong)(sizeof(stbrp_context)))); int num_nodes = (int)(pw - padding); stbrp_node * nodes = (stbrp_node *)(CRuntime.Malloc((ulong)(sizeof(stbrp_node) * num_nodes))); if (((context) == (null)) || ((nodes) == (null))) { if (context != (null)) { CRuntime.Free(context); } if (nodes != (null)) { CRuntime.Free(nodes); } return((int)(0)); } spc.user_allocator_context = alloc_context; spc.width = (int)(pw); spc.height = (int)(ph); spc.pixels = pixels; spc.pack_info = context; spc.nodes = nodes; spc.padding = (int)(padding); spc.stride_in_bytes = (int)(stride_in_bytes != 0 ? stride_in_bytes : pw); spc.h_oversample = (uint)(1); spc.v_oversample = (uint)(1); spc.skip_missing = (int)(0); stbrp_init_target(context, (int)(pw - padding), (int)(ph - padding), nodes, (int)(num_nodes)); if ((pixels) != null) { CRuntime.Memset(pixels, (int)(0), (ulong)(pw * ph)); } return((int)(1)); }
public static void stbi__vertical_flip(void *image, int w, int h, int bytesPerPixel) { var row = 0; var bytes_per_row = (ulong)(w * bytesPerPixel); var temp = stackalloc byte[2048]; var bytes = (byte *)image; for (row = 0; row < h >> 1; row++) { var row0 = bytes + (ulong)row * bytes_per_row; var row1 = bytes + (ulong)(h - row - 1) * bytes_per_row; var bytes_left = bytes_per_row; while (bytes_left != 0) { var bytes_copy = bytes_left < 2048 ? bytes_left : 2048; CRuntime.Memcpy(temp, row0, bytes_copy); CRuntime.Memcpy(row0, row1, bytes_copy); CRuntime.Memcpy(row1, temp, bytes_copy); row0 += bytes_copy; row1 += bytes_copy; bytes_left -= bytes_copy; } } }
public static byte *stbi__convert_format(byte *data, int img_n, int req_comp, uint x, uint y) { var i = 0; var j = 0; byte *good; if (req_comp == img_n) { return(data); } good = (byte *)stbi__malloc_mad3(req_comp, (int)x, (int)y, 0); if (good == null) { CRuntime.free(data); return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (j = 0; j < (int)y; ++j) { var src = data + j * x * img_n; var dest = good + j * x * req_comp; switch (img_n * 8 + req_comp) { case 1 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 2) { dest[0] = src[0]; dest[1] = 255; } break; case 1 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 1 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; case 2 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 1) { dest[0] = src[0]; } break; case 2 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 2 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; case 3 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; case 3 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; case 3 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; case 4 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; case 4 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; case 4 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; default: return((byte *)(ulong)(stbi__err("0") != 0 ? (byte *)null : null)); } } CRuntime.free(data); return(good); }
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_png_file(StbiPng z, int scan, int reqComp) { var palette = stackalloc byte[1024]; var pal_img_n = (byte)0; var has_trans = (byte)0; var tc = stackalloc byte[3]; tc[0] = 0; var tc16 = stackalloc ushort[3]; var ioff = (uint)0; var idata_limit = (uint)0; uint i = 0; var pal_len = (uint)0; var first = 1; var k = 0; var interlace = 0; var color = 0; var is_iphone = 0; var s = z.S; z.Expanded = null; z.Idata = null; z.Out = null; if (stbi__check_png_header(s) == 0) { return(0); } if (scan == STBI_SCAN_TYPE) { return(1); } for (; ;) { var c = stbi__get_chunk_header(s); switch (c.type) { case ((uint)'C' << 24) + ((uint)'g' << 16) + ((uint)'B' << 8) + 'I': is_iphone = 1; stbi__skip(s, (int)c.length); break; case ((uint)'I' << 24) + ((uint)'H' << 16) + ((uint)'D' << 8) + 'R': { var comp = 0; var filter = 0; if (first == 0) { return(stbi__err("multiple IHDR")); } first = 0; if (c.length != 13) { return(stbi__err("bad IHDR len")); } s.ImgX = stbi__get32be(s); if (s.ImgX > 1 << 24) { return(stbi__err("too large")); } s.ImgY = stbi__get32be(s); if (s.ImgY > 1 << 24) { return(stbi__err("too large")); } z.Depth = stbi__get8(s); if (z.Depth != 1 && z.Depth != 2 && z.Depth != 4 && z.Depth != 8 && z.Depth != 16) { return(stbi__err("1/2/4/8/16-bit only")); } color = stbi__get8(s); if (color > 6) { return(stbi__err("bad ctype")); } if (color == 3 && z.Depth == 16) { return(stbi__err("bad ctype")); } if (color == 3) { pal_img_n = 3; } else if ((color & 1) != 0) { return(stbi__err("bad ctype")); } comp = stbi__get8(s); if (comp != 0) { return(stbi__err("bad comp method")); } filter = stbi__get8(s); if (filter != 0) { return(stbi__err("bad filter method")); } interlace = stbi__get8(s); if (interlace > 1) { return(stbi__err("bad interlace method")); } if (s.ImgX == 0 || s.ImgY == 0) { return(stbi__err("0-pixel image")); } if (pal_img_n == 0) { s.ImgN = ((color & 2) != 0 ? 3 : 1) + ((color & 4) != 0 ? 1 : 0); if ((1 << 30) / s.ImgX / s.ImgN < s.ImgY) { return(stbi__err("too large")); } if (scan == STBI_SCAN_HEADER) { return(1); } } else { s.ImgN = 1; if ((1 << 30) / s.ImgX / 4 < s.ImgY) { return(stbi__err("too large")); } } break; } case ((uint)'P' << 24) + ((uint)'L' << 16) + ((uint)'T' << 8) + 'E': { if (first != 0) { return(stbi__err("first not IHDR")); } if (c.length > 256 * 3) { return(stbi__err("invalid PLTE")); } pal_len = c.length / 3; if (pal_len * 3 != c.length) { return(stbi__err("invalid PLTE")); } for (i = (uint)0; i < pal_len; ++i) { palette[i * 4 + 0] = stbi__get8(s); palette[i * 4 + 1] = stbi__get8(s); palette[i * 4 + 2] = stbi__get8(s); palette[i * 4 + 3] = 255; } break; } case ((uint)'t' << 24) + ((uint)'R' << 16) + ((uint)'N' << 8) + 'S': { if (first != 0) { return(stbi__err("first not IHDR")); } if (z.Idata != null) { return(stbi__err("tRNS after IDAT")); } if (pal_img_n != 0) { if (scan == STBI_SCAN_HEADER) { s.ImgN = 4; return(1); } if (pal_len == 0) { return(stbi__err("tRNS before PLTE")); } if (c.length > pal_len) { return(stbi__err("bad tRNS len")); } pal_img_n = 4; for (i = (uint)0; i < c.length; ++i) { palette[i * 4 + 3] = stbi__get8(s); } } else { if ((s.ImgN & 1) == 0) { return(stbi__err("tRNS with alpha")); } if (c.length != (uint)s.ImgN * 2) { return(stbi__err("bad tRNS len")); } has_trans = 1; if (z.Depth == 16) { for (k = 0; k < s.ImgN; ++k) { tc16[k] = (ushort)stbi__get16be(s); } } else { for (k = 0; k < s.ImgN; ++k) { tc[k] = (byte)((byte)(stbi__get16be(s) & 255) * StbiDepthScaleTable[z.Depth]); } } } break; } case ((uint)'I' << 24) + ((uint)'D' << 16) + ((uint)'A' << 8) + 'T': { if (first != 0) { return(stbi__err("first not IHDR")); } if (pal_img_n != 0 && pal_len == 0) { return(stbi__err("no PLTE")); } if (scan == STBI_SCAN_HEADER) { s.ImgN = pal_img_n; return(1); } if ((int)(ioff + c.length) < (int)ioff) { return(0); } if (ioff + c.length > idata_limit) { var idata_limit_old = idata_limit; byte *p; if (idata_limit == 0) { idata_limit = c.length > 4096 ? c.length : 4096; } while (ioff + c.length > idata_limit) { idata_limit *= 2; } p = (byte *)CRuntime.Realloc(z.Idata, (ulong)idata_limit); if (p == null) { return(stbi__err("outofmem")); } z.Idata = p; } if (stbi__getn(s, z.Idata + ioff, (int)c.length) == 0) { return(stbi__err("outofdata")); } ioff += c.length; break; } case ((uint)'I' << 24) + ((uint)'E' << 16) + ((uint)'N' << 8) + 'D': { uint raw_len = 0; uint bpl = 0; if (first != 0) { return(stbi__err("first not IHDR")); } if (scan != STBI_SCAN_LOAD) { return(1); } if (z.Idata == null) { return(stbi__err("no IDAT")); } bpl = (uint)((s.ImgX * z.Depth + 7) / 8); raw_len = (uint)(bpl * s.ImgY * s.ImgN + s.ImgY); z.Expanded = (byte *)stbi_zlib_decode_malloc_guesssize_headerflag((sbyte *)z.Idata, (int)ioff, (int)raw_len, (int *)&raw_len, is_iphone != 0 ? 0 : 1); if (z.Expanded == null) { return(0); } CRuntime.Free(z.Idata); z.Idata = null; if (reqComp == s.ImgN + 1 && reqComp != 3 && pal_img_n == 0 || has_trans != 0) { s.ImgOutN = s.ImgN + 1; } else { s.ImgOutN = s.ImgN; } if (stbi__create_png_image(z, z.Expanded, raw_len, s.ImgOutN, z.Depth, color, interlace) == 0) { return(0); } if (has_trans != 0) { if (z.Depth == 16) { if (stbi__compute_transparency16(z, tc16, s.ImgOutN) == 0) { return(0); } } else { if (stbi__compute_transparency(z, tc, s.ImgOutN) == 0) { return(0); } } } if (is_iphone != 0 && StbiDeIphoneFlag != 0 && s.ImgOutN > 2) { stbi__de_iphone(z); } if (pal_img_n != 0) { s.ImgN = pal_img_n; s.ImgOutN = pal_img_n; if (reqComp >= 3) { s.ImgOutN = reqComp; } if (stbi__expand_png_palette(z, palette, (int)pal_len, s.ImgOutN) == 0) { return(0); } } else if (has_trans != 0) { ++s.ImgN; } CRuntime.Free(z.Expanded); z.Expanded = null; return(1); } default: if (first != 0) { return(stbi__err("first not IHDR")); } if ((c.type & (1 << 29)) == 0) { var invalid_chunk = c.type + " PNG chunk not known"; return(stbi__err(invalid_chunk)); } stbi__skip(s, (int)c.length); break; } stbi__get32be(s); } }
private static void *stbi__malloc(int size) { return(CRuntime.malloc((ulong)size)); }
public static int stbi__create_png_image(StbiPng a, byte *imageData, uint imageDataLen, int outN, int depth, int color, int interlaced) { var bytes = depth == 16 ? 2 : 1; var out_bytes = outN * bytes; byte *final; var p = 0; if (interlaced == 0) { return(stbi__create_png_image_raw(a, imageData, imageDataLen, outN, a.S.ImgX, a.S.ImgY, depth, color)); } final = (byte *)stbi__malloc_mad3((int)a.S.ImgX, (int)a.S.ImgY, out_bytes, 0); for (p = 0; p < 7; ++p) { var xorig = stackalloc int[7]; xorig[0] = 0; xorig[1] = 4; xorig[2] = 0; xorig[3] = 2; xorig[4] = 0; xorig[5] = 1; xorig[6] = 0; var yorig = stackalloc int[7]; yorig[0] = 0; yorig[1] = 0; yorig[2] = 4; yorig[3] = 0; yorig[4] = 2; yorig[5] = 0; yorig[6] = 1; var xspc = stackalloc int[7]; xspc[0] = 8; xspc[1] = 8; xspc[2] = 4; xspc[3] = 4; xspc[4] = 2; xspc[5] = 2; xspc[6] = 1; var yspc = stackalloc int[7]; yspc[0] = 8; yspc[1] = 8; yspc[2] = 8; yspc[3] = 4; yspc[4] = 4; yspc[5] = 2; yspc[6] = 2; var i = 0; var j = 0; var x = 0; var y = 0; x = (int)((a.S.ImgX - xorig[p] + xspc[p] - 1) / xspc[p]); y = (int)((a.S.ImgY - yorig[p] + yspc[p] - 1) / yspc[p]); if (x != 0 && y != 0) { var img_len = (uint)((((a.S.ImgN * x * depth + 7) >> 3) + 1) * y); if (stbi__create_png_image_raw(a, imageData, imageDataLen, outN, (uint)x, (uint)y, depth, color) == 0) { CRuntime.Free(final); return(0); } for (j = 0; j < y; ++j) { for (i = 0; i < x; ++i) { var out_y = j * yspc[p] + yorig[p]; var out_x = i * xspc[p] + xorig[p]; CRuntime.Memcpy(final + out_y * a.S.ImgX * out_bytes + out_x * out_bytes, a.Out + (j * x + i) * out_bytes, (ulong)out_bytes); } } CRuntime.Free(a.Out); imageData += img_len; imageDataLen -= img_len; } } a.Out = final; return(1); }
public static int stbi__create_png_image_raw(StbiPng a, byte *raw, uint rawLen, int outN, uint x, uint y, int depth, int color) { var bytes = depth == 16 ? 2 : 1; var s = a.S; uint i = 0; uint j = 0; var stride = (uint)(x * outN * bytes); uint img_len = 0; uint img_width_bytes = 0; var k = 0; var img_n = s.ImgN; var output_bytes = outN * bytes; var filter_bytes = img_n * bytes; var width = (int)x; a.Out = (byte *)stbi__malloc_mad3((int)x, (int)y, output_bytes, 0); if (a.Out == null) { return(stbi__err("outofmem")); } if (stbi__mad3sizes_valid(img_n, (int)x, depth, 7) == 0) { return(stbi__err("too large")); } img_width_bytes = (uint)((img_n * x * depth + 7) >> 3); img_len = (img_width_bytes + 1) * y; if (rawLen < img_len) { return(stbi__err("not enough pixels")); } for (j = (uint)0; j < y; ++j) { var cur = a.Out + stride * j; byte *prior; var filter = (int)*raw++; if (filter > 4) { return(stbi__err("invalid filter")); } if (depth < 8) { cur += x * outN - img_width_bytes; filter_bytes = 1; width = (int)img_width_bytes; } prior = cur - stride; if (j == 0) { filter = FirstRowFilter[filter]; } for (k = 0; k < filter_bytes; ++k) { switch (filter) { case STBI_F_NONE: cur[k] = raw[k]; break; case STBI_F_SUB: cur[k] = raw[k]; break; case STBI_F_UP: cur[k] = (byte)((raw[k] + prior[k]) & 255); break; case STBI_F_AVG: cur[k] = (byte)((raw[k] + (prior[k] >> 1)) & 255); break; case STBI_F_PAETH: cur[k] = (byte)((raw[k] + stbi__paeth(0, prior[k], 0)) & 255); break; case STBI_F_AVG_FIRST: cur[k] = raw[k]; break; case STBI_F_PAETH_FIRST: cur[k] = raw[k]; break; } } if (depth == 8) { if (img_n != outN) { cur[img_n] = 255; } raw += img_n; cur += outN; prior += outN; } else if (depth == 16) { if (img_n != outN) { cur[filter_bytes] = 255; cur[filter_bytes + 1] = 255; } raw += filter_bytes; cur += output_bytes; prior += output_bytes; } else { raw += 1; cur += 1; prior += 1; } if (depth < 8 || img_n == outN) { var nk = (width - 1) * filter_bytes; switch (filter) { case STBI_F_NONE: CRuntime.Memcpy(cur, raw, (ulong)nk); break; case STBI_F_SUB: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + cur[k - filter_bytes]) & 255); } break; case STBI_F_UP: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + prior[k]) & 255); } break; case STBI_F_AVG: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)) & 255); } break; case STBI_F_PAETH: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])) & 255); } break; case STBI_F_AVG_FIRST: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + (cur[k - filter_bytes] >> 1)) & 255); } break; case STBI_F_PAETH_FIRST: for (k = 0; k < nk; ++k) { cur[k] = (byte)((raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)) & 255); } break; } raw += nk; } else { switch (filter) { case STBI_F_NONE: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = raw[k]; } } break; case STBI_F_SUB: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + cur[k - output_bytes]) & 255); } } break; case STBI_F_UP: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + prior[k]) & 255); } } break; case STBI_F_AVG: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)) & 255); } } break; case STBI_F_PAETH: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])) & 255); } } break; case STBI_F_AVG_FIRST: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + (cur[k - output_bytes] >> 1)) & 255); } } break; case STBI_F_PAETH_FIRST: for (i = x - 1; i >= 1; --i, cur[filter_bytes] = (byte)255, raw += filter_bytes, cur += output_bytes, prior += output_bytes) { for (k = 0; k < filter_bytes; ++k) { cur[k] = (byte)((raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)) & 255); } } break; } if (depth == 16) { cur = a.Out + stride * j; for (i = (uint)0; i < x; ++i, cur += output_bytes) { cur[filter_bytes + 1] = 255; } } } } if (depth < 8) { for (j = (uint)0; j < y; ++j) { var cur = a.Out + stride * j; var in_ = a.Out + stride * j + x * outN - img_width_bytes; var scale = (byte)(color == 0 ? StbiDepthScaleTable[depth] : 1); if (depth == 4) { for (k = (int)(x * img_n); k >= 2; k -= 2, ++in_) { *cur++ = (byte)(scale * (*in_ >> 4)); *cur++ = (byte)(scale * (*in_ & 0x0f)); } if (k > 0) { *cur++ = (byte)(scale * (*in_ >> 4)); } } else if (depth == 2) { for (k = (int)(x * img_n); k >= 4; k -= 4, ++in_) { *cur++ = (byte)(scale * (*in_ >> 6)); *cur++ = (byte)(scale * ((*in_ >> 4) & 0x03)); *cur++ = (byte)(scale * ((*in_ >> 2) & 0x03)); *cur++ = (byte)(scale * (*in_ & 0x03)); } if (k > 0) { *cur++ = (byte)(scale * (*in_ >> 6)); } if (k > 1) { *cur++ = (byte)(scale * ((*in_ >> 4) & 0x03)); } if (k > 2) { *cur++ = (byte)(scale * ((*in_ >> 2) & 0x03)); } } else if (depth == 1) { for (k = (int)(x * img_n); k >= 8; k -= 8, ++in_) { *cur++ = (byte)(scale * (*in_ >> 7)); *cur++ = (byte)(scale * ((*in_ >> 6) & 0x01)); *cur++ = (byte)(scale * ((*in_ >> 5) & 0x01)); *cur++ = (byte)(scale * ((*in_ >> 4) & 0x01)); *cur++ = (byte)(scale * ((*in_ >> 3) & 0x01)); *cur++ = (byte)(scale * ((*in_ >> 2) & 0x01)); *cur++ = (byte)(scale * ((*in_ >> 1) & 0x01)); *cur++ = (byte)(scale * (*in_ & 0x01)); } if (k > 0) { *cur++ = (byte)(scale * (*in_ >> 7)); } if (k > 1) { *cur++ = (byte)(scale * ((*in_ >> 6) & 0x01)); } if (k > 2) { *cur++ = (byte)(scale * ((*in_ >> 5) & 0x01)); } if (k > 3) { *cur++ = (byte)(scale * ((*in_ >> 4) & 0x01)); } if (k > 4) { *cur++ = (byte)(scale * ((*in_ >> 3) & 0x01)); } if (k > 5) { *cur++ = (byte)(scale * ((*in_ >> 2) & 0x01)); } if (k > 6) { *cur++ = (byte)(scale * ((*in_ >> 1) & 0x01)); } } if (img_n != outN) { var q = 0; cur = a.Out + stride * j; if (img_n == 1) { for (q = (int)(x - 1); q >= 0; --q) { cur[q * 2 + 1] = 255; cur[q * 2 + 0] = cur[q]; } } else { for (q = (int)(x - 1); q >= 0; --q) { cur[q * 4 + 3] = 255; cur[q * 4 + 2] = cur[q * 3 + 2]; cur[q * 4 + 1] = cur[q * 3 + 1]; cur[q * 4 + 0] = cur[q * 3 + 0]; } } } } } else if (depth == 16) { var cur = a.Out; var cur16 = (ushort *)cur; for (i = (uint)0; i < x * y * outN; ++i, cur16++, cur += 2) { *cur16 = (ushort)((cur[0] << 8) | cur[1]); } } return(1); }
public static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { stbtt__point *points = null; int num_points = 0; float objspace_flatness_squared = objspace_flatness * objspace_flatness; int i = 0; int n = 0; int start = 0; int pass = 0; for (i = 0; (i) < (num_verts); ++i) { if ((vertices[i].type) == (STBTT_vmove)) { ++n; } } *num_contours = n; if ((n) == (0)) { return(null); } *contour_lengths = (int *)(CRuntime.Malloc((ulong)(sizeof(int) * n))); if ((*contour_lengths) == (null)) { *num_contours = 0; return(null); } for (pass = 0; (pass) < (2); ++pass) { float x = 0; float y = 0; if ((pass) == (1)) { points = (stbtt__point *)(CRuntime.Malloc((ulong)(num_points * sizeof(stbtt__point)))); if ((points) == (null)) { goto error; } } num_points = 0; n = -1; for (i = 0; (i) < (num_verts); ++i) { switch (vertices[i].type) { case STBTT_vmove: if ((n) >= (0)) { (*contour_lengths)[n] = num_points - start; } ++n; start = num_points; x = vertices[i].x; y = vertices[i].y; stbtt__add_point(points, num_points++, x, y); break; case STBTT_vline: x = vertices[i].x; y = vertices[i].y; stbtt__add_point(points, num_points++, x, y); break; case STBTT_vcurve: stbtt__tesselate_curve(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); x = vertices[i].x; y = vertices[i].y; break; case STBTT_vcubic: stbtt__tesselate_cubic(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].cx1, vertices[i].cy1, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); x = vertices[i].x; y = vertices[i].y; break; } } (*contour_lengths)[n] = num_points - start; } return(points); error: ; CRuntime.Free(points); CRuntime.Free(*contour_lengths); *contour_lengths = null; *num_contours = 0; return(null); }
public static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) { float dx0 = x1 - x0; float dy0 = y1 - y0; float dx1 = x2 - x1; float dy1 = y2 - y1; float dx2 = x3 - x2; float dy2 = y3 - y2; float dx = x3 - x0; float dy = y3 - y0; float longlen = (float)(CRuntime.Sqrt(dx0 * dx0 + dy0 * dy0) + CRuntime.Sqrt(dx1 * dx1 + dy1 * dy1) + CRuntime.Sqrt(dx2 * dx2 + dy2 * dy2)); float shortlen = (float)(CRuntime.Sqrt(dx * dx + dy * dy)); float flatness_squared = longlen * longlen - shortlen * shortlen; if ((n) > (16)) { return; } if ((flatness_squared) > (objspace_flatness_squared)) { float x01 = (x0 + x1) / 2; float y01 = (y0 + y1) / 2; float x12 = (x1 + x2) / 2; float y12 = (y1 + y2) / 2; float x23 = (x2 + x3) / 2; float y23 = (y2 + y3) / 2; float xa = (x01 + x12) / 2; float ya = (y01 + y12) / 2; float xb = (x12 + x23) / 2; float yb = (y12 + y23) / 2; float mx = (xa + xb) / 2; float my = (ya + yb) / 2; stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1); stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1); } else { stbtt__add_point(points, *num_points, x3, y3); *num_points = *num_points + 1; } }
public static int stbi__zbuild_huffman(stbi__zhuffman *z, byte *sizelist, int num) { var i = 0; var k = 0; var code = 0; var next_code = stackalloc int[16]; var sizes = stackalloc int[17]; CRuntime.memset(sizes, 0, (ulong)sizeof(int)); CRuntime.memset(z->fast, 0, (ulong)((1 << 9) * sizeof(ushort))); 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] = (ushort)code; z->firstsymbol[i] = (ushort)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) { var s = (int)sizelist[i]; if (s != 0) { var c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; var fastv = (ushort)((s << 9) | i); z->size[c] = (byte)s; z->value[c] = (ushort)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); }
public static void stbtt_FreeSDF(byte *bitmap, void *userdata) { CRuntime.Free(bitmap); }
public static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) { int i = 0; float *orig = stackalloc float[2]; float *ray = stackalloc float[2]; ray[0] = 1; ray[1] = 0; float y_frac = 0; int winding = 0; orig[0] = x; orig[1] = y; y_frac = ((float)(CRuntime.Fmod(y, 1.0f))); if ((y_frac) < (0.01f)) { y += 0.01f; } else if ((y_frac) > (0.99f)) { y -= 0.01f; } orig[1] = y; for (i = 0; (i) < (nverts); ++i) { if ((verts[i].type) == (STBTT_vline)) { int x0 = verts[i - 1].x; int y0 = verts[i - 1].y; int x1 = verts[i].x; int y1 = verts[i].y; if ((((y) > ((y0) < (y1) ? (y0) : (y1))) && ((y) < ((y0) < (y1) ? (y1) : (y0)))) && ((x) > ((x0) < (x1) ? (x0) : (x1)))) { float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; if ((x_inter) < (x)) { winding += ((y0) < (y1)) ? 1 : -1; } } } if ((verts[i].type) == (STBTT_vcurve)) { int x0 = verts[i - 1].x; int y0 = verts[i - 1].y; int x1 = verts[i].cx; int y1 = verts[i].cy; int x2 = verts[i].x; int y2 = verts[i].y; int ax = (x0) < ((x1) < (x2) ? (x1) : (x2)) ? (x0) : ((x1) < (x2) ? (x1) : (x2)); int ay = (y0) < ((y1) < (y2) ? (y1) : (y2)) ? (y0) : ((y1) < (y2) ? (y1) : (y2)); int by = (y0) < ((y1) < (y2) ? (y2) : (y1)) ? ((y1) < (y2) ? (y2) : (y1)) : (y0); if ((((y) > (ay)) && ((y) < (by))) && ((x) > (ax))) { float *q0 = stackalloc float[2]; float *q1 = stackalloc float[2]; float *q2 = stackalloc float[2]; float *hits = stackalloc float[4]; q0[0] = x0; q0[1] = y0; q1[0] = x1; q1[1] = y1; q2[0] = x2; q2[1] = y2; if (((equal(q0, q1)) != 0) || ((equal(q1, q2)) != 0)) { x0 = verts[i - 1].x; y0 = verts[i - 1].y; x1 = verts[i].x; y1 = verts[i].y; if ((((y) > ((y0) < (y1) ? (y0) : (y1))) && ((y) < ((y0) < (y1) ? (y1) : (y0)))) && ((x) > ((x0) < (x1) ? (x0) : (x1)))) { float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; if ((x_inter) < (x)) { winding += ((y0) < (y1)) ? 1 : -1; } } } else { int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); if ((num_hits) >= (1)) { if ((hits[0]) < (0)) { winding += (hits[1]) < (0) ? -1 : 1; } } if ((num_hits) >= (2)) { if ((hits[2]) < (0)) { winding += (hits[3]) < (0) ? -1 : 1; } } } } } } return(winding); }
public static int stbtt__ray_intersect_bezier(float *orig, float *ray, float *q0, float *q1, float *q2, float *hits) { float q0perp = q0[1] * ray[0] - q0[0] * ray[1]; float q1perp = q1[1] * ray[0] - q1[0] * ray[1]; float q2perp = q2[1] * ray[0] - q2[0] * ray[1]; float roperp = orig[1] * ray[0] - orig[0] * ray[1]; float a = q0perp - 2 * q1perp + q2perp; float b = q1perp - q0perp; float c = q0perp - roperp; float s0 = 0; float s1 = 0; int num_s = 0; if (a != 0.0) { float discr = b * b - a * c; if ((discr) > (0.0)) { float rcpna = -1 / a; float d = (float)(CRuntime.Sqrt(discr)); s0 = (b + d) * rcpna; s1 = (b - d) * rcpna; if (((s0) >= (0.0)) && (s0 <= 1.0)) { num_s = 1; } if ((((d) > (0.0)) && ((s1) >= (0.0))) && (s1 <= 1.0)) { if ((num_s) == (0)) { s0 = s1; } ++num_s; } } } else { s0 = c / (-2 * b); if (((s0) >= (0.0)) && (s0 <= 1.0)) { num_s = 1; } } if ((num_s) == (0)) { return(0); } else { float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]); float rayn_x = ray[0] * rcp_len2; float rayn_y = ray[1] * rcp_len2; float q0d = q0[0] * rayn_x + q0[1] * rayn_y; float q1d = q1[0] * rayn_x + q1[1] * rayn_y; float q2d = q2[0] * rayn_x + q2[1] * rayn_y; float rod = orig[0] * rayn_x + orig[1] * rayn_y; float q10d = q1d - q0d; float q20d = q2d - q0d; float q0rd = q0d - rod; hits[0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d; hits[1] = a * s0 + b; if ((num_s) > (1)) { hits[2] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d; hits[3] = a * s1 + b; return(2); } else { return(1); } } }
public static void stbtt__v_prefilter(byte *pixels, int w, int h, int stride_in_bytes, uint kernel_width) { byte *buffer = stackalloc byte[8]; int safe_h = (int)(h - kernel_width); int j = 0; CRuntime.Memset(buffer, 0, (ulong)(8)); for (j = 0; (j) < (w); ++j) { int i = 0; uint total = 0; CRuntime.Memset(buffer, 0, (ulong)(kernel_width)); total = 0; switch (kernel_width) { case 2: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = ((byte)(total / 2)); } break; case 3: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = ((byte)(total / 3)); } break; case 4: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = ((byte)(total / 4)); } break; case 5: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = ((byte)(total / 5)); } break; default: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = ((byte)(total / kernel_width)); } break; } for (; (i) < (h); ++i) { total -= buffer[i & (8 - 1)]; pixels[i * stride_in_bytes] = ((byte)(total / kernel_width)); } pixels += 1; } }
public static ushort *stbi__convert_format16(ushort *data, int imgN, int reqComp, uint x, uint y) { var i = 0; var j = 0; ushort *good; if (reqComp == imgN) { return(data); } good = (ushort *)stbi__malloc((ulong)(reqComp * x * y * 2)); if (good == null) { CRuntime.Free(data); return((ushort *)(byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (j = 0; j < (int)y; ++j) { var src = data + j * x * imgN; var dest = good + j * x * reqComp; switch (imgN * 8 + reqComp) { case 1 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; case 1 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 1 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 1, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; case 2 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 1) { dest[0] = src[0]; } break; case 2 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; case 2 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 2, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; case 3 * 8 + 4: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; case 3 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; case 3 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 3, dest += 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; case 4 * 8 + 1: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; case 4 * 8 + 2: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; case 4 * 8 + 3: for (i = (int)(x - 1); i >= 0; --i, src += 4, dest += 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; default: return((ushort *)(byte *)(ulong)(stbi__err("0") != 0 ? (byte *)null : null)); } } CRuntime.Free(data); return(good); }
public static void *stbi__bmp_load(StbiContext s, int *x, int *y, int *comp, int reqComp, StbiResultInfo *ri) { byte *out_; var mr = (uint)0; var mg = (uint)0; var mb = (uint)0; var ma = (uint)0; uint all_a = 0; var pal = stackalloc byte[256 * 4]; var psize = 0; var i = 0; var j = 0; var width = 0; var flip_vertically = 0; var pad = 0; var target = 0; var info = new StbiBmpData(); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == null) { return(null); } flip_vertically = (int)s.ImgY > 0 ? 1 : 0; s.ImgY = (uint)CRuntime.Abs((int)s.ImgY); mr = info.mr; mg = info.mg; mb = info.mb; ma = info.ma; all_a = info.all_a; if (info.hsz == 12) { if (info.bpp < 24) { psize = (info.offset - 14 - 24) / 3; } } else { if (info.bpp < 16) { psize = (info.offset - 14 - info.hsz) >> 2; } } s.ImgN = ma != 0 ? 4 : 3; if (reqComp != 0 && reqComp >= 3) { target = reqComp; } else { target = s.ImgN; } if (stbi__mad3sizes_valid(target, (int)s.ImgX, (int)s.ImgY, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null)); } out_ = (byte *)stbi__malloc_mad3(target, (int)s.ImgX, (int)s.ImgY, 0); if (out_ == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } if (info.bpp < 16) { var z = 0; if (psize == 0 || psize > 256) { CRuntime.Free(out_); return((byte *)(ulong)(stbi__err("invalid") != 0 ? (byte *)null : null)); } for (i = 0; i < psize; ++i) { pal[i * 4 + 2] = stbi__get8(s); pal[i * 4 + 1] = stbi__get8(s); pal[i * 4 + 0] = stbi__get8(s); if (info.hsz != 12) { stbi__get8(s); } pal[i * 4 + 3] = 255; } stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); if (info.bpp == 1) { width = (int)((s.ImgX + 7) >> 3); } else if (info.bpp == 4) { width = (int)((s.ImgX + 1) >> 1); } else if (info.bpp == 8) { width = (int)s.ImgX; } else { CRuntime.Free(out_); return((byte *)(ulong)(stbi__err("bad bpp") != 0 ? (byte *)null : null)); } pad = -width & 3; if (info.bpp == 1) { for (j = 0; j < (int)s.ImgY; ++j) { var bit_offset = 7; var v = (int)stbi__get8(s); for (i = 0; i < (int)s.ImgX; ++i) { var color = (v >> bit_offset) & 0x1; out_[z++] = pal[color * 4 + 0]; out_[z++] = pal[color * 4 + 1]; out_[z++] = pal[color * 4 + 2]; if (target == 4) { out_[z++] = 255; } if (i + 1 == (int)s.ImgX) { break; } if (--bit_offset < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j = 0; j < (int)s.ImgY; ++j) { for (i = 0; i < (int)s.ImgX; i += 2) { var v = (int)stbi__get8(s); var v2 = 0; if (info.bpp == 4) { v2 = v & 15; v >>= 4; } out_[z++] = pal[v * 4 + 0]; out_[z++] = pal[v * 4 + 1]; out_[z++] = pal[v * 4 + 2]; if (target == 4) { out_[z++] = 255; } if (i + 1 == (int)s.ImgX) { break; } v = info.bpp == 8 ? stbi__get8(s) : v2; out_[z++] = pal[v * 4 + 0]; out_[z++] = pal[v * 4 + 1]; out_[z++] = pal[v * 4 + 2]; if (target == 4) { out_[z++] = 255; } } stbi__skip(s, pad); } } } else { var rshift = 0; var gshift = 0; var bshift = 0; var ashift = 0; var rcount = 0; var gcount = 0; var bcount = 0; var acount = 0; var z = 0; var easy = 0; stbi__skip(s, info.offset - 14 - info.hsz); if (info.bpp == 24) { width = (int)(3 * s.ImgX); } else if (info.bpp == 16) { width = (int)(2 * s.ImgX); } else { width = 0; } pad = -width & 3; if (info.bpp == 24) { easy = 1; } else if (info.bpp == 32) { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) { easy = 2; } } if (easy == 0) { if (mr == 0 || mg == 0 || mb == 0) { CRuntime.Free(out_); return((byte *)(ulong)(stbi__err("bad masks") != 0 ? (byte *)null : null)); } rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); } for (j = 0; j < (int)s.ImgY; ++j) { if (easy != 0) { for (i = 0; i < (int)s.ImgX; ++i) { byte a = 0; out_[z + 2] = stbi__get8(s); out_[z + 1] = stbi__get8(s); out_[z + 0] = stbi__get8(s); z += 3; a = (byte)(easy == 2 ? stbi__get8(s) : 255); all_a |= a; if (target == 4) { out_[z++] = a; } } } else { var bpp = info.bpp; for (i = 0; i < (int)s.ImgX; ++i) { var v = bpp == 16 ? (uint)stbi__get16le(s) : stbi__get32le(s); uint a = 0; out_[z++] = (byte)(stbi__shiftsigned(v & mr, rshift, rcount) & 255); out_[z++] = (byte)(stbi__shiftsigned(v & mg, gshift, gcount) & 255); out_[z++] = (byte)(stbi__shiftsigned(v & mb, bshift, bcount) & 255); a = (uint)(ma != 0 ? stbi__shiftsigned(v & ma, ashift, acount) : 255); all_a |= a; if (target == 4) { out_[z++] = (byte)(a & 255); } } } stbi__skip(s, pad); } } if (target == 4 && all_a == 0) { for (i = (int)(4 * s.ImgX * s.ImgY - 1); i >= 0; i -= 4) { out_[i] = 255; } } if (flip_vertically != 0) { byte t = 0; for (j = 0; j < (int)s.ImgY >> 1; ++j) { var p1 = out_ + j * s.ImgX * target; var p2 = out_ + (s.ImgY - 1 - j) * s.ImgX * target; for (i = 0; i < (int)s.ImgX * target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (reqComp != 0 && reqComp != target) { out_ = stbi__convert_format(out_, target, reqComp, s.ImgX, s.ImgY); if (out_ == null) { return(out_); } } *x = (int)s.ImgX; *y = (int)s.ImgY; if (comp != null) { *comp = s.ImgN; } return(out_); }
public static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { stbtt__hheap hh = new stbtt__hheap(); stbtt__active_edge *active = (null); int y = 0; int j = 0; int i = 0; float *scanline_data = stackalloc float[129]; float *scanline; float *scanline2; if ((result->w) > (64)) { scanline = (float *)(CRuntime.Malloc((ulong)((result->w * 2 + 1) * sizeof(float)))); } else { scanline = scanline_data; } scanline2 = scanline + result->w; y = off_y; e[n].y0 = (float)(off_y + result->h) + 1; while ((j) < (result->h)) { float scan_y_top = y + 0.0f; float scan_y_bottom = y + 1.0f; stbtt__active_edge **step = &active; CRuntime.Memset(scanline, 0, (ulong)(result->w * sizeof(float))); CRuntime.Memset(scanline2, 0, (ulong)((result->w + 1) * sizeof(float))); while ((*step) != null) { stbtt__active_edge *z = *step; if (z->ey <= scan_y_top) { *step = z->next; z->direction = 0; stbtt__hheap_free(&hh, z); } else { step = &((*step)->next); } } while (e->y0 <= scan_y_bottom) { if (e->y0 != e->y1) { stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); if (z != (null)) { if (((j) == (0)) && (off_y != 0)) { if ((z->ey) < (scan_y_top)) { z->ey = scan_y_top; } } z->next = active; active = z; } } ++e; } if ((active) != null) { stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); } { float sum = 0; for (i = 0; (i) < (result->w); ++i) { float k = 0; int m = 0; sum += scanline2[i]; k = scanline[i] + sum; k = CRuntime.Fabs(k) * 255 + 0.5f; m = ((int)(k)); if ((m) > (255)) { m = 255; } result->pixels[j * result->stride + i] = ((byte)(m)); } } step = &active; while ((*step) != null) { stbtt__active_edge *z = *step; z->fx += z->fdx; step = &((*step)->next); } ++y; ++j; } stbtt__hheap_cleanup(&hh, userdata); if (scanline != scanline_data) { CRuntime.Free(scanline); } }
public static void stbtt_PackEnd(stbtt_pack_context spc) { CRuntime.Free(spc.nodes); CRuntime.Free(spc.pack_info); }