예제 #1
0
        public static void *stbi__gif_load(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                           stbi__result_info *ri)
        {
            byte *u = null;
            var   g = new stbi__gif();

            u = stbi__gif_load_next(s, g, comp, req_comp, null);

            if (u != null)
            {
                *x = g.w;
                *y = g.h;
                if (req_comp != 0 && req_comp != 4)
                {
                    u = stbi__convert_format(u, 4, req_comp, (uint)g.w, (uint)g.h);
                }
            }
            else if (g._out_ != null)
            {
                CRuntime.free(g._out_);
            }

            CRuntime.free(g.history);
            CRuntime.free(g.background);
            return(u);
        }
 public static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                     stbi__result_info *ri, int bpc)
 {
     ri->bits_per_channel = 8;
     ri->channel_order    = STBI_ORDER_RGB;
     ri->num_channels     = 0;
     if (stbi__jpeg_test(s) != 0)
     {
         return(stbi__jpeg_load(s, x, y, comp, req_comp, ri));
     }
     if (stbi__png_test(s) != 0)
     {
         return(stbi__png_load(s, x, y, comp, req_comp, ri));
     }
     if (stbi__bmp_test(s) != 0)
     {
         return(stbi__bmp_load(s, x, y, comp, req_comp, ri));
     }
     if (stbi__gif_test(s) != 0)
     {
         return(stbi__gif_load(s, x, y, comp, req_comp, ri));
     }
     if (stbi__psd_test(s) != 0)
     {
         return(stbi__psd_load(s, x, y, comp, req_comp, ri, bpc));
     }
     if (stbi__tga_test(s) != 0)
     {
         return(stbi__tga_load(s, x, y, comp, req_comp, ri));
     }
     return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? (byte *)null : null));
 }
