public static int stbi_write_hdr_core(StbiWriteContext s, int x, int y, int comp, float *data) { if ((y <= 0) || (x <= 0) || (data == null)) { return(0); } var scratch = (byte *)(CRuntime.Malloc((ulong)(x * 4))); int i; var header = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; var bytes = Encoding.UTF8.GetBytes(header); fixed(byte *ptr = bytes) { s.Func(s.Context, ((sbyte *)ptr), bytes.Length); } var str = string.Format("EXPOSURE= 1.0000000000000\n\n-Y {0} +X {1}\n", y, x); bytes = Encoding.UTF8.GetBytes(str); fixed(byte *ptr = bytes) { s.Func(s.Context, ((sbyte *)ptr), bytes.Length); } for (i = 0; i < y; i++) { stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp * i * x); } CRuntime.Free(scratch); return(1); }
public static int stbtt_PackFontRanges(stbtt_pack_context spc, byte *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info = new stbtt_fontinfo(); int i = 0; int j = 0; int n = 0; int return_value = (int)(1); stbrp_rect * rects; for (i = (int)(0); (i) < (num_ranges); ++i) { for (j = (int)(0); (j) < (ranges[i].num_chars); ++j) { ranges[i].chardata_for_range[j].x0 = (ushort)(ranges[i].chardata_for_range[j].y0 = (ushort)(ranges[i].chardata_for_range[j].x1 = (ushort)(ranges[i].chardata_for_range[j].y1 = (ushort)(0)))); } } n = (int)(0); for (i = (int)(0); (i) < (num_ranges); ++i) { n += (int)(ranges[i].num_chars); } rects = (stbrp_rect *)(CRuntime.Malloc((ulong)(sizeof(stbrp_rect) * n))); if ((rects) == (null)) { return((int)(0)); } info.userdata = spc.user_allocator_context; stbtt_InitFont(info, fontdata, (int)(stbtt_GetFontOffsetForIndex(fontdata, (int)(font_index)))); n = (int)(stbtt_PackFontRangesGatherRects(spc, info, ranges, (int)(num_ranges), rects)); stbtt_PackFontRangesPackRects(spc, rects, (int)(n)); return_value = (int)(stbtt_PackFontRangesRenderIntoRects(spc, info, ranges, (int)(num_ranges), rects)); CRuntime.Free(rects); return((int)(return_value)); }
public static void *stbi__do_png(StbiPng p, int *x, int *y, int *n, int reqComp, StbiResultInfo *ri) { void *result = null; if (reqComp < 0 || reqComp > 4) { return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? (byte *)null : null)); } if (stbi__parse_png_file(p, STBI_SCAN_LOAD, reqComp) != 0) { if (p.Depth < 8) { ri->bits_per_channel = 8; } else { ri->bits_per_channel = p.Depth; } result = p.Out; p.Out = null; if (reqComp != 0 && reqComp != p.S.ImgOutN) { if (ri->bits_per_channel == 8) { result = stbi__convert_format((byte *)result, p.S.ImgOutN, reqComp, p.S.ImgX, p.S.ImgY); } else { result = stbi__convert_format16((ushort *)result, p.S.ImgOutN, reqComp, p.S.ImgX, p.S.ImgY); } p.S.ImgOutN = reqComp; if (result == null) { return(result); } } *x = (int)p.S.ImgX; *y = (int)p.S.ImgY; if (n != null) { *n = p.S.ImgN; } } CRuntime.Free(p.Out); p.Out = null; CRuntime.Free(p.Expanded); p.Expanded = null; CRuntime.Free(p.Idata); p.Idata = null; return(result); }
public static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) { stbtt__hheap_chunk *c = hh->head; while ((c) != null) { stbtt__hheap_chunk *n = c->next; CRuntime.Free(c); c = n; } }
public static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) { float y_scale_inv = (invert) != 0 ? -scale_y : scale_y; stbtt__edge *e; int n = 0; int i = 0; int j = 0; int k = 0; int m = 0; int vsubsample = 1; n = 0; for (i = 0; (i) < (windings); ++i) { n += wcount[i]; } e = (stbtt__edge *)(CRuntime.Malloc((ulong)(sizeof(stbtt__edge) * (n + 1)))); if ((e) == (null)) { return; } n = 0; m = 0; for (i = 0; (i) < (windings); ++i) { stbtt__point *p = pts + m; m += wcount[i]; j = wcount[i] - 1; for (k = 0; (k) < (wcount[i]); j = k++) { int a = k; int b = j; if ((p[j].y) == (p[k].y)) { continue; } e[n].invert = 0; if ((((invert) != 0) && ((p[j].y) > (p[k].y))) || ((invert == 0) && ((p[j].y) < (p[k].y)))) { e[n].invert = 1; a = j; b = k; } e[n].x0 = p[a].x * scale_x + shift_x; e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; e[n].x1 = p[b].x * scale_x + shift_x; e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; ++n; } } stbtt__sort_edges(e, n); stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); CRuntime.Free(e); }
public static void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { float scale = (scale_x) > (scale_y) ? scale_y : scale_x; int winding_count = 0; int * winding_lengths = (null); stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); if ((windings) != null) { stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); CRuntime.Free(winding_lengths); CRuntime.Free(windings); } }
public static byte *stbi__convert_16_to_8(ushort *orig, int w, int h, int channels) { var i = 0; var img_len = w * h * channels; byte *reduced; reduced = (byte *)stbi__malloc((ulong)img_len); if (reduced == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (i = 0; i < img_len; ++i) { reduced[i] = (byte)((orig[i] >> 8) & 0xFF); } CRuntime.Free(orig); return(reduced); }
public static ushort *stbi__convert_8_to_16(byte *orig, int w, int h, int channels) { var i = 0; var img_len = w * h * channels; ushort *enlarged; enlarged = (ushort *)stbi__malloc((ulong)(img_len * 2)); if (enlarged == null) { return((ushort *)(byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null)); } for (i = 0; i < img_len; ++i) { enlarged[i] = (ushort)((orig[i] << 8) + orig[i]); } CRuntime.Free(orig); return(enlarged); }
public static int stbi__expand_png_palette(StbiPng a, byte *palette, int len, int palImgN) { uint i = 0; var pixel_count = a.S.ImgX * a.S.ImgY; byte *p; byte *temp_out; var orig = a.Out; p = (byte *)stbi__malloc_mad2((int)pixel_count, palImgN, 0); if (p == null) { return(stbi__err("outofmem")); } temp_out = p; if (palImgN == 3) { for (i = (uint)0; i < pixel_count; ++i) { var n = orig[i] * 4; p[0] = palette[n]; p[1] = palette[n + 1]; p[2] = palette[n + 2]; p += 3; } } else { for (i = (uint)0; i < pixel_count; ++i) { var n = orig[i] * 4; p[0] = palette[n]; p[1] = palette[n + 1]; p[2] = palette[n + 2]; p[3] = palette[n + 3]; p += 4; } } CRuntime.Free(a.Out); a.Out = temp_out; return(1); }
public void Dispose() { if (Pal != null) { CRuntime.Free(Pal); Pal = null; } if (Lpal != null) { CRuntime.Free(Lpal); Lpal = null; } if (Codes != null) { CRuntime.Free(Codes); Codes = null; } }
public static int stbi_write_png_to_func(WriteCallback func, void *context, int x, int y, int comp, void *data, int strideBytes ) { int len; var png = stbi_write_png_to_mem((byte *)(data), strideBytes, x, y, comp, &len); if (png == null) { return(0); } func(context, png, len); CRuntime.Free(png); return(1); }
public static sbyte *stbi_zlib_decode_malloc_guesssize(sbyte *buffer, int len, int initialSize, int *outlen) { var a = new StbiZbuf(); var p = (sbyte *)stbi__malloc((ulong)initialSize); if (p == null) { return(null); } a.zbuffer = (byte *)buffer; a.zbuffer_end = (byte *)buffer + len; if (stbi__do_zlib(&a, p, initialSize, 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 unsafe ImageResult FromStream(Stream stream, ColorComponents requiredComponents = ColorComponents.Default) { byte *result = null; try { int x, y, comp; var context = new StbImage.StbiContext(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_noheader_malloc(sbyte *buffer, int len, int *outlen) { var a = new StbiZbuf(); 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 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 stbtt_PackEnd(stbtt_pack_context spc) { CRuntime.Free(spc.nodes); CRuntime.Free(spc.pack_info); }
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 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); } }
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 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 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 stbtt_FreeSDF(byte *bitmap, void *userdata) { CRuntime.Free(bitmap); }
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); }