예제 #1
0
        public void read(Reader reader, bool skipHeader = false, int clrCnt = 0x80)
        {
            #region Header
            if (!skipHeader)
            {
                reader.seek(6, System.IO.SeekOrigin.Begin); // GIF89a

                width  = reader.ReadByte();
                width |= (ushort)(reader.ReadByte() << 8);

                height  = reader.ReadByte();
                height |= (ushort)(reader.ReadByte() << 8);

                byte info = reader.ReadByte(); // Palette Size
                clrCnt = (info & 0x7) + 1;
                if (clrCnt > 0)
                {
                    clrCnt = 1 << clrCnt;
                }
                reader.ReadByte(); // background colour index
                reader.ReadByte(); // unused

                if (clrCnt != 0x100)
                {
                    throw new Exception("RSDK-Formatted Gif files must use 256 colours!");
                }
            }

            for (int c = 0; c < clrCnt; ++c)
            {
                palette[c].R = reader.ReadByte();
                palette[c].G = reader.ReadByte();
                palette[c].B = reader.ReadByte();
            }
            #endregion

            #region Blocks
            byte blockType = reader.ReadByte();
            while (blockType != 0 && blockType != ';')
            {
                switch (blockType)
                {
                default:     // Unknown
                    Console.WriteLine($"Unknown Block Type ({blockType})");
                    break;

                case (byte)'!':     // Extension
                {
                    byte extensionType = reader.ReadByte();
                    switch (extensionType)
                    {
                    case 0xF9:             // Graphics Control Extension
                    {
                        int    blockSize        = reader.ReadByte();
                        byte   disposalFlag     = reader.ReadByte();
                        ushort frameDelay       = reader.ReadUInt16();
                        byte   transparentIndex = reader.ReadByte();
                        reader.ReadByte();                 // terminator
                    }
                    break;

                    case 0x01:             // Plain Text Extension
                    case 0xFE:             // Comment Extension
                    case 0xFF:             // Application Extension
                    {
                        int blockSize = reader.ReadByte();
                        while (blockSize != 0)
                        {
                            // Read block
                            reader.BaseStream.Position += blockSize;
                            blockSize = reader.ReadByte();                 // next block Size, if its 0 we know its the end of block
                        }
                    }
                    break;

                    default:             // Unknown
                        Console.WriteLine($"Unknown Extension Type ({extensionType})");
                        return;
                    }
                }
                break;

                case (byte)',':     // Image descriptor
                {
                    int left   = reader.ReadUInt16();
                    int top    = reader.ReadUInt16();
                    int right  = reader.ReadUInt16();
                    int bottom = reader.ReadUInt16();

                    byte info2      = reader.ReadByte();
                    bool interlaced = (info2 & 0x40) != 0;
                    if (info2 >> 7 == 1)
                    {
                        for (int c = 0x80; c < 0x100; ++c)
                        {
                            palette[c].R = reader.ReadByte();
                            palette[c].G = reader.ReadByte();
                            palette[c].B = reader.ReadByte();
                        }
                    }

                    readPictureData(width, height, interlaced, reader);
                }
                break;
                }

                blockType = reader.ReadByte();
            }
            #endregion

            if (!skipHeader)
            {
                reader.Close();
            }
        }