예제 #3
0
        public static void *stbi__png_load(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                           stbi__result_info *ri)
        {
            var p = new stbi__png();

            p.s = s;
            return(stbi__do_png(p, x, y, comp, req_comp, ri));
        }
        public static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                            stbi__result_info *ri, int bpc)
        {
            CRuntime.memset(ri, 0, (ulong)sizeof(stbi__result_info));
            ri->bits_per_channel = 8;
            ri->channel_order    = STBI_ORDER_RGB;
            ri->num_channels     = 0;
            if (stbi__png_test(s) != 0)
            {
                return(stbi__png_load(s, x, y, comp, req_comp, ri));
            }
            if (stbi__bmp_test(s) != 0)
            {
                return(stbi__bmp_load(s, x, y, comp, req_comp, ri));
            }
            if (stbi__gif_test(s) != 0)
            {
                return(stbi__gif_load(s, x, y, comp, req_comp, ri));
            }
            if (stbi__psd_test(s) != 0)
            {
                return(stbi__psd_load(s, x, y, comp, req_comp, ri, bpc));
            }
            if (stbi__jpeg_test(s) != 0)
            {
                return(stbi__jpeg_load(s, x, y, comp, req_comp, ri));
            }
            if (stbi__hdr_test(s) != 0)
            {
                var hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri);
                return(stbi__hdr_to_ldr(hdr, *x, *y, req_comp != 0 ? req_comp : *comp));
            }

            if (stbi__tga_test(s) != 0)
            {
                return(stbi__tga_load(s, x, y, comp, req_comp, ri));
            }
            return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? 0 : 0));
        }
                    public static void *stbi__tga_load(stbi__context s, int *x, int *y, int *comp,
                                                       int req_comp, stbi__result_info *ri)
                    {
                        var   tga_offset         = (int)stbi__get8(s);
                        var   tga_indexed        = (int)stbi__get8(s);
                        var   tga_image_type     = (int)stbi__get8(s);
                        var   tga_is_RLE         = 0;
                        var   tga_palette_start  = stbi__get16le(s);
                        var   tga_palette_len    = stbi__get16le(s);
                        var   tga_palette_bits   = (int)stbi__get8(s);
                        var   tga_x_origin       = stbi__get16le(s);
                        var   tga_y_origin       = stbi__get16le(s);
                        var   tga_width          = stbi__get16le(s);
                        var   tga_height         = stbi__get16le(s);
                        var   tga_bits_per_pixel = (int)stbi__get8(s);
                        var   tga_comp           = 0;
                        var   tga_rgb16          = 0;
                        var   tga_inverted       = (int)stbi__get8(s);
                        byte *tga_data;
                        byte *tga_palette = null;
                        var   i           = 0;
                        var   j           = 0;
                        var   raw_data    = stackalloc byte[4];

                        raw_data[0] = 0;
                        var RLE_count       = 0;
                        var RLE_repeating   = 0;
                        var read_next_pixel = 1;

                        if (tga_image_type >= 8)
                        {
                            tga_image_type -= 8;
                            tga_is_RLE      = 1;
                        }
                        tga_inverted = 1 - ((tga_inverted >> 5) & 1);
                        if (tga_indexed != 0)
                        {
                            tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
                        }
                        else
                        {
                            tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) ? 1 : 0, &tga_rgb16);
                        }
                        if (tga_comp == 0)
                        {
                            return((byte *)(ulong)((stbi__err("bad format") != 0) ? (byte *)null : null));
                        }
                        *x = tga_width;
                        *y = tga_height;
                        if (comp != null)
                        {
                            *comp = tga_comp;
                        }
                        if (stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0) == 0)
                        {
                            return((byte *)(ulong)((stbi__err("too large") != 0) ? (byte *)null : null));
                        }
                        tga_data = (byte *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
                        if (tga_data == null)
                        {
                            return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null));
                        }
                        stbi__skip(s, tga_offset);
                        if ((tga_indexed == 0) && (tga_is_RLE == 0) && (tga_rgb16 == 0))
                        {
                            for (i = 0; i < tga_height; ++i)
                            {
                                var row     = tga_inverted != 0 ? tga_height - i - 1 : i;
                                var tga_row = tga_data + row * tga_width * tga_comp;
                                stbi__getn(s, tga_row, tga_width * tga_comp);
                            }
                        }
                        else
                        {
                            if (tga_indexed != 0)
                            {
                                stbi__skip(s, tga_palette_start);
                                tga_palette = (byte *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
                                if (tga_palette == null)
                                {
                                    CRuntime.free(tga_data);
                                    return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null));
                                }
                                if (tga_rgb16 != 0)
                                {
                                    var pal_entry = tga_palette;
                                    for (i = 0; i < tga_palette_len; ++i)
                                    {
                                        stbi__tga_read_rgb16(s, pal_entry);
                                        pal_entry += tga_comp;
                                    }
                                }
                                else
                                {
                                    if (stbi__getn(s, tga_palette, tga_palette_len * tga_comp) == 0)
                                    {
                                        CRuntime.free(tga_data);
                                        CRuntime.free(tga_palette);
                                        return((byte *)(ulong)((stbi__err("bad palette") != 0) ? (byte *)null : null));
                                    }
                                }
                            }
                            for (i = 0; i < tga_width * tga_height; ++i)
                            {
                                if (tga_is_RLE != 0)
                                {
                                    if (RLE_count == 0)
                                    {
                                        var RLE_cmd = (int)stbi__get8(s);
                                        RLE_count       = 1 + (RLE_cmd & 127);
                                        RLE_repeating   = RLE_cmd >> 7;
                                        read_next_pixel = 1;
                                    }
                                    else
                                    {
                                        if (RLE_repeating == 0)
                                        {
                                            read_next_pixel = 1;
                                        }
                                    }
                                }
                                else
                                {
                                    read_next_pixel = 1;
                                }
                                if (read_next_pixel != 0)
                                {
                                    if (tga_indexed != 0)
                                    {
                                        var pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
                                        if (pal_idx >= tga_palette_len)
                                        {
                                            pal_idx = 0;
                                        }
                                        pal_idx *= tga_comp;
                                        for (j = 0; j < tga_comp; ++j)
                                        {
                                            raw_data[j] = tga_palette[pal_idx + j];
                                        }
                                    }
                                    else
                                    {
                                        if (tga_rgb16 != 0)
                                        {
                                            stbi__tga_read_rgb16(s, raw_data);
                                        }
                                        else
                                        {
                                            for (j = 0; j < tga_comp; ++j)
                                            {
                                                raw_data[j] = stbi__get8(s);
                                            }
                                        }
                                    }
                                    read_next_pixel = 0;
                                }
                                for (j = 0; j < tga_comp; ++j)
                                {
                                    tga_data[i * tga_comp + j] = raw_data[j];
                                }
                                --RLE_count;
                            }
                            if (tga_inverted != 0)
                            {
                                for (j = 0; j * 2 < tga_height; ++j)
                                {
                                    var index1 = j * tga_width * tga_comp;
                                    var index2 = (tga_height - 1 - j) * tga_width * tga_comp;
                                    for (i = tga_width * tga_comp; i > 0; --i)
                                    {
                                        var temp = tga_data[index1];
                                        tga_data[index1] = tga_data[index2];
                                        tga_data[index2] = temp;
                                        ++index1;
                                        ++index2;
                                    }
                                }
                            }
                            if (tga_palette != null)
                            {
                                CRuntime.free(tga_palette);
                            }
                        }
                        if ((tga_comp >= 3) && (tga_rgb16 == 0))
                        {
                            var tga_pixel = tga_data;
                            for (i = 0; i < tga_width * tga_height; ++i)
                            {
                                var temp = tga_pixel[0];
                                tga_pixel[0] = tga_pixel[2];
                                tga_pixel[2] = temp;
                                tga_pixel   += tga_comp;
                            }
                        }
                        if (req_comp != 0 && req_comp != tga_comp)
                        {
                            tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, (uint)tga_width, (uint)tga_height);
                        }
                        tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0;
                        return(tga_data);
                    }
