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));
        }
Ejemplo n.º 2
0
        public static unsafe ImageResultFloat FromStream(Stream stream,
                                                         ColorComponents requiredComponents = ColorComponents.Default)
        {
            float *result = null;

            try
            {
                int x, y, comp;

                var context = new StbImage.stbi__context(stream);

                result = StbImage.stbi__loadf_main(context, &x, &y, &comp, (int)requiredComponents);

                return(FromResult(result, x, y, (ColorComponents)comp, requiredComponents));
            }
            finally
            {
                if (result != null)
                {
                    CRuntime.free(result);
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        public static unsafe ImageResult FromStream(Stream stream,
                                                    ColorComponents requiredComponents = ColorComponents.Default)
        {
            byte *result = null;

            try
            {
                int x, y, comp;

                var context = new stbi__context(stream);

                result = 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);
                }
            }
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        public static int stbi__zexpand(stbi__zbuf *z, sbyte *zout, int n)
        {
            sbyte *q;
            uint   cur       = 0;
            uint   limit     = 0;
            uint   old_limit = 0;

            z->zout = zout;
            if (z->z_expandable == 0)
            {
                return(stbi__err("output buffer limit"));
            }
            cur   = (uint)(z->zout - z->zout_start);
            limit = old_limit = (uint)(z->zout_end - z->zout_start);
            if (0xffffffff - cur < (uint)n)
            {
                return(stbi__err("outofmem"));
            }
            while (cur + n > limit)
            {
                if (limit > 0xffffffff / 2)
                {
                    return(stbi__err("outofmem"));
                }
                limit *= 2;
            }

            q = (sbyte *)CRuntime.realloc(z->zout_start, (ulong)limit);
            if (q == null)
            {
                return(stbi__err("outofmem"));
            }
            z->zout_start = q;
            z->zout       = q + cur;
            z->zout_end   = q + limit;
            return(1);
        }
        public static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
        {
            var row           = 0;
            var bytes_per_row = (ulong)(w * bytes_per_pixel);
            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 void *stbi__malloc(ulong size)
 {
     return(CRuntime.malloc(size));
 }
        public static ushort *stbi__convert_format16(ushort *data, int img_n, int req_comp, uint x, uint y)
        {
            var     i = 0;
            var     j = 0;
            ushort *good;

            if (req_comp == img_n)
            {
                return(data);
            }
            good = (ushort *)stbi__malloc((ulong)(req_comp * 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 * 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] = 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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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 int stbi__hdr_info(stbi__context s, int *x, int *y, int *comp)
        {
            var    buffer = stackalloc sbyte[1024];
            sbyte *token;
            var    valid = 0;
            var    dummy = 0;

            if (x == null)
            {
                x = &dummy;
            }
            if (y == null)
            {
                y = &dummy;
            }
            if (comp == null)
            {
                comp = &dummy;
            }
            if (stbi__hdr_test(s) == 0)
            {
                stbi__rewind(s);
                return(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)
            {
                stbi__rewind(s);
                return(0);
            }

            token = stbi__hdr_gettoken(s, buffer);
            if (CRuntime.strncmp(token, "-Y ", 3) != 0)
            {
                stbi__rewind(s);
                return(0);
            }

            token += 3;
            *y = (int)CRuntime.strtol(token, &token, 10);
            while (*token == 32)
            {
                ++token;
            }

            if (CRuntime.strncmp(token, "+X ", 3) != 0)
            {
                stbi__rewind(s);
                return(0);
            }

            token += 3;
            *x    = (int)CRuntime.strtol(token, null, 10);
            *comp = 3;
            return(1);
        }
        public static int stbi__create_png_image(stbi__png a, byte *image_data, uint image_data_len, int out_n,
                                                 int depth, int color, int interlaced)
        {
            var   bytes     = depth == 16 ? 2 : 1;
            var   out_bytes = out_n * bytes;
            byte *final;
            var   p = 0;

            if (interlaced == 0)
            {
                return(stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a.s.img_x, a.s.img_y, depth,
                                                  color));
            }
            final = (byte *)stbi__malloc_mad3((int)a.s.img_x, (int)a.s.img_y, 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.img_x - xorig[p] + xspc[p] - 1) / xspc[p]);
                y = (int)((a.s.img_y - yorig[p] + yspc[p] - 1) / yspc[p]);
                if (x != 0 && y != 0)
                {
                    var img_len = (uint)((((a.s.img_n * x * depth + 7) >> 3) + 1) * y);
                    if (stbi__create_png_image_raw(a, image_data, image_data_len, out_n, (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.img_x * out_bytes + out_x * out_bytes,
                                            a._out_ + (j * x + i) * out_bytes, (ulong)out_bytes);
                        }
                    }

                    CRuntime.free(a._out_);
                    image_data     += img_len;
                    image_data_len -= img_len;
                }
            }

            a._out_ = final;
            return(1);
        }
        public static int stbi__create_png_image_raw(stbi__png a, byte *raw, uint raw_len, int out_n, 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 * out_n * bytes);
            uint img_len         = 0;
            uint img_width_bytes = 0;
            var  k               = 0;
            var  img_n           = s.img_n;
            var  output_bytes    = out_n * 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 (raw_len < 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 * out_n - img_width_bytes;
                    filter_bytes = 1;
                    width        = (int)img_width_bytes;
                }

                prior = cur - stride;
                if (j == 0)
                {
                    filter = first_row_filter[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 != out_n)
                    {
                        cur[img_n] = 255;
                    }
                    raw   += img_n;
                    cur   += out_n;
                    prior += out_n;
                }
                else if (depth == 16)
                {
                    if (img_n != out_n)
                    {
                        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 == out_n)
                {
                    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 * out_n - img_width_bytes;
                    var scale = (byte)(color == 0 ? stbi__depth_scale_table[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 != out_n)
                    {
                        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 * out_n; ++i, cur16++, cur += 2)
                {
                    *cur16 = (ushort)((cur[0] << 8) | cur[1]);
                }
            }

            return(1);
        }
        public static byte *stbi__hdr_to_ldr(float *data, int x, int y, int comp)
        {
            var   i = 0;
            var   k = 0;
            var   n = 0;
            byte *output;

            if (data == null)
            {
                return(null);
            }
            output = (byte *)stbi__malloc_mad3(x, y, comp, 0);
            if (output == null)
            {
                CRuntime.free(data);
                return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
            }

            if ((comp & 1) != 0)
            {
                n = comp;
            }
            else
            {
                n = comp - 1;
            }
            for (i = 0; i < x * y; ++i)
            {
                for (k = 0; k < n; ++k)
                {
                    var z = (float)CRuntime.pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 +
                            0.5f;
                    if (z < 0)
                    {
                        z = 0;
                    }
                    if (z > 255)
                    {
                        z = 255;
                    }
                    output[i * comp + k] = (byte)(int)z;
                }

                if (k < comp)
                {
                    var z = data[i * comp + k] * 255 + 0.5f;
                    if (z < 0)
                    {
                        z = 0;
                    }
                    if (z > 255)
                    {
                        z = 255;
                    }
                    output[i * comp + k] = (byte)(int)z;
                }
            }

            CRuntime.free(data);
            return(output);
        }
Ejemplo n.º 16
0
        public static void *stbi__load_gif_main(stbi__context s, int **delays, int *x, int *y, int *z, int *comp,
                                                int req_comp)
        {
            if (stbi__gif_test(s) != 0)
            {
                var   layers      = 0;
                byte *u           = null;
                byte *_out_       = null;
                byte *two_back    = null;
                var   g           = new stbi__gif();
                var   stride      = 0;
                var   out_size    = 0;
                var   delays_size = 0;
                if (delays != null)
                {
                    *delays = null;
                }

                do
                {
                    u = stbi__gif_load_next(s, g, comp, req_comp, two_back);
                    if (u != null)
                    {
                        *x = g.w;
                        *y = g.h;
                        ++layers;
                        stride = g.w * g.h * 4;
                        if (_out_ != null)
                        {
                            void *tmp = (byte *)CRuntime.realloc(_out_, (ulong)(layers * stride));
                            if (tmp == null)
                            {
                                return(stbi__load_gif_main_outofmem(g, _out_, delays));
                            }

                            _out_    = (byte *)tmp;
                            out_size = layers * stride;

                            if (delays != null)
                            {
                                var new_delays = (int *)CRuntime.realloc(*delays, (ulong)(sizeof(int) * layers));
                                if (new_delays == null)
                                {
                                    return(stbi__load_gif_main_outofmem(g, _out_, delays));
                                }
                                *delays     = new_delays;
                                delays_size = layers * sizeof(int);
                            }
                        }
                        else
                        {
                            _out_ = (byte *)stbi__malloc((ulong)(layers * stride));
                            if (_out_ == null)
                            {
                                return(stbi__load_gif_main_outofmem(g, _out_, delays));
                            }
                            out_size = layers * stride;
                            if (delays != null)
                            {
                                *delays = (int *)stbi__malloc((ulong)(layers * sizeof(int)));
                                if (*delays == null)
                                {
                                    return(stbi__load_gif_main_outofmem(g, _out_, delays));
                                }
                                delays_size = layers * sizeof(int);
                            }
                        }

                        CRuntime.memcpy(_out_ + (layers - 1) * stride, u, (ulong)stride);
                        if (layers >= 2)
                        {
                            two_back = _out_ - 2 * stride;
                        }

                        if (delays != null)
                        {
                            (*delays)[layers - 1U] = g.delay;
                        }
                    }
                } while (u != null);

                CRuntime.free(g._out_);
                CRuntime.free(g.history);
                CRuntime.free(g.background);
                if (req_comp != 0 && req_comp != 4)
                {
                    _out_ = stbi__convert_format(_out_, 4, req_comp, (uint)(layers * g.w), (uint)g.h);
                }
                *z = layers;
                return(_out_);
            }

            return((byte *)(ulong)(stbi__err("not GIF") != 0 ? 0 : 0));
        }
        public static int stbi__parse_png_file(stbi__png z, int scan, int req_comp)
        {
            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.img_x = stbi__get32be(s);
                    if (s.img_x > 1 << 24)
                    {
                        return(stbi__err("too large"));
                    }
                    s.img_y = stbi__get32be(s);
                    if (s.img_y > 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.img_x == 0 || s.img_y == 0)
                    {
                        return(stbi__err("0-pixel image"));
                    }
                    if (pal_img_n == 0)
                    {
                        s.img_n = ((color & 2) != 0 ? 3 : 1) + ((color & 4) != 0 ? 1 : 0);
                        if ((1 << 30) / s.img_x / s.img_n < s.img_y)
                        {
                            return(stbi__err("too large"));
                        }
                        if (scan == STBI__SCAN_header)
                        {
                            return(1);
                        }
                    }
                    else
                    {
                        s.img_n = 1;
                        if ((1 << 30) / s.img_x / 4 < s.img_y)
                        {
                            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.img_n = 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.img_n & 1) == 0)
                        {
                            return(stbi__err("tRNS with alpha"));
                        }
                        if (c.length != (uint)s.img_n * 2)
                        {
                            return(stbi__err("bad tRNS len"));
                        }
                        has_trans = 1;
                        if (z.depth == 16)
                        {
                            for (k = 0; k < s.img_n; ++k)
                            {
                                tc16[k] = (ushort)stbi__get16be(s);
                            }
                        }
                        else
                        {
                            for (k = 0; k < s.img_n; ++k)
                            {
                                tc[k] = (byte)((byte)(stbi__get16be(s) & 255) * stbi__depth_scale_table[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.img_n = 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.img_x * z.depth + 7) / 8);
                    raw_len    = (uint)(bpl * s.img_y * s.img_n + s.img_y);
                    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 (req_comp == s.img_n + 1 && req_comp != 3 && pal_img_n == 0 || has_trans != 0)
                    {
                        s.img_out_n = s.img_n + 1;
                    }
                    else
                    {
                        s.img_out_n = s.img_n;
                    }
                    if (stbi__create_png_image(z, z.expanded, raw_len, s.img_out_n, z.depth, color, interlace) == 0)
                    {
                        return(0);
                    }
                    if (has_trans != 0)
                    {
                        if (z.depth == 16)
                        {
                            if (stbi__compute_transparency16(z, tc16, s.img_out_n) == 0)
                            {
                                return(0);
                            }
                        }
                        else
                        {
                            if (stbi__compute_transparency(z, tc, s.img_out_n) == 0)
                            {
                                return(0);
                            }
                        }
                    }

                    if (is_iphone != 0 && stbi__de_iphone_flag != 0 && s.img_out_n > 2)
                    {
                        stbi__de_iphone(z);
                    }
                    if (pal_img_n != 0)
                    {
                        s.img_n     = pal_img_n;
                        s.img_out_n = pal_img_n;
                        if (req_comp >= 3)
                        {
                            s.img_out_n = req_comp;
                        }
                        if (stbi__expand_png_palette(z, palette, (int)pal_len, s.img_out_n) == 0)
                        {
                            return(0);
                        }
                    }
                    else if (has_trans != 0)
                    {
                        ++s.img_n;
                    }

                    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);
            }
        }
Ejemplo n.º 18
0
        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__tga_load(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                           stbi__result_info *ri)
        {
            int   tga_offset         = stbi__get8(s);
            int   tga_indexed        = stbi__get8(s);
            int   tga_image_type     = stbi__get8(s);
            var   tga_is_RLE         = 0;
            var   tga_palette_start  = stbi__get16le(s);
            var   tga_palette_len    = stbi__get16le(s);
            int   tga_palette_bits   = 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);
            int   tga_bits_per_pixel = stbi__get8(s);
            var   tga_comp           = 0;
            var   tga_rgb16          = 0;
            int   tga_inverted       = stbi__get8(s);
            byte *tga_data;
            byte *tga_palette     = null;
            var   i               = 0;
            var   j               = 0;
            var   raw_data        = stackalloc byte[] { 0, 0, 0, 0 };
            var   RLE_count       = 0;
            var   RLE_repeating   = 0;
            var   read_next_pixel = 1;

            if (tga_height > 1 << 24)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            if (tga_width > 1 << 24)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            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 ? 0 : 0));
            }
            *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 ? 0 : 0));
            }
            tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
            if (tga_data == null)
            {
                return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
            }
            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)
                {
                    if (tga_palette_len == 0)
                    {
                        CRuntime.free(tga_data);
                        return((byte *)(ulong)(stbi__err("bad palette") != 0 ? 0 : 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 ? 0 : 0));
                    }

                    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 ? 0 : 0));
                    }
                }

                for (i = 0; i < tga_width * tga_height; ++i)
                {
                    if (tga_is_RLE != 0)
                    {
                        if (RLE_count == 0)
                        {
                            int RLE_cmd = 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);
        }
Ejemplo n.º 20
0
        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 ? 0 : 0));
            }
            if (stbi__get16be(s) != 1)
            {
                return((byte *)(ulong)(stbi__err("wrong version") != 0 ? 0 : 0));
            }
            stbi__skip(s, 6);
            channelCount = stbi__get16be(s);
            if (channelCount < 0 || channelCount > 16)
            {
                return((byte *)(ulong)(stbi__err("wrong channel count") != 0 ? 0 : 0));
            }
            h = (int)stbi__get32be(s);
            w = (int)stbi__get32be(s);
            if (h > 1 << 24)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            if (w > 1 << 24)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            bitdepth = stbi__get16be(s);
            if (bitdepth != 8 && bitdepth != 16)
            {
                return((byte *)(ulong)(stbi__err("unsupported bit depth") != 0 ? 0 : 0));
            }
            if (stbi__get16be(s) != 3)
            {
                return((byte *)(ulong)(stbi__err("wrong color format") != 0 ? 0 : 0));
            }
            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 ? 0 : 0));
            }
            if (stbi__mad3sizes_valid(4, w, h, 0) == 0)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            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 ? 0 : 0));
            }
            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 ? 0 : 0));
                        }
                    }
                }
            }
            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_);
        }
