Ejemplo n.º 1
0
 public static void *stbi__load_main(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                     StbiResultInfo *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, reqComp, ri));
     }
     if (stbi__png_test(s) != 0)
     {
         return(stbi__png_load(s, x, y, comp, reqComp, ri));
     }
     if (stbi__bmp_test(s) != 0)
     {
         return(stbi__bmp_load(s, x, y, comp, reqComp, ri));
     }
     if (stbi__gif_test(s) != 0)
     {
         return(stbi__gif_load(s, x, y, comp, reqComp, ri));
     }
     if (stbi__tga_test(s) != 0)
     {
         return(stbi__tga_load(s, x, y, comp, reqComp, ri));
     }
     return((byte *)(ulong)(stbi__err("unknown image type") != 0 ? (byte *)null : null));
 }
Ejemplo n.º 2
0
        public static void *stbi__gif_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *ri)
        {
            byte *u = null;
            var   g = new StbiGif();

            u = stbi__gif_load_next(s, g, comp, reqComp, null);
            if (u != null)
            {
                *x = g.W;
                *y = g.H;
                if (reqComp != 0 && reqComp != 4)
                {
                    u = stbi__convert_format(u, 4, reqComp, (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);
        }
Ejemplo n.º 3
0
        public static void *stbi__png_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *ri)
        {
            var p = new StbiPng();

            p.S = s;
            return(stbi__do_png(p, x, y, comp, reqComp, ri));
        }
Ejemplo n.º 4
0
        public static void *stbi__do_png(StbiPng p, int *x, int *y, int *n, int reqComp, StbiResultInfo *ri)
        {
            void *result = null;

            if (reqComp < 0 || reqComp > 4)
            {
                return((byte *)(ulong)(stbi__err("bad req_comp") != 0 ? (byte *)null : null));
            }
            if (stbi__parse_png_file(p, STBI_SCAN_LOAD, reqComp) != 0)
            {
                if (p.Depth < 8)
                {
                    ri->bits_per_channel = 8;
                }
                else
                {
                    ri->bits_per_channel = p.Depth;
                }
                result = p.Out;
                p.Out  = null;
                if (reqComp != 0 && reqComp != p.S.ImgOutN)
                {
                    if (ri->bits_per_channel == 8)
                    {
                        result = stbi__convert_format((byte *)result, p.S.ImgOutN, reqComp, p.S.ImgX, p.S.ImgY);
                    }
                    else
                    {
                        result = stbi__convert_format16((ushort *)result, p.S.ImgOutN, reqComp, p.S.ImgX,
                                                        p.S.ImgY);
                    }
                    p.S.ImgOutN = reqComp;
                    if (result == null)
                    {
                        return(result);
                    }
                }

                *x = (int)p.S.ImgX;
                *y = (int)p.S.ImgY;
                if (n != null)
                {
                    *n = p.S.ImgN;
                }
            }

            CRuntime.Free(p.Out);
            p.Out = null;
            CRuntime.Free(p.Expanded);
            p.Expanded = null;
            CRuntime.Free(p.Idata);
            p.Idata = null;
            return(result);
        }
Ejemplo n.º 5
0
        public static void *stbi__bmp_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *ri)
        {
            byte *out_;
            var   mr              = (uint)0;
            var   mg              = (uint)0;
            var   mb              = (uint)0;
            var   ma              = (uint)0;
            uint  all_a           = 0;
            var   pal             = stackalloc byte[256 * 4];
            var   psize           = 0;
            var   i               = 0;
            var   j               = 0;
            var   width           = 0;
            var   flip_vertically = 0;
            var   pad             = 0;
            var   target          = 0;
            var   info            = new StbiBmpData();

            info.all_a = 255;
            if (stbi__bmp_parse_header(s, &info) == null)
            {
                return(null);
            }
            flip_vertically = (int)s.ImgY > 0 ? 1 : 0;
            s.ImgY          = (uint)CRuntime.Abs((int)s.ImgY);
            mr    = info.mr;
            mg    = info.mg;
            mb    = info.mb;
            ma    = info.ma;
            all_a = info.all_a;
            if (info.hsz == 12)
            {
                if (info.bpp < 24)
                {
                    psize = (info.offset - 14 - 24) / 3;
                }
            }
            else
            {
                if (info.bpp < 16)
                {
                    psize = (info.offset - 14 - info.hsz) >> 2;
                }
            }

            s.ImgN = ma != 0 ? 4 : 3;
            if (reqComp != 0 && reqComp >= 3)
            {
                target = reqComp;
            }
            else
            {
                target = s.ImgN;
            }
            if (stbi__mad3sizes_valid(target, (int)s.ImgX, (int)s.ImgY, 0) == 0)
            {
                return((byte *)(ulong)(stbi__err("too large") != 0 ? (byte *)null : null));
            }
            out_ = (byte *)stbi__malloc_mad3(target, (int)s.ImgX, (int)s.ImgY, 0);
            if (out_ == null)
            {
                return((byte *)(ulong)(stbi__err("outofmem") != 0 ? (byte *)null : null));
            }
            if (info.bpp < 16)
            {
                var z = 0;
                if (psize == 0 || psize > 256)
                {
                    CRuntime.Free(out_);
                    return((byte *)(ulong)(stbi__err("invalid") != 0 ? (byte *)null : null));
                }

                for (i = 0; i < psize; ++i)
                {
                    pal[i * 4 + 2] = stbi__get8(s);
                    pal[i * 4 + 1] = stbi__get8(s);
                    pal[i * 4 + 0] = stbi__get8(s);
                    if (info.hsz != 12)
                    {
                        stbi__get8(s);
                    }
                    pal[i * 4 + 3] = 255;
                }

                stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
                if (info.bpp == 1)
                {
                    width = (int)((s.ImgX + 7) >> 3);
                }
                else if (info.bpp == 4)
                {
                    width = (int)((s.ImgX + 1) >> 1);
                }
                else if (info.bpp == 8)
                {
                    width = (int)s.ImgX;
                }
                else
                {
                    CRuntime.Free(out_);
                    return((byte *)(ulong)(stbi__err("bad bpp") != 0 ? (byte *)null : null));
                }

                pad = -width & 3;
                if (info.bpp == 1)
                {
                    for (j = 0; j < (int)s.ImgY; ++j)
                    {
                        var bit_offset = 7;
                        var v          = (int)stbi__get8(s);
                        for (i = 0; i < (int)s.ImgX; ++i)
                        {
                            var color = (v >> bit_offset) & 0x1;
                            out_[z++] = pal[color * 4 + 0];
                            out_[z++] = pal[color * 4 + 1];
                            out_[z++] = pal[color * 4 + 2];
                            if (target == 4)
                            {
                                out_[z++] = 255;
                            }
                            if (i + 1 == (int)s.ImgX)
                            {
                                break;
                            }
                            if (--bit_offset < 0)
                            {
                                bit_offset = 7;
                                v          = stbi__get8(s);
                            }
                        }

                        stbi__skip(s, pad);
                    }
                }
                else
                {
                    for (j = 0; j < (int)s.ImgY; ++j)
                    {
                        for (i = 0; i < (int)s.ImgX; i += 2)
                        {
                            var v  = (int)stbi__get8(s);
                            var v2 = 0;
                            if (info.bpp == 4)
                            {
                                v2  = v & 15;
                                v >>= 4;
                            }

                            out_[z++] = pal[v * 4 + 0];
                            out_[z++] = pal[v * 4 + 1];
                            out_[z++] = pal[v * 4 + 2];
                            if (target == 4)
                            {
                                out_[z++] = 255;
                            }
                            if (i + 1 == (int)s.ImgX)
                            {
                                break;
                            }
                            v         = info.bpp == 8 ? stbi__get8(s) : v2;
                            out_[z++] = pal[v * 4 + 0];
                            out_[z++] = pal[v * 4 + 1];
                            out_[z++] = pal[v * 4 + 2];
                            if (target == 4)
                            {
                                out_[z++] = 255;
                            }
                        }

                        stbi__skip(s, pad);
                    }
                }
            }
            else
            {
                var rshift = 0;
                var gshift = 0;
                var bshift = 0;
                var ashift = 0;
                var rcount = 0;
                var gcount = 0;
                var bcount = 0;
                var acount = 0;
                var z      = 0;
                var easy   = 0;
                stbi__skip(s, info.offset - 14 - info.hsz);
                if (info.bpp == 24)
                {
                    width = (int)(3 * s.ImgX);
                }
                else if (info.bpp == 16)
                {
                    width = (int)(2 * s.ImgX);
                }
                else
                {
                    width = 0;
                }
                pad = -width & 3;
                if (info.bpp == 24)
                {
                    easy = 1;
                }
                else if (info.bpp == 32)
                {
                    if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
                    {
                        easy = 2;
                    }
                }
                if (easy == 0)
                {
                    if (mr == 0 || mg == 0 || mb == 0)
                    {
                        CRuntime.Free(out_);
                        return((byte *)(ulong)(stbi__err("bad masks") != 0 ? (byte *)null : null));
                    }

                    rshift = stbi__high_bit(mr) - 7;
                    rcount = stbi__bitcount(mr);
                    gshift = stbi__high_bit(mg) - 7;
                    gcount = stbi__bitcount(mg);
                    bshift = stbi__high_bit(mb) - 7;
                    bcount = stbi__bitcount(mb);
                    ashift = stbi__high_bit(ma) - 7;
                    acount = stbi__bitcount(ma);
                }

                for (j = 0; j < (int)s.ImgY; ++j)
                {
                    if (easy != 0)
                    {
                        for (i = 0; i < (int)s.ImgX; ++i)
                        {
                            byte a = 0;
                            out_[z + 2] = stbi__get8(s);
                            out_[z + 1] = stbi__get8(s);
                            out_[z + 0] = stbi__get8(s);
                            z          += 3;
                            a           = (byte)(easy == 2 ? stbi__get8(s) : 255);
                            all_a      |= a;
                            if (target == 4)
                            {
                                out_[z++] = a;
                            }
                        }
                    }
                    else
                    {
                        var bpp = info.bpp;
                        for (i = 0; i < (int)s.ImgX; ++i)
                        {
                            var  v = bpp == 16 ? (uint)stbi__get16le(s) : stbi__get32le(s);
                            uint a = 0;
                            out_[z++] = (byte)(stbi__shiftsigned(v & mr, rshift, rcount) & 255);
                            out_[z++] = (byte)(stbi__shiftsigned(v & mg, gshift, gcount) & 255);
                            out_[z++] = (byte)(stbi__shiftsigned(v & mb, bshift, bcount) & 255);
                            a         = (uint)(ma != 0 ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
                            all_a    |= a;
                            if (target == 4)
                            {
                                out_[z++] = (byte)(a & 255);
                            }
                        }
                    }

                    stbi__skip(s, pad);
                }
            }

            if (target == 4 && all_a == 0)
            {
                for (i = (int)(4 * s.ImgX * s.ImgY - 1); i >= 0; i -= 4)
                {
                    out_[i] = 255;
                }
            }
            if (flip_vertically != 0)
            {
                byte t = 0;
                for (j = 0; j < (int)s.ImgY >> 1; ++j)
                {
                    var p1 = out_ + j * s.ImgX * target;
                    var p2 = out_ + (s.ImgY - 1 - j) * s.ImgX * target;
                    for (i = 0; i < (int)s.ImgX * target; ++i)
                    {
                        t     = p1[i];
                        p1[i] = p2[i];
                        p2[i] = t;
                    }
                }
            }

            if (reqComp != 0 && reqComp != target)
            {
                out_ = stbi__convert_format(out_, target, reqComp, s.ImgX, s.ImgY);
                if (out_ == null)
                {
                    return(out_);
                }
            }

            *x = (int)s.ImgX;
            *y = (int)s.ImgY;
            if (comp != null)
            {
                *comp = s.ImgN;
            }
            return(out_);
        }
Ejemplo n.º 6
0
        public static void *stbi__tga_load(StbiContext s, int *x, int *y, int *comp, int reqComp,
                                           StbiResultInfo *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 (reqComp != 0 && reqComp != tga_comp)
            {
                tga_data = stbi__convert_format(tga_data, tga_comp, reqComp, (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);
        }