示例#1
0
        private void ConstructorStreamTest(bool xmlDebugging)
        {
            MemoryStream s = CreateStream();

            // Extra stuff not included in the frame stream, to pass to the
            // constructor.
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = WikipediaExample.LogicalScreenDescriptor;

            _frame = new GifFrame(s, lsd, colourTable, ext, null, null, xmlDebugging);

            Assert.AreEqual(ErrorState.Ok, _frame.ConsolidatedState);

            WikipediaExample.CheckImage(_frame.TheImage);
            WikipediaExample.CheckImageDescriptor(_frame.ImageDescriptor);
            WikipediaExample.CheckGraphicControlExtension(_frame.GraphicControlExtension);
            WikipediaExample.CheckImageData(_frame.IndexedPixels);
            Assert.AreEqual(0, _frame.BackgroundColour.R);
            Assert.AreEqual(0, _frame.BackgroundColour.G);
            Assert.AreEqual(0, _frame.BackgroundColour.B);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _frame.DebugXml);
            }
        }
        public void ConstructorTestBackgroundColourIndexTooLarge()
        {
            ReportStart();
            int  width                     = 15;
            int  height                    = 20;
            Size screenSize                = new Size(width, height);
            bool hasGlobalColourTable      = true;
            int  colourResolution          = 6;
            bool colourTableIsSorted       = false;
            int  globalColourTableSizeBits = 3;
            int  backgroundColourIndex     = byte.MaxValue + 1;
            int  pixelAspectRatio          = 2;

            try
            {
                _lsd = new LogicalScreenDescriptor(screenSize,
                                                   hasGlobalColourTable,
                                                   colourResolution,
                                                   colourTableIsSorted,
                                                   globalColourTableSizeBits,
                                                   backgroundColourIndex,
                                                   pixelAspectRatio);
            }
            catch (ArgumentException ex)
            {
                string message
                    = "Background colour index cannot be more than "
                      + byte.MaxValue + ". "
                      + "Supplied value: " + backgroundColourIndex;
                StringAssert.Contains(message, ex.Message);
                Assert.AreEqual("backgroundColourIndex", ex.ParamName);
                ReportEnd();
                throw;
            }
        }
示例#3
0
        /// <summary>
        /// Decodes the supplied GIF stream.
        /// </summary>
        public void Decode()
        {
            _frameDelays           = new List <int>();
            _loadedFrames          = new Queue <GifFrame>();
            _frames                = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _header = new GifHeader(_stream);
            if (_header.ErrorState != ErrorState.Ok)
            {
                return;
            }

            _lsd = new LogicalScreenDescriptor(_stream);
            if (TestState(ErrorState.EndOfInputStream))
            {
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(_stream, _lsd.GlobalColourTableSize);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(_stream);
            }

            ApplyMemoryFields();
        }
 /// <summary>
 /// Checks whether the supplied logical screen descriptor matches that
 /// returned by this class.
 /// </summary>
 /// <param name="lsd"></param>
 internal static void CheckLogicalScreenDescriptor(LogicalScreenDescriptor lsd)
 {
     Assert.AreEqual(BackgroundColourIndex,
                     lsd.BackgroundColourIndex,
                     "BackgroundColourIndex");
     Assert.AreEqual(ColourResolution,
                     lsd.ColourResolution,
                     "ColourResolution");
     Assert.AreEqual(GlobalColourTableSize,
                     lsd.GlobalColourTableSize,
                     "GlobalColourTableSize");
     Assert.AreEqual(GlobalColourTableSizeBits,
                     lsd.GlobalColourTableSizeBits,
                     "GlobalColourTableSizeBits");
     Assert.AreEqual(HasGlobalColourTable,
                     lsd.HasGlobalColourTable,
                     "HasGlobalColourTable");
     Assert.AreEqual(LogicalScreenSize,
                     lsd.LogicalScreenSize,
                     "LogicalScreenSize");
     Assert.AreEqual(PixelAspectRatio,
                     lsd.PixelAspectRatio,
                     "PixelAspectRatio");
     Assert.AreEqual(GlobalColourTableIsSorted,
                     lsd.GlobalColourTableIsSorted,
                     "GlobalColourTableIsSorted");
 }
        private void ConstructorStreamTest(bool xmlDebugging)
        {
            int  width                     = 15;
            int  height                    = 20;
            Size screenSize                = new Size(width, height);
            bool hasGlobalColourTable      = true;
            int  colourResolution          = 6;
            bool colourTableIsSorted       = false;
            int  globalColourTableSizeBits = 3;
            int  backgroundColourIndex     = 12;
            int  pixelAspectRatio          = 2;

            MemoryStream s = new MemoryStream();

            // Write screen width and height, least significant bit first
            s.WriteByte((byte)(width & 0xff));
            s.WriteByte((byte)((width & 0xff00) >> 8));
            s.WriteByte((byte)(height & 0xff));
            s.WriteByte((byte)((height & 0xff00) >> 8));

            // Packed fields:
            //	bit 1 = global colour table flag
            //	bits 2-4 = colour resolution
            //	bit 5 = sort flag
            //	bits 6-8 = global colour table size
            byte packed = (byte)
                          (
                (hasGlobalColourTable ? 1 : 0) << 7
                    | (colourResolution & 7) << 4
                    | (colourTableIsSorted ? 1 : 0) << 3
                    | (globalColourTableSizeBits & 7)
                          );

            s.WriteByte(packed);

            s.WriteByte((byte)backgroundColourIndex);
            s.WriteByte((byte)pixelAspectRatio);

            s.Seek(0, SeekOrigin.Begin);
            _lsd = new LogicalScreenDescriptor(s, xmlDebugging);

            Assert.AreEqual(ErrorState.Ok, _lsd.ConsolidatedState);
            Assert.AreEqual(screenSize, _lsd.LogicalScreenSize);
            Assert.AreEqual(hasGlobalColourTable, _lsd.HasGlobalColourTable);
            Assert.AreEqual(colourResolution, _lsd.ColourResolution);
            Assert.AreEqual(colourTableIsSorted, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(globalColourTableSizeBits,
                            _lsd.GlobalColourTableSizeBits);
            Assert.AreEqual(Math.Pow(2, globalColourTableSizeBits + 1),
                            _lsd.GlobalColourTableSize);
            Assert.AreEqual(backgroundColourIndex, _lsd.BackgroundColourIndex);
            Assert.AreEqual(pixelAspectRatio, _lsd.PixelAspectRatio);
            Assert.AreEqual(ErrorState.Ok, _lsd.ConsolidatedState);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _lsd.DebugXml);
            }
        }
示例#6
0
 public GifFrame(Stream inputStream,
                 LogicalScreenDescriptor lsd,
                 ColourTable gct,
                 GraphicControlExtension gce,
                 GifFrame previousFrame,
                 GifFrame previousFrameBut1)
     : base(inputStream, lsd, gct, gce, previousFrame, previousFrameBut1)
 {
 }
