public static void *stbi__gif_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { byte *u = null; var g = new stbi__gif(); u = stbi__gif_load_next(s, g, comp, req_comp, null); if (u != null) { *x = g.w; *y = g.h; if (req_comp != 0 && req_comp != 4) { u = stbi__convert_format(u, 4, req_comp, (uint)g.w, (uint)g.h); } } else if (g._out_ != null) { CRuntime.free(g._out_); } CRuntime.free(g.history); CRuntime.free(g.background); return(u); }
public static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { ri->bits_per_channel = 8; ri->channel_order = STBI_ORDER_RGB; ri->num_channels = 0; if (stbi__jpeg_test(s) != 0) { return(stbi__jpeg_load(s, x, y, comp, req_comp, ri)); } if (stbi__png_test(s) != 0) { return(stbi__png_load(s, x, y, comp, req_comp, ri)); } if (stbi__bmp_test(s) != 0) { return(stbi__bmp_load(s, x, y, comp, req_comp, ri)); } if (stbi__gif_test(s) != 0) { return(stbi__gif_load(s, x, y, comp, req_comp, ri)); } if (stbi__psd_test(s) != 0) { return(stbi__psd_load(s, x, y, comp, req_comp, ri, bpc)); } if (stbi__tga_test(s) != 0) { return(stbi__tga_load(s, x, y, comp, req_comp, ri)); } return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? (byte *)null : null)); }
public static void *stbi__png_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { var p = new stbi__png(); p.s = s; return(stbi__do_png(p, x, y, comp, req_comp, ri)); }
public static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { CRuntime.memset(ri, 0, (ulong)sizeof(stbi__result_info)); ri->bits_per_channel = 8; ri->channel_order = STBI_ORDER_RGB; ri->num_channels = 0; if (stbi__png_test(s) != 0) { return(stbi__png_load(s, x, y, comp, req_comp, ri)); } if (stbi__bmp_test(s) != 0) { return(stbi__bmp_load(s, x, y, comp, req_comp, ri)); } if (stbi__gif_test(s) != 0) { return(stbi__gif_load(s, x, y, comp, req_comp, ri)); } if (stbi__psd_test(s) != 0) { return(stbi__psd_load(s, x, y, comp, req_comp, ri, bpc)); } if (stbi__jpeg_test(s) != 0) { return(stbi__jpeg_load(s, x, y, comp, req_comp, ri)); } if (stbi__hdr_test(s) != 0) { var hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); return(stbi__hdr_to_ldr(hdr, *x, *y, req_comp != 0 ? req_comp : *comp)); } if (stbi__tga_test(s) != 0) { return(stbi__tga_load(s, x, y, comp, req_comp, ri)); } return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? 0 : 0)); }
public static void *stbi__tga_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { var tga_offset = (int)stbi__get8(s); var tga_indexed = (int)stbi__get8(s); var tga_image_type = (int)stbi__get8(s); var tga_is_RLE = 0; var tga_palette_start = stbi__get16le(s); var tga_palette_len = stbi__get16le(s); var tga_palette_bits = (int)stbi__get8(s); var tga_x_origin = stbi__get16le(s); var tga_y_origin = stbi__get16le(s); var tga_width = stbi__get16le(s); var tga_height = stbi__get16le(s); var tga_bits_per_pixel = (int)stbi__get8(s); var tga_comp = 0; var tga_rgb16 = 0; var tga_inverted = (int)stbi__get8(s); byte *tga_data; byte *tga_palette = null; var i = 0; var j = 0; var raw_data = stackalloc 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, &tga_rgb16); } else { tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) ? 1 : 0, &tga_rgb16); } if (tga_comp == 0) { return((byte *)(ulong)((stbi__err("bad format") != 0) ? (byte *)null : null)); } *x = tga_width; *y = tga_height; if (comp != null) { *comp = tga_comp; } if (stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0) == 0) { return((byte *)(ulong)((stbi__err("too large") != 0) ? (byte *)null : null)); } tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (tga_data == null) { return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null)); } stbi__skip(s, 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; var tga_row = tga_data + row * tga_width * tga_comp; stbi__getn(s, tga_row, tga_width * tga_comp); } } else { if (tga_indexed != 0) { stbi__skip(s, tga_palette_start); tga_palette = (byte *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); if (tga_palette == null) { CRuntime.free(tga_data); return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null)); } if (tga_rgb16 != 0) { var pal_entry = tga_palette; for (i = 0; i < tga_palette_len; ++i) { stbi__tga_read_rgb16(s, pal_entry); pal_entry += tga_comp; } } else { if (stbi__getn(s, tga_palette, tga_palette_len * tga_comp) == 0) { CRuntime.free(tga_data); CRuntime.free(tga_palette); return((byte *)(ulong)((stbi__err("bad palette") != 0) ? (byte *)null : null)); } } } for (i = 0; i < tga_width * tga_height; ++i) { if (tga_is_RLE != 0) { if (RLE_count == 0) { var RLE_cmd = (int)stbi__get8(s); 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(s) : stbi__get16le(s); 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(s, raw_data); } else { for (j = 0; j < tga_comp; ++j) { raw_data[j] = stbi__get8(s); } } } 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_palette != null) { CRuntime.free(tga_palette); } } if ((tga_comp >= 3) && (tga_rgb16 == 0)) { var tga_pixel = 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; } } if (req_comp != 0 && req_comp != tga_comp) { tga_data = 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(tga_data); }
public static void *stbi__psd_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, 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(s) != 0x38425053) { return((byte *)(ulong)((stbi__err("not PSD") != 0) ? (byte *)null : null)); } if (stbi__get16be(s) != 1) { return((byte *)(ulong)((stbi__err("wrong version") != 0) ? (byte *)null : null)); } stbi__skip(s, 6); channelCount = stbi__get16be(s); if ((channelCount < 0) || (channelCount > 16)) { return((byte *)(ulong)((stbi__err("wrong channel count") != 0) ? (byte *)null : null)); } h = (int)stbi__get32be(s); w = (int)stbi__get32be(s); bitdepth = stbi__get16be(s); if ((bitdepth != 8) && (bitdepth != 16)) { return((byte *)(ulong)((stbi__err("unsupported bit depth") != 0) ? (byte *)null : null)); } if (stbi__get16be(s) != 3) { return((byte *)(ulong)((stbi__err("wrong color format") != 0) ? (byte *)null : null)); } stbi__skip(s, (int)stbi__get32be(s)); stbi__skip(s, (int)stbi__get32be(s)); stbi__skip(s, (int)stbi__get32be(s)); compression = stbi__get16be(s); if (compression > 1) { return((byte *)(ulong)((stbi__err("bad compression") != 0) ? (byte *)null : null)); } if (stbi__mad3sizes_valid(4, w, h, 0) == 0) { return((byte *)(ulong)((stbi__err("too large") != 0) ? (byte *)null : null)); } if ((compression == 0) && (bitdepth == 16) && (bpc == 16)) { _out_ = (byte *)stbi__malloc_mad3(8, w, h, 0); ri->bits_per_channel = 16; } else { _out_ = (byte *)stbi__malloc((ulong)(4 * w * h)); } if (_out_ == null) { return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null)); } pixelCount = w * h; if (compression != 0) { stbi__skip(s, h * channelCount * 2); for (channel = 0; channel < 4; channel++) { byte *p; p = _out_ + channel; if (channel >= channelCount) { for (i = 0; i < pixelCount; i++, p += 4) { *p = (byte)((channel == 3) ? 255 : 0); } } else { if (stbi__psd_decode_rle(s, p, pixelCount) == 0) { CRuntime.free(_out_); return((byte *)(ulong)((stbi__err("corrupt") != 0) ? (byte *)null : null)); } } } } else { for (channel = 0; channel < 4; channel++) { if (channel >= channelCount) { if ((bitdepth == 16) && (bpc == 16)) { var q = (ushort *)_out_ + channel; var val = (ushort)((channel == 3) ? 65535 : 0); for (i = 0; i < pixelCount; i++, q += 4) { *q = val; } } else { var p = _out_ + channel; var val = (byte)((channel == 3) ? 255 : 0); for (i = 0; i < pixelCount; i++, p += 4) { *p = val; } } } else { if (ri->bits_per_channel == 16) { var q = (ushort *)_out_ + channel; for (i = 0; i < pixelCount; i++, q += 4) { *q = (ushort)stbi__get16be(s); } } else { var p = _out_ + channel; if (bitdepth == 16) { for (i = 0; i < pixelCount; i++, p += 4) { *p = (byte)(stbi__get16be(s) >> 8); } } else { for (i = 0; i < pixelCount; i++, p += 4) { *p = stbi__get8(s); } } } } } } if (channelCount >= 4) { if (ri->bits_per_channel == 16) { for (i = 0; i < w * h; ++i) { var pixel = (ushort *)_out_ + 4 * i; if ((pixel[3] != 0) && (pixel[3] != 65535)) { var a = pixel[3] / 65535.0f; var ra = 1.0f / a; var inv_a = 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); } } } else { for (i = 0; i < w * h; ++i) { var pixel = _out_ + 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); } } } } if ((req_comp != 0) && (req_comp != 4)) { if (ri->bits_per_channel == 16) { _out_ = (byte *)stbi__convert_format16((ushort *)_out_, 4, req_comp, (uint)w, (uint)h); } else { _out_ = stbi__convert_format(_out_, 4, req_comp, (uint)w, (uint)h); } if (_out_ == null) { return(_out_); } } if (comp != null) { *comp = 4; } *y = h; *x = w; return(_out_); }
public static float *stbi__hdr_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { var buffer = stackalloc sbyte[1024]; sbyte *token; var valid = 0; var width = 0; var height = 0; byte * scanline; float *hdr_data; var len = 0; byte count = 0; byte value = 0; var i = 0; var j = 0; var k = 0; var c1 = 0; var c2 = 0; var z = 0; sbyte *headerToken; headerToken = stbi__hdr_gettoken(s, buffer); if (CRuntime.strcmp(headerToken, "#?RADIANCE") != 0 && CRuntime.strcmp(headerToken, "#?RGBE") != 0) { return((float *)(ulong)(stbi__err("not HDR") != 0 ? 0 : 0)); } for (; ;) { token = stbi__hdr_gettoken(s, buffer); if (token[0] == 0) { break; } if (CRuntime.strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) { valid = 1; } } if (valid == 0) { return((float *)(ulong)(stbi__err("unsupported format") != 0 ? 0 : 0)); } token = stbi__hdr_gettoken(s, buffer); if (CRuntime.strncmp(token, "-Y ", 3) != 0) { return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0)); } token += 3; height = (int)CRuntime.strtol(token, &token, 10); while (*token == 32) { ++token; } if (CRuntime.strncmp(token, "+X ", 3) != 0) { return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0)); } token += 3; width = (int)CRuntime.strtol(token, null, 10); if (height > 1 << 24) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (width > 1 << 24) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } *x = width; *y = height; if (comp != null) { *comp = 3; } if (req_comp == 0) { req_comp = 3; } if (stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0) == 0) { return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); if (hdr_data == null) { return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } main_decode_loop: var enterMainDecode = false; if (enterMainDecode) { for (; j < height; ++j) { for (; i < width; ++i) { var rgbe = stackalloc byte[4]; stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } goto finish; } if (width < 8 || width >= 32768) { i = j = 0; enterMainDecode = true; goto main_decode_loop; } scanline = null; for (j = 0; j < height; ++j) { c1 = stbi__get8(s); c2 = stbi__get8(s); len = stbi__get8(s); if (c1 != 2 || c2 != 2 || (len & 0x80) != 0) { var rgbe = stackalloc byte[4]; rgbe[0] = (byte)c1; rgbe[1] = (byte)c2; rgbe[2] = (byte)len; rgbe[3] = stbi__get8(s); stbi__hdr_convert(hdr_data, rgbe, req_comp); i = 1; j = 0; CRuntime.free(scanline); goto main_decode_loop; } len <<= 8; len |= stbi__get8(s); if (len != width) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("invalid decoded scanline length") != 0 ? 0 : 0)); } if (scanline == null) { scanline = (byte *)stbi__malloc_mad2(width, 4, 0); if (scanline == null) { CRuntime.free(hdr_data); return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } } for (k = 0; k < 4; ++k) { var nleft = 0; i = 0; while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { value = stbi__get8(s); count -= 128; if (count > nleft) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0)); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = value; } } else { if (count > nleft) { CRuntime.free(hdr_data); CRuntime.free(scanline); return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0)); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = stbi__get8(s); } } } } for (i = 0; i < width; ++i) { stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); } } if (scanline != null) { CRuntime.free(scanline); } finish: return(hdr_data); }
private static float *stbi__hdr_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { byte * buffer = stackalloc byte[STBI__HDR_BUFLEN]; byte * token; bool valid = false; int width, height; byte * scanline; float *hdr_data; int len; byte count, value; int i, j, k, c1, c2, z; byte * headerToken; // Check identifier headerToken = stbi__hdr_gettoken(s, buffer); if (strcmp(headerToken, "#?RADIANCE") && strcmp(headerToken, "#?RGBE")) { stbi__errpf("Corrupt HDR image"); return(null); } // Parse header for (; ;) { token = stbi__hdr_gettoken(s, buffer); if (token[0] == 0) { break; } if (!strcmp(token, "FORMAT=32-bit_rle_rgbe")) { valid = true; } } if (!valid) { stbi__errpf("Unsupported HDR format"); return(null); } // Parse width and height // can't use sscanf() if we're not using stdio! token = stbi__hdr_gettoken(s, buffer); if (strncmp(token, "-Y ", 3)) { stbi__errpf("Unsupported HDR format"); return(null); } token += 3; height = (int)strtol(token, &token, 10); while (*token == ' ') { ++token; } if (strncmp(token, "+X ", 3)) { stbi__errpf("Unsupported HDR format"); return(null); } token += 3; width = (int)strtol(token, null, 10); *x = width; *y = height; if (comp != null) { *comp = 3; } if (req_comp == 0) { req_comp = 3; } if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) { stbi__errpf("HDR image is too large"); return(null); } // Read data hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); if (hdr_data == null) { stbi__errpf("Out of memory"); return(null); } // Load image data // image data is stored as some number of sca if (width < 8 || width >= 32768) { // Read flat data for (j = 0; j < height; ++j) { for (i = 0; i < width; ++i) { byte *rgbe = stackalloc byte[4]; //main_decode_loop: stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } } else { // Read RLE-encoded data scanline = null; for (j = 0; j < height; ++j) { c1 = stbi__get8(s); c2 = stbi__get8(s); len = stbi__get8(s); if (c1 != (byte)2 || c2 != (byte)2 || ((len & 0x80) != 0)) { // not run-length encoded, so we have to actually use THIS data as a decoded // pixel (note this can't be a valid pixel--one of RGB must be >= 128) byte *rgbe = stackalloc byte[4]; rgbe[0] = (byte)c1; rgbe[1] = (byte)c2; rgbe[2] = (byte)len; rgbe[3] = (byte)stbi__get8(s); stbi__hdr_convert(hdr_data, rgbe, req_comp); i = 1; j = 0; if (scanline != null) { STBI_FREE(scanline); scanline = null; } //goto main_decode_loop; // yes, this makes no sense // this replaced goto statement. stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); ++j; ++i; // Read flat data for (; j < height; ++j) { for (; i < width; ++i) { stbi__getn(s, rgbe, 4); stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } break; // end of goto. } len <<= 8; len |= stbi__get8(s); if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("invalid decoded scanline length | corrupt HDR"); return(null); } if (scanline == null) { scanline = (byte *)stbi__malloc_mad2(width, 4, 0); if (scanline == null) { STBI_FREE(hdr_data); stbi__errpf("Out of memory"); return(null); } } for (k = 0; k < 4; ++k) { int nleft; i = 0; while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { // Run value = stbi__get8(s); count -= (byte)128; if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("corrupt | bad RLE data in HDR"); return(null); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = value; } } else { // Dump if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("corrupt | bad RLE data in HDR"); return(null); } for (z = 0; z < count; ++z) { scanline[i++ *4 + k] = stbi__get8(s); } } } } for (i = 0; i < width; ++i) { stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); } } if (scanline != null) { STBI_FREE(scanline); scanline = null; } } return(hdr_data); }
private static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { // make sure it's initialized if we add new fields ri->num_channels = 0; ri->channel_order = 0; ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order ri->num_channels = 0; //if (stbi__hdr_test(s)) { float *hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); return(stbi__hdr_to_ldr(hdr, *x, *y, req_comp != 0 ? req_comp : *comp)); //} //return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); }
public static void *stbi__bmp_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *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 stbi__bmp_data(); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == null) { return(null); } flip_vertically = (int)s.img_y > 0 ? 1 : 0; s.img_y = (uint)CRuntime.abs((int)s.img_y); 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.img_n = ma != 0 ? 4 : 3; if (req_comp != 0 && req_comp >= 3) { target = req_comp; } else { target = s.img_n; } if (stbi__mad3sizes_valid(target, (int)s.img_x, (int)s.img_y, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null)); } _out_ = (byte *)stbi__malloc_mad3(target, (int)s.img_x, (int)s.img_y, 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.img_x + 7) >> 3); } else if (info.bpp == 4) { width = (int)((s.img_x + 1) >> 1); } else if (info.bpp == 8) { width = (int)s.img_x; } 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.img_y; ++j) { var bit_offset = 7; var v = (int)stbi__get8(s); for (i = 0; i < (int)s.img_x; ++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.img_x) { break; } if (--bit_offset < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j = 0; j < (int)s.img_y; ++j) { for (i = 0; i < (int)s.img_x; 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.img_x) { 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.img_x); } else if (info.bpp == 16) { width = (int)(2 * s.img_x); } 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.img_y; ++j) { if (easy != 0) { for (i = 0; i < (int)s.img_x; ++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.img_x; ++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.img_x * s.img_y - 1); i >= 0; i -= 4) { _out_[i] = 255; } } if (flip_vertically != 0) { byte t = 0; for (j = 0; j < (int)s.img_y >> 1; ++j) { var p1 = _out_ + j * s.img_x * target; var p2 = _out_ + (s.img_y - 1 - j) * s.img_x * target; for (i = 0; i < (int)s.img_x * target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (req_comp != 0 && req_comp != target) { _out_ = stbi__convert_format(_out_, target, req_comp, s.img_x, s.img_y); if (_out_ == null) { return(_out_); } } *x = (int)s.img_x; *y = (int)s.img_y; if (comp != null) { *comp = s.img_n; } return(_out_); }
public static void *stbi__do_png(stbi__png p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { void *result = null; if (req_comp < 0 || req_comp > 4) { return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? (byte *)null : null)); } if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp) != 0) { if (p.depth < 8) { ri->bits_per_channel = 8; } else { ri->bits_per_channel = p.depth; } result = p._out_; p._out_ = null; if (req_comp != 0 && req_comp != p.s.img_out_n) { if (ri->bits_per_channel == 8) { result = stbi__convert_format((byte *)result, p.s.img_out_n, req_comp, p.s.img_x, p.s.img_y); } else { result = stbi__convert_format16((ushort *)result, p.s.img_out_n, req_comp, p.s.img_x, p.s.img_y); } p.s.img_out_n = req_comp; if (result == null) { return(result); } } *x = (int)p.s.img_x; *y = (int)p.s.img_y; if (n != null) { *n = p.s.img_n; } } CRuntime.free(p._out_); p._out_ = null; CRuntime.free(p.expanded); p.expanded = null; CRuntime.free(p.idata); p.idata = null; return(result); }