예제 #6
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) ? (byte *)null : null));
                        }
                        if (stbi__get16be(s) != 1)
                        {
                            return((byte *)(ulong)((stbi__err("wrong version") != 0) ? (byte *)null : null));
                        }
                        stbi__skip(s, 6);
                        channelCount = stbi__get16be(s);
                        if ((channelCount < 0) || (channelCount > 16))
                        {
                            return((byte *)(ulong)((stbi__err("wrong channel count") != 0) ? (byte *)null : null));
                        }
                        h        = (int)stbi__get32be(s);
                        w        = (int)stbi__get32be(s);
                        bitdepth = stbi__get16be(s);
                        if ((bitdepth != 8) && (bitdepth != 16))
                        {
                            return((byte *)(ulong)((stbi__err("unsupported bit depth") != 0) ? (byte *)null : null));
                        }
                        if (stbi__get16be(s) != 3)
                        {
                            return((byte *)(ulong)((stbi__err("wrong color format") != 0) ? (byte *)null : null));
                        }
                        stbi__skip(s, (int)stbi__get32be(s));
                        stbi__skip(s, (int)stbi__get32be(s));
                        stbi__skip(s, (int)stbi__get32be(s));
                        compression = stbi__get16be(s);
                        if (compression > 1)
                        {
                            return((byte *)(ulong)((stbi__err("bad compression") != 0) ? (byte *)null : null));
                        }
                        if (stbi__mad3sizes_valid(4, w, h, 0) == 0)
                        {
                            return((byte *)(ulong)((stbi__err("too large") != 0) ? (byte *)null : null));
                        }
                        if ((compression == 0) && (bitdepth == 16) && (bpc == 16))
                        {
                            _out_ = (byte *)stbi__malloc_mad3(8, w, h, 0);
                            ri->bits_per_channel = 16;
                        }
                        else
                        {
                            _out_ = (byte *)stbi__malloc((ulong)(4 * w * h));
                        }
                        if (_out_ == null)
                        {
                            return((byte *)(ulong)((stbi__err("outofmem") != 0) ? (byte *)null : null));
                        }
                        pixelCount = w * h;
                        if (compression != 0)
                        {
                            stbi__skip(s, h * channelCount * 2);
                            for (channel = 0; channel < 4; channel++)
                            {
                                byte *p;
                                p = _out_ + channel;
                                if (channel >= channelCount)
                                {
                                    for (i = 0; i < pixelCount; i++, p += 4)
                                    {
                                        *p = (byte)((channel == 3) ? 255 : 0);
                                    }
                                }
                                else
                                {
                                    if (stbi__psd_decode_rle(s, p, pixelCount) == 0)
                                    {
                                        CRuntime.free(_out_);
                                        return((byte *)(ulong)((stbi__err("corrupt") != 0) ? (byte *)null : null));
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (channel = 0; channel < 4; channel++)
                            {
                                if (channel >= channelCount)
                                {
                                    if ((bitdepth == 16) && (bpc == 16))
                                    {
                                        var q   = (ushort *)_out_ + channel;
                                        var val = (ushort)((channel == 3) ? 65535 : 0);
                                        for (i = 0; i < pixelCount; i++, q += 4)
                                        {
                                            *q = val;
                                        }
                                    }
                                    else
                                    {
                                        var p   = _out_ + channel;
                                        var val = (byte)((channel == 3) ? 255 : 0);
                                        for (i = 0; i < pixelCount; i++, p += 4)
                                        {
                                            *p = val;
                                        }
                                    }
                                }
                                else
                                {
                                    if (ri->bits_per_channel == 16)
                                    {
                                        var q = (ushort *)_out_ + channel;
                                        for (i = 0; i < pixelCount; i++, q += 4)
                                        {
                                            *q = (ushort)stbi__get16be(s);
                                        }
                                    }
                                    else
                                    {
                                        var p = _out_ + channel;
                                        if (bitdepth == 16)
                                        {
                                            for (i = 0; i < pixelCount; i++, p += 4)
                                            {
                                                *p = (byte)(stbi__get16be(s) >> 8);
                                            }
                                        }
                                        else
                                        {
                                            for (i = 0; i < pixelCount; i++, p += 4)
                                            {
                                                *p = stbi__get8(s);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (channelCount >= 4)
                        {
                            if (ri->bits_per_channel == 16)
                            {
                                for (i = 0; i < w * h; ++i)
                                {
                                    var pixel = (ushort *)_out_ + 4 * i;
                                    if ((pixel[3] != 0) && (pixel[3] != 65535))
                                    {
                                        var a     = pixel[3] / 65535.0f;
                                        var ra    = 1.0f / a;
                                        var inv_a = 65535.0f * (1 - ra);
                                        pixel[0] = (ushort)(pixel[0] * ra + inv_a);
                                        pixel[1] = (ushort)(pixel[1] * ra + inv_a);
                                        pixel[2] = (ushort)(pixel[2] * ra + inv_a);
                                    }
                                }
                            }
                            else
                            {
                                for (i = 0; i < w * h; ++i)
                                {
                                    var pixel = _out_ + 4 * i;
                                    if ((pixel[3] != 0) && (pixel[3] != 255))
                                    {
                                        var a     = pixel[3] / 255.0f;
                                        var ra    = 1.0f / a;
                                        var inv_a = 255.0f * (1 - ra);
                                        pixel[0] = (byte)(pixel[0] * ra + inv_a);
                                        pixel[1] = (byte)(pixel[1] * ra + inv_a);
                                        pixel[2] = (byte)(pixel[2] * ra + inv_a);
                                    }
                                }
                            }
                        }
                        if ((req_comp != 0) && (req_comp != 4))
                        {
                            if (ri->bits_per_channel == 16)
                            {
                                _out_ = (byte *)stbi__convert_format16((ushort *)_out_, 4, req_comp, (uint)w, (uint)h);
                            }
                            else
                            {
                                _out_ = stbi__convert_format(_out_, 4, req_comp, (uint)w, (uint)h);
                            }
                            if (_out_ == null)
                            {
                                return(_out_);
                            }
                        }
                        if (comp != null)
                        {
                            *comp = 4;
                        }
                        *y = h;
                        *x = w;
                        return(_out_);
                    }
        public static float *stbi__hdr_load(stbi__context s, int *x, int *y, int *comp, int req_comp,
                                            stbi__result_info *ri)
        {
            var    buffer = stackalloc sbyte[1024];
            sbyte *token;
            var    valid  = 0;
            var    width  = 0;
            var    height = 0;
            byte * scanline;
            float *hdr_data;
            var    len   = 0;
            byte   count = 0;
            byte   value = 0;
            var    i     = 0;
            var    j     = 0;
            var    k     = 0;
            var    c1    = 0;
            var    c2    = 0;
            var    z     = 0;
            sbyte *headerToken;

            headerToken = stbi__hdr_gettoken(s, buffer);
            if (CRuntime.strcmp(headerToken, "#?RADIANCE") != 0 && CRuntime.strcmp(headerToken, "#?RGBE") != 0)
            {
                return((float *)(ulong)(stbi__err("not HDR") != 0 ? 0 : 0));
            }
            for (; ;)
            {
                token = stbi__hdr_gettoken(s, buffer);
                if (token[0] == 0)
                {
                    break;
                }
                if (CRuntime.strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0)
                {
                    valid = 1;
                }
            }

            if (valid == 0)
            {
                return((float *)(ulong)(stbi__err("unsupported format") != 0 ? 0 : 0));
            }
            token = stbi__hdr_gettoken(s, buffer);
            if (CRuntime.strncmp(token, "-Y ", 3) != 0)
            {
                return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0));
            }
            token += 3;
            height = (int)CRuntime.strtol(token, &token, 10);
            while (*token == 32)
            {
                ++token;
            }

            if (CRuntime.strncmp(token, "+X ", 3) != 0)
            {
                return((float *)(ulong)(stbi__err("unsupported data layout") != 0 ? 0 : 0));
            }
            token += 3;
            width  = (int)CRuntime.strtol(token, null, 10);
            if (height > 1 << 24)
            {
                return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            if (width > 1 << 24)
            {
                return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            *x = width;
            *y = height;
            if (comp != null)
            {
                *comp = 3;
            }
            if (req_comp == 0)
            {
                req_comp = 3;
            }
            if (stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0) == 0)
            {
                return((float *)(ulong)(stbi__err("too large") != 0 ? 0 : 0));
            }
            hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
            if (hdr_data == null)
            {
                return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
            }

main_decode_loop:
            var enterMainDecode = false;

            if (enterMainDecode)
            {
                for (; j < height; ++j)
                {
                    for (; i < width; ++i)
                    {
                        var rgbe = stackalloc byte[4];
                        stbi__getn(s, rgbe, 4);
                        stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
                    }
                }

                goto finish;
            }

            if (width < 8 || width >= 32768)
            {
                i = j = 0;

                enterMainDecode = true;
                goto main_decode_loop;
            }

            scanline = null;
            for (j = 0; j < height; ++j)
            {
                c1  = stbi__get8(s);
                c2  = stbi__get8(s);
                len = stbi__get8(s);
                if (c1 != 2 || c2 != 2 || (len & 0x80) != 0)
                {
                    var rgbe = stackalloc byte[4];
                    rgbe[0] = (byte)c1;
                    rgbe[1] = (byte)c2;
                    rgbe[2] = (byte)len;
                    rgbe[3] = stbi__get8(s);
                    stbi__hdr_convert(hdr_data, rgbe, req_comp);
                    i = 1;
                    j = 0;
                    CRuntime.free(scanline);
                    goto main_decode_loop;
                }

                len <<= 8;
                len  |= stbi__get8(s);
                if (len != width)
                {
                    CRuntime.free(hdr_data);
                    CRuntime.free(scanline);
                    return((float *)(ulong)(stbi__err("invalid decoded scanline length") != 0 ? 0 : 0));
                }

                if (scanline == null)
                {
                    scanline = (byte *)stbi__malloc_mad2(width, 4, 0);
                    if (scanline == null)
                    {
                        CRuntime.free(hdr_data);
                        return((float *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
                    }
                }

                for (k = 0; k < 4; ++k)
                {
                    var nleft = 0;
                    i = 0;
                    while ((nleft = width - i) > 0)
                    {
                        count = stbi__get8(s);
                        if (count > 128)
                        {
                            value  = stbi__get8(s);
                            count -= 128;
                            if (count > nleft)
                            {
                                CRuntime.free(hdr_data);
                                CRuntime.free(scanline);
                                return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0));
                            }

                            for (z = 0; z < count; ++z)
                            {
                                scanline[i++ *4 + k] = value;
                            }
                        }
                        else
                        {
                            if (count > nleft)
                            {
                                CRuntime.free(hdr_data);
                                CRuntime.free(scanline);
                                return((float *)(ulong)(stbi__err("corrupt") != 0 ? 0 : 0));
                            }

                            for (z = 0; z < count; ++z)
                            {
                                scanline[i++ *4 + k] = stbi__get8(s);
                            }
                        }
                    }
                }

                for (i = 0; i < width; ++i)
                {
                    stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp);
                }
            }

            if (scanline != null)
            {
                CRuntime.free(scanline);
            }

finish:
            return(hdr_data);
        }
예제 #8
0
        private static float *stbi__hdr_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
        {
            byte * buffer = stackalloc byte[STBI__HDR_BUFLEN];
            byte * token;
            bool   valid = false;
            int    width, height;
            byte * scanline;
            float *hdr_data;
            int    len;
            byte   count, value;
            int    i, j, k, c1, c2, z;
            byte * headerToken;

            // Check identifier
            headerToken = stbi__hdr_gettoken(s, buffer);
            if (strcmp(headerToken, "#?RADIANCE") && strcmp(headerToken, "#?RGBE"))
            {
                stbi__errpf("Corrupt HDR image"); return(null);
            }

            // Parse header
            for (; ;)
            {
                token = stbi__hdr_gettoken(s, buffer);
                if (token[0] == 0)
                {
                    break;
                }
                if (!strcmp(token, "FORMAT=32-bit_rle_rgbe"))
                {
                    valid = true;
                }
            }

            if (!valid)
            {
                stbi__errpf("Unsupported HDR format"); return(null);
            }

            // Parse width and height
            // can't use sscanf() if we're not using stdio!
            token = stbi__hdr_gettoken(s, buffer);
            if (strncmp(token, "-Y ", 3))
            {
                stbi__errpf("Unsupported HDR format"); return(null);
            }
            token += 3;
            height = (int)strtol(token, &token, 10);
            while (*token == ' ')
            {
                ++token;
            }
            if (strncmp(token, "+X ", 3))
            {
                stbi__errpf("Unsupported HDR format"); return(null);
            }
            token += 3;
            width  = (int)strtol(token, null, 10);

            *x = width;
            *y = height;

            if (comp != null)
            {
                *comp = 3;
            }
            if (req_comp == 0)
            {
                req_comp = 3;
            }

            if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
            {
                stbi__errpf("HDR image is too large"); return(null);
            }
            // Read data
            hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
            if (hdr_data == null)
            {
                stbi__errpf("Out of memory"); return(null);
            }

            // Load image data
            // image data is stored as some number of sca
            if (width < 8 || width >= 32768)
            {
                // Read flat data
                for (j = 0; j < height; ++j)
                {
                    for (i = 0; i < width; ++i)
                    {
                        byte *rgbe = stackalloc byte[4];
                        //main_decode_loop:
                        stbi__getn(s, rgbe, 4);
                        stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
                    }
                }
            }
            else
            {
                // Read RLE-encoded data
                scanline = null;

                for (j = 0; j < height; ++j)
                {
                    c1  = stbi__get8(s);
                    c2  = stbi__get8(s);
                    len = stbi__get8(s);
                    if (c1 != (byte)2 || c2 != (byte)2 || ((len & 0x80) != 0))
                    {
                        // not run-length encoded, so we have to actually use THIS data as a decoded
                        // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
                        byte *rgbe = stackalloc byte[4];
                        rgbe[0] = (byte)c1;
                        rgbe[1] = (byte)c2;
                        rgbe[2] = (byte)len;
                        rgbe[3] = (byte)stbi__get8(s);
                        stbi__hdr_convert(hdr_data, rgbe, req_comp);
                        i = 1;
                        j = 0;
                        if (scanline != null)
                        {
                            STBI_FREE(scanline); scanline = null;
                        }
                        //goto main_decode_loop; // yes, this makes no sense
                        // this replaced goto statement.
                        stbi__getn(s, rgbe, 4);
                        stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
                        ++j; ++i;
                        // Read flat data
                        for (; j < height; ++j)
                        {
                            for (; i < width; ++i)
                            {
                                stbi__getn(s, rgbe, 4);
                                stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
                            }
                        }
                        break;
                        // end of goto.
                    }
                    len <<= 8;
                    len  |= stbi__get8(s);
                    if (len != width)
                    {
                        STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("invalid decoded scanline length | corrupt HDR"); return(null);
                    }
                    if (scanline == null)
                    {
                        scanline = (byte *)stbi__malloc_mad2(width, 4, 0);
                        if (scanline == null)
                        {
                            STBI_FREE(hdr_data);
                            stbi__errpf("Out of memory");
                            return(null);
                        }
                    }

                    for (k = 0; k < 4; ++k)
                    {
                        int nleft;
                        i = 0;
                        while ((nleft = width - i) > 0)
                        {
                            count = stbi__get8(s);
                            if (count > 128)
                            {
                                // Run
                                value  = stbi__get8(s);
                                count -= (byte)128;
                                if (count > nleft)
                                {
                                    STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("corrupt | bad RLE data in HDR"); return(null);
                                }
                                for (z = 0; z < count; ++z)
                                {
                                    scanline[i++ *4 + k] = value;
                                }
                            }
                            else
                            {
                                // Dump
                                if (count > nleft)
                                {
                                    STBI_FREE(hdr_data); STBI_FREE(scanline); stbi__errpf("corrupt | bad RLE data in HDR"); return(null);
                                }
                                for (z = 0; z < count; ++z)
                                {
                                    scanline[i++ *4 + k] = stbi__get8(s);
                                }
                            }
                        }
                    }
                    for (i = 0; i < width; ++i)
                    {
                        stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp);
                    }
                }
                if (scanline != null)
                {
                    STBI_FREE(scanline); scanline = null;
                }
            }

            return(hdr_data);
        }
예제 #9
0
        private static void *stbi__load_main(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
        {
            // make sure it's initialized if we add new fields
            ri->num_channels     = 0; ri->channel_order = 0;
            ri->bits_per_channel = 8;              // default is 8 so most paths don't have to be changed
            ri->channel_order    = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
            ri->num_channels     = 0;

            //if (stbi__hdr_test(s)) {
            float *hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri);

            return(stbi__hdr_to_ldr(hdr, *x, *y, req_comp != 0 ? req_comp : *comp));
            //}

            //return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
        }
예제 #10
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_);
        }
예제 #11
0
        public static void *stbi__do_png(stbi__png p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
        {
            void *result = null;

            if (req_comp < 0 || req_comp > 4)
            {
                return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? (byte *)null : null));
            }
            if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp) != 0)
            {
                if (p.depth < 8)
                {
                    ri->bits_per_channel = 8;
                }
                else
                {
                    ri->bits_per_channel = p.depth;
                }
                result  = p._out_;
                p._out_ = null;
                if (req_comp != 0 && req_comp != p.s.img_out_n)
                {
                    if (ri->bits_per_channel == 8)
                    {
                        result = stbi__convert_format((byte *)result, p.s.img_out_n, req_comp, p.s.img_x, p.s.img_y);
                    }
                    else
                    {
                        result = stbi__convert_format16((ushort *)result, p.s.img_out_n, req_comp, p.s.img_x,
                                                        p.s.img_y);
                    }
                    p.s.img_out_n = req_comp;
                    if (result == null)
                    {
                        return(result);
                    }
                }

                *x = (int)p.s.img_x;
                *y = (int)p.s.img_y;
                if (n != null)
                {
                    *n = p.s.img_n;
                }
            }

            CRuntime.free(p._out_);
            p._out_ = null;
            CRuntime.free(p.expanded);
            p.expanded = null;
            CRuntime.free(p.idata);
            p.idata = null;
            return(result);
        }