示例#7
0
        public void ConvertFrame()
        {
            for (var i = 0; i < Frames.Count; i++)
            {
                var  index = i;//(int)context;
                var  colorTable = colorTables[index];
                var  localColorTableFlag = (byte)(colorTable == globalColorTable ? 0 : 1);
                var  localColorTableSize = GetColorTableSize(colorTable);
                byte transparentColorFlag = 0, transparentColorIndex = 0;
                byte max;
                var  colorIndexes            = GetColorIndexes(Frames[index].Texture, scale, colorTable, localColorTableFlag, ref transparentColorFlag, ref transparentColorIndex, out max);
                var  graphicControlExtension = new GraphicControlExtension(4, 0, (byte)Frames[index].DisposalMethod, 0, transparentColorFlag, (ushort)(100 * Frames[index].Delay), transparentColorIndex);
                var  imageDescriptor         = new ImageDescriptor(0, 0, Width, Height, localColorTableFlag, 0, 0, 0, localColorTableSize);
                var  minCodeSize             = LzwEncoder.GetMinCodeSize(max);
                var  lzw = LzwEncoder.Encode(colorIndexes, minCodeSize);
                var  tableBasedImageData = new TableBasedImageData(minCodeSize, lzw);
                var  tmpBytes            = new List <byte>();

                tmpBytes.AddRange(graphicControlExtension.GetBytes());
                tmpBytes.AddRange(imageDescriptor.GetBytes());

                if (localColorTableFlag == 1)
                {
                    tmpBytes.AddRange(ColorTableToBytes(colorTable, localColorTableSize));
                }

                tmpBytes.AddRange(tableBasedImageData.GetBytes());


                encoded.Add(index, tmpBytes);
                // encodeProgress.Progress++;

                if (encoded.Count == Frames.Count)
                {
                    var globalColorTableSize    = GetColorTableSize(globalColorTable);
                    var logicalScreenDescriptor = new LogicalScreenDescriptor(Width, Height, 1, 7, 0, globalColorTableSize, 0, 0);
                    var binary = new List <byte>();

                    binary.AddRange(Encoding.UTF8.GetBytes(header));
                    binary.AddRange(logicalScreenDescriptor.GetBytes());
                    binary.AddRange(ColorTableToBytes(globalColorTable, globalColorTableSize));
                    binary.AddRange(applicationExtension.GetBytes());
                    binary.AddRange(encoded.OrderBy(j => j.Key).SelectMany(j => j.Value));
                    binary.Add(0x3B); // GIF Trailer.

                    bytes = binary.ToArray();
                    // encodeProgress.Completed = true;
                }

                // onProgress(encodeProgress);
            }

            currentStep++;
        }
示例#8
0
        public GifImageSource(Stream stream)
        {
            try
            {
                _gifStream = new MemoryStream();
                stream.CopyTo(_gifStream);
                _gifStream.Seek(0, SeekOrigin.Begin);

                using (var reader = new BinaryReader(_gifStream))
                {
                    var gifSign = new string(reader.ReadChars(6));

                    var gif89a = string.Equals(gifSign, "gif89a", StringComparison.OrdinalIgnoreCase);
                    var gif87a = string.Equals(gifSign, "gif87a", StringComparison.OrdinalIgnoreCase);

                    if ((gif87a || gif89a) == false)
                    {
                        return;
                    }

                    _sreenDescriptor = LogicalScreenDescriptor.Read(reader);
                    _globalPalette   = _sreenDescriptor.HasGlobalPalette ? GifPalette.Read(reader, _sreenDescriptor.GlobalPaletteColorCount) : null;

                    while (true)
                    {
                        var ch = reader.ReadChar();

                        if (ch == ';' && reader.BaseStream.Position == reader.BaseStream.Length)
                        {
                            break;
                        }

                        switch (ch)
                        {
                        case '!':
                            SkipExtension(reader);
                            break;

                        case ',':
                            _frames.Add(ReadImage(reader));
                            break;
                        }
                    }
                }

                _isValid = true;
            }
            catch (Exception)
            {
                _isValid = false;
            }
        }
示例#9
0
        /// <summary>
        /// Reads GIF image from stream
        /// </summary>
        /// <param name="inputStream">
        /// Stream containing GIF file.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The supplied stream is null.
        /// </exception>
        private void ReadStream(Stream inputStream)
        {
            _frames = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _readStreamCounterText = "Reading stream byte";
            AddCounter(_readStreamCounterText, (int)inputStream.Length);
            _header = new GifHeader(inputStream, XmlDebugging);
            MyProgressCounters[_readStreamCounterText].Value
                = (int)inputStream.Position;
            WriteDebugXmlNode(_header.DebugXmlReader);
            if (_header.ErrorState != ErrorState.Ok)
            {
                WriteDebugXmlFinish();
                return;
            }

            _lsd = new LogicalScreenDescriptor(inputStream, XmlDebugging);
            MyProgressCounters[_readStreamCounterText].Value
                = (int)inputStream.Position;
            WriteDebugXmlNode(_lsd.DebugXmlReader);
            if (TestState(ErrorState.EndOfInputStream))
            {
                WriteDebugXmlFinish();
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(inputStream,
                                       _lsd.GlobalColourTableSize,
                                       XmlDebugging);
                MyProgressCounters[_readStreamCounterText].Value
                    = (int)inputStream.Position;
                WriteDebugXmlNode(_gct.DebugXmlReader);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(inputStream);
                MyProgressCounters[_readStreamCounterText].Value
                    = (int)inputStream.Position;
            }
            inputStream.Close();
            WriteDebugXmlFinish();
            RemoveCounter(_readStreamCounterText);
        }
示例#10
0
        CheckLogicalScreenDescriptor(Stream s,
                                     bool shouldHaveGlobalColourTable)
        {
            // check logical screen descriptor
            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor(s);

            Assert.AreEqual(ErrorState.Ok,
                            lsd.ConsolidatedState,
                            "Logical screen descriptor consolidated state");
            Assert.AreEqual(new Size(2, 2),
                            lsd.LogicalScreenSize,
                            "Logical screen size");
            Assert.AreEqual(shouldHaveGlobalColourTable,
                            lsd.HasGlobalColourTable,
                            "Should have global colour table");
            Assert.AreEqual(false,
                            lsd.GlobalColourTableIsSorted,
                            "Global colour table is sorted");
            return(lsd);
        }
示例#11
0
        public void ConstructorStreamNullLogicalScreenDescriptorTest()
        {
            MemoryStream s = CreateStream();

            // Extra stuff not included in the frame stream, to pass to the
            // constructor
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = null;

            try
            {
                _frame = new GifFrame(s, lsd, colourTable, ext, null, null);
            }
            catch (ArgumentNullException ex)
            {
                Assert.AreEqual("lsd", ex.ParamName);
                throw;
            }
        }
