Beispiel #1
0
        public static byte[] stbi_zlib_decode_malloc_guesssize_headerflag(byte[] buffer, int len, int initial_size,
                                                                          out int outlen, int parse_header)
        {
            outlen = 0;
            var a = new ZLib();
            var p = new byte[initial_size];

            a.zbuffer     = new FakePtr <byte>(buffer);
            a.zbuffer_end = new FakePtr <byte>(buffer, +len);
            if (a.stbi__do_zlib(p, initial_size, 1, parse_header) != 0)
            {
                outlen = a.zout.Offset;
                return(a.zout_start);
            }

            return(null);
        }
Beispiel #2
0
        private int stbi__parse_png_file(int scan, int req_comp)
        {
            var palette   = new byte[1024];
            var pal_img_n = (byte)0;
            var has_trans = (byte)0;
            var tc        = new byte[3];

            tc[0] = 0;

            var  tc16        = new ushort[3];
            var  ioff        = 0;
            var  idata_limit = 0;
            uint i           = 0;
            var  pal_len     = (uint)0;
            var  first       = 1;
            var  k           = 0;
            var  interlace   = 0;
            var  color       = 0;
            var  is_iphone   = 0;

            expanded = null;
            idata    = null;
            _out_    = null;
            if (!stbi__check_png_header(Stream))
            {
                return(0);
            }
            if (scan == STBI__SCAN_type)
            {
                return(1);
            }
            for (; ;)
            {
                var c = stbi__get_chunk_header();
                switch (c.type)
                {
                case ((uint)'C' << 24) + ((uint)'g' << 16) + ((uint)'B' << 8) + 'I':
                    is_iphone = 1;
                    stbi__skip((int)c.length);
                    break;

                case ((uint)'I' << 24) + ((uint)'H' << 16) + ((uint)'D' << 8) + 'R':
                {
                    var comp   = 0;
                    var filter = 0;
                    if (first == 0)
                    {
                        stbi__err("multiple IHDR");
                    }
                    first = 0;
                    if (c.length != 13)
                    {
                        stbi__err("bad IHDR len");
                    }
                    img_x = (int)stbi__get32be();
                    if (img_x > 1 << 24)
                    {
                        stbi__err("too large");
                    }
                    img_y = (int)stbi__get32be();
                    if (img_y > 1 << 24)
                    {
                        stbi__err("too large");
                    }
                    depth = stbi__get8();
                    if (depth != 1 && depth != 2 && depth != 4 && depth != 8 && depth != 16)
                    {
                        stbi__err("1/2/4/8/16-bit only");
                    }
                    color = stbi__get8();
                    if (color > 6)
                    {
                        stbi__err("bad ctype");
                    }
                    if (color == 3 && depth == 16)
                    {
                        stbi__err("bad ctype");
                    }
                    if (color == 3)
                    {
                        pal_img_n = 3;
                    }
                    else if ((color & 1) != 0)
                    {
                        stbi__err("bad ctype");
                    }
                    comp = stbi__get8();
                    if (comp != 0)
                    {
                        stbi__err("bad comp method");
                    }
                    filter = stbi__get8();
                    if (filter != 0)
                    {
                        stbi__err("bad filter method");
                    }
                    interlace = stbi__get8();
                    if (interlace > 1)
                    {
                        stbi__err("bad interlace method");
                    }
                    if (img_x == 0 || img_y == 0)
                    {
                        stbi__err("0-pixel image");
                    }
                    if (pal_img_n == 0)
                    {
                        img_n = ((color & 2) != 0 ? 3 : 1) + ((color & 4) != 0 ? 1 : 0);
                        if ((1 << 30) / img_x / img_n < img_y)
                        {
                            stbi__err("too large");
                        }
                        if (scan == STBI__SCAN_header)
                        {
                            return(1);
                        }
                    }
                    else
                    {
                        img_n = 1;
                        if ((1 << 30) / img_x / 4 < img_y)
                        {
                            stbi__err("too large");
                        }
                    }

                    break;
                }

                case ((uint)'P' << 24) + ((uint)'L' << 16) + ((uint)'T' << 8) + 'E':
                {
                    if (first != 0)
                    {
                        stbi__err("first not IHDR");
                    }
                    if (c.length > 256 * 3)
                    {
                        stbi__err("invalid PLTE");
                    }
                    pal_len = c.length / 3;
                    if (pal_len * 3 != c.length)
                    {
                        stbi__err("invalid PLTE");
                    }
                    for (i = (uint)0; i < pal_len; ++i)
                    {
                        palette[i * 4 + 0] = stbi__get8();
                        palette[i * 4 + 1] = stbi__get8();
                        palette[i * 4 + 2] = stbi__get8();
                        palette[i * 4 + 3] = 255;
                    }

                    break;
                }

                case ((uint)'t' << 24) + ((uint)'R' << 16) + ((uint)'N' << 8) + 'S':
                {
                    if (first != 0)
                    {
                        stbi__err("first not IHDR");
                    }
                    if (idata != null)
                    {
                        stbi__err("tRNS after IDAT");
                    }
                    if (pal_img_n != 0)
                    {
                        if (scan == STBI__SCAN_header)
                        {
                            img_n = 4;
                            return(1);
                        }

                        if (pal_len == 0)
                        {
                            stbi__err("tRNS before PLTE");
                        }
                        if (c.length > pal_len)
                        {
                            stbi__err("bad tRNS len");
                        }
                        pal_img_n = 4;
                        for (i = (uint)0; i < c.length; ++i)
                        {
                            palette[i * 4 + 3] = stbi__get8();
                        }
                    }
                    else
                    {
                        if ((img_n & 1) == 0)
                        {
                            stbi__err("tRNS with alpha");
                        }
                        if (c.length != (uint)img_n * 2)
                        {
                            stbi__err("bad tRNS len");
                        }
                        has_trans = 1;
                        if (depth == 16)
                        {
                            for (k = 0; k < img_n; ++k)
                            {
                                tc16[k] = (ushort)stbi__get16be();
                            }
                        }
                        else
                        {
                            for (k = 0; k < img_n; ++k)
                            {
                                tc[k] = (byte)((byte)(stbi__get16be() & 255) * stbi__depth_scale_table[depth]);
                            }
                        }
                    }

                    break;
                }

                case ((uint)'I' << 24) + ((uint)'D' << 16) + ((uint)'A' << 8) + 'T':
                {
                    if (first != 0)
                    {
                        stbi__err("first not IHDR");
                    }
                    if (pal_img_n != 0 && pal_len == 0)
                    {
                        stbi__err("no PLTE");
                    }
                    if (scan == STBI__SCAN_header)
                    {
                        img_n = pal_img_n;
                        return(1);
                    }

                    if ((int)(ioff + c.length) < ioff)
                    {
                        return(0);
                    }
                    if (ioff + c.length > idata_limit)
                    {
                        var idata_limit_old = (uint)idata_limit;
                        if (idata_limit == 0)
                        {
                            idata_limit = (int)(c.length > 4096 ? c.length : 4096);
                        }
                        while (ioff + c.length > idata_limit)
                        {
                            idata_limit *= 2;
                        }

                        Array.Resize(ref idata, idata_limit);
                    }

                    if (!stbi__getn(idata, ioff, (int)c.length))
                    {
                        stbi__err("outofdata");
                    }
                    ioff += (int)c.length;
                    break;
                }

                case ((uint)'I' << 24) + ((uint)'E' << 16) + ((uint)'N' << 8) + 'D':
                {
                    var  raw_len = 0;
                    uint bpl     = 0;
                    if (first != 0)
                    {
                        stbi__err("first not IHDR");
                    }
                    if (scan != STBI__SCAN_load)
                    {
                        return(1);
                    }
                    if (idata == null)
                    {
                        stbi__err("no IDAT");
                    }
                    bpl      = (uint)((img_x * depth + 7) / 8);
                    raw_len  = (int)(bpl * img_y * img_n + img_y);
                    expanded = ZLib.stbi_zlib_decode_malloc_guesssize_headerflag(idata, ioff, raw_len, out raw_len,
                                                                                 is_iphone != 0 ? 0 : 1);
                    if (expanded == null)
                    {
                        return(0);
                    }
                    idata = null;
                    if (req_comp == img_n + 1 && req_comp != 3 && pal_img_n == 0 || has_trans != 0)
                    {
                        img_out_n = img_n + 1;
                    }
                    else
                    {
                        img_out_n = img_n;
                    }
                    if (stbi__create_png_image(new FakePtr <byte>(expanded), (uint)raw_len, img_out_n, depth, color,
                                               interlace) == 0)
                    {
                        return(0);
                    }
                    if (has_trans != 0)
                    {
                        if (depth == 16)
                        {
                            if (stbi__compute_transparency16(tc16, img_out_n) == 0)
                            {
                                return(0);
                            }
                        }
                        else
                        {
                            if (stbi__compute_transparency(tc, img_out_n) == 0)
                            {
                                return(0);
                            }
                        }
                    }

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

                    expanded = null;
                    return(1);
                }

                default:
                    if (first != 0)
                    {
                        stbi__err("first not IHDR");
                    }
                    if ((c.type & (1 << 29)) == 0)
                    {
                        var invalid_chunk = c.type + " PNG chunk not known";
                        stbi__err(invalid_chunk);
                    }

                    stbi__skip((int)c.length);
                    break;
                }

                stbi__get32be();
            }
        }