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 ); }
/// <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 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 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; } }
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; } }
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 ); }
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(); }
/// <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 ); } }