示例#12
0
        private void WriteLogicalScreenDescriptor(LogicalScreenDescriptor screen)
        {
            var colorTableSizeIndex = ColorTable.TableSizes.IndexOf(screen.SizeOfGlobalColorTable);

            var data = new byte[7];

            data[0] = (byte)(screen.Width & 0xFF);
            data[1] = (byte)((screen.Width & 0xFF00) >> 8);
            data[2] = (byte)(screen.Height & 0xFF);
            data[3] = (byte)((screen.Height & 0xFF00) >> 8);
            data[4] = (byte)((screen.GlobalColorTableFlag ? 1 : 0) << 7 |
                             (screen.ColorResolution - 1) << 4 |
                             (screen.SortFlag ? 1 : 0) << 3 |
                             colorTableSizeIndex);
            data[5] = (byte)screen.BackgroundColorIndex;
            data[6] = screen.PixelAspectRatio == null
                ? byte.MinValue
                : (byte)Math.Min(Math.Max((int)Math.Round(screen.PixelAspectRatio.Value * 64 - 15), byte.MinValue + 1), byte.MaxValue);

            this.output.Write(data, 0, data.Length);
        }
示例#13
0
        private void ConstructorStreamNoImageDataTest(bool xmlDebugging)
        {
            MemoryStream s = new MemoryStream();

            // Image descriptor
            byte[] idBytes = WikipediaExample.ImageDescriptorBytes;
            s.Write(idBytes, 0, idBytes.Length);

            // miss out the image data
//			// Table-based image data
//			byte[] imageData = WikipediaExample.ImageDataBytes;
//			s.Write( imageData, 0, imageData.Length );
            byte[] imageData = new byte[]
            {
                0x08,                 // LZW minimum code size
//				0x00, // block size = 11
//				// 11 bytes of LZW encoded data follows
//				0x00, 0x01, 0x04, 0x18, 0x28, 0x70, 0xA0, 0xC1, 0x83, 0x01, 0x01,
                0x00                 // block terminator
            };
            s.Write(imageData, 0, imageData.Length);

            s.Seek(0, SeekOrigin.Begin);

            // Extra stuff not included in the frame stream, to pass to the
            // constructor
            ColourTable             colourTable = WikipediaExample.GlobalColourTable;
            GraphicControlExtension ext         = WikipediaExample.GraphicControlExtension;
            LogicalScreenDescriptor lsd         = WikipediaExample.LogicalScreenDescriptor;

            _frame = new GifFrame(s, lsd, colourTable, ext, null, null, xmlDebugging);

            Assert.AreEqual(ErrorState.TooFewPixelsInImageData,
                            _frame.ConsolidatedState);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _frame.DebugXml);
            }
        }
        /// <summary>
        /// Populates the Logical Screen Descriptor byte[] from the source image, and performs lexical parsing on the array.
        /// </summary>
        /// <param name="bytes"></param>
        public static LogicalScreenDescriptor ParseLogicalScreenDescriptor(byte[] bytes)
        {
            string packedField          = Convert.ToString(bytes[4], 2).PadLeft(8, '0');
            int    globalColorTableSize = Convert.ToInt32(packedField.Substring(5, 3), 2);

            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor()
            {
                Bytes                  = (byte[])bytes.Clone(),
                CanvasWidth            = BitConverter.ToInt32(new byte[] { bytes[0], bytes[1], 0, 0 }, 0),
                CanvasHeight           = BitConverter.ToInt32(new byte[] { bytes[2], bytes[3], 0, 0 }, 0),
                PackedField            = packedField,
                HasGlobalColorTable    = packedField.Substring(0, 1) == "1",
                ColorResolution        = Convert.ToInt32(packedField.Substring(1, 3), 2),
                SortFlag               = packedField.Substring(4, 1) == "1",
                GlobalColorTableSize   = globalColorTableSize,
                GlobalColorTableLength = 3 * (int)(Math.Pow(2, globalColorTableSize + 1)), // 3 * (2 ^ (n + 1)), where n equals the GlobalColorTableSize
                BackgroundColorIndex   = bytes[5],
                PixelAspectRatio       = bytes[6]
            };

            return(lsd);
        }
        private void ConstructorStreamEndOfStreamTest(bool xmlDebugging)
        {
            Size screenSize                = new Size(12, 4);
            bool hasGlobalColourTable      = false;
            int  colourResolution          = 3;
            bool globalColourTableIsSorted = true;
            int  globalColourTableSizeBits = 4;
            int  backgroundColourIndex     = 2;
            int  pixelAspectRatio          = 1;

            _lsd = new LogicalScreenDescriptor(screenSize,
                                               hasGlobalColourTable,
                                               colourResolution,
                                               globalColourTableIsSorted,
                                               globalColourTableSizeBits,
                                               backgroundColourIndex,
                                               pixelAspectRatio);

            MemoryStream s = new MemoryStream();

            _lsd.WriteToStream(s);
            s.SetLength(s.Length - 1);               // remove final byte from stream
            s.Seek(0, SeekOrigin.Begin);
            _lsd = new LogicalScreenDescriptor(s, xmlDebugging);

            Assert.AreEqual(ErrorState.EndOfInputStream, _lsd.ConsolidatedState);
            Assert.AreEqual(screenSize, _lsd.LogicalScreenSize);
            Assert.AreEqual(hasGlobalColourTable, _lsd.HasGlobalColourTable);
            Assert.AreEqual(colourResolution, _lsd.ColourResolution);
            Assert.AreEqual(globalColourTableIsSorted, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(globalColourTableSizeBits, _lsd.GlobalColourTableSizeBits);
            Assert.AreEqual(backgroundColourIndex, _lsd.BackgroundColourIndex);
            Assert.AreEqual(-1, _lsd.PixelAspectRatio);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _lsd.DebugXml);
            }
        }
        public void WriteToStreamTest()
        {
            ReportStart();

            Size screenSize                = new Size(12, 4);
            bool hasGlobalColourTable      = false;
            int  colourResolution          = 3;
            bool globalColourTableIsSorted = true;
            int  globalColourTableSizeBits = 4;
            int  backgroundColourIndex     = 2;
            int  pixelAspectRatio          = 1;

            _lsd = new LogicalScreenDescriptor(screenSize,
                                               hasGlobalColourTable,
                                               colourResolution,
                                               globalColourTableIsSorted,
                                               globalColourTableSizeBits,
                                               backgroundColourIndex,
                                               pixelAspectRatio);

            MemoryStream s = new MemoryStream();

            _lsd.WriteToStream(s);
            s.Seek(0, SeekOrigin.Begin);
            _lsd = new LogicalScreenDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, _lsd.ConsolidatedState);
            Assert.AreEqual(screenSize, _lsd.LogicalScreenSize);
            Assert.AreEqual(hasGlobalColourTable, _lsd.HasGlobalColourTable);
            Assert.AreEqual(colourResolution, _lsd.ColourResolution);
            Assert.AreEqual(globalColourTableIsSorted, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(globalColourTableSizeBits, _lsd.GlobalColourTableSizeBits);
            Assert.AreEqual(backgroundColourIndex, _lsd.BackgroundColourIndex);
            Assert.AreEqual(pixelAspectRatio, _lsd.PixelAspectRatio);

            ReportEnd();
        }
