示例#1
0
        /// <summary>
        /// Read gif header
        /// </summary>
        /// <returns>Data of gif header</returns>
        /// <exception cref="ArgumentException">If file is not gif file</exception>
        public GifHeader ReadHeader()
        {
            AssertToken(Token.Header);

            // Header
            headerStartPosition     = currentStream.Position;
            firstFrameStartPosition = -1;
            currentStream.Read(headerBuffer, 0, headerBuffer.Length);

            if (BitUtils.CheckString(headerBuffer, "GIF87a"))
            {
                header.version = GifVersion.Gif87a;
            }
            else if (BitUtils.CheckString(headerBuffer, "GIF89a"))
            {
                header.version = GifVersion.Gif89a;
            }
            else
            {
                throw new ArgumentException("Invalid or corrupted Gif file");
            }

            // Screen descriptor
            header.width  = currentStream.ReadInt16LittleEndian();
            header.height = currentStream.ReadInt16LittleEndian();

            var flags = currentStream.ReadByte8();

            header.globalColorTableSize = BitUtils.GetColorTableSize(flags.GetBitsFromByte(0, 3));
            header.sortColors           = flags.GetBitFromByte(3);
            header.colorResolution      = flags.GetBitsFromByte(4, 3);
            header.hasGlobalColorTable  = flags.GetBitFromByte(7);

            header.transparentColorIndex = currentStream.ReadByte8();
            header.pixelAspectRatio      = currentStream.ReadByte8();

            canvas.SetSize(header.width, header.height);

            if (header.hasGlobalColorTable)
            {
                SetCurrentToken(Token.Palette);
                nextPaletteIsGlobal = true;
            }
            else
            {
                DetermineNextToken();
            }

            return(header);
        }
示例#2
0
        private Token DetermineNextToken()
        {
            while (true)
            {
                var blockType = currentStream.ReadByte8();
                switch (blockType)
                {
                case ExtensionBlock:
                    var extensionType = currentStream.ReadByte8();
                    switch (extensionType)
                    {
                    case commentLabel: return(SetCurrentToken(Token.Comment));

                    case PlainTextLabel: return(SetCurrentToken(Token.PlainText));

                    case GraphicControlLabel: return(SetCurrentToken(Token.GraphicsControl));

                    case applicationExtensionLabel:
                    {
                        currentStream.AssertByte(11);
                        currentStream.Read(extensionApplicationBuffer, 0, 11);

                        var token = BitUtils.CheckString(extensionApplicationBuffer, "NETSCAPE2.0")
                                    ? Token.NetscapeExtension
                                    : Token.ApplicationExtension;

                        return(SetCurrentToken(token));
                    }

                    default: BitUtils.SkipGifBlocks(currentStream); break;
                    }

                    break;

                case ImageDescriptorBlock: return(SetCurrentToken(Token.ImageDescriptor));

                case EndOfFile: return(SetCurrentToken(Token.EndOfFile));

                default: throw new ArgumentException(String.Format("Unknown block type {0}", blockType));
                }
            }
        }