public GifHeaderDirectory Extract([NotNull] SequentialReader reader)
        {
            var directory = new GifHeaderDirectory();

            // FILE HEADER
            //
            // 3 - signature: "GIF"
            // 3 - version: either "87a" or "89a"
            //
            // LOGICAL SCREEN DESCRIPTOR
            //
            // 2 - pixel width
            // 2 - pixel height
            // 1 - screen and color map information flags (0 is LSB)
            //       0-2  Size of the global color table
            //       3    Color table sort flag (89a only)
            //       4-6  Color resolution
            //       7    Global color table flag
            // 1 - background color index
            // 1 - pixel aspect ratio

            reader.IsMotorolaByteOrder = false;

            try
            {
                var signature = reader.GetString(3);
                if (signature != "GIF")
                {
                    directory.AddError("Invalid GIF file signature");
                    return directory;
                }
                var version = reader.GetString(3);
                if (version != Gif87AVersionIdentifier && version != Gif89AVersionIdentifier)
                {
                    directory.AddError("Unexpected GIF version");
                    return directory;
                }
                directory.Set(GifHeaderDirectory.TagGifFormatVersion, version);
                directory.Set(GifHeaderDirectory.TagImageWidth, reader.GetUInt16());
                directory.Set(GifHeaderDirectory.TagImageHeight, reader.GetUInt16());
                var flags = reader.GetByte();
                // First three bits = (BPP - 1)
                var colorTableSize = 1 << ((flags & 7) + 1);
                directory.Set(GifHeaderDirectory.TagColorTableSize, colorTableSize);
                if (version == Gif89AVersionIdentifier)
                {
                    var isColorTableSorted = (flags & 8) != 0;
                    directory.Set(GifHeaderDirectory.TagIsColorTableSorted, isColorTableSorted);
                }
                var bitsPerPixel = ((flags & 0x70) >> 4) + 1;
                directory.Set(GifHeaderDirectory.TagBitsPerPixel, bitsPerPixel);
                var hasGlobalColorTable = (flags & 0xf) != 0;
                directory.Set(GifHeaderDirectory.TagHasGlobalColorTable, hasGlobalColorTable);
                directory.Set(GifHeaderDirectory.TagBackgroundColorIndex, reader.GetByte());
                int aspectRatioByte = reader.GetByte();
                if (aspectRatioByte != 0)
                {
                    var pixelAspectRatio = (float)((aspectRatioByte + 15d) / 64d);
                    directory.Set(GifHeaderDirectory.TagPixelAspectRatio, pixelAspectRatio);
                }
            }
            catch (IOException)
            {
                directory.AddError("Unable to read BMP header");
            }

            return directory;
        }
        /// <summary>Reads the fixed-position GIF header.</summary>
        private static GifHeaderDirectory ReadGifHeader(SequentialReader reader)
        {
            // FILE HEADER
            //
            // 3 - signature: "GIF"
            // 3 - version: either "87a" or "89a"
            //
            // LOGICAL SCREEN DESCRIPTOR
            //
            // 2 - pixel width
            // 2 - pixel height
            // 1 - screen and color map information flags (0 is LSB)
            //       0-2  Size of the global color table
            //       3    Color table sort flag (89a only)
            //       4-6  Color resolution
            //       7    Global color table flag
            // 1 - background color index
            // 1 - pixel aspect ratio

            var headerDirectory = new GifHeaderDirectory();

            var signature = reader.GetString(3, Encoding.UTF8);
            if (signature != "GIF")
            {
                headerDirectory.AddError("Invalid GIF file signature");
                return headerDirectory;
            }

            var version = reader.GetString(3, Encoding.UTF8);
            if (version != Gif87AVersionIdentifier && version != Gif89AVersionIdentifier)
            {
                headerDirectory.AddError($"Unexpected GIF version \"{version}\"");
                return headerDirectory;
            }

            headerDirectory.Set(GifHeaderDirectory.TagGifFormatVersion, version);

            // LOGICAL SCREEN DESCRIPTOR

            headerDirectory.Set(GifHeaderDirectory.TagImageWidth, reader.GetUInt16());
            headerDirectory.Set(GifHeaderDirectory.TagImageHeight, reader.GetUInt16());

            var flags = reader.GetByte();

            // First three bits = (BPP - 1)
            var colorTableSize = 1 << ((flags & 7) + 1);
            var bitsPerPixel = ((flags & 0x70) >> 4) + 1;
            var hasGlobalColorTable = (flags >> 7) != 0;

            headerDirectory.Set(GifHeaderDirectory.TagColorTableSize, colorTableSize);

            if (version == Gif89AVersionIdentifier)
            {
                var isColorTableSorted = (flags & 8) != 0;
                headerDirectory.Set(GifHeaderDirectory.TagIsColorTableSorted, isColorTableSorted);
            }

            headerDirectory.Set(GifHeaderDirectory.TagBitsPerPixel, bitsPerPixel);
            headerDirectory.Set(GifHeaderDirectory.TagHasGlobalColorTable, hasGlobalColorTable);

            headerDirectory.Set(GifHeaderDirectory.TagBackgroundColorIndex, reader.GetByte());

            int aspectRatioByte = reader.GetByte();
            if (aspectRatioByte != 0)
            {
                var pixelAspectRatio = (float)((aspectRatioByte + 15d) / 64d);
                headerDirectory.Set(GifHeaderDirectory.TagPixelAspectRatio, pixelAspectRatio);
            }

            return headerDirectory;
        }