示例#17
0
        /// <summary>
        /// Reads GIF image from stream
        /// </summary>
        /// <param name="inputStream">
        /// Stream containing GIF file.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The supplied stream is null.
        /// </exception>
        private void ReadStream(Stream inputStream)
        {
            _frames = new Collection <GifFrame>();
            _applicationExtensions = new Collection <ApplicationExtension>();
            _gct = null;

            _header = new GifHeader(inputStream, XmlDebugging);
            WriteDebugXmlNode(_header.DebugXmlReader);
            if (_header.ErrorState != ErrorState.Ok)
            {
                WriteDebugXmlFinish();
                return;
            }

            _lsd = new LogicalScreenDescriptor(inputStream, XmlDebugging);
            WriteDebugXmlNode(_lsd.DebugXmlReader);
            if (TestState(ErrorState.EndOfInputStream))
            {
                WriteDebugXmlFinish();
                return;
            }

            if (_lsd.HasGlobalColourTable)
            {
                _gct = new ColourTable(inputStream,
                                       _lsd.GlobalColourTableSize,
                                       XmlDebugging);
                WriteDebugXmlNode(_gct.DebugXmlReader);
            }

            if (ConsolidatedState == ErrorState.Ok)
            {
                ReadContents(inputStream);
            }
            inputStream.Close();
            WriteDebugXmlFinish();
        }
        public void ConstructorTest()
        {
            ReportStart();

            int  width                     = 15;
            int  height                    = 20;
            Size screenSize                = new Size(width, height);
            bool hasGlobalColourTable      = true;
            int  colourResolution          = 6;
            bool colourTableIsSorted       = false;
            int  globalColourTableSizeBits = 3;
            int  backgroundColourIndex     = 12;
            int  pixelAspectRatio          = 2;

            _lsd = new LogicalScreenDescriptor(screenSize,
                                               hasGlobalColourTable,
                                               colourResolution,
                                               colourTableIsSorted,
                                               globalColourTableSizeBits,
                                               backgroundColourIndex,
                                               pixelAspectRatio);

            Assert.AreEqual(screenSize, _lsd.LogicalScreenSize);
            Assert.AreEqual(hasGlobalColourTable, _lsd.HasGlobalColourTable);
            Assert.AreEqual(colourResolution, _lsd.ColourResolution);
            Assert.AreEqual(colourTableIsSorted, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(globalColourTableSizeBits,
                            _lsd.GlobalColourTableSizeBits);
            Assert.AreEqual(Math.Pow(2, globalColourTableSizeBits + 1),
                            _lsd.GlobalColourTableSize);
            Assert.AreEqual(backgroundColourIndex, _lsd.BackgroundColourIndex);
            Assert.AreEqual(pixelAspectRatio, _lsd.PixelAspectRatio);
            Assert.AreEqual(ErrorState.Ok, _lsd.ConsolidatedState);

            ReportEnd();
        }
示例#19
0
 /// <summary>
 /// 写逻辑屏幕标识符
 /// </summary>
 /// <param name="lsd"></param>
 internal void WriteLSD(LogicalScreenDescriptor lsd)
 {
     WriteBytes(lsd.GetBuffer());
 }
示例#20
0
        /// <summary>
        /// Encode GIF in multiple threads.
        /// </summary>
        public void EncodeParallel(Action <EncodeProgress> onProgress, int scale = 1)        // TODO: Refact.
        {
            if (_free)
            {
                throw new Exception("The Free version doesn't support this feature. Please consider buying the Full version of Power GIF.");
            }

            const string header               = "GIF89a";
            var          width                = (ushort)(Frames[0].Texture.width * scale);
            var          height               = (ushort)(Frames[0].Texture.height * scale);
            var          globalColorTable     = new List <Color32>();
            var          applicationExtension = new ApplicationExtension();
            var          encoded              = new Dictionary <int, List <byte> >();
            var          encodeProgress       = new EncodeProgress {
                FrameCount = Frames.Count
            };
            var colorTables      = new List <Color32> [Frames.Count];
            var distinctColors   = new Dictionary <int, List <Color32> >();
            var manualResetEvent = new ManualResetEvent(false);

            for (var i = 0; i < Frames.Count; i++)
            {
                var frame = Frames[i];

                ThreadPool.QueueUserWorkItem(context =>
                {
                    var distinct = frame.Texture.GetPixels32().Distinct().ToList();

                    lock (distinctColors)
                    {
                        distinctColors.Add((int)context, distinct);

                        if (distinctColors.Count == Frames.Count)
                        {
                            manualResetEvent.Set();
                        }
                    }
                }, i);
            }

            manualResetEvent.WaitOne();

            for (var i = 0; i < Frames.Count; i++)
            {
                var colors = distinctColors[i];
                var add    = colors.Where(j => !globalColorTable.Contains(j)).ToList();

                if (globalColorTable.Count + add.Count <= 256)
                {
                    globalColorTable.AddRange(add);
                    colorTables[i] = globalColorTable;
                }
                else if (colors.Count <= 256)                 // Introduce local color table.
                {
                    colorTables[i] = colors;
                }
                else
                {
                    onProgress(new EncodeProgress {
                        Completed = true, Exception = new Exception($"Frame #{i} contains more than 256 colors!")
                    });
                    return;
                }
            }

            ReplaceTransparentColor(ref globalColorTable);

            for (var i = 0; i < Frames.Count; i++)             // Don't use Parallel.For to leave .NET compatibility.
            {
                ThreadPool.QueueUserWorkItem(context =>
                {
                    var index                 = (int)context;
                    var colorTable            = colorTables[index];
                    var localColorTableFlag   = (byte)(colorTable == globalColorTable ? 0 : 1);
                    var localColorTableSize   = GetColorTableSize(colorTable);
                    byte transparentColorFlag = 0, transparentColorIndex = 0;
                    byte max;
                    var colorIndexes            = GetColorIndexes(Frames[index].Texture, scale, colorTable, localColorTableFlag, ref transparentColorFlag, ref transparentColorIndex, out max);
                    var graphicControlExtension = new GraphicControlExtension(4, 0, (byte)Frames[index].DisposalMethod, 0, transparentColorFlag, (ushort)(100 * Frames[index].Delay), transparentColorIndex);
                    var imageDescriptor         = new ImageDescriptor(0, 0, width, height, localColorTableFlag, 0, 0, 0, localColorTableSize);
                    var minCodeSize             = LzwEncoder.GetMinCodeSize(max);
                    var lzw = LzwEncoder.Encode(colorIndexes, minCodeSize);
                    var tableBasedImageData = new TableBasedImageData(minCodeSize, lzw);
                    var bytes = new List <byte>();

                    bytes.AddRange(graphicControlExtension.GetBytes());
                    bytes.AddRange(imageDescriptor.GetBytes());

                    if (localColorTableFlag == 1)
                    {
                        bytes.AddRange(ColorTableToBytes(colorTable, localColorTableSize));
                    }

                    bytes.AddRange(tableBasedImageData.GetBytes());

                    lock (encoded)
                    {
                        encoded.Add(index, bytes);
                        encodeProgress.Progress++;

                        if (encoded.Count == Frames.Count)
                        {
                            var globalColorTableSize    = GetColorTableSize(globalColorTable);
                            var logicalScreenDescriptor = new LogicalScreenDescriptor(width, height, 1, 7, 0, globalColorTableSize, 0, 0);
                            var binary = new List <byte>();

                            binary.AddRange(Encoding.UTF8.GetBytes(header));
                            binary.AddRange(logicalScreenDescriptor.GetBytes());
                            binary.AddRange(ColorTableToBytes(globalColorTable, globalColorTableSize));
                            binary.AddRange(applicationExtension.GetBytes());
                            binary.AddRange(encoded.OrderBy(j => j.Key).SelectMany(j => j.Value));
                            binary.Add(0x3B);                         // GIF Trailer.

                            encodeProgress.Bytes     = binary.ToArray();
                            encodeProgress.Completed = true;
                        }

                        onProgress(encodeProgress);
                    }
                }, i);
            }
        }
示例#21
0
        public void WikipediaExampleTest()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            GifFrame frame = new GifFrame(WikipediaExample.ExpectedBitmap);

            frame.Delay = WikipediaExample.DelayTime;
            _e.AddFrame(frame);

            // TODO: some way of creating/testing a UseLocal version of WikipediaExample
            string fileName = "WikipediaExampleUseGlobal.gif";

            _e.WriteToFile(fileName);
            Stream s = File.OpenRead(fileName);

            int code;

            // check GIF header
            GifHeader gh = new GifHeader(s);

            Assert.AreEqual(ErrorState.Ok, gh.ConsolidatedState);

            // check logical screen descriptor
            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, lsd.ConsolidatedState);
            WikipediaExample.CheckLogicalScreenDescriptor(lsd);

            // read global colour table
            ColourTable gct
                = new ColourTable(s, WikipediaExample.GlobalColourTableSize);

            Assert.AreEqual(ErrorState.Ok, gct.ConsolidatedState);
            // cannot compare global colour table as different encoders will
            // produce difference colour tables.
