Пример #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);
        }
Пример #2
0
 public static void *stbi__load_gif_main_outofmem(stbi__gif g, byte *_out_, int **delays)
 {
     CRuntime.free(g._out_);
     CRuntime.free(g.history);
     CRuntime.free(g.background);
     if (_out_ != null)
     {
         CRuntime.free(_out_);
     }
     if (delays != null && *delays != null)
     {
         CRuntime.free(*delays);
     }
     return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0));
 }
Пример #3
0
        public static int stbi__gif_header(stbi__context s, stbi__gif g, int *comp, int is_info)
        {
            byte version = 0;

            if (stbi__get8(s) != 71 || stbi__get8(s) != 73 || stbi__get8(s) != 70 || stbi__get8(s) != 56)
            {
                return(stbi__err("not GIF"));
            }
            version = stbi__get8(s);
            if (version != 55 && version != 57)
            {
                return(stbi__err("not GIF"));
            }
            if (stbi__get8(s) != 97)
            {
                return(stbi__err("not GIF"));
            }
            stbi__g_failure_reason = "";
            g.w           = stbi__get16le(s);
            g.h           = stbi__get16le(s);
            g.flags       = stbi__get8(s);
            g.bgindex     = stbi__get8(s);
            g.ratio       = stbi__get8(s);
            g.transparent = -1;
            if (g.w > 1 << 24)
            {
                return(stbi__err("too large"));
            }
            if (g.h > 1 << 24)
            {
                return(stbi__err("too large"));
            }
            if (comp != null)
            {
                *comp = 4;
            }
            if (is_info != 0)
            {
                return(1);
            }
            if ((g.flags & 0x80) != 0)
            {
                stbi__gif_parse_colortable(s, g.pal, 2 << (g.flags & 7), -1);
            }
            return(1);
        }
                    public static int stbi__gif_info_raw(stbi__context s, int *x, int *y, int *comp)
                    {
                        var g = new stbi__gif();

                        if (stbi__gif_header(s, g, comp, 1) == 0)
                        {
                            stbi__rewind(s);
                            return(0);
                        }
                        if (x != null)
                        {
                            *x = g.w;
                        }
                        if (y != null)
                        {
                            *y = g.h;
                        }
                        return(1);
                    }
Пример #5
0
        public static void stbi__out_gif_code(stbi__gif g, ushort code)
        {
            byte *p;
            byte *c;
            var   idx = 0;

            if (g.codes[code].prefix >= 0)
            {
                stbi__out_gif_code(g, (ushort)g.codes[code].prefix);
            }
            if (g.cur_y >= g.max_y)
            {
                return;
            }
            idx = g.cur_x + g.cur_y;
            p   = &g._out_[idx];
            g.history[idx / 4] = 1;
            c = &g.color_table[g.codes[code].suffix * 4];
            if (c[3] > 128)
            {
                p[0] = c[2];
                p[1] = c[1];
                p[2] = c[0];
                p[3] = c[3];
            }

            g.cur_x += 4;
            if (g.cur_x >= g.max_x)
            {
                g.cur_x  = g.start_x;
                g.cur_y += g.step;
                while (g.cur_y >= g.max_y && g.parse > 0)
                {
                    g.step  = (1 << g.parse) * g.line_size;
                    g.cur_y = g.start_y + (g.step >> 1);
                    --g.parse;
                }
            }
        }
                    public static int stbi__gif_header(stbi__context s, stbi__gif g, int *comp, int is_info)
                    {
                        byte version = 0;

                        if ((stbi__get8(s) != 'G') || (stbi__get8(s) != 'I') || (stbi__get8(s) != 'F') || (stbi__get8(s) != '8'))
                        {
                            return(stbi__err("not GIF"));
                        }
                        version = stbi__get8(s);
                        if ((version != '7') && (version != '9'))
                        {
                            return(stbi__err("not GIF"));
                        }
                        if (stbi__get8(s) != 'a')
                        {
                            return(stbi__err("not GIF"));
                        }
                        stbi__g_failure_reason = "";
                        g.w           = stbi__get16le(s);
                        g.h           = stbi__get16le(s);
                        g.flags       = stbi__get8(s);
                        g.bgindex     = stbi__get8(s);
                        g.ratio       = stbi__get8(s);
                        g.transparent = -1;
                        if (comp != null)
                        {
                            *comp = 4;
                        }
                        if (is_info != 0)
                        {
                            return(1);
                        }
                        if ((g.flags & 0x80) != 0)
                        {
                            stbi__gif_parse_colortable(s, g.pal, 2 << (g.flags & 7), -1);
                        }
                        return(1);
                    }
