private static void CheckNetscapeExtension(Stream s, int loopCount) { // 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(loopCount, ne.LoopCount); }
/// <summary> /// Writes a Netscape application extension defining the repeat count /// to the supplied output stream, if the repeat count is greater than /// or equal to zero. /// </summary> /// <param name="outputStream"> /// The stream to write to. /// </param> private void WriteNetscapeExtension(Stream outputStream) { // Repeat count -1 means don't repeat the animation, so don't add // a Netscape extension. if (_repeatCount >= 0) { outputStream.WriteByte(GifComponent.CodeExtensionIntroducer); outputStream.WriteByte(GifComponent.CodeApplicationExtensionLabel); NetscapeExtension ne = new NetscapeExtension(_repeatCount); ne.WriteToStream(outputStream); } }
public void ConstructorIntTest() { _ne = new NetscapeExtension(257); Assert.AreEqual("NETSCAPE", _ne.ApplicationIdentifier); Assert.AreEqual("2.0", _ne.ApplicationAuthenticationCode); Assert.AreEqual(2, _ne.ApplicationData.Count); Assert.AreEqual(3, _ne.ApplicationData[0].Data.Length); Assert.AreEqual(1, _ne.ApplicationData[0].Data[0]); Assert.AreEqual(1, _ne.ApplicationData[0].Data[1]); Assert.AreEqual(1, _ne.ApplicationData[0].Data[2]); Assert.AreEqual(0, _ne.ApplicationData[1].Data.Length); Assert.AreEqual(257, _ne.LoopCount); }
public void ConstructorTest() { byte[] idData = new byte[] { (byte)'N', (byte)'E', (byte)'T', (byte)'S', (byte)'C', (byte)'A', (byte)'P', (byte)'E', (byte)'2', (byte)'.', (byte)'0', }; DataBlock idBlock = new DataBlock(11, idData); Collection <DataBlock> appData = new Collection <DataBlock>(); // First byte in the data block is always 1 for a netscape extension // Second and third bytes are the loop count, lsb first byte[] loopCount = new byte[] { 1, 4, 0 }; appData.Add(new DataBlock(3, loopCount)); // Add the block terminator appData.Add(new DataBlock(0, new byte[0])); ApplicationExtension appExt = new ApplicationExtension(idBlock, appData); _ne = new NetscapeExtension(appExt); Assert.AreEqual(4, _ne.LoopCount); Assert.AreEqual("NETSCAPE", _ne.ApplicationIdentifier); Assert.AreEqual("2.0", _ne.ApplicationAuthenticationCode); Assert.AreEqual(ErrorState.Ok, _ne.ConsolidatedState); }
public void ConstructorTestNot2Point0() { byte[] idData = new byte[] { (byte)'N', (byte)'E', (byte)'T', (byte)'S', (byte)'C', (byte)'A', (byte)'P', (byte)'E', (byte)'3', (byte)'.', (byte)'0', }; DataBlock idBlock = new DataBlock(11, idData); ApplicationExtension appExt = new ApplicationExtension(idBlock, new Collection <DataBlock>()); try { _ne = new NetscapeExtension(appExt); } catch (ArgumentException ex) { string message = "The application authentication code is not '2.0' " + "therefore this application extension is not a " + "Netscape extension. Application authentication code: 3.0"; StringAssert.Contains(message, ex.Message); Assert.AreEqual("applicationExtension", ex.ParamName); throw; } }
public void ConstructorTestNotNetscape() { byte[] idData = new byte[] { (byte)'B', (byte)'I', (byte)'G', (byte)'P', (byte)'A', (byte)'N', (byte)'T', (byte)'S', (byte)'2', (byte)'.', (byte)'0', }; DataBlock idBlock = new DataBlock(11, idData); ApplicationExtension appExt = new ApplicationExtension(idBlock, new Collection <DataBlock>()); try { _ne = new NetscapeExtension(appExt); } catch (ArgumentException ex) { string message = "The application identifier is not 'NETSCAPE' " + "therefore this application extension is not a " + "Netscape extension. Application identifier: BIGPANTS"; StringAssert.Contains(message, ex.Message); Assert.AreEqual("applicationExtension", ex.ParamName); throw; } }
/// <summary> /// Main file parser. Reads GIF content blocks. /// </summary> /// <param name="inputStream"> /// Input stream from which the GIF data is to be read. /// </param> private void ReadContents(Stream inputStream) { // read GIF file content blocks bool done = false; GraphicControlExtension lastGce = null; string message; // for error conditions while (!done && ConsolidatedState == ErrorState.Ok) { int code = Read(inputStream); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; WriteCodeToDebugXml(code); switch (code) { case CodeImageSeparator: WriteDebugXmlComment("0x2C - image separator"); AddFrame(inputStream, lastGce); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; break; case CodeExtensionIntroducer: WriteDebugXmlComment("0x21 - extension introducer"); code = Read(inputStream); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; WriteCodeToDebugXml(code); switch (code) { case CodePlaintextLabel: // FEATURE: handle plain text extension WriteDebugXmlComment("0x01 - plain text extension"); SkipBlocks(inputStream); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; break; case CodeGraphicControlLabel: WriteDebugXmlComment("0xF9 - graphic control label"); lastGce = new GraphicControlExtension(inputStream, XmlDebugging); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; WriteDebugXmlNode(lastGce.DebugXmlReader); break; case CodeCommentLabel: // FEATURE: handle comment extension WriteDebugXmlComment("0xFE - comment extension"); SkipBlocks(inputStream); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; break; case CodeApplicationExtensionLabel: WriteDebugXmlComment("0xFF - application extension label"); ApplicationExtension ext = new ApplicationExtension(inputStream, XmlDebugging); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; WriteDebugXmlNode(ext.DebugXmlReader); if (ext.ApplicationIdentifier == "NETSCAPE" && ext.ApplicationAuthenticationCode == "2.0") { _netscapeExtension = new NetscapeExtension(ext); } else { // TESTME: ReadContents - non-Netscape application extension _applicationExtensions.Add(ext); } break; default: // uninteresting extension // TESTME: ReadContents - uninteresting extension WriteDebugXmlComment("Ignoring this extension"); SkipBlocks(inputStream); MyProgressCounters[_readStreamCounterText].Value = (int)inputStream.Position; break; } break; case CodeTrailer: // We've reached an explicit end-of-data marker, so stop // processing the stream. WriteDebugXmlComment("0x3B - end of data"); done = true; break; case 0x00: // bad byte, but keep going and see what happens WriteDebugXmlComment("0x00 - unexpected code"); message = "Unexpected block terminator encountered at " + "position " + inputStream.Position + " after reading " + _frames.Count + " frames."; SetStatus(ErrorState.UnexpectedBlockTerminator, message); break; case -1: // reached the end of the input stream WriteDebugXmlComment("-1 - end of input stream"); message = "Reached the end of the input stream without " + "encountering trailer 0x3b"; SetStatus(ErrorState.EndOfInputStream, message); break; default: WriteDebugXmlComment("Not a recognised code"); message = "Bad data block introducer: 0x" + code.ToString("X", CultureInfo.InvariantCulture).PadLeft(2, '0') + " (" + code + ") at position " + inputStream.Position + " (" + inputStream.Position.ToString("X", CultureInfo.InvariantCulture) + " hex) after reading " + _frames.Count + " frames."; SetStatus(ErrorState.BadDataBlockIntroducer, message); break; } } }
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(); }