//			WikipediaExample.CheckGlobalColourTable( gct );

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for app extension label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeApplicationExtensionLabel, code);

            // check netscape extension
            ApplicationExtension ae = new ApplicationExtension(s);

            Assert.AreEqual(ErrorState.Ok, ae.ConsolidatedState);
            NetscapeExtension ne = new NetscapeExtension(ae);

            Assert.AreEqual(ErrorState.Ok, ne.ConsolidatedState);
            Assert.AreEqual(0, ne.LoopCount);

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for gce label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeGraphicControlLabel, code);

            // check graphic control extension
            GraphicControlExtension gce = new GraphicControlExtension(s);

            Assert.AreEqual(ErrorState.Ok, gce.ConsolidatedState);
            WikipediaExample.CheckGraphicControlExtension(gce);

            // check for image separator
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeImageSeparator, code);

            // check for image descriptor
            ImageDescriptor id = new ImageDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, id.ConsolidatedState);
            WikipediaExample.CheckImageDescriptor(id);

            // read, decode and check image data
            // Cannot compare encoded LZW data directly as different encoders
            // will create different colour tables, so even if the bitmaps are
            // identical, the colour indices will be different
            int pixelCount = WikipediaExample.FrameSize.Width
                             * WikipediaExample.FrameSize.Height;
            TableBasedImageData tbid = new TableBasedImageData(s, pixelCount);

            for (int y = 0; y < WikipediaExample.LogicalScreenSize.Height; y++)
            {
                for (int x = 0; x < WikipediaExample.LogicalScreenSize.Width; x++)
                {
                    int i = (y * WikipediaExample.LogicalScreenSize.Width) + x;
                    Assert.AreEqual(WikipediaExample.ExpectedBitmap.GetPixel(x, y),
                                    gct[tbid.Pixels[i]],
                                    "X: " + x + ", Y: " + y);
                }
            }

            // Check for block terminator after image data
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(0x00, code);

            // check for GIF trailer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeTrailer, code);

            // check we're at the end of the stream
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(-1, code);
            s.Close();

            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);
            BitmapAssert.AreEqual(WikipediaExample.ExpectedBitmap,
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "");
            ReportEnd();
        }
示例#22
0
 /// <summary>
 /// 从文件数据流中读取图形控制扩展(Graphic Control Extension)
 /// </summary>
 /// <param name="stream"></param>
 /// <returns></returns>
 internal LogicalScreenDescriptor GetLCD(Stream stream)
 {
     LogicalScreenDescriptor lcd = new LogicalScreenDescriptor();
     lcd.Width = ReadShort();
     lcd.Height = ReadShort();
     lcd.Packed = (byte)Read();
     lcd.GlobalColorTableFlag = ((lcd.Packed & 0x80) >> 7) == 1;
     lcd.ColorResoluTion = (byte)((lcd.Packed & 0x60) >> 5);
     lcd.SortFlag = (byte)(lcd.Packed & 0x10) >> 4;
     lcd.GlobalColorTableSize = 2 << (lcd.Packed & 0x07);
     lcd.BgColorIndex = (byte)Read();
     lcd.PixcelAspect = (byte)Read();
     return lcd;
 }