Пример #7
0
        public static byte *stbi__process_gif_raster(stbi__context s, stbi__gif g)
        {
            byte           lzw_cs     = 0;
            var            len        = 0;
            var            init_code  = 0;
            uint           first      = 0;
            var            codesize   = 0;
            var            codemask   = 0;
            var            avail      = 0;
            var            oldcode    = 0;
            var            bits       = 0;
            var            valid_bits = 0;
            var            clear      = 0;
            stbi__gif_lzw *p;

            lzw_cs = stbi__get8(s);
            if (lzw_cs > 12)
            {
                return(null);
            }
            clear      = 1 << lzw_cs;
            first      = 1;
            codesize   = lzw_cs + 1;
            codemask   = (1 << codesize) - 1;
            bits       = 0;
            valid_bits = 0;
            for (init_code = 0; init_code < clear; init_code++)
            {
                g.codes[init_code].prefix = -1;
                g.codes[init_code].first  = (byte)init_code;
                g.codes[init_code].suffix = (byte)init_code;
            }

            avail   = clear + 2;
            oldcode = -1;
            len     = 0;
            for (; ;)
            {
                if (valid_bits < codesize)
                {
                    if (len == 0)
                    {
                        len = stbi__get8(s);
                        if (len == 0)
                        {
                            return(g._out_);
                        }
                    }

                    --len;
                    bits       |= stbi__get8(s) << valid_bits;
                    valid_bits += 8;
                }
                else
                {
                    var code = bits & codemask;
                    bits      >>= codesize;
                    valid_bits -= codesize;
                    if (code == clear)
                    {
                        codesize = lzw_cs + 1;
                        codemask = (1 << codesize) - 1;
                        avail    = clear + 2;
                        oldcode  = -1;
                        first    = 0;
                    }
                    else if (code == clear + 1)
                    {
                        stbi__skip(s, len);
                        while ((len = stbi__get8(s)) > 0)
                        {
                            stbi__skip(s, len);
                        }

                        return(g._out_);
                    }
                    else if (code <= avail)
                    {
                        if (first != 0)
                        {
                            return((byte *)(ulong)(stbi__err("no clear code") != 0 ? 0 : 0));
                        }

                        if (oldcode >= 0)
                        {
                            p = &g.codes[avail++];
                            if (avail > 8192)
                            {
                                return((byte *)(ulong)(stbi__err("too many codes") != 0 ? 0 : 0));
                            }

                            p->prefix = (short)oldcode;
                            p->first  = g.codes[oldcode].first;
                            p->suffix = code == avail ? p->first : g.codes[code].first;
                        }
                        else if (code == avail)
                        {
                            return((byte *)(ulong)(stbi__err("illegal code in raster") != 0 ? 0 : 0));
                        }

                        stbi__out_gif_code(g, (ushort)code);
                        if ((avail & codemask) == 0 && avail <= 0x0FFF)
                        {
                            codesize++;
                            codemask = (1 << codesize) - 1;
                        }

                        oldcode = code;
                    }
                    else
                    {
                        return((byte *)(ulong)(stbi__err("illegal code in raster") != 0 ? 0 : 0));
                    }
                }
            }
        }
Пример #8
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));
        }
Пример #9
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));
                }
            }
        }