Ejemplo n.º 21
0
        public static byte *stbi__gif_load_next(stbi__context s, stbi__gif g, int *comp, int req_comp, byte *two_back)
        {
            var dispose     = 0;
            var first_frame = 0;
            var pi          = 0;
            var pcount      = 0;

            first_frame = 0;
            if (g._out_ == null)
            {
                if (stbi__gif_header(s, g, comp, 0) == 0)
                {
                    return(null);
                }
                if (stbi__mad3sizes_valid(4, g.w, g.h, 0) == 0)
                {
                    return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
                }
                pcount       = g.w * g.h;
                g._out_      = (byte *)stbi__malloc((ulong)(4 * pcount));
                g.background = (byte *)stbi__malloc((ulong)(4 * pcount));
                g.history    = (byte *)stbi__malloc((ulong)pcount);
                if (g._out_ == null || g.background == null || g.history == null)
                {
                    return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
                }
                CRuntime.memset(g._out_, 0x00, (ulong)(4 * pcount));
                CRuntime.memset(g.background, 0x00, (ulong)(4 * pcount));
                CRuntime.memset(g.history, 0x00, (ulong)pcount);
                first_frame = 1;
            }
            else
            {
                dispose = (g.eflags & 0x1C) >> 2;
                pcount  = g.w * g.h;
                if (dispose == 3 && two_back == null)
                {
                    dispose = 2;
                }

                if (dispose == 3)
                {
                    for (pi = 0; pi < pcount; ++pi)
                    {
                        if (g.history[pi] != 0)
                        {
                            CRuntime.memcpy(&g._out_[pi * 4], &two_back[pi * 4], (ulong)4);
                        }
                    }
                }
                else if (dispose == 2)
                {
                    for (pi = 0; pi < pcount; ++pi)
                    {
                        if (g.history[pi] != 0)
                        {
                            CRuntime.memcpy(&g._out_[pi * 4], &g.background[pi * 4], (ulong)4);
                        }
                    }
                }

                CRuntime.memcpy(g.background, g._out_, (ulong)(4 * g.w * g.h));
            }

            CRuntime.memset(g.history, 0x00, (ulong)(g.w * g.h));
            for (; ;)
            {
                int tag = stbi__get8(s);
                switch (tag)
                {
                case 0x2C:
                {
                    var   x = 0;
                    var   y = 0;
                    var   w = 0;
                    var   h = 0;
                    byte *o;
                    x = stbi__get16le(s);
                    y = stbi__get16le(s);
                    w = stbi__get16le(s);
                    h = stbi__get16le(s);
                    if (x + w > g.w || y + h > g.h)
                    {
                        return((byte *)(ulong)(stbi__err("bad Image Descriptor") != 0 ? 0 : 0));
                    }
                    g.line_size = g.w * 4;
                    g.start_x   = x * 4;
                    g.start_y   = y * g.line_size;
                    g.max_x     = g.start_x + w * 4;
                    g.max_y     = g.start_y + h * g.line_size;
                    g.cur_x     = g.start_x;
                    g.cur_y     = g.start_y;
                    if (w == 0)
                    {
                        g.cur_y = g.max_y;
                    }
                    g.lflags = stbi__get8(s);
                    if ((g.lflags & 0x40) != 0)
                    {
                        g.step  = 8 * g.line_size;
                        g.parse = 3;
                    }
                    else
                    {
                        g.step  = g.line_size;
                        g.parse = 0;
                    }

                    if ((g.lflags & 0x80) != 0)
                    {
                        stbi__gif_parse_colortable(s, g.lpal, 2 << (g.lflags & 7),
                                                   (g.eflags & 0x01) != 0 ? g.transparent : -1);
                        g.color_table = (byte *)g.lpal;
                    }
                    else if ((g.flags & 0x80) != 0)
                    {
                        g.color_table = (byte *)g.pal;
                    }
                    else
                    {
                        return((byte *)(ulong)(stbi__err("missing color table") != 0 ? 0 : 0));
                    }

                    o = stbi__process_gif_raster(s, g);
                    if (o == null)
                    {
                        return(null);
                    }
                    pcount = g.w * g.h;
                    if (first_frame != 0 && g.bgindex > 0)
                    {
                        for (pi = 0; pi < pcount; ++pi)
                        {
                            if (g.history[pi] == 0)
                            {
                                g.pal[g.bgindex][3] = 255;
                                CRuntime.memcpy(&g._out_[pi * 4], &g.pal[g.bgindex], (ulong)4);
                            }
                        }
                    }

                    return(o);
                }

                case 0x21:
                {
                    var len = 0;
                    int ext = stbi__get8(s);
                    if (ext == 0xF9)
                    {
                        len = stbi__get8(s);
                        if (len == 4)
                        {
                            g.eflags = stbi__get8(s);
                            g.delay  = 10 * stbi__get16le(s);
                            if (g.transparent >= 0)
                            {
                                g.pal[g.transparent][3] = 255;
                            }

                            if ((g.eflags & 0x01) != 0)
                            {
                                g.transparent = stbi__get8(s);
                                if (g.transparent >= 0)
                                {
                                    g.pal[g.transparent][3] = 0;
                                }
                            }
                            else
                            {
                                stbi__skip(s, 1);
                                g.transparent = -1;
                            }
                        }
                        else
                        {
                            stbi__skip(s, len);
                            break;
                        }
                    }

                    while ((len = stbi__get8(s)) != 0)
                    {
                        stbi__skip(s, len);
                    }

                    break;
                }

                case 0x3B:
                    return(null);

                default:
                    return((byte *)(ulong)(stbi__err("unknown code") != 0 ? 0 : 0));
                }
            }
        }
        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);
        }
Ejemplo n.º 23
0
 private static void *stbi__malloc(int size)
 {
     return(CRuntime.malloc((ulong)size));
 }
        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 ? 0 : 0));
            }

            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:
                    ;
                    CRuntime.free(data);
                    CRuntime.free(good);
                    return((byte *)(ulong)(stbi__err("unsupported") != 0 ? 0 : 0));
                }
            }

            CRuntime.free(data);
            return(good);
        }