示例#23
0
        /// <summary>
        /// Iterator can be used for large GIF-files in order to display progress bar.
        /// </summary>
        public IEnumerable <List <byte> > EncodeIterator(int scale = 1)
        {
            if (_free)
            {
                if (Frames[0].Texture.width > 256 || Frames[0].Texture.height > 256)
                {
                    throw new Exception("The free version has maximum supported size 256x256 px. Please consider buying the Full version of Power GIF.");
                }
                if (Frames.Count > 20)
                {
                    throw new Exception("The Free version is limited by 20 frames. Please consider buying the Full version of Power GIF.");
                }
            }

            const string header               = "GIF89a";
            var          width                = (ushort)(Frames[0].Texture.width * scale);
            var          height               = (ushort)(Frames[0].Texture.height * scale);
            var          globalColorTable     = new List <Color32>();
            var          applicationExtension = new ApplicationExtension();
            var          bytes                = new List <byte>();
            var          colorTables          = new List <Color32> [Frames.Count];
            var          distinctColors       = new Dictionary <int, List <Color32> >();
            var          manualResetEvent     = new ManualResetEvent(false);

            for (var i = 0; i < Frames.Count; i++)
            {
                var frame = Frames[i];

                ThreadPool.QueueUserWorkItem(context =>
                {
                    var distinct = frame.Texture.GetPixels32().Distinct().ToList();

                    lock (distinctColors)
                    {
                        distinctColors.Add((int)context, distinct);

                        if (distinctColors.Count == Frames.Count)
                        {
                            manualResetEvent.Set();
                        }
                    }
                }, i);
            }

            manualResetEvent.WaitOne();

            for (var i = 0; i < Frames.Count; i++)
            {
                var colors = distinctColors[i];
                var add    = colors.Where(j => !globalColorTable.Contains(j)).ToList();

                if (globalColorTable.Count + add.Count <= 256)
                {
                    globalColorTable.AddRange(add);
                    colorTables[i] = globalColorTable;
                }
                else if (add.Count <= 256)                 // Introducing local color table
                {
                    colorTables[i] = colors;
                }
                else
                {
                    throw new Exception($"Frame #{i} contains more than 256 colors!");
                }
            }

            ReplaceTransparentColor(ref globalColorTable);

            for (var i = 0; i < Frames.Count; i++)
            {
                var  frame = Frames[i];
                var  colorTable = colorTables[i];
                var  localColorTableFlag = (byte)(colorTable == globalColorTable ? 0 : 1);
                var  localColorTableSize = GetColorTableSize(colorTable);
                byte transparentColorFlag = 0, transparentColorIndex = 0;
                byte max;
                var  colorIndexes            = GetColorIndexes(frame.Texture, scale, colorTable, localColorTableFlag, ref transparentColorFlag, ref transparentColorIndex, out max);
                var  graphicControlExtension = new GraphicControlExtension(4, 0, (byte)frame.DisposalMethod, 0, transparentColorFlag, (ushort)(100 * frame.Delay), transparentColorIndex);
                var  imageDescriptor         = new ImageDescriptor(0, 0, width, height, localColorTableFlag, 0, 0, 0, localColorTableSize);
                var  minCodeSize             = LzwEncoder.GetMinCodeSize(max);
                var  lzw = LzwEncoder.Encode(colorIndexes, minCodeSize);
                var  tableBasedImageData = new TableBasedImageData(minCodeSize, lzw);

                bytes.Clear();
                bytes.AddRange(graphicControlExtension.GetBytes());
                bytes.AddRange(imageDescriptor.GetBytes());

                if (localColorTableFlag == 1)
                {
                    bytes.AddRange(ColorTableToBytes(colorTable, localColorTableSize));
                }

                bytes.AddRange(tableBasedImageData.GetBytes());

                yield return(bytes);
            }

            yield return(new List <byte> {
                0x3B
            });                                               // GIF Trailer.

            // Then output GIF header as last iterator element! This way we can build global color table "on fly" instead of expensive building operation.

            var globalColorTableSize    = GetColorTableSize(globalColorTable);
            var logicalScreenDescriptor = new LogicalScreenDescriptor(width, height, 1, 7, 0, globalColorTableSize, 0, 0);

            bytes.Clear();
            bytes.AddRange(Encoding.UTF8.GetBytes(header));
            bytes.AddRange(logicalScreenDescriptor.GetBytes());
            bytes.AddRange(ColorTableToBytes(globalColorTable, globalColorTableSize));
            bytes.AddRange(applicationExtension.GetBytes());

            yield return(bytes);
        }
示例#24
0
        /// <summary>
        /// Tests the AnimatedGifEncoder and the encoded GIF file it produces
        /// using the supplied parameters as property values.
        /// </summary>
        private void TestAnimatedGifEncoder(ColourTableStrategy strategy,
                                            int colourQuality,
                                            Size logicalScreenSize)
        {
            _e = new AnimatedGifEncoder();

            // Check default properties set by constructor.
            Assert.AreEqual(ColourTableStrategy.UseGlobal,
                            _e.ColourTableStrategy,
                            "Colour table strategy set by constructor");
            Assert.AreEqual(10,
                            _e.SamplingFactor,
                            "Colour quantization quality set by constructor");
            Assert.AreEqual(Size.Empty,
                            _e.LogicalScreenSize,
                            "Logical screen size set by constructor");

            _e.ColourTableStrategy = strategy;
            _e.SamplingFactor      = colourQuality;
            _e.LogicalScreenSize   = logicalScreenSize;

            // Check property set/gets
            Assert.AreEqual(strategy,
                            _e.ColourTableStrategy,
                            "Colour table strategy property set/get");
            Assert.AreEqual(colourQuality,
                            _e.SamplingFactor,
                            "Colour quantization quality property set/get");
            Assert.AreEqual(logicalScreenSize,
                            _e.LogicalScreenSize,
                            "Logical screen size property get/set");

            foreach (GifFrame thisFrame in _frames)
            {
                _e.AddFrame(thisFrame);
            }

            StackTrace t = new StackTrace();
            StackFrame f = t.GetFrame(1);
            string     fileName
                = "Checks." + this.GetType().Name
                  + "." + f.GetMethod().Name + ".gif";

            _e.WriteToFile(fileName);

            Stream s = File.OpenRead(fileName);

            // global info
            CheckGifHeader(s);
            bool shouldHaveGlobalColourTable
                = (strategy == ColourTableStrategy.UseGlobal);
            LogicalScreenDescriptor lsd
                = CheckLogicalScreenDescriptor(s, shouldHaveGlobalColourTable);

            // Only check the global colour table if there should be one
            ColourTable gct = null;

            if (shouldHaveGlobalColourTable)
            {
                gct = CheckColourTable(s, lsd.GlobalColourTableSize);
            }

            CheckExtensionIntroducer(s);
            CheckAppExtensionLabel(s);
            CheckNetscapeExtension(s, 0);

            CheckFrame(s, gct, Bitmap1());
            CheckFrame(s, gct, Bitmap2());

            // end of image data
            CheckGifTrailer(s);
            CheckEndOfStream(s);
            s.Close();

            // Check the file using the decoder
            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok,
                            _d.ConsolidatedState,
                            "Decoder consolidated state");
            Assert.AreEqual(2, _d.Frames.Count, "Decoder frame count");
            Assert.AreEqual(shouldHaveGlobalColourTable,
                            _d.LogicalScreenDescriptor.HasGlobalColourTable,
                            "Should have global colour table");
            Assert.AreEqual(logicalScreenSize,
                            _d.LogicalScreenDescriptor.LogicalScreenSize,
                            "Decoder logical screen size");

            BitmapAssert.AreEqual(Bitmap1(),
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "frame 0");
            BitmapAssert.AreEqual(Bitmap2(),
                                  (Bitmap)_d.Frames[1].TheImage,
                                  "frame 1");

            bool shouldHaveLocalColourTable = !shouldHaveGlobalColourTable;

            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[0].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[1].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
        }
