예제 #1
0
        public static GifRenderBlock Read(Stream s)
        {
            GifRenderBlock ret = new GifRenderBlock();

            ret.Shift = s.Position;
            s.ReadByte();

            ret.LeftPosition = s.ReadUshort();
            ret.TopPosition  = s.ReadUshort();
            ret.Width        = s.ReadUshort();
            ret.Height       = s.ReadUshort();
            ret.PackedByte   = (byte)s.ReadByte();
            if (ret.LocalColorTableFlag)
            {
                ret.ColorTable = new GifColorTable();
                ret.ColorTable.ColorsAmount = (int)Math.Pow(2, ret.SizeOfColorTable + 1);
                ret.ColorTable.Read(s);
            }
            ret.LZWMinCodeSize = (byte)s.ReadByte();

            var           b  = s.ReadByte();
            List <byte[]> dl = new List <byte[]>();

            while (b != 0)
            {
                ret.Data.Add((byte)b);
                var dd = new byte[b];
                s.Read(dd, 0, b);
                ret.Data.AddRange(dd);
                dl.Add(dd);
                b = s.ReadByte();
            }
            ret.DataList = dl.ToArray();
            return(ret);
        }
예제 #2
0
        public static byte[] GetDecodedData(GifRenderBlock imgBlock)
        {
            // Combine LZW compressed data
            List <byte> lzwData = new List <byte>();

            for (int i = 0; i < imgBlock.DataList.Length; i++)
            {
                for (int k = 0; k < imgBlock.DataList[i].Length; k++)
                {
                    lzwData.Add(imgBlock.DataList[i][k]);
                }
            }

            // LZW decode
            int needDataSize = imgBlock.Height * imgBlock.Width;

            byte[] decodedData = DecodeGifLZW(lzwData, imgBlock.LZWMinCodeSize, needDataSize);

            // Sort interlace GIF
            if (imgBlock.InterlaceFlag)
            {
                decodedData = SortInterlaceGifData(decodedData, imgBlock.Width);
            }
            return(decodedData);
        }
예제 #3
0
        public static GifContainer Parse(Stream fs)
        {
            GifContainer ret = new GifContainer();

            {
                ret.Header.Read(fs);
                ret.LogicalScreen.Read(fs);
                int findex = 0;
                //lookahead
                while (true)
                {
                    var b = fs.ReadByte();
                    fs.Position--;
                    if (b == 0x3b)
                    {
                        break;
                    }

                    if (b == 0x21)
                    {
                        b = fs.ReadByte();
                        var b2 = fs.ReadByte();
                        fs.Position -= 2;;
                        if (b2 == 0xf9)
                        {
                            ret.Data.Add(GraphicControlExtension.Read(fs));
                        }
                        else
                        if (b2 == 0xff)
                        {
                            ret.Data.Add(GifApplicationExtension.Read(fs));
                        }
                        else
                        if (b2 == 0xfe)
                        {
                            ret.Data.Add(GifCommentBlock.Read(fs));
                        }
                        else
                        {
                            throw new GifParsingException("unknown header: " + b.ToString("X2") + b2.ToString("X2") + ", shift: " + fs.Position);
                        }
                    }
                    else
                    if (b == 0x2c)
                    {
                        var r = GifRenderBlock.Read(fs);
                        ret.Data.Add(r);
                        r.FrameIndex = findex++;
                    }
                    else
                    {
                        throw new GifParsingException("unknown header: " + b.ToString("X2") + ", shift: " + fs.Position);
                    }
                }
            }

            ret.UpdateInfo();
            return(ret);
        }
예제 #4
0
        public MemoryStream GetRawFrameStream(int index)
        {
            MemoryStream ms = new MemoryStream();

            Header.Write(ms);

            //LogicalScreen.GlobalColorTable.Colors[LogicalScreen.Desc.BackgroundColorIndex] = Color.Black;
            LogicalScreen.Write(ms);
            int frame = 0;

            for (int i = 0; i < Data.Count; i++)
            {
                var t = Data[i];
                if (frame == index && t is GifRenderBlock)
                {
                    int j = 0;
                    for (j = i - 1; j > 0; j--)
                    {
                        if (Data[j] is GifRenderBlock)
                        {
                            j++;
                            break;
                        }
                    }
                    LastGceBlock = null;
                    for (int y = j; y <= i; y++)
                    {
                        if (Data[y] is GraphicControlExtension)
                        {
                            LastGceBlock = Data[y] as GraphicControlExtension;
                            // LogicalScreen.GlobalColorTable.Colors[LastGceBlock.TransparentColorIndex] = Color.Black;
                        }
                        if (Data[y] is GifRenderBlock)
                        {
                            LastRenderBlock = Data[y] as GifRenderBlock;
                        }
                        Data[y].Write(ms);
                    }

                    break;
                }
                if (t is GifRenderBlock)
                {
                    frame++;
                }
            }
            ms.WriteByte(0x3b);
            return(ms);
        }
예제 #5
0
        public GraphicControlExtension GetGceBlock(GifRenderBlock gr)
        {
            GraphicControlExtension gce = null;

            foreach (var item in Data)
            {
                if (item is GraphicControlExtension)
                {
                    gce = item as GraphicControlExtension;
                }
                if (gr == item)
                {
                    break;
                }
            }
            return(gce);
        }
예제 #6
0
        public Bitmap GetDecodedBmp(int _index)
        {
            var fr  = GetRenderBlock(_index);
            var gce = GetGceBlock(fr);

            LastRenderBlock = fr;
            LastGceBlock    = gce;
            Bitmap     decbmp = new Bitmap(fr.Width, fr.Height);
            LockBitmap l      = new LockBitmap(decbmp);

            l.LockBits();

            var           dec  = GifParser.GetDecodedData(fr);
            GifColorTable clrt = LogicalScreen.GlobalColorTable;

            if (fr.LocalColorTableFlag)
            {
                clrt = fr.ColorTable;
            }
            for (int i = 0; i < fr.Width; i++)
            {
                for (int j = 0; j < fr.Height; j++)
                {
                    int index = j * fr.Width + i;
                    var clr   = clrt.Colors[dec[index]];
                    if (gce.TransparencyFlag && gce.TransparentColorIndex == dec[index])
                    {
                        l.SetPixel(i, j, Color.Transparent);
                    }
                    else
                    {
                        l.SetPixel(i, j, clr);
                    }
                }
            }
            l.UnlockBits();
            return(decbmp);
        }