public static void stbtt_GetGlyphBitmapBox(stbtt_fontinfo font, int glyph, float scale_x, float scale_y, ref int x0, ref int y0, ref int x1, ref int y1) { var px0 = new FakePtr <int>(1) { Value = x0 }; var px1 = new FakePtr <int>(1) { Value = x1 }; var py0 = new FakePtr <int>(1) { Value = y0 }; var py1 = new FakePtr <int>(1) { Value = y1 }; stbtt_GetGlyphBitmapBox(font, glyph, scale_x, scale_y, px0, py0, px1, py1); x0 = px0.Value; x1 = px1.Value; y0 = py0.Value; y1 = py1.Value; }
private int stbi__expand_png_palette(byte[] palette, int len, int pal_img_n) { uint i = 0; var pixel_count = (uint)(img_x * img_y); var orig = _out_; _out_ = new byte[pixel_count * pal_img_n]; var p = new FakePtr <byte>(_out_); if (pal_img_n == 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; } } return(1); }
public static int stbtt_GetGlyphBox(stbtt_fontinfo info, int glyph_index, ref int x0, ref int y0, ref int x1, ref int y1) { var px0 = new FakePtr <int>(1) { Value = x0 }; var px1 = new FakePtr <int>(1) { Value = x1 }; var py0 = new FakePtr <int>(1) { Value = y0 }; var py1 = new FakePtr <int>(1) { Value = y1 }; var result = stbtt_GetGlyphBox(info, glyph_index, px0, py0, px1, py1); x0 = px0.Value; x1 = px1.Value; y0 = py0.Value; y1 = py1.Value; return(result); }
private int stbi__compute_transparency(byte[] tc, int out_n) { uint i = 0; var pixel_count = (uint)(img_x * img_y); var p = new FakePtr <byte>(_out_); if (out_n == 2) { for (i = (uint)0; i < pixel_count; ++i) { p[1] = (byte)(p[0] == tc[0] ? 0 : 255); p += 2; } } else { for (i = (uint)0; i < pixel_count; ++i) { if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) { p[3] = 0; } p += 4; } } return(1); }
private static void BlurCols(FakePtr <byte> dst, int w, int h, int dstStride, int alpha) { var x = 0; var y = 0; for (y = 0; y < h; y++) { var z = 0; for (x = 1; x < w; x++) { z += (alpha * ((dst[x] << 7) - z)) >> 16; dst[x] = (byte)(z >> 7); } dst[w - 1] = 0; z = 0; for (x = w - 2; x >= 0; x--) { z += (alpha * ((dst[x] << 7) - z)) >> 16; dst[x] = (byte)(z >> 7); } dst[0] = 0; dst += dstStride; } }
private static void BlurRows(FakePtr <byte> dst, int w, int h, int dstStride, int alpha) { var x = 0; var y = 0; for (x = 0; x < w; x++) { var z = 0; for (y = dstStride; y < h * dstStride; y += dstStride) { z += (alpha * ((dst[y] << 7) - z)) >> 16; dst[y] = (byte)(z >> 7); } dst[(h - 1) * dstStride] = 0; z = 0; for (y = (h - 2) * dstStride; y >= 0; y -= dstStride) { z += (alpha * ((dst[y] << 7) - z)) >> 16; dst[y] = (byte)(z >> 7); } dst[0] = 0; dst++; } }
public void stbtt__dict_get_ints(int key, out uint _out_) { var temp = new FakePtr <uint>(new uint[1]); stbtt__dict_get_ints(key, 1, temp); _out_ = temp[0]; }
static bool stbtt_tag(FakePtr <byte> p, string str) { return(stbtt_tag4(p, (byte)(str.Length >= 1 ? str[0] : 0), (byte)(str.Length >= 2 ? str[1] : 0), (byte)(str.Length >= 3 ? str[2] : 0), (byte)(str.Length >= 4 ? str[3] : 0))); }
private int stbi__do_zlib(byte[] obuf, int olen, int exp, int parse_header) { zout_start = obuf; zout = new FakePtr <byte>(obuf); zout_end = new FakePtr <byte>(obuf, olen); z_expandable = exp; return(stbi__parse_zlib(parse_header)); }
public void stbtt__rasterize(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) { var y_scale_inv = invert != 0 ? -scale_y : scale_y; var n = 0; var i = 0; var j = 0; var k = 0; var m = 0; var vsubsample = 1; n = 0; for (i = 0; i < windings; ++i) { n += wcount[i]; } var e = new stbtt__edge[n + 1]; for (i = 0; i < e.Length; ++i) { e[i] = new stbtt__edge(); } n = 0; m = 0; for (i = 0; i < windings; ++i) { var p = new FakePtr <stbtt__point>(pts, m); m += wcount[i]; j = wcount[i] - 1; for (k = 0; k < wcount[i]; j = k++) { var a = k; var 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; } } var ptr = new FakePtr <stbtt__edge>(e); stbtt__sort_edges(ptr, n); stbtt__rasterize_sorted_edges(ptr, n, vsubsample, off_x, off_y); }
public void stbtt__dict_get_ints(int key, int outcount, FakePtr <uint> _out_) { var i = 0; var operands = stbtt__dict_get(key); for (i = 0; i < outcount && operands.cursor < operands.size; i++) { _out_[i] = operands.stbtt__cff_int(); } }
public static FakePtr <T> CreateWithSize(int size) { var result = new FakePtr <T>(new T[size]); for (int i = 0; i < size; ++i) { result[i] = new T(); } return(result); }
private void stbi__tga_read_rgb16(FakePtr <byte> _out_) { var px = (ushort)stbi__get16le(); var fiveBitMask = (ushort)31; var r = (px >> 10) & fiveBitMask; var g = (px >> 5) & fiveBitMask; var b = px & fiveBitMask; _out_[0] = (byte)(r * 255 / 31); _out_[1] = (byte)(g * 255 / 31); _out_[2] = (byte)(b * 255 / 31); }
private void stbi__de_iphone() { uint i = 0; var pixel_count = (uint)(img_x * img_y); var p = new FakePtr <byte>(_out_); if (img_out_n == 3) { for (i = (uint)0; i < pixel_count; ++i) { var t = p[0]; p[0] = p[2]; p[2] = t; p += 3; } } else { if (stbi__unpremultiply_on_load != 0) { for (i = (uint)0; i < pixel_count; ++i) { var a = p[3]; var t = p[0]; if (a != 0) { var half = (byte)(a / 2); p[0] = (byte)((p[2] * 255 + half) / a); p[1] = (byte)((p[1] * 255 + half) / a); p[2] = (byte)((t * 255 + half) / a); } else { p[0] = p[2]; p[2] = t; } p += 4; } } else { for (i = (uint)0; i < pixel_count; ++i) { var t = p[0]; p[0] = p[2]; p[2] = t; p += 4; } } } }
private int stbi__psd_decode_rle(FakePtr <byte> p, int pixelCount) { var count = 0; var nleft = 0; var len = 0; count = 0; while ((nleft = pixelCount - count) > 0) { len = stbi__get8(); if (len == 128) { } else if (len < 128) { len++; if (len > nleft) { return(0); } count += len; while (len != 0) { p.Value = stbi__get8(); p += 4; len--; } } else if (len > 128) { byte val = 0; len = 257 - len; if (len > nleft) { return(0); } val = stbi__get8(); count += len; while (len != 0) { p.Value = val; p += 4; len--; } } } return(1); }
public int stbtt_PackFontRange(byte[] fontdata, int font_index, float font_size, int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar[] chardata_for_range) { var range = new stbtt_pack_range(); range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; range.array_of_unicode_codepoints = null; range.num_chars = num_chars_in_range; range.chardata_for_range = chardata_for_range; range.font_size = font_size; var ranges = new FakePtr <stbtt_pack_range>(range); return(stbtt_PackFontRanges(fontdata, font_index, ranges, 1)); }
private int stbi__parse_uncompressed_block() { var header = new byte[4]; var len = 0; var nlen = 0; var k = 0; if ((num_bits & 7) != 0) { stbi__zreceive(num_bits & 7); } k = 0; while (num_bits > 0) { header[k++] = (byte)(code_buffer & 255); code_buffer >>= 8; num_bits -= 8; } while (k < 4) { header[k++] = stbi__zget8(); } len = header[1] * 256 + header[0]; nlen = header[3] * 256 + header[2]; if (nlen != (len ^ 0xffff)) { Decoder.stbi__err("zlib corrupt"); } if (zbuffer.Offset + len > zbuffer_end.Offset) { Decoder.stbi__err("read past buffer"); } if (zout.Offset + len > zout_end.Offset) { if (stbi__zexpand(zout, len) == 0) { return(0); } } for (var i = 0; i < len; i++) { zout[i] = zbuffer[i]; } zbuffer += len; zout += len; return(1); }
static uint stbtt__find_table(FakePtr <byte> data, int fontstart, string tag) { int num_tables = ttUSHORT(data + fontstart + 4); int tabledir = fontstart + 12; int i; for (i = 0; i < num_tables; ++i) { int loc = tabledir + 16 * i; if (stbtt_tag(data + loc + 0, tag)) { return(ttULONG(data + loc + 8)); } } return(0); }
public int stbtt_PackFontRangesGatherRects(FontInfo info, FakePtr <stbtt_pack_range> ranges, int num_ranges, stbrp_rect[] rects) { var i = 0; var j = 0; var k = 0; var missing_glyph_added = 0; k = 0; for (i = 0; i < num_ranges; ++i) { var fh = ranges[i].font_size; var scale = fh > 0 ? info.stbtt_ScaleForPixelHeight(fh) : info.stbtt_ScaleForMappingEmToPixels(-fh); ranges[i].h_oversample = (byte)this.h_oversample; ranges[i].v_oversample = (byte)this.v_oversample; for (j = 0; j < ranges[i].num_chars; ++j) { var x0 = 0; var y0 = 0; var x1 = 0; var y1 = 0; var codepoint = ranges[i].array_of_unicode_codepoints == null ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; var glyph = info.stbtt_FindGlyphIndex(codepoint); if (glyph == 0 && (this.skip_missing != 0 || missing_glyph_added != 0)) { rects[k].w = rects[k].h = 0; } else { info.stbtt_GetGlyphBitmapBoxSubpixel(glyph, scale * this.h_oversample, scale * this.v_oversample, 0, 0, ref x0, ref y0, ref x1, ref y1); rects[k].w = (int)(x1 - x0 + this.padding + this.h_oversample - 1); rects[k].h = (int)(y1 - y0 + this.padding + this.v_oversample - 1); if (glyph == 0) { missing_glyph_added = 1; } } ++k; } } return(k); }
public static uint stbtt__find_table(FakePtr <byte> data, uint fontstart, string tag) { int num_tables = ttUSHORT(data + fontstart + 4); var tabledir = fontstart + 12; int i; for (i = 0; (i) < num_tables; ++i) { var loc = (int)(tabledir + 16 * i); if (((data)[loc] == (tag[0])) && ((data)[loc + 1] == tag[1]) && ((data)[loc + 2] == tag[2]) && ((data)[loc + 3] == (tag[3]))) { return(ttULONG(data + loc + 8)); } } return(0); }
private void Blur(byte[] dst, int w, int h, int dstStride, int blur) { var alpha = 0; float sigma = 0; if (blur < 1) { return; } sigma = blur * 0.57735f; alpha = (int)((1 << 16) * (1.0f - Math.Exp(-2.3f / (sigma + 1.0f)))); var ptr = new FakePtr <byte>(dst); BlurRows(ptr, w, h, dstStride, alpha); BlurCols(ptr, w, h, dstStride, alpha); BlurRows(ptr, w, h, dstStride, alpha); BlurCols(ptr, w, h, dstStride, alpha); }
public int stbtt_PackBegin(byte[] pixels, int pw, int ph, int stride_in_bytes, int padding) { var context = new stbrp_context(pw - padding, ph - padding); this.width = pw; this.height = ph; this.pixels = new FakePtr <byte>(pixels); this.pack_info = context; this.padding = padding; this.stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; this.h_oversample = 1; this.v_oversample = 1; this.skip_missing = 0; if (pixels != null) { Array.Clear(pixels, 0, pw * ph); } return(1); }
public void RenderGlyph(GraphicsDevice device, FontGlyph glyph) { var pad = glyph.Pad; // Render glyph to byte buffer var buffer = new byte[glyph.Bounds.Width * glyph.Bounds.Height]; Array.Clear(buffer, 0, buffer.Length); var g = glyph.Index; FakePtr <byte> dst = new FakePtr <byte>(buffer, pad + pad * glyph.Bounds.Width); glyph.Font.RenderGlyphBitmap(dst, glyph.Bounds.Width - pad * 2, glyph.Bounds.Height - pad * 2, glyph.Bounds.Width, g); if (glyph.Blur > 0) { Blur(buffer, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, glyph.Blur); } // Byte buffer to RGBA var colorBuffer = new Color[glyph.Bounds.Width * glyph.Bounds.Height]; for (var i = 0; i < colorBuffer.Length; ++i) { var c = buffer[i]; colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 255; colorBuffer[i].A = c; } // Write to texture if (Texture == null) { Texture = new Texture2D(device, Width, Height); } Texture.SetData(0, glyph.Bounds, colorBuffer, 0, colorBuffer.Length); }
public int stbtt_PackFontRanges(byte[] fontdata, int font_index, FakePtr <stbtt_pack_range> ranges, int num_ranges) { var info = new FontInfo(); var i = 0; var j = 0; var n = 0; var return_value = 1; stbrp_rect[] rects; for (i = 0; i < num_ranges; ++i) { for (j = 0; j < ranges[i].num_chars; ++j) { ranges[i].chardata_for_range[j].x0 = ranges[i].chardata_for_range[j].y0 = ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0; } } n = 0; for (i = 0; i < num_ranges; ++i) { n += ranges[i].num_chars; } rects = new stbrp_rect[n]; for (i = 0; i < rects.Length; ++i) { rects[i] = new stbrp_rect(); } if (rects == null) { return(0); } info.stbtt_InitFont(fontdata, Common.stbtt_GetFontOffsetForIndex(fontdata, font_index)); n = stbtt_PackFontRangesGatherRects(info, ranges, num_ranges, rects); stbtt_PackFontRangesPackRects(rects, n); return_value = stbtt_PackFontRangesRenderIntoRects(info, ranges, num_ranges, rects); return(return_value); }
private void stbi__out_gif_code(ushort code) { var idx = 0; if (codes[code].prefix >= 0) { stbi__out_gif_code((ushort)codes[code].prefix); } if (cur_y >= max_y) { return; } idx = cur_x + cur_y; history[idx / 4] = 1; var c = new FakePtr <byte>(color_table, codes[code].suffix * 4); if (c[3] > 128) { var p = new FakePtr <byte>(_out_, idx); p[0] = c[2]; p[1] = c[1]; p[2] = c[0]; p[3] = c[3]; } cur_x += 4; if (cur_x >= max_x) { cur_x = start_x; cur_y += step; while (cur_y >= max_y && parse > 0) { step = (1 << parse) * line_size; cur_y = start_y + (step >> 1); --parse; } } }
public static void stbi__vertical_flip(byte[] image, int w, int h, int bytes_per_pixel) { int row = 0; int bytes_per_row = w * bytes_per_pixel; byte[] temp = new byte[2048]; for (row = (int)(0); (row) < (h >> 1); row++) { FakePtr <byte> row0 = new FakePtr <byte>(image, (int)(row * bytes_per_row)); FakePtr <byte> row1 = new FakePtr <byte>(image, (int)((h - row - 1) * bytes_per_row)); int bytes_left = bytes_per_row; while ((bytes_left) != 0) { int bytes_copy = (((bytes_left) < (2048)) ? bytes_left : 2048); temp.memcpy(row0, bytes_copy); row0.memcpy(row1, bytes_copy); row1.memcpy(temp, bytes_copy); row0 += bytes_copy; row1 += bytes_copy; bytes_left -= bytes_copy; } } }
private int stbi__zexpand(FakePtr <byte> zout, int n) { var cur = 0; var limit = 0; var old_limit = 0; this.zout = zout; if (z_expandable == 0) { Decoder.stbi__err("output buffer limit"); } cur = this.zout.Offset; limit = old_limit = zout_end.Offset; while (cur + n > limit) { limit *= 2; } Array.Resize(ref zout_start, limit); this.zout = new FakePtr <byte>(zout_start, cur); zout_end = new FakePtr <byte>(zout_start, limit); return(1); }
static int stbtt_InitFont(ref stbtt_fontinfo info, FakePtr <byte> data2, int fontstart) { FakePtr <byte> data = (FakePtr <byte>)data2; uint i; info.data = data; info.fontstart = fontstart; info.name = stbtt__find_table(data, fontstart, "name"); // required if (info.name == 0) { return(0); } var format = ttUSHORT(data + info.name); var nameRecordCount = ttUSHORT(data + info.name + 2); var stringOffset = ttUSHORT(data + info.name + 4); var offset = info.name + stringOffset; var nameRecords = new stbtt_name_record[nameRecordCount]; for (i = 0; i < nameRecordCount; ++i) { uint name_record = info.name + 6 + 12 * i; var nr = nameRecords[i]; nr.platformId = ttUSHORT(data + name_record); nr.platformSpecificId = ttUSHORT(data + name_record + 2); nr.languageId = ttUSHORT(data + name_record + 4); nr.nameId = ttUSHORT(data + name_record + 6); nr.length = ttUSHORT(data + name_record + 8); nr.offset = ttUSHORT(data + name_record + 10) + offset; nameRecords[i] = nr; } info.nameRecords = nameRecords; return(1); }
private ImageResult InternalDecode(ColorComponents?requiredComponents, int bpc) { var pixelCount = 0; var channelCount = 0; var compression = 0; var channel = 0; var i = 0; var bitdepth = 0; var w = 0; var h = 0; byte[] _out_; if (stbi__get32be() != 0x38425053) { stbi__err("not PSD"); } if (stbi__get16be() != 1) { stbi__err("wrong version"); } stbi__skip(6); channelCount = stbi__get16be(); if (channelCount < 0 || channelCount > 16) { stbi__err("wrong channel count"); } h = (int)stbi__get32be(); w = (int)stbi__get32be(); bitdepth = stbi__get16be(); if (bitdepth != 8 && bitdepth != 16) { stbi__err("unsupported bit depth"); } if (stbi__get16be() != 3) { stbi__err("wrong color format"); } stbi__skip((int)stbi__get32be()); stbi__skip((int)stbi__get32be()); stbi__skip((int)stbi__get32be()); compression = stbi__get16be(); if (compression > 1) { stbi__err("bad compression"); } var bits_per_channel = 8; if (compression == 0 && bitdepth == 16 && bpc == 16) { _out_ = new byte[8 * w * h]; bits_per_channel = 16; } else { _out_ = new byte[4 * w * h]; } pixelCount = w * h; var ptr = new FakePtr <byte>(_out_); if (compression != 0) { stbi__skip(h * channelCount * 2); for (channel = 0; channel < 4; channel++) { FakePtr <byte> p; p = ptr + channel; if (channel >= channelCount) { for (i = 0; i < pixelCount; i++, p += 4) { p.Set((byte)(channel == 3 ? 255 : 0)); } } else { if (stbi__psd_decode_rle(p, pixelCount) == 0) { stbi__err("corrupt"); } } } } else { for (channel = 0; channel < 4; channel++) { if (channel >= channelCount) { if (bitdepth == 16 && bpc == 16) { throw new NotImplementedException(); } /* ushort* q = ((ushort*)(ptr)) + channel; * ushort val = (ushort)((channel) == (3) ? 65535 : 0); * for (i = (int)(0); (i) < (pixelCount); i++, q += 4) * { * q = (ushort)(val); * }*/ var p = ptr + channel; var val = (byte)(channel == 3 ? 255 : 0); for (i = 0; i < pixelCount; i++, p += 4) { p.Set(val); } } else { if (bits_per_channel == 16) { throw new NotImplementedException(); } /* ushort* q = ((ushort*)(ptr)) + channel; * for (i = (int)(0); (i) < (pixelCount); i++, q += 4) * { * q = ((ushort)(stbi__get16be())); * }*/ var p = ptr + channel; if (bitdepth == 16) { for (i = 0; i < pixelCount; i++, p += 4) { p.Set((byte)(stbi__get16be() >> 8)); } } else { for (i = 0; i < pixelCount; i++, p += 4) { p.Set(stbi__get8()); } } } } } if (channelCount >= 4) { if (bits_per_channel == 16) { throw new NotImplementedException(); } /* for (i = (int)(0); (i) < (w * h); ++i) * { * ushort* pixel = (ushort*)(ptr) + 4 * i; * if ((pixel[3] != 0) && (pixel[3] != 65535)) * { * float a = (float)(pixel[3] / 65535.0f); * float ra = (float)(1.0f / a); * float inv_a = (float)(65535.0f * (1 - ra)); * pixel[0] = ((ushort)(pixel[0] * ra + inv_a)); * pixel[1] = ((ushort)(pixel[1] * ra + inv_a)); * pixel[2] = ((ushort)(pixel[2] * ra + inv_a)); * } * }*/ for (i = 0; i < w * h; ++i) { var pixel = ptr + 4 * i; if (pixel[3] != 0 && pixel[3] != 255) { var a = pixel[3] / 255.0f; var ra = 1.0f / a; var inv_a = 255.0f * (1 - ra); pixel[0] = (byte)(pixel[0] * ra + inv_a); pixel[1] = (byte)(pixel[1] * ra + inv_a); pixel[2] = (byte)(pixel[2] * ra + inv_a); } } } var req_comp = requiredComponents.ToReqComp(); if (req_comp != 0 && req_comp != 4) { if (bits_per_channel == 16) { _out_ = Conversion.stbi__convert_format16(_out_, 4, req_comp, (uint)w, (uint)h); } else { _out_ = Conversion.stbi__convert_format(_out_, 4, req_comp, (uint)w, (uint)h); } } return(new ImageResult { Width = w, Height = h, SourceComponents = ColorComponents.RedGreenBlueAlpha, ColorComponents = requiredComponents != null ? requiredComponents.Value : ColorComponents.RedGreenBlueAlpha, BitsPerChannel = bits_per_channel, Data = _out_ }); }
private ImageResult InternalDecode(ColorComponents?requiredComponents) { var tga_offset = (int)stbi__get8(); var tga_indexed = (int)stbi__get8(); var tga_image_type = (int)stbi__get8(); var tga_is_RLE = 0; var tga_palette_start = stbi__get16le(); var tga_palette_len = stbi__get16le(); var tga_palette_bits = (int)stbi__get8(); var tga_x_origin = stbi__get16le(); var tga_y_origin = stbi__get16le(); var tga_width = stbi__get16le(); var tga_height = stbi__get16le(); var tga_bits_per_pixel = (int)stbi__get8(); var tga_comp = 0; var tga_rgb16 = 0; var tga_inverted = (int)stbi__get8(); byte[] tga_data; byte[] tga_palette = null; var i = 0; var j = 0; var raw_data = new byte[4]; raw_data[0] = 0; var RLE_count = 0; var RLE_repeating = 0; var read_next_pixel = 1; if (tga_image_type >= 8) { tga_image_type -= 8; tga_is_RLE = 1; } tga_inverted = 1 - ((tga_inverted >> 5) & 1); if (tga_indexed != 0) { tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, out tga_rgb16); } else { tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, tga_image_type == 3 ? 1 : 0, out tga_rgb16); } if (tga_comp == 0) { stbi__err("bad format"); } tga_data = new byte[tga_width * tga_height * tga_comp]; stbi__skip(tga_offset); if (tga_indexed == 0 && tga_is_RLE == 0 && tga_rgb16 == 0) { for (i = 0; i < tga_height; ++i) { var row = tga_inverted != 0 ? tga_height - i - 1 : i; stbi__getn(tga_data, row * tga_width * tga_comp, tga_width * tga_comp); } } else { if (tga_indexed != 0) { stbi__skip(tga_palette_start); tga_palette = new byte[tga_palette_len * tga_comp]; if (tga_rgb16 != 0) { var pal_entry = new FakePtr <byte>(tga_palette); for (i = 0; i < tga_palette_len; ++i) { stbi__tga_read_rgb16(pal_entry); pal_entry += tga_comp; } } else if (!stbi__getn(tga_palette, 0, tga_palette_len * tga_comp)) { stbi__err("bad palette"); } } for (i = 0; i < tga_width * tga_height; ++i) { if (tga_is_RLE != 0) { if (RLE_count == 0) { var RLE_cmd = (int)stbi__get8(); RLE_count = 1 + (RLE_cmd & 127); RLE_repeating = RLE_cmd >> 7; read_next_pixel = 1; } else if (RLE_repeating == 0) { read_next_pixel = 1; } } else { read_next_pixel = 1; } if (read_next_pixel != 0) { if (tga_indexed != 0) { var pal_idx = tga_bits_per_pixel == 8 ? stbi__get8() : stbi__get16le(); if (pal_idx >= tga_palette_len) { pal_idx = 0; } pal_idx *= tga_comp; for (j = 0; j < tga_comp; ++j) { raw_data[j] = tga_palette[pal_idx + j]; } } else if (tga_rgb16 != 0) { stbi__tga_read_rgb16(new FakePtr <byte>(raw_data)); } else { for (j = 0; j < tga_comp; ++j) { raw_data[j] = stbi__get8(); } } read_next_pixel = 0; } for (j = 0; j < tga_comp; ++j) { tga_data[i * tga_comp + j] = raw_data[j]; } --RLE_count; } if (tga_inverted != 0) { for (j = 0; j * 2 < tga_height; ++j) { var index1 = j * tga_width * tga_comp; var index2 = (tga_height - 1 - j) * tga_width * tga_comp; for (i = tga_width * tga_comp; i > 0; --i) { var temp = tga_data[index1]; tga_data[index1] = tga_data[index2]; tga_data[index2] = temp; ++index1; ++index2; } } } } if (tga_comp >= 3 && tga_rgb16 == 0) { var tga_pixel = new FakePtr <byte>(tga_data); for (i = 0; i < tga_width * tga_height; ++i) { var temp = tga_pixel[0]; tga_pixel[0] = tga_pixel[2]; tga_pixel[2] = temp; tga_pixel += tga_comp; } } var req_comp = requiredComponents.ToReqComp(); if (req_comp != 0 && req_comp != tga_comp) { tga_data = Conversion.stbi__convert_format(tga_data, tga_comp, req_comp, (uint)tga_width, (uint)tga_height); } tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0; return(new ImageResult { Width = tga_width, Height = tga_height, SourceComponents = (ColorComponents)tga_comp, ColorComponents = requiredComponents != null ? requiredComponents.Value : (ColorComponents)tga_comp, BitsPerChannel = 8, Data = tga_data }); }