示例#25
0
        /// <summary>
        /// 合并多个gif动画,在空间坐标上
        /// </summary>
        /// <param name="sourceGifs">原图像</param>
        /// <param name="outPath">合并后图像</param>
        public static void Merge(List <string> sourceGifs, string outPath)
        {
            List <List <GifFrame> > frames = new List <List <GifFrame> >();

            foreach (string source in sourceGifs)
            {
                if (!File.Exists(source))
                {
                    throw new IOException(string.Format("文件{0}不存在!", source));
                }
                using (Bitmap ora_Img = new Bitmap(source))
                {
                    if (ora_Img.RawFormat.Guid != ImageFormat.Gif.Guid)
                    {
                        throw new IOException(string.Format("文件{0}!", source));
                    }
                }
                GifImage gifImage = GifDecoder.Decode(source);
                ThinkDisposalMethod(gifImage);
                int index = 0;
                foreach (GifFrame f in gifImage.Frames)
                {
                    if (frames.Count <= index)
                    {
                        List <GifFrame> list = new List <GifFrame>();
                        frames.Add(list);
                    }
                    List <GifFrame> frameList = frames[index];
                    frameList.Add(f);
                    index++;
                }
            }
            List <GifFrame> frameCol   = new List <GifFrame>();
            int             frameIndex = 0;

            foreach (List <GifFrame> fs in frames)
            {
                GifFrame frame = Merge(fs);
                frameCol.Add(frame);
                if (frame.Image.Width != frameCol[0].Image.Width ||
                    frame.Image.Height != frameCol[0].Image.Height)
                {
                    frame.ImageDescriptor.XOffSet         = frames[frameIndex][0].ImageDescriptor.XOffSet;
                    frame.ImageDescriptor.YOffSet         = frames[frameIndex][0].ImageDescriptor.YOffSet;
                    frame.GraphicExtension.DisposalMethod = frames[frameIndex][0].GraphicExtension.DisposalMethod;
                }
                frame.GraphicExtension.Delay = frame.Delay = frames[frameIndex][0].Delay;
                frameIndex++;
            }
            GifImage gifImg = new GifImage();

            gifImg.Header = "GIF89a";
            LogicalScreenDescriptor lcd = new LogicalScreenDescriptor();

            lcd.Width  = (short)frameCol[0].Image.Width;
            lcd.Height = (short)frameCol[0].Image.Height;
            gifImg.LogicalScreenDescriptor = lcd;
            ApplicationEx        ape  = new ApplicationEx();
            List <ApplicationEx> apps = new List <ApplicationEx>();

            apps.Add(ape);
            gifImg.ApplictionExtensions = apps;
            gifImg.Frames = frameCol;
            GifEncoder.Encode(gifImg, outPath);
        }
示例#26
0
        private void DecodeRotatingGlobe(bool xmlDebugging)
        {
            string fileName
                = @"images\globe\spinning globe better 200px transparent background.gif";

            _decoder = new GifDecoder(fileName, xmlDebugging);
            WriteMessage("Started decoding. XmlDebugging=" + xmlDebugging);
            _decoder.Decode();
            WriteMessage("Finished decoding. XmlDebugging=" + xmlDebugging);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _decoder.DebugXml);
            }

            _lsd = _decoder.LogicalScreenDescriptor;
            int expectedColourTableSize = 64;

            Assert.AreEqual(ErrorState.Ok, _decoder.ConsolidatedState);
            Assert.AreEqual("GIF", _decoder.Header.Signature);
            Assert.AreEqual("89a", _decoder.Header.Version);
            Assert.IsNotNull(_decoder.GlobalColourTable);
            Assert.AreEqual(true, _lsd.HasGlobalColourTable);
            Assert.AreEqual(expectedColourTableSize,
                            _lsd.GlobalColourTableSize);
            Assert.AreEqual(expectedColourTableSize,
                            _decoder.GlobalColourTable.Length);
            Assert.AreEqual(2, _lsd.ColourResolution);
            Assert.AreEqual(Color.FromArgb(255, 255, 255, 255),
                            _decoder.BackgroundColour);
            Assert.AreEqual(63, _lsd.BackgroundColourIndex);
            Assert.AreEqual(false, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(200, _lsd.LogicalScreenSize.Width);
            Assert.AreEqual(191, _lsd.LogicalScreenSize.Height);
            Assert.AreEqual(0, _lsd.PixelAspectRatio);
            Assert.AreEqual(0, _decoder.NetscapeExtension.LoopCount);
            Assert.AreEqual(ErrorState.Ok, _decoder.ErrorState);
            Assert.AreEqual(20, _decoder.Frames.Count);
            int    frameNumber = 0;
            string frameId;

            foreach (GifFrame thisFrame in _decoder.Frames)
            {
                frameId = "Frame " + frameNumber;
                Assert.IsNull(thisFrame.LocalColourTable, frameId);
                Assert.AreEqual(10, thisFrame.Delay, frameId);

                #region image descriptor tests
                ImageDescriptor descriptor = thisFrame.ImageDescriptor;
                Assert.AreEqual(false, descriptor.HasLocalColourTable, frameId);
                Assert.AreEqual(2,
                                descriptor.LocalColourTableSize,
                                frameId);
                Assert.AreEqual(200, descriptor.Size.Width, frameId);
                Assert.AreEqual(191, descriptor.Size.Height, frameId);
                Assert.AreEqual(0, descriptor.Position.X, frameId);
                Assert.AreEqual(0, descriptor.Position.Y, frameId);
                Assert.AreEqual(false, descriptor.IsInterlaced, frameId);
                Assert.AreEqual(false, descriptor.IsSorted, frameId);
                #endregion

                #region graphic control extension tests
                GraphicControlExtension gce = thisFrame.GraphicControlExtension;
                Assert.AreEqual(4, gce.BlockSize, frameId);
                Assert.AreEqual(10, gce.DelayTime, frameId);
                if (frameNumber == 19)
                {
                    Assert.AreEqual(DisposalMethod.DoNotDispose,
                                    gce.DisposalMethod, frameId);
                }
                else
                {
                    Assert.AreEqual(DisposalMethod.RestoreToBackgroundColour,
                                    gce.DisposalMethod, frameId);
                }
                Assert.AreEqual(63, gce.TransparentColourIndex, frameId);
                Assert.IsTrue(gce.HasTransparentColour, frameId);
                Assert.IsFalse(gce.ExpectsUserInput, frameId);
                #endregion

                frameNumber++;
            }

            CompareFrames(fileName);
        }