Esempio n. 3
0
        public GifHeaderDirectory Extract([NotNull] SequentialReader reader)
        {
            var directory = new GifHeaderDirectory();

            // FILE HEADER
            //
            // 3 - signature: "GIF"
            // 3 - version: either "87a" or "89a"
            //
            // LOGICAL SCREEN DESCRIPTOR
            //
            // 2 - pixel width
            // 2 - pixel height
            // 1 - screen and color map information flags (0 is LSB)
            //       0-2  Size of the global color table
            //       3    Color table sort flag (89a only)
            //       4-6  Color resolution
            //       7    Global color table flag
            // 1 - background color index
            // 1 - pixel aspect ratio

            reader.IsMotorolaByteOrder = false;

            try
            {
                var signature = reader.GetString(3);
                if (signature != "GIF")
                {
                    directory.AddError("Invalid GIF file signature");
                    return(directory);
                }
                var version = reader.GetString(3);
                if (version != Gif87AVersionIdentifier && version != Gif89AVersionIdentifier)
                {
                    directory.AddError("Unexpected GIF version");
                    return(directory);
                }
                directory.Set(GifHeaderDirectory.TagGifFormatVersion, version);
                directory.Set(GifHeaderDirectory.TagImageWidth, reader.GetUInt16());
                directory.Set(GifHeaderDirectory.TagImageHeight, reader.GetUInt16());
                var flags = reader.GetByte();
                // First three bits = (BPP - 1)
                var colorTableSize = 1 << ((flags & 7) + 1);
                directory.Set(GifHeaderDirectory.TagColorTableSize, colorTableSize);
                if (version == Gif89AVersionIdentifier)
                {
                    var isColorTableSorted = (flags & 8) != 0;
                    directory.Set(GifHeaderDirectory.TagIsColorTableSorted, isColorTableSorted);
                }
                var bitsPerPixel = ((flags & 0x70) >> 4) + 1;
                directory.Set(GifHeaderDirectory.TagBitsPerPixel, bitsPerPixel);
                var hasGlobalColorTable = (flags & 0xf) != 0;
                directory.Set(GifHeaderDirectory.TagHasGlobalColorTable, hasGlobalColorTable);
                directory.Set(GifHeaderDirectory.TagTransparentColorIndex, reader.GetByte());
                int aspectRatioByte = reader.GetByte();
                if (aspectRatioByte != 0)
                {
                    var pixelAspectRatio = (float)((aspectRatioByte + 15d) / 64d);
                    directory.Set(GifHeaderDirectory.TagPixelAspectRatio, pixelAspectRatio);
                }
            }
            catch (IOException)
            {
                directory.AddError("Unable to read BMP header");
            }

            return(directory);
        }