コード例 #1
0
            public static GraphicRenderingBlock Create(byte[] data, ref int offset)
            {
                GraphicRenderingBlock grb = new GraphicRenderingBlock();

                //
                // Image descriptor.
                //
                Debug.Assert(data[offset] == IMAGE_SEPARATOR);
                offset++;
                grb.ImageLeftPosition = RawData.FetchLittleUshort(data, ref offset);
                grb.ImageTopPosition  = RawData.FetchLittleUshort(data, ref offset);
                grb.ImageWidth        = RawData.FetchLittleUshort(data, ref offset);
                grb.ImageHeight       = RawData.FetchLittleUshort(data, ref offset);
                byte pak = data[offset++];

                grb.LocalColorTableFlag = (pak & 0x80) != 0;
                grb.InterlaceFlag       = (pak & 0x40) != 0;
                grb.SortFlag            = (pak & 0x20) != 0;
                grb.LocalColorTableSize = (byte)(pak & 0x07);

                //
                // Local color table (optional).
                //
                if (grb.LocalColorTableFlag)
                {
                    // Size is expressed as a power of 2. TableSize=7 is 256 entries, 3 bytes each.
                    int tableLen = 1 << (grb.LocalColorTableSize + 1);
                    grb.LocalColorTable = new byte[tableLen * 3];
                    for (int i = 0; i < tableLen * 3; i++)
                    {
                        grb.LocalColorTable[i] = data[offset++];
                    }
                }
                else
                {
                    grb.LocalColorTable = new byte[0];
                }

                //
                // Table based image data.
                //
                grb.ImageData        = data;
                grb.ImageStartOffset = offset++;
                while (data[offset] != 0)
                {
                    offset += data[offset] + 1;
                }
                grb.ImageEndOffset = offset++;

                return(grb);
            }
コード例 #2
0
        private bool Unpack(byte[] gifData)
        {
            //
            // Header.  Signature ("GIF") + version ("87a" or "89a").
            //
            if (RawData.CompareArrays(gifData, 0, GIF87A, 0, GIF87A.Length))
            {
                FileVer = FileVersion.Gif87a;
            }
            else if (RawData.CompareArrays(gifData, 0, GIF89A, 0, GIF87A.Length))
            {
                FileVer = FileVersion.Gif89a;
            }
            else
            {
                Debug.WriteLine("GIF signature not found");
                return(false);
            }
            //Debug.WriteLine("GIF: found signature " + FileVer);

            byte pak;

            //
            // Logical screen descriptor.
            //
            int offset = GIF87A.Length;

            LogicalScreenWidth  = RawData.FetchLittleUshort(gifData, ref offset);
            LogicalScreenHeight = RawData.FetchLittleUshort(gifData, ref offset);
            pak = gifData[offset++];
            GlobalColorTableFlag = (pak & 0x80) != 0;
            ColorResolution      = (byte)((pak >> 4) & 0x07);
            SortFlag             = (pak & 0x08) != 0;
            GlobalColorTableSize = (byte)(pak & 0x07);
            BackgroundColorIndex = gifData[offset++];
            PixelAspectRatio     = gifData[offset++];

            //
            // Global color table.
            //
            if (GlobalColorTableFlag)
            {
                // Size is expressed as a power of 2.  TableSize=7 is 256 entries, 3 bytes each.
                int tableLen = 1 << (GlobalColorTableSize + 1);
                GlobalColorTable = new byte[tableLen * 3];
                for (int i = 0; i < tableLen * 3; i++)
                {
                    GlobalColorTable[i] = gifData[offset++];
                }
            }
            else
            {
                GlobalColorTable = new byte[0];
            }

            //
            // Various blocks follow.  Continue until EOF is reached.
            //
            GraphicControlExtension lastGce = null;

            while (true)
            {
                if (offset >= gifData.Length)
                {
                    Debug.WriteLine("Error: GIF unpacker ran off end of buffer");
                    return(false);
                }
                if (gifData[offset] == GIF_TRAILER)
                {
                    break;
                }
                else if (gifData[offset] == EXTENSION_INTRODUCER)
                {
                    if (gifData[offset + 1] == GRAPHIC_CONTROL_LABEL)
                    {
                        lastGce = GraphicControlExtension.Create(gifData, ref offset);
                    }
                    else
                    {
                        Debug.WriteLine("Skipping unknown extension 0x" +
                                        gifData[offset + 1].ToString("x2"));
                        offset += 2;
                        while (gifData[offset] != 0)
                        {
                            offset += gifData[offset] + 1;
                        }
                        offset++;
                    }
                }
                else if (gifData[offset] == IMAGE_SEPARATOR)
                {
                    GraphicRenderingBlock grb = GraphicRenderingBlock.Create(gifData, ref offset);
                    if (grb != null)
                    {
                        if (lastGce != null)
                        {
                            grb.GraphicControlExt = lastGce;
                        }
                        ImageBlocks.Add(grb);
                    }

                    // this resets after the image
                    lastGce = null;
                }
                else
                {
                    Debug.WriteLine("Found unknown block start 0x" +
                                    gifData[offset].ToString("x2"));
                    return(false);
                }
            }

            return(true);
        }