示例#27
0
        /// <summary>
        /// Writes a Logical Screen Descriptor to the supplied stream.
        /// Also writes a global colour table if required.
        /// </summary>
        /// <param name="outputStream">
        /// The stream to write to.
        /// </param>
        private void WriteLogicalScreenDescriptor(Stream outputStream)
        {
            bool hasGlobalColourTable      = _strategy == ColourTableStrategy.UseGlobal;
            int  colourResolution          = 7;     // TODO: parameterise colourResolution?
            bool globalColourTableIsSorted = false; // Sorting of colour tables is not currently supported
            int  backgroundColorIndex      = 0;     // TODO: parameterise backgroundColourIndex?
            int  pixelAspectRatio          = 0;     // TODO: parameterise pixelAspectRatio?

            if (_strategy == ColourTableStrategy.UseGlobal)
            {
                if (_quantizerType == QuantizerType.UseSuppliedPalette)
                {
                    // use supplied palette
                    _globalColourTable = new ColourTable();
                    //AddCounter( buildColourTableCounterText,
                    //   _palette.Count );
                    int paletteIndex = 0;
                    foreach (Color c in _palette)
                    {
                        _globalColourTable.Add(c);
                        //MyProgressCounters[buildColourTableCounterText].Value
                        //= paletteIndex;
                        paletteIndex++;
                    }
                    _globalColourTable.Pad();
                    //RemoveCounter( buildColourTableCounterText );
                }
                else
                {
                    // Analyse the pixels in all the images to build the
                    // global colour table.
                    Collection <Image> images = new Collection <Image>();
                    foreach (GifFrame thisFrame in _frames)
                    {
                        Image thisImage = thisFrame.TheImage;
                        images.Add(thisImage);
                    }
                    _pixelAnalysis = new PixelAnalysis(images);
                    _pixelAnalysis.ColourQuality = _quality;
                    _pixelAnalysis.Analyse();
                    _globalColourTable = _pixelAnalysis.ColourTable;
                }
                LogicalScreenDescriptor lsd =
                    new LogicalScreenDescriptor(_logicalScreenSize,
                                                hasGlobalColourTable,
                                                colourResolution,
                                                globalColourTableIsSorted,
                                                _globalColourTable.SizeBits,
                                                backgroundColorIndex,
                                                pixelAspectRatio);
                lsd.WriteToStream(outputStream);
                _globalColourTable.WriteToStream(outputStream);
            }
            else
            {
                LogicalScreenDescriptor lsd =
                    new LogicalScreenDescriptor(_logicalScreenSize,
                                                hasGlobalColourTable,
                                                colourResolution,
                                                globalColourTableIsSorted,
                                                7,
                                                backgroundColorIndex,
                                                pixelAspectRatio);
                lsd.WriteToStream(outputStream);
            }
        }
示例#28
0
        private void DecodeSmiley(bool xmlDebugging)
        {
            string fileName = @"images\smiley\smiley.gif";

            _decoder = new GifDecoder(fileName, xmlDebugging);
            _decoder.Decode();
            _lsd = _decoder.LogicalScreenDescriptor;
            int expectedColourTableSize = 128;

            Assert.AreEqual("GIF", _decoder.Header.Signature);
            Assert.AreEqual("89a", _decoder.Header.Version);
            Assert.IsNotNull(_decoder.GlobalColourTable);
            Assert.AreEqual(true, _lsd.HasGlobalColourTable);
            Assert.AreEqual(expectedColourTableSize,
                            _lsd.GlobalColourTableSize);
            Assert.AreEqual(expectedColourTableSize,
                            _decoder.GlobalColourTable.Length);
            Assert.AreEqual(7, _lsd.ColourResolution);
            Assert.AreEqual(Color.FromArgb(255, 0, 0, 255), _decoder.BackgroundColour);
            Assert.AreEqual(0, _lsd.BackgroundColourIndex);
            Assert.AreEqual(false, _lsd.GlobalColourTableIsSorted);
            Assert.AreEqual(18, _lsd.LogicalScreenSize.Width);
            Assert.AreEqual(18, _lsd.LogicalScreenSize.Height);
            Assert.AreEqual(0, _lsd.PixelAspectRatio);
            Assert.AreEqual(0, _decoder.NetscapeExtension.LoopCount);
            Assert.AreEqual(ErrorState.Ok, _decoder.ConsolidatedState);
            Assert.AreEqual(4, _decoder.Frames.Count);
            int    frameNumber = 0;
            string frameId;

            foreach (GifFrame thisFrame in _decoder.Frames)
            {
                frameId = "Frame " + frameNumber;
                Assert.IsNull(thisFrame.LocalColourTable, frameId);

                #region image descriptor properties
                ImageDescriptor descriptor = thisFrame.ImageDescriptor;
                Assert.AreEqual(false, descriptor.HasLocalColourTable, frameId);
                Assert.AreEqual(expectedColourTableSize,
                                descriptor.LocalColourTableSize,
                                frameId);
                Assert.AreEqual(false, descriptor.IsInterlaced, frameId);
                Assert.AreEqual(false, descriptor.IsSorted, frameId);
                #endregion

                #region graphic control extension properties
                GraphicControlExtension gce = thisFrame.GraphicControlExtension;
                Assert.AreEqual(4, gce.BlockSize, frameId);
                Assert.AreEqual(0, gce.TransparentColourIndex, frameId);
                Assert.IsTrue(gce.HasTransparentColour, frameId);
                Assert.IsFalse(gce.ExpectsUserInput, frameId);
                #endregion

                switch (frameNumber)
                {
                case 0:
                    Assert.AreEqual(250, thisFrame.Delay, frameId);
                    Assert.AreEqual(250, gce.DelayTime, frameId);
                    Assert.AreEqual(DisposalMethod.DoNotDispose,
                                    gce.DisposalMethod, frameId);
                    break;

                case 1:
                    Assert.AreEqual(5, thisFrame.Delay, frameId);
                    Assert.AreEqual(5, gce.DelayTime, frameId);
                    Assert.AreEqual(DisposalMethod.RestoreToBackgroundColour,
                                    gce.DisposalMethod, frameId);
                    break;

                case 2:
                    Assert.AreEqual(10, thisFrame.Delay, frameId);
                    Assert.AreEqual(10, gce.DelayTime, frameId);
                    Assert.AreEqual(DisposalMethod.RestoreToBackgroundColour,
                                    gce.DisposalMethod, frameId);
                    break;

                case 3:
                    Assert.AreEqual(5, thisFrame.Delay, frameId);
                    Assert.AreEqual(5, gce.DelayTime, frameId);
                    Assert.AreEqual(DisposalMethod.DoNotDispose,
                                    gce.DisposalMethod, frameId);
                    break;
                }
                frameNumber++;
            }
            CompareFrames(fileName);

            if (xmlDebugging)
            {
                Assert.AreEqual(ExpectedDebugXml, _decoder.DebugXml);
            }
        }