Esempio n. 1
0
        public static byte *stbi__gif_load_next(StbiContext s, StbiGif g, int *comp, int reqComp, byte *twoBack)
        {
            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 ? (byte *)null : null));
                }
                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 ? (byte *)null : null));
                }
                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 && twoBack == null)
                {
                    dispose = 2;
                }
                if (dispose == 3)
                {
                    for (pi = 0; pi < pcount; ++pi)
                    {
                        if (g.History[pi] != 0)
                        {
                            CRuntime.Memcpy(&g.Out[pi * 4], &twoBack[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 (; ;)
            {
                var tag = (int)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 ? (byte *)null : null));
                    }
                    g.LineSize = g.W * 4;
                    g.StartX   = x * 4;
                    g.StartY   = y * g.LineSize;
                    g.MaxX     = g.StartX + w * 4;
                    g.MaxY     = g.StartY + h * g.LineSize;
                    g.CurX     = g.StartX;
                    g.CurY     = g.StartY;
                    if (w == 0)
                    {
                        g.CurY = g.MaxY;
                    }
                    g.Lflags = stbi__get8(s);
                    if ((g.Lflags & 0x40) != 0)
                    {
                        g.Step  = 8 * g.LineSize;
                        g.Parse = 3;
                    }
                    else
                    {
                        g.Step  = g.LineSize;
                        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.ColorTable = g.Lpal;
                    }
                    else if ((g.Flags & 0x80) != 0)
                    {
                        g.ColorTable = g.Pal;
                    }
                    else
                    {
                        return((byte *)(ulong)(stbi__err("missing color table") != 0 ? (byte *)null : null));
                    }

                    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 * 4 + 3] = 255;
                                CRuntime.Memcpy(&g.Out[pi * 4], &g.Pal[g.Bgindex], (ulong)4);
                            }
                        }
                    }

                    return(o);
                }

                case 0x21:
                {
                    var len = 0;
                    var ext = (int)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 * 4 + 3] = 255;
                            }
                            if ((g.Eflags & 0x01) != 0)
                            {
                                g.Transparent = stbi__get8(s);
                                if (g.Transparent >= 0)
                                {
                                    g.Pal[g.Transparent * 4 + 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 ? (byte *)null : null));
                }
            }
        }