diff --git a/.gitignore b/.gitignore index d08534c..65cf512 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,7 @@ obj/ _ReSharper*/ [Tt]est[Rr]esult* *.cachefile -*.DotSettings \ No newline at end of file +*.DotSettings +/.vs +/codealike.json +/packages \ No newline at end of file diff --git a/APNG.NET.sln b/APNG.NET.sln index 8dbfff1..49bc7ce 100644 --- a/APNG.NET.sln +++ b/APNG.NET.sln @@ -1,26 +1,20 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29613.14 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG", "LibAPNG\LibAPNG.csproj", "{6A14ED50-7995-4EAF-B6D5-6E734283B415}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.Test", "LibAPNG.Test\LibAPNG.Test.csproj", "{AC9F9813-FE62-4797-9A06-3D51D5AAFA97}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.XNA.Test", "LibAPNG.XNA.Test\LibAPNG.XNA.Test\LibAPNG.XNA.Test.csproj", "{35CF1CD3-A197-4A14-9B92-15868DC808E5}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36B4DA2A-244D-4453-81B0-4F38305D740C}" ProjectSection(SolutionItems) = preProject README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.XNA.APNGPipelineExtension", "LibAPNG.XNA.APNGPipelineExtension\LibAPNG.XNA.APNGPipelineExtension.csproj", "{9FC6885B-1347-48EB-B427-34BCF8778483}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG", "LibAPNG\LibAPNG.csproj", "{7604B0C8-8EBC-40CD-BF8B-BF21EF213908}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.XNA.APNGTextureProvider", "LibAPNG.XNA.APNGTextureProvider\LibAPNG.XNA.APNGTextureProvider.csproj", "{1AFB77F4-21AF-4830-82A1-95E9FB683AA6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.WPF", "LibAPNG.WPF\LibAPNG.WPF.csproj", "{455F16BC-AE64-4620-B55D-D4E70467CF9D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.XNA.Test.WithPipeline", "LibAPNG.XNA.Test.WithPipeline\LibAPNG.XNA.Test.WithPipeline\LibAPNG.XNA.Test.WithPipeline.csproj", "{183127B8-43E4-4354-BC87-720845739963}" -EndProject -Project("{96E2B04D-8817-42C6-938A-82C39BA4D311}") = "LibAPNG.XNA.Test.WithPipelineContent", "LibAPNG.XNA.Test.WithPipeline\LibAPNG.XNA.Test.WithPipelineContent\LibAPNG.XNA.Test.WithPipelineContent.contentproj", "{AD4E5B87-F690-4A78-A304-223C5DCC8AB6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibAPNG.WPF.Test", "LibAPNG.WPF.Test\LibAPNG.WPF.Test.csproj", "{3F186A97-A92D-46C1-BFD5-41D930DB6773}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -32,16 +26,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Debug|x86.ActiveCfg = Debug|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Release|Any CPU.Build.0 = Release|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6A14ED50-7995-4EAF-B6D5-6E734283B415}.Release|x86.ActiveCfg = Release|Any CPU {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Debug|Any CPU.ActiveCfg = Debug|x86 {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Debug|Mixed Platforms.Build.0 = Debug|x86 @@ -52,56 +36,47 @@ Global {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Release|Mixed Platforms.Build.0 = Release|x86 {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Release|x86.ActiveCfg = Release|x86 {AC9F9813-FE62-4797-9A06-3D51D5AAFA97}.Release|x86.Build.0 = Release|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Debug|Any CPU.ActiveCfg = Debug|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Debug|x86.ActiveCfg = Debug|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Debug|x86.Build.0 = Debug|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Release|Any CPU.ActiveCfg = Release|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Release|Mixed Platforms.Build.0 = Release|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Release|x86.ActiveCfg = Release|x86 - {35CF1CD3-A197-4A14-9B92-15868DC808E5}.Release|x86.Build.0 = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|Any CPU.ActiveCfg = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|Any CPU.Build.0 = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|x86.ActiveCfg = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Debug|x86.Build.0 = Debug|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|Any CPU.ActiveCfg = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|Any CPU.Build.0 = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|Mixed Platforms.Build.0 = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|x86.ActiveCfg = Release|x86 - {9FC6885B-1347-48EB-B427-34BCF8778483}.Release|x86.Build.0 = Release|x86 - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Debug|x86.ActiveCfg = Debug|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Release|Any CPU.Build.0 = Release|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6}.Release|x86.ActiveCfg = Release|Any CPU - {183127B8-43E4-4354-BC87-720845739963}.Debug|Any CPU.ActiveCfg = Debug|x86 - {183127B8-43E4-4354-BC87-720845739963}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {183127B8-43E4-4354-BC87-720845739963}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {183127B8-43E4-4354-BC87-720845739963}.Debug|x86.ActiveCfg = Debug|x86 - {183127B8-43E4-4354-BC87-720845739963}.Debug|x86.Build.0 = Debug|x86 - {183127B8-43E4-4354-BC87-720845739963}.Release|Any CPU.ActiveCfg = Release|x86 - {183127B8-43E4-4354-BC87-720845739963}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {183127B8-43E4-4354-BC87-720845739963}.Release|Mixed Platforms.Build.0 = Release|x86 - {183127B8-43E4-4354-BC87-720845739963}.Release|x86.ActiveCfg = Release|x86 - {183127B8-43E4-4354-BC87-720845739963}.Release|x86.Build.0 = Release|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Debug|Any CPU.ActiveCfg = Debug|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Debug|x86.ActiveCfg = Debug|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Release|Any CPU.ActiveCfg = Release|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6}.Release|x86.ActiveCfg = Release|x86 + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|x86.ActiveCfg = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Debug|x86.Build.0 = Debug|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|Any CPU.Build.0 = Release|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|x86.ActiveCfg = Release|Any CPU + {7604B0C8-8EBC-40CD-BF8B-BF21EF213908}.Release|x86.Build.0 = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|x86.ActiveCfg = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Debug|x86.Build.0 = Debug|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|Any CPU.Build.0 = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|x86.ActiveCfg = Release|Any CPU + {455F16BC-AE64-4620-B55D-D4E70467CF9D}.Release|x86.Build.0 = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|x86.ActiveCfg = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Debug|x86.Build.0 = Debug|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|Any CPU.Build.0 = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|x86.ActiveCfg = Release|Any CPU + {3F186A97-A92D-46C1-BFD5-41D930DB6773}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7497765F-20D8-40D8-94AD-2392E65320B1} + EndGlobalSection EndGlobal diff --git a/LibAPNG.Test/LibAPNG.Test.csproj b/LibAPNG.Test/LibAPNG.Test.csproj index 862ede2..672489c 100644 --- a/LibAPNG.Test/LibAPNG.Test.csproj +++ b/LibAPNG.Test/LibAPNG.Test.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,8 +10,9 @@ Properties LibAPNG.Test LibAPNG.Test - v4.0 - Client + v4.7.2 + + 512 @@ -23,6 +24,7 @@ DEBUG;TRACE prompt 4 + false x86 @@ -32,6 +34,7 @@ TRACE prompt 4 + false @@ -47,16 +50,17 @@ - - {6A14ED50-7995-4EAF-B6D5-6E734283B415} - LibAPNG - - - + PreserveNewest + + + {7604b0c8-8ebc-40cd-bf8b-bf21ef213908} + LibAPNG + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/LibAPNG.WPF.Test/Properties/Settings.Designer.cs b/LibAPNG.WPF.Test/Properties/Settings.Designer.cs new file mode 100644 index 0000000..aa724c4 --- /dev/null +++ b/LibAPNG.WPF.Test/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace LibAPNG.WPF.Test.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/LibAPNG.WPF.Test/Properties/Settings.settings b/LibAPNG.WPF.Test/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/LibAPNG.WPF.Test/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipelineContent/firefox.png b/LibAPNG.WPF.Test/firefox.png similarity index 100% rename from LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipelineContent/firefox.png rename to LibAPNG.WPF.Test/firefox.png diff --git a/LibAPNG.WPF.Test/packages.config b/LibAPNG.WPF.Test/packages.config new file mode 100644 index 0000000..23e6c23 --- /dev/null +++ b/LibAPNG.WPF.Test/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LibAPNG.WPF/Extensions.cs b/LibAPNG.WPF/Extensions.cs new file mode 100644 index 0000000..90302b7 --- /dev/null +++ b/LibAPNG.WPF/Extensions.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; + +namespace LibAPNG.WPF +{ + public static class Extensions + { + public static BitmapSource[] ToBitmapSources(this APNG apng) + { + var list = new List(); + + if (apng.IsSimplePNG) + { + var frameBitmap = BitmapFactory.ConvertToPbgra32Format( + BitmapFrame.Create(apng.DefaultImage.GetStream(), BitmapCreateOptions.None, BitmapCacheOption.OnLoad)); + + list.Add(frameBitmap); + return list.ToArray(); + } + + var firstFrame = apng.Frames.First(); + var width = firstFrame.IHDRChunk.Width; + var height = firstFrame.IHDRChunk.Height; + + WriteableBitmap backgroundBitmap = null; + foreach (var frame in apng.Frames) + { + var fcTlChunk = frame.fcTLChunk; + WriteableBitmap foregroundBitmap; + + var frameBitmap = BitmapFactory.ConvertToPbgra32Format( + BitmapFrame.Create(frame.GetStream(), BitmapCreateOptions.None, BitmapCacheOption.OnLoad)); + + if (fcTlChunk.XOffset == 0 && + fcTlChunk.YOffset == 0 && + fcTlChunk.Width == width && + fcTlChunk.Height == height && + fcTlChunk.BlendOp == BlendOps.APNGBlendOpSource) + { + foregroundBitmap = frameBitmap; + } + else + { + foregroundBitmap = backgroundBitmap ?? BitmapFactory.New(width, height); + + using (foregroundBitmap.GetBitmapContext()) + { + // blend_op + switch (fcTlChunk.BlendOp) + { + case BlendOps.APNGBlendOpSource: + foregroundBitmap.Blit( + new Rect(fcTlChunk.XOffset, fcTlChunk.YOffset, fcTlChunk.Width, fcTlChunk.Height), + frameBitmap, + new Rect(0, 0, frameBitmap.PixelWidth, frameBitmap.PixelHeight), + WriteableBitmapExtensions.BlendMode.None); + break; + + case BlendOps.APNGBlendOpOver: + foregroundBitmap.Blit( + new Rect(fcTlChunk.XOffset, fcTlChunk.YOffset, fcTlChunk.Width, fcTlChunk.Height), + frameBitmap, + new Rect(0, 0, frameBitmap.PixelWidth, frameBitmap.PixelHeight), + WriteableBitmapExtensions.BlendMode.Alpha); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + // dispose_op + switch (fcTlChunk.DisposeOp) + { + case DisposeOps.APNGDisposeOpNone: + backgroundBitmap = foregroundBitmap.Clone(); + break; + case DisposeOps.APNGDisposeOpBackground: + backgroundBitmap = null; + break; + case DisposeOps.APNGDisposeOpPrevious: + backgroundBitmap = backgroundBitmap?.Clone(); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + list.Add(foregroundBitmap); + } + + return list.ToArray(); + } + + public static ObjectAnimationUsingKeyFrames ToAnimation(this APNG apng) + { + var bitmaps = ToBitmapSources(apng); + var animation = new ObjectAnimationUsingKeyFrames(); + + // Repeat + if (apng.acTLChunk.NumPlays == 0) + animation.RepeatBehavior = RepeatBehavior.Forever; + + // KeyFrames + var keyTime = TimeSpan.Zero; + foreach (var (frame, index) in apng.Frames.Select((item, index) => (item, index))) + { + var key = new DiscreteObjectKeyFrame + { + KeyTime = keyTime, + Value = bitmaps[index] + }; + animation.KeyFrames.Add(key); + + var delayDen = (double)(frame.fcTLChunk.DelayDen == 0 ? 100 : frame.fcTLChunk.DelayDen); + keyTime += frame.fcTLChunk.DelayNum == 0 + ? TimeSpan.FromMilliseconds(1) + : TimeSpan.FromSeconds(frame.fcTLChunk.DelayNum / delayDen); + } + + animation.Duration = keyTime; + return animation; + } + + + public static Storyboard CreateStoryboardFor(this Timeline animation, Image image) + { + var storyboard = new Storyboard(); + + Storyboard.SetTargetName(animation, image.Name); + Storyboard.SetTargetProperty(animation, new PropertyPath(Image.SourceProperty)); + + storyboard.Children.Add(animation); + + return storyboard; + } + } +} diff --git a/LibAPNG.XNA.APNGTextureProvider/LibAPNG.XNA.APNGTextureProvider.csproj b/LibAPNG.WPF/LibAPNG.WPF.csproj similarity index 52% rename from LibAPNG.XNA.APNGTextureProvider/LibAPNG.XNA.APNGTextureProvider.csproj rename to LibAPNG.WPF/LibAPNG.WPF.csproj index f232c7a..d8c6f51 100644 --- a/LibAPNG.XNA.APNGTextureProvider/LibAPNG.XNA.APNGTextureProvider.csproj +++ b/LibAPNG.WPF/LibAPNG.WPF.csproj @@ -1,17 +1,17 @@  - + Debug AnyCPU - {1AFB77F4-21AF-4830-82A1-95E9FB683AA6} + {455F16BC-AE64-4620-B55D-D4E70467CF9D} Library Properties - LibAPNG.XNA.APNGTextureProvider - LibAPNG.XNA.APNGTextureProvider - v4.0 + LibAPNG.WPF + LibAPNG.WPF + v4.7.2 512 - Client + true true @@ -31,38 +31,33 @@ 4 - - False - - - False - - - False - - - False - + + + + + + ..\..\ApngSample\packages\WriteableBitmapEx.1.6.5\lib\net40\WriteableBitmapEx.Wpf.dll + - - - + + + + {6a14ed50-7995-4eaf-b6d5-6e734283b415} + LibAPNG + + + + + - \ No newline at end of file diff --git a/LibAPNG.WPF/Properties/AssemblyInfo.cs b/LibAPNG.WPF/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c01bc5c --- /dev/null +++ b/LibAPNG.WPF/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// 制御されます。アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle("LibAPNG.WPF")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LibAPNG.WPF")] +[assembly: AssemblyCopyright("Copyright © jz5 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから +// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible(false)] + +// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります +[assembly: Guid("455f16bc-ae64-4620-b55d-d4e70467cf9d")] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// メジャー バージョン +// マイナー バージョン +// ビルド番号 +// リビジョン +// +// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LibAPNG.WPF/packages.config b/LibAPNG.WPF/packages.config new file mode 100644 index 0000000..23e6c23 --- /dev/null +++ b/LibAPNG.WPF/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/APNGContentImporter.cs b/LibAPNG.XNA.APNGPipelineExtension/APNGContentImporter.cs deleted file mode 100644 index d7bc5f3..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/APNGContentImporter.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Drawing; -using System.IO; -using Microsoft.Xna.Framework.Content.Pipeline; -using Microsoft.Xna.Framework.Content.Pipeline.Graphics; -using Color = Microsoft.Xna.Framework.Color; - -namespace LibAPNG.XNA.APNGPipelineExtension -{ - [ContentImporter(".png", DisplayName = "APNG Importer", DefaultProcessor = "APNG Processor")] - public class APNGContentImporter : ContentImporter - { - public override APNGFrameList Import(string filename, ContentImporterContext context) - { - var apng = new APNG(filename); - - APNGFrameList frameList; - - if (apng.IsSimplePNG) - { - frameList = new APNGFrameList(0); - frameList.AddFrame(new TimeSpan(), BuildTextureContent(apng.DefaultImage.GetStream().ToArray())); - } - else - { - frameList = new APNGFrameList(apng.acTLChunk.NumPlays); - - if (!apng.DefaultImageIsAnimeated) - frameList.AddFrame( - new TimeSpan(TimeSpan.TicksPerSecond * apng.DefaultImage.fcTLChunk.DelayNum / - apng.DefaultImage.fcTLChunk.DelayDen), - BuildTextureContent(apng.DefaultImage.GetStream().ToArray())); - - foreach (LibAPNG.Frame frame in apng.Frames) - { - frameList.AddFrame( - new TimeSpan(TimeSpan.TicksPerSecond * frame.fcTLChunk.DelayNum - / frame.fcTLChunk.DelayDen), - BuildTextureContent(frame.GetStream().ToArray())); - } - } - - return frameList; - } - - private Texture2DContent BuildTextureContent(byte[] buffer) - { - var bitmap = new Bitmap(new MemoryStream(buffer)); - - var bitmapContent = new PixelBitmapContent(bitmap.Width, bitmap.Height); - - for (int i = 0; i < bitmap.Width; i++) - { - for (int j = 0; j < bitmap.Height; j++) - { - System.Drawing.Color from = bitmap.GetPixel(i, j); - - //System.Drawing.Color to Microsoft.Xna.Framework.Color - var to = new Color(from.R, from.G, from.B, from.A); - bitmapContent.SetPixel(i, j, to); - } - } - - return new Texture2DContent {Mipmaps = new MipmapChain(bitmapContent)}; - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/APNGContentProcessor.cs b/LibAPNG.XNA.APNGPipelineExtension/APNGContentProcessor.cs deleted file mode 100644 index e0f471c..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/APNGContentProcessor.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.ComponentModel; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Content.Pipeline; -using Microsoft.Xna.Framework.Content.Pipeline.Graphics; -using Microsoft.Xna.Framework.Content.Pipeline.Processors; - -namespace LibAPNG.XNA.APNGPipelineExtension -{ - [ContentProcessor(DisplayName = "APNG Processor")] - public class APNGContentProcessor : ContentProcessor - { - public APNGContentProcessor() - { - ColorKeyColor = Color.Magenta; - ColorKeyEnabled = true; - GenerateMipmaps = false; - PremultiplyAlpha = true; - ResizeToPowerOfTwo = false; - } - - [DefaultValue(typeof (Color), "255, 0, 255, 255")] - public Color ColorKeyColor { get; set; } - - [DefaultValue(true)] - public bool ColorKeyEnabled { get; set; } - - [DefaultValue(false)] - public bool GenerateMipmaps { get; set; } - - [DefaultValue(true)] - public bool PremultiplyAlpha { get; set; } - - [DefaultValue(false)] - public bool ResizeToPowerOfTwo { get; set; } - - [DefaultValue(TextureProcessorOutputFormat.Color)] - public TextureProcessorOutputFormat TextureFormat { get; set; } - - public override APNGFrameList Process(APNGFrameList input, ContentProcessorContext context) - { - for (int i = 0; i < input.Frames.Length; i++) - { - ProcessSingleFrame(input.Frames[i].Content); - } - - return input; - } - - internal void ProcessSingleFrame(TextureContent input) - { - bool colorKeyEnabled = ColorKeyEnabled; - bool premultiplyAlpha = PremultiplyAlpha; - Type bitmapType = null; - if (colorKeyEnabled || premultiplyAlpha) - { - Type type2; - input.Validate(null); - bitmapType = input.Faces[0][0].GetType(); - if (TextureProcessorUtils.IsHighPrecisionFormat(bitmapType)) - { - type2 = typeof (PixelBitmapContent); - } - else - { - type2 = typeof (PixelBitmapContent); - } - input.ConvertBitmapType(type2); - } - if (colorKeyEnabled) - { - TextureProcessorUtils.ColorKey(input, ColorKeyColor); - } - if (premultiplyAlpha) - { - TextureProcessorUtils.PremultiplyAlpha(input); - } - if (ResizeToPowerOfTwo) - { - TextureProcessorUtils.ResizeToPowerOfTwo(input); - } - if (GenerateMipmaps) - { - input.GenerateMipmaps(false); - } - TextureProcessorUtils.ChangeTextureToRequestedFormat(input, bitmapType, TextureFormat); - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/APNGContentTypeWriter.cs b/LibAPNG.XNA.APNGPipelineExtension/APNGContentTypeWriter.cs deleted file mode 100644 index 5a25df2..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/APNGContentTypeWriter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Xna.Framework.Content.Pipeline; -using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler; - -namespace LibAPNG.XNA.APNGPipelineExtension -{ - [ContentTypeWriter] - public class APNGContentTypeWriter : ContentTypeWriter - { - protected override void Write(ContentWriter output, APNGFrameList value) - { - output.Write(value.LoopCount); - output.Write(value.Frames.Length); - foreach (Frame frame in value.Frames) - { - output.Write(frame.DelayTime.Ticks); - output.WriteObject(frame.Content); - } - } - - public override string GetRuntimeReader(TargetPlatform targetPlatform) - { - return "LibAPNG.XNA.APNGTextureProvider.APNGContentTypeReader,LibAPNG.XNA.APNGTextureProvider"; - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/APNGFrameList.cs b/LibAPNG.XNA.APNGPipelineExtension/APNGFrameList.cs deleted file mode 100644 index fbaf7d4..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/APNGFrameList.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Xna.Framework.Content.Pipeline.Graphics; - -namespace LibAPNG.XNA.APNGPipelineExtension -{ - public struct Frame - { - public TextureContent Content; - public TimeSpan DelayTime; - } - - public struct APNGFrameList - { - private readonly List _frames; - public uint LoopCount; - - public APNGFrameList(uint loopCount) - { - LoopCount = loopCount; - - _frames = new List(); - } - - public Frame[] Frames - { - get { return _frames.ToArray(); } - } - - public void AddFrame(TimeSpan delayTime, TextureContent content) - { - _frames.Add(new Frame {DelayTime = delayTime, Content = content}); - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/LibAPNG.XNA.APNGPipelineExtension.csproj b/LibAPNG.XNA.APNGPipelineExtension/LibAPNG.XNA.APNGPipelineExtension.csproj deleted file mode 100644 index b1ee47f..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/LibAPNG.XNA.APNGPipelineExtension.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - - {9FC6885B-1347-48EB-B427-34BCF8778483} - Debug - x86 - Library - Properties - LibAPNG.XNA.APNGPipelineExtension - LibAPNG.XNA.APNGPipelineExtension - v4.0 - Windows - v4.0 - Client - - - true - full - false - bin\x86\Debug - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\x86\Release - TRACE - prompt - 4 - x86 - - - - ..\..\..\..\Game Development\EAGSS\LibAPNG.dll - - - True - - - - - True - - - true - - - - - - 4.0 - - - 4.0 - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/Properties/AssemblyInfo.cs b/LibAPNG.XNA.APNGPipelineExtension/Properties/AssemblyInfo.cs deleted file mode 100644 index 43dacc9..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("LibAPNG.XNA.APNGPipelineExtension")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Paddy Xu")] -[assembly: AssemblyProduct("LibAPNG.XNA.APNGPipelineExtension")] -[assembly: AssemblyCopyright("Copyright © Paddy Xu 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("b1d63af0-8073-4073-ac08-723aa1118fec")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/LibAPNG.XNA.APNGPipelineExtension/TextureProcessorUtils.cs b/LibAPNG.XNA.APNGPipelineExtension/TextureProcessorUtils.cs deleted file mode 100644 index cb95b02..0000000 --- a/LibAPNG.XNA.APNGPipelineExtension/TextureProcessorUtils.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Content.Pipeline.Graphics; -using Microsoft.Xna.Framework.Content.Pipeline.Processors; -using Microsoft.Xna.Framework.Graphics.PackedVector; - -namespace LibAPNG.XNA.APNGPipelineExtension -{ - // The code below is from Microsoft.Xna.Framework.Content.Pipeline.Processors.TextureProcessorUtils. - internal static class TextureProcessorUtils - { - private static void BestGuessCompress(TextureContent texture) - { - texture.ConvertBitmapType(typeof (PixelBitmapContent)); - if (!(texture is Texture3DContent)) - { - texture.ConvertBitmapType(HasFractionalAlpha(texture) - ? typeof (Dxt5BitmapContent) - : typeof (Dxt1BitmapContent)); - } - } - - internal static void ChangeTextureToRequestedFormat(TextureContent texture, - Type originalType, - TextureProcessorOutputFormat textureFormat) - { - switch (textureFormat) - { - case TextureProcessorOutputFormat.NoChange: - if (originalType == null) - { - break; - } - texture.ConvertBitmapType(originalType); - return; - - case TextureProcessorOutputFormat.Color: - texture.ConvertBitmapType(typeof (PixelBitmapContent)); - return; - - case TextureProcessorOutputFormat.DxtCompressed: - BestGuessCompress(texture); - break; - - default: - return; - } - } - - public static void ColorKey(TextureContent texture, Color colorKey) - { - foreach (MipmapChain chain in texture.Faces) - { - foreach (BitmapContent content in chain) - { - var content3 = content as PixelBitmapContent; - if (content3 == null) - { - var content2 = content as PixelBitmapContent; - if (content2 == null) - { - throw new NotSupportedException(); - } - content2.ReplaceColor(colorKey.ToVector4(), Vector4.Zero); - } - else - { - content3.ReplaceColor(colorKey, Color.Transparent); - } - } - } - } - - private static bool HasFractionalAlpha(TextureContent texture) - { - foreach (MipmapChain chain in texture.Faces) - { - foreach (PixelBitmapContent content in chain) - { - for (int i = 0; i < content.Height; i++) - { - if (content.GetRow(i).Select(color => color.A).Any(a => (a != 0xff) && (a != 0))) - { - return true; - } - } - } - } - return false; - } - - public static bool IsHighPrecisionFormat(Type bitmapType) - { - if ((((!typeof (PixelBitmapContent).IsAssignableFrom(bitmapType) - && !typeof (PixelBitmapContent).IsAssignableFrom(bitmapType)) - && (!typeof (PixelBitmapContent).IsAssignableFrom(bitmapType) - && !typeof (PixelBitmapContent).IsAssignableFrom(bitmapType))) - && ((!typeof (PixelBitmapContent).IsAssignableFrom(bitmapType) - && !typeof (PixelBitmapContent).IsAssignableFrom(bitmapType)) - && (!typeof (PixelBitmapContent).IsAssignableFrom(bitmapType) - && !typeof (PixelBitmapContent).IsAssignableFrom(bitmapType)))) - && (!typeof (PixelBitmapContent).IsAssignableFrom(bitmapType) - && !typeof (PixelBitmapContent).IsAssignableFrom(bitmapType))) - { - return typeof (PixelBitmapContent).IsAssignableFrom(bitmapType); - } - return true; - } - - public static void PremultiplyAlpha(TextureContent texture) - { - foreach (MipmapChain chain in texture.Faces) - { - foreach (BitmapContent content3 in chain) - { - var content2 = content3 as PixelBitmapContent; - if (content2 != null) - { - for (int i = 0; i < content2.Height; i++) - { - Color[] row = content2.GetRow(i); - for (int j = 0; j < row.Length; j++) - { - Color color = row[j]; - if (color.A < 0xff) - { - row[j] = Color.FromNonPremultiplied(color.R, color.G, color.B, color.A); - } - } - } - } - else - { - var content = content3 as PixelBitmapContent; - if (content == null) - { - throw new NotSupportedException(); - } - for (int k = 0; k < content.Height; k++) - { - Vector4[] vectorArray = content.GetRow(k); - for (int m = 0; m < vectorArray.Length; m++) - { - Vector4 vector = vectorArray[m]; - if (vector.W < 1f) - { - vector.X *= vector.W; - vector.Y *= vector.W; - vector.Z *= vector.W; - vectorArray[m] = vector; - } - } - } - } - } - } - } - - public static void ResizeToPowerOfTwo(TextureContent texture) - { - foreach (MipmapChain chain in texture.Faces) - { - for (int i = 0; i < chain.Count; i++) - { - BitmapContent source = chain[i]; - int width = RoundUpToPowerOfTwo(source.Width); - int height = RoundUpToPowerOfTwo(source.Height); - if ((width != source.Width) || (height != source.Height)) - { - chain[i] = ConvertBitmap(source, source.GetType(), width, height); - } - } - } - } - - private static BitmapContent ConvertBitmap(BitmapContent source, Type newType, int width, int height) - { - BitmapContent content; - try - { - content = (BitmapContent)Activator.CreateInstance(newType, new object[] {width, height}); - } - catch (TargetInvocationException exception) - { - throw new Exception(exception.InnerException.Message); - } - BitmapContent.Copy(source, content); - return content; - } - - private static int RoundUpToPowerOfTwo(int value) - { - int num = 1; - while (num < value) - { - num = num << 1; - } - return num; - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGTextureProvider/APNGContentTypeReader.cs b/LibAPNG.XNA.APNGTextureProvider/APNGContentTypeReader.cs deleted file mode 100644 index cca63dd..0000000 --- a/LibAPNG.XNA.APNGTextureProvider/APNGContentTypeReader.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Microsoft.Xna.Framework.Content; -using Microsoft.Xna.Framework.Graphics; - -namespace LibAPNG.XNA.APNGTextureProvider -{ - public class APNGContentTypeReader : ContentTypeReader - { - protected override APNGTexture Read(ContentReader input, APNGTexture existingInstance) - { - var list = new APNGTexture(input.ReadUInt32()); - - int frameCount = input.ReadInt32(); - - for (int i = 0; i < frameCount; ++i) - { - list.AddFrame(new TimeSpan(input.ReadInt64()), input.ReadObject()); - } - - return list; - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGTextureProvider/APNGTexture.cs b/LibAPNG.XNA.APNGTextureProvider/APNGTexture.cs deleted file mode 100644 index 8d5ea38..0000000 --- a/LibAPNG.XNA.APNGTextureProvider/APNGTexture.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace LibAPNG.XNA.APNGTextureProvider -{ - public class APNGTexture : IDisposable - { - private readonly List _frames; - private int _currentIndex; - private int _playedCount; - private TimeSpan _waitTime = TimeSpan.Zero; - - public APNGTexture(uint loopCount) - { - LoopCount = loopCount; - - _frames = new List(); - } - - public bool IsDisposed { get; private set; } - - public uint LoopCount { get; private set; } - - public Texture2D CurrentFrame - { - get { return _frames[_currentIndex].Texture; } - } - - public Frame[] Frames - { - get { return _frames.ToArray(); } - } - - public void Dispose() - { - if (!IsDisposed) - { - IsDisposed = true; - - foreach (Frame frame in _frames) - { - if (!frame.Texture.IsDisposed) - frame.Texture.Dispose(); - } - } - } - - public void Update(GameTime gameTime) - { - if (_frames.Count == 1) - { - _currentIndex = 0; - } - else - { - if (LoopCount != 0) - { - if (_playedCount >= LoopCount) - { - _currentIndex = 0; - } - else - { - NextFrame(gameTime); - } - } - else - { - NextFrame(gameTime); - } - } - } - - private void NextFrame(GameTime gameTime) - { - if (_waitTime < _frames[_currentIndex].DelayTime) - { - _waitTime += gameTime.ElapsedGameTime; - return; - } - - _waitTime = TimeSpan.Zero; - - if (++_currentIndex == _frames.Count) - { - _currentIndex = 0; - _playedCount++; - } - } - - internal void AddFrame(TimeSpan delayTime, Texture2D texture) - { - _frames.Add(new Frame {DelayTime = delayTime, Texture = texture}); - } - - ~APNGTexture() - { - Dispose(); - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGTextureProvider/Frame.cs b/LibAPNG.XNA.APNGTextureProvider/Frame.cs deleted file mode 100644 index b5c5ca5..0000000 --- a/LibAPNG.XNA.APNGTextureProvider/Frame.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using Microsoft.Xna.Framework.Graphics; - -namespace LibAPNG.XNA.APNGTextureProvider -{ - public struct Frame - { - public TimeSpan DelayTime; - public Texture2D Texture; - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.APNGTextureProvider/Properties/AssemblyInfo.cs b/LibAPNG.XNA.APNGTextureProvider/Properties/AssemblyInfo.cs deleted file mode 100644 index edd844a..0000000 --- a/LibAPNG.XNA.APNGTextureProvider/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 - -[assembly: AssemblyTitle("LibAPNG.XNA.APNGTextureProvider")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Paddy Xu")] -[assembly: AssemblyProduct("LibAPNG.XNA.APNGTextureProvider")] -[assembly: AssemblyCopyright("Copyright © Paddy Xu 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 - -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID - -[assembly: Guid("dafe36a5-00ef-45c8-818a-48684c4ab674")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game.ico b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game.ico deleted file mode 100644 index 8cff41e..0000000 Binary files a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game.ico and /dev/null differ diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game1.cs b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game1.cs deleted file mode 100644 index 3fbc359..0000000 --- a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Game1.cs +++ /dev/null @@ -1,89 +0,0 @@ -using LibAPNG.XNA.APNGTextureProvider; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; - -namespace LibAPNG.XNA.Test.WithPipeline -{ - /// - /// This is the main type for your game - /// - public class Game1 : Game - { - private GraphicsDeviceManager graphics; - private SpriteBatch spriteBatch; - - private APNGTexture t; - - public Game1() - { - graphics = new GraphicsDeviceManager(this); - Content.RootDirectory = "Content"; - } - - /// - /// Allows the game to perform any initialization it needs to before starting to run. - /// This is where it can query for any required services and load any non-graphic - /// related content. Calling base.Initialize will enumerate through any components - /// and initialize them as well. - /// - protected override void Initialize() - { - // TODO: Add your initialization logic here - - base.Initialize(); - } - - /// - /// LoadContent will be called once per game and is the place to load - /// all of your content. - /// - protected override void LoadContent() - { - // Create a new SpriteBatch, which can be used to draw textures. - spriteBatch = new SpriteBatch(GraphicsDevice); - - t = Content.Load("firefox"); - } - - /// - /// UnloadContent will be called once per game and is the place to unload - /// all content. - /// - protected override void UnloadContent() - { - // TODO: Unload any non ContentManager content here - } - - /// - /// Allows the game to run logic such as updating the world, - /// checking for collisions, gathering input, and playing audio. - /// - /// Provides a snapshot of timing values. - protected override void Update(GameTime gameTime) - { - // Allows the game to exit - if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) - Exit(); - - t.Update(gameTime); - - base.Update(gameTime); - } - - /// - /// This is called when the game should draw itself. - /// - /// Provides a snapshot of timing values. - protected override void Draw(GameTime gameTime) - { - GraphicsDevice.Clear(Color.CornflowerBlue); - - spriteBatch.Begin(); - spriteBatch.Draw(t.CurrentFrame, new Vector2(20, 20), Color.White); - spriteBatch.End(); - - base.Draw(gameTime); - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/GameThumbnail.png b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/GameThumbnail.png deleted file mode 100644 index 462311a..0000000 Binary files a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/GameThumbnail.png and /dev/null differ diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline.csproj b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline.csproj deleted file mode 100644 index ccb096a..0000000 --- a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline.csproj +++ /dev/null @@ -1,127 +0,0 @@ - - - - {183127B8-43E4-4354-BC87-720845739963} - {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Debug - x86 - WinExe - Properties - LibAPNG.XNA.Test.WithPipeline - LibAPNG.XNA.Test.WithPipeline - v4.0 - Client - v4.0 - Windows - Reach - 237f68bd-c820-4d58-878f-a4f005941837 - Game - Game.ico - GameThumbnail.png - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\x86\Debug - DEBUG;TRACE;WINDOWS - prompt - 4 - true - false - x86 - false - - - pdbonly - true - bin\x86\Release - TRACE;WINDOWS - prompt - 4 - true - false - x86 - true - - - - - - - - - - - - - - - - - - - - - - true - - - - - {1afb77f4-21af-4830-82a1-95e9fb683aa6} - LibAPNG.XNA.APNGTextureProvider - - - LibAPNG.XNA.Test.WithPipelineContent - Content - - - - - False - Microsoft .NET Framework 4 Client Profile %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Windows Installer 4.5 - true - - - - - - \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Program.cs b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Program.cs deleted file mode 100644 index 56a987d..0000000 --- a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace LibAPNG.XNA.Test.WithPipeline -{ -#if WINDOWS || XBOX - internal static class Program - { - /// - /// The main entry point for the application. - /// - private static void Main(string[] args) - { - using (var game = new Game1()) - { - game.Run(); - } - } - } -#endif -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Properties/AssemblyInfo.cs b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Properties/AssemblyInfo.cs deleted file mode 100644 index ee83037..0000000 --- a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipeline/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("LibAPNG.XNA.Test.WithPipeline")] -[assembly: AssemblyProduct("LibAPNG.XNA.Test.WithPipeline")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyCompany("Paddy Xu")] -[assembly: AssemblyCopyright("Copyright © Paddy Xu 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. Only Windows -// assemblies support COM. - -[assembly: ComVisible(false)] - -// On Windows, the following GUID is for the ID of the typelib if this -// project is exposed to COM. On other platforms, it unique identifies the -// title storage container when deploying this assembly to the device. - -[assembly: Guid("45528625-6553-4b24-944d-e7a006a3ad8c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly: AssemblyVersion("1.0.0.0")] \ No newline at end of file diff --git a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipelineContent/LibAPNG.XNA.Test.WithPipelineContent.contentproj b/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipelineContent/LibAPNG.XNA.Test.WithPipelineContent.contentproj deleted file mode 100644 index 5cecbeb..0000000 --- a/LibAPNG.XNA.Test.WithPipeline/LibAPNG.XNA.Test.WithPipelineContent/LibAPNG.XNA.Test.WithPipelineContent.contentproj +++ /dev/null @@ -1,53 +0,0 @@ - - - - {AD4E5B87-F690-4A78-A304-223C5DCC8AB6} - {96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Debug - x86 - Library - Properties - v4.0 - v4.0 - bin\$(Platform)\$(Configuration) - Content - - - x86 - - - x86 - - - LibAPNG.XNA.Test.WithPipelineContent - - - - - - - - - - - - firefox - APNGContentImporter - APNGContentProcessor - - - - - {9fc6885b-1347-48eb-b427-34bcf8778483} - LibAPNG.XNA.APNGPipelineExtension - - - - - \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGFrame.cs b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGFrame.cs deleted file mode 100644 index 25f5f09..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGFrame.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.IO; -using LibAPNG; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Graphics.PackedVector; - -namespace LibAPNGTest.APNGHelper -{ - internal struct APNGFrame - { - #region Constants and Fields - - internal BlendOps BlendOp; - internal TimeSpan DelayTime; - internal DisposeOps DisposeOp; - internal Texture2D FrameTexture; - internal int Height; - internal int Width; - internal int X; - internal int Y; - - #endregion Constants and Fields - - #region Constructors and Destructors - - internal APNGFrame(Game game, Frame frame) - { - if (frame.fcTLChunk != null) - { - X = (int)frame.fcTLChunk.XOffset; - Y = (int)frame.fcTLChunk.YOffset; - Width = (int)frame.fcTLChunk.Width; - Height = (int)frame.fcTLChunk.Height; - BlendOp = frame.fcTLChunk.BlendOp; - DisposeOp = frame.fcTLChunk.DisposeOp; - DelayTime = new TimeSpan( - TimeSpan.TicksPerSecond * frame.fcTLChunk.DelayNum / frame.fcTLChunk.DelayDen); - } - else - { - X = 0; - Y = 0; - Width = frame.IHDRChunk.Width; - Height = frame.IHDRChunk.Height; - BlendOp = BlendOps.APNGBlendOpSource; - DisposeOp = DisposeOps.APNGDisposeOpNone; - DelayTime = TimeSpan.Zero; - } - - // frame.GetStream() is not seekable, so we build a new MemoryStream. - FrameTexture = Texture2D.FromStream( - game.GraphicsDevice, - new MemoryStream(frame.GetStream().ToArray())); - MultiplyAlpha(FrameTexture); - } - - #endregion Constructors and Destructors - - #region Methods - - private static void MultiplyAlpha(Texture2D ret) - { - var data = new Byte4[ret.Width * ret.Height]; - - ret.GetData(data); - for (int i = 0; i < data.Length; i++) - { - Vector4 vec = data[i].ToVector4(); - - float alpha = vec.W / 255.0f; - var a = (int)(vec.W); - var r = (int)(alpha * vec.X); - var g = (int)(alpha * vec.Y); - var b = (int)(alpha * vec.Z); - var packed = (uint)((a << 24) + (b << 16) + (g << 8) + r); - - data[i].PackedValue = packed; - } - - ret.SetData(data); - } - - #endregion Methods - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGHelper.cs b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGHelper.cs deleted file mode 100644 index 47450a6..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/APNGHelper/APNGHelper.cs +++ /dev/null @@ -1,209 +0,0 @@ -using System; -using System.Collections.Generic; -using LibAPNG; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace LibAPNGTest.APNGHelper -{ - public class APNGHelper - { - #region Constants and Fields - - private readonly List frameList = new List(); - private readonly Game game; - private readonly int numPlays; - private readonly List renderedTextureList = new List(); - private readonly SpriteBatch sb; - private int alreadyPlays; - private TimeSpan alreadyWaitTime = TimeSpan.Zero; - private APNGFrame baseFrame; - private int currentPlayedIndex; - - #endregion Constants and Fields - - #region Constructors and Destructors - - public APNGHelper(Game game, string pngFile) - { - this.game = game; - - var image = new APNG(pngFile); - numPlays = (int)image.acTLChunk.NumPlays; - baseFrame = new APNGFrame(game, image.DefaultImage); - - if (image.IsSimplePNG) - { - CurrentFrame = baseFrame.FrameTexture; - } - else - { - numPlays = (int)image.acTLChunk.NumPlays; - - foreach (Frame frame in image.Frames) - { - frameList.Add(new APNGFrame(this.game, frame)); - } - - sb = new SpriteBatch(this.game.GraphicsDevice); - - RenderEachFrame(); - - CurrentFrame = renderedTextureList[0]; - } - } - - #endregion Constructors and Destructors - - #region Public Properties - - public Texture2D CurrentFrame { get; private set; } - - #endregion Public Properties - - #region Public Methods and Operators - - public void Update(GameTime gameTime) - { - if (CurrentFrame == null) - { - CurrentFrame = baseFrame.FrameTexture; - } - - if (numPlays != 0 && alreadyPlays >= numPlays) - { - CurrentFrame = renderedTextureList[0]; - } - - if (alreadyWaitTime > frameList[currentPlayedIndex].DelayTime) - { - currentPlayedIndex = currentPlayedIndex < renderedTextureList.Count - 1 - ? currentPlayedIndex + 1 - : 0; - - CurrentFrame = renderedTextureList[currentPlayedIndex]; - - alreadyWaitTime = TimeSpan.Zero; - - alreadyPlays++; - } - else - { - alreadyWaitTime += gameTime.ElapsedGameTime; - } - } - - #endregion Public Methods and Operators - - #region Methods - - private void RenderEachFrame() - { - for (int crtIndex = 0; crtIndex < frameList.Count; crtIndex++) - { - var currentTexture = new RenderTarget2D( - game.GraphicsDevice, - baseFrame.Width, - baseFrame.Height); - - game.GraphicsDevice.SetRenderTarget(currentTexture); - game.GraphicsDevice.Clear(Color.Transparent); - - // if this is the first frame, just draw. - if (crtIndex == 0) - { - goto LABEL_DRAW_NEW_FRAME; - } - - // Restore previous texture - sb.Begin(); - sb.Draw(renderedTextureList[crtIndex - 1], Vector2.Zero, Color.White); - sb.End(); - - APNGFrame crtFrame = frameList[crtIndex - 1]; - - switch (crtFrame.DisposeOp) - { - // Do nothing. - case DisposeOps.APNGDisposeOpNone: - break; - - // Set current Rectangle to transparent. - case DisposeOps.APNGDisposeOpBackground: - LABEL_APNG_DISPOSE_OP_BACKGROUND: - var t2 = new Texture2D(game.GraphicsDevice, 1, 1); - sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque); - sb.Draw( - t2, - new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height), - Color.White); - sb.End(); - break; - - // Rollback to previous frame. - case DisposeOps.APNGDisposeOpPrevious: - // If the first `fcTL` chunk uses a `dispose_op` of APNG_DISPOSE_OP_PREVIOUS - // it should be treated as APNG_DISPOSE_OP_BACKGROUND. - if (crtIndex - 1 == 0) - { - goto LABEL_APNG_DISPOSE_OP_BACKGROUND; - } - - APNGFrame prevFrame = frameList[crtIndex - 2]; - - sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque); - sb.Draw( - prevFrame.FrameTexture, - new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height), - new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height), - Color.White); - sb.End(); - break; - } - - LABEL_DRAW_NEW_FRAME: - // Now let's look at the new frame. - if (crtIndex == 0) - { - crtFrame = frameList[0]; - } - else - { - crtFrame = crtIndex < frameList.Count - ? frameList[crtIndex] - : frameList[0]; - } - - switch (crtFrame.BlendOp) - { - // Do not apply alpha - case BlendOps.APNGBlendOpSource: - sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque); - sb.Draw( - crtFrame.FrameTexture, - new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height), - Color.White); - sb.End(); - break; - - // Apply alpha - case BlendOps.APNGBlendOpOver: - sb.Begin(); - sb.Draw( - crtFrame.FrameTexture, - new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height), - Color.White); - sb.End(); - break; - } - - renderedTextureList.Add(currentTexture); - } - - // Okay it's all over now - game.GraphicsDevice.SetRenderTarget(null); - } - - #endregion Methods - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game.ico b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game.ico deleted file mode 100644 index 8cff41e..0000000 Binary files a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game.ico and /dev/null differ diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game1.cs b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game1.cs deleted file mode 100644 index 86ee5fe..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Game1.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; - -namespace LibAPNGTest -{ - /// - /// This is the main type for your game - /// - public class Game1 : Game - { - private APNGHelper.APNGHelper apng; - private GraphicsDeviceManager graphics; - private SpriteBatch spriteBatch; - - public Game1() - { - graphics = new GraphicsDeviceManager(this); - Content.RootDirectory = "Content"; - } - - /// - /// Allows the game to perform any initialization it needs to before starting to run. - /// This is where it can query for any required services and load any non-graphic - /// related content. Calling base.Initialize will enumerate through any components - /// and initialize them as well. - /// - protected override void Initialize() - { - // TODO: Add your initialization logic here - - base.Initialize(); - } - - /// - /// LoadContent will be called once per game and is the place to load - /// all of your content. - /// - protected override void LoadContent() - { - // Create a new SpriteBatch, which can be used to draw textures. - spriteBatch = new SpriteBatch(GraphicsDevice); - - apng = new APNGHelper.APNGHelper(this, @"monkey.png"); - } - - /// - /// UnloadContent will be called once per game and is the place to unload - /// all content. - /// - protected override void UnloadContent() - { - // TODO: Unload any non ContentManager content here - } - - /// - /// Allows the game to run logic such as updating the world, - /// checking for collisions, gathering input, and playing audio. - /// - /// Provides a snapshot of timing values. - protected override void Update(GameTime gameTime) - { - // Allows the game to exit - if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) - Exit(); - - apng.Update(gameTime); - - base.Update(gameTime); - } - - /// - /// This is called when the game should draw itself. - /// - /// Provides a snapshot of timing values. - protected override void Draw(GameTime gameTime) - { - GraphicsDevice.Clear(Color.CornflowerBlue); - - spriteBatch.Begin(); - spriteBatch.Draw(apng.CurrentFrame, new Vector2(40, 40), Color.White); - spriteBatch.End(); - - base.Draw(gameTime); - } - } -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/GameThumbnail.png b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/GameThumbnail.png deleted file mode 100644 index 462311a..0000000 Binary files a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/GameThumbnail.png and /dev/null differ diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/LibAPNG.XNA.Test.csproj b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/LibAPNG.XNA.Test.csproj deleted file mode 100644 index 42b4de0..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/LibAPNG.XNA.Test.csproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - {35CF1CD3-A197-4A14-9B92-15868DC808E5} - {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Debug - x86 - WinExe - Properties - LibAPNGTest - LibAPNG.XNA.Test - v4.0 - Client - v4.0 - Windows - HiDef - f0367e71-a447-49c0-b20a-c5fbceeda8f5 - Game - Game.ico - GameThumbnail.png - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\x86\Debug - DEBUG;TRACE;WINDOWS - prompt - 4 - true - false - x86 - false - - - pdbonly - true - bin\x86\Release - TRACE;WINDOWS - prompt - 4 - true - false - x86 - true - - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - - False - Microsoft .NET Framework 4 Client Profile %28x86 和 x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Windows Installer 3.1 - true - - - False - Microsoft XNA Framework Redistributable 4.0 - true - - - - - {6A14ED50-7995-4EAF-B6D5-6E734283B415} - LibAPNG - - - - - - \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Program.cs b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Program.cs deleted file mode 100644 index 319ae84..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace LibAPNGTest -{ -#if WINDOWS || XBOX - - internal static class Program - { - /// - /// The main entry point for the application. - /// - private static void Main(string[] args) - { - using (var game = new Game1()) - { - game.Run(); - } - } - } - -#endif -} \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Properties/AssemblyInfo.cs b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Properties/AssemblyInfo.cs deleted file mode 100644 index 40c2aa4..0000000 --- a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("LibAPNG.XNA.Test")] -[assembly: AssemblyProduct("LibAPNG.XNA.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyCompany("Amemiya")] -[assembly: AssemblyCopyright("Copyright © Amemiya 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. Only Windows -// assemblies support COM. - -[assembly: ComVisible(false)] - -// On Windows, the following GUID is for the ID of the typelib if this -// project is exposed to COM. On other platforms, it unique identifies the -// title storage container when deploying this assembly to the device. - -[assembly: Guid("9318ec54-4af9-4eda-bfa3-0d6a489d23b6")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly: AssemblyVersion("1.0.0.0")] \ No newline at end of file diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/firefox.png b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/firefox.png deleted file mode 100644 index 3947c13..0000000 Binary files a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/firefox.png and /dev/null differ diff --git a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/monkey.png b/LibAPNG.XNA.Test/LibAPNG.XNA.Test/monkey.png deleted file mode 100644 index 4691539..0000000 Binary files a/LibAPNG.XNA.Test/LibAPNG.XNA.Test/monkey.png and /dev/null differ diff --git a/LibAPNG/APNG.cs b/LibAPNG/APNG.cs index 0cd3d5f..9ec676a 100644 --- a/LibAPNG/APNG.cs +++ b/LibAPNG/APNG.cs @@ -44,7 +44,6 @@ public APNG(byte[] fileBytes) { case "IHDR": throw new Exception("Only single IHDR is allowed."); - break; case "acTL": if (IsSimplePNG) @@ -80,12 +79,12 @@ public APNG(byte[] fileBytes) if (frame != null) frames.Add(frame); frame = new Frame - { - IHDRChunk = IHDRChunk, - fcTLChunk = new fcTLChunk(chunk) - }; + { + IHDRChunk = IHDRChunk, + fcTLChunk = new fcTLChunk(chunk) + }; } - // Otherwise this fcTL is used by the DEFAULT IMAGE. + // Otherwise this fcTL is used by the DEFAULT IMAGE. else { defaultImage.fcTLChunk = new fcTLChunk(chunk); diff --git a/LibAPNG/Chunks/Chunk.cs b/LibAPNG/Chunks/Chunk.cs index 670f5b7..ef95c6d 100644 --- a/LibAPNG/Chunks/Chunk.cs +++ b/LibAPNG/Chunks/Chunk.cs @@ -78,9 +78,9 @@ public byte[] RawData /// /// Modify the ChunkData part. /// - public void ModifyChunkData(int postion, byte[] newData) + public void ModifyChunkData(int position, byte[] newData) { - Array.Copy(newData, 0, ChunkData, postion, newData.Length); + Array.Copy(newData, 0, ChunkData, position, newData.Length); using (var msCrc = new MemoryStream()) { @@ -94,9 +94,9 @@ public void ModifyChunkData(int postion, byte[] newData) /// /// Modify the ChunkData part. /// - public void ModifyChunkData(int postion, uint newData) + public void ModifyChunkData(int position, uint newData) { - ModifyChunkData(postion, BitConverter.GetBytes(newData)); + ModifyChunkData(position, BitConverter.GetBytes(newData)); } protected virtual void ParseData(MemoryStream ms) diff --git a/LibAPNG/Chunks/fdATChunk.cs b/LibAPNG/Chunks/fdATChunk.cs index 1246452..2e7f053 100644 --- a/LibAPNG/Chunks/fdATChunk.cs +++ b/LibAPNG/Chunks/fdATChunk.cs @@ -34,7 +34,7 @@ public IDATChunk ToIDATChunk() uint newCrc; using (var msCrc = new MemoryStream()) { - msCrc.WriteBytes(new[] {(byte)'I', (byte)'D', (byte)'A', (byte)'T'}); + msCrc.WriteBytes(new[] { (byte)'I', (byte)'D', (byte)'A', (byte)'T' }); msCrc.WriteBytes(FrameData); newCrc = CrcHelper.Calculate(msCrc.ToArray()); @@ -43,7 +43,7 @@ public IDATChunk ToIDATChunk() using (var ms = new MemoryStream()) { ms.WriteUInt32(Helper.ConvertEndian(Length - 4)); - ms.WriteBytes(new[] {(byte)'I', (byte)'D', (byte)'A', (byte)'T'}); + ms.WriteBytes(new[] { (byte)'I', (byte)'D', (byte)'A', (byte)'T' }); ms.WriteBytes(FrameData); ms.WriteUInt32(Helper.ConvertEndian(newCrc)); ms.Position = 0; diff --git a/LibAPNG/Frame.cs b/LibAPNG/Frame.cs index 071ab40..7ce1701 100644 --- a/LibAPNG/Frame.cs +++ b/LibAPNG/Frame.cs @@ -8,7 +8,7 @@ namespace LibAPNG /// public class Frame { - public static byte[] Signature = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; + public static byte[] Signature = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; private List idatChunks = new List(); private List otherChunks = new List(); @@ -76,17 +76,17 @@ public MemoryStream GetStream() } // Write image data - using (var ms = new MemoryStream()) - { - ms.WriteBytes(Signature); - ms.WriteBytes(ihdrChunk.RawData); - otherChunks.ForEach(o => ms.WriteBytes(o.RawData)); - idatChunks.ForEach(i => ms.WriteBytes(i.RawData)); - ms.WriteBytes(IENDChunk.RawData); + var ms = new MemoryStream(); - ms.Position = 0; - return ms; - } + ms.WriteBytes(Signature); + ms.WriteBytes(ihdrChunk.RawData); + otherChunks.ForEach(o => ms.WriteBytes(o.RawData)); + idatChunks.ForEach(i => ms.WriteBytes(i.RawData)); + ms.WriteBytes(IENDChunk.RawData); + + ms.Flush(); + ms.Position = 0; + return ms; } } } \ No newline at end of file diff --git a/LibAPNG/LibAPNG.csproj b/LibAPNG/LibAPNG.csproj index 8351b92..9f5c4f4 100644 --- a/LibAPNG/LibAPNG.csproj +++ b/LibAPNG/LibAPNG.csproj @@ -1,69 +1,7 @@ - - + + - Debug - AnyCPU - 8.0.30703 - 2.0 - {6A14ED50-7995-4EAF-B6D5-6E734283B415} - Library - Properties - LibAPNG - LibAPNG - v4.0 - 512 - Client + netstandard2.0 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - bin\Debug\LibAPNG.xml - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + diff --git a/LibAPNG/Properties/AssemblyInfo.cs b/LibAPNG/Properties/AssemblyInfo.cs deleted file mode 100644 index e4e585f..0000000 --- a/LibAPNG/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 - -[assembly: AssemblyTitle("LibAPNG")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Amemiya")] -[assembly: AssemblyProduct("LibAPNG")] -[assembly: AssemblyCopyright("Copyright © Amemiya 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 - -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID - -[assembly: Guid("9c5d262b-6ff9-4b72-b8c5-d5598cddc2ab")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 内部版本号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("0.2.*")] \ No newline at end of file diff --git a/README.md b/README.md index e308433..2b115b2 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,50 @@ # APNG.NET -*A fully-managed APNG Parser* -## Introduction -I've been searching for days looking for a simple, easy-to-use animation controller for my game engine until I found [this article](http://www.codeproject.com/Articles/36179/APNG-Viewer). Then I noticed I could use APNG to bundle multiply image into one single file and describe the animation process internally (no coding needed). In APNG format, each frame have an `fcTL` chunk (frame control chunk), which contains many useful information such as `frame_height`; `x_offset` and `delay_time`. So we can set all these up when we build an APNG and copy it directly to game folder - no any coding needed. +*A fully-managed APNG (Animated Portable Network Graphics) Parser* -## PNG and APNG specification support status -* For simple PNG, All chunks but `IHDR`, `IDAT` and `IEND` are **unsupported**, and will be **ignored** during the parsing. -* For APNG, the library **can only** parse `IHDR`, `acTL`, `fcTL`, `IDAT`, `fdAT` and `IEND` chunks. -* Multiply frame sizes are **supported**. This means you can reduce the file size by using *Differential Frames*. (use [APNG Anime Maker](https://sites.google.com/site/cphktool/apng-anime-maker)) -* All `DISPOSE_OP` and `BLEND_OP` are **supported**. +**Original is https://github.com/xupefei/APNG.NET** -## What's next +## Difference -* *Differential frames* support in `LibAPNG.XNA.APNGPipelineExtension`. +* LibAPNG is **.NET Standard** libary +* Extensions for **WPF** (.NET Framework) + * Convert each PNG frame to `BitmapSource` objects + * Create key frame animation, So you can display APNG to `Image` control using `Storyboard`. +* Remove XNA projects +* Update to Visual Studio 2019 -## About the code +## Usages -This repository contains 5 projects: +### APNG to BitmapSource objects -Basic component: +```cs +var apng = new APNG("a.png"); +var bitmaps = apng.ToBitmapSources(); -* **APNG Parser** -> An managed DLL which handle parsing APNG image file. -> This library is *backward-compatible*: It means you can use this library to read an simple PNG image, with no error produced. +// Save to PNG files +foreach (var (bitmap, index) in bitmaps.Select((item, index) => (item, index))) +{ + using (var fileStream = new FileStream($"{index}.png", FileMode.Create)) + { + var encoder = new PngBitmapEncoder(); + encoder.Frames.Add(BitmapFrame.Create(bitmap)); + encoder.Save(fileStream); + } +} +``` -* **APNG Test Extractor** -> A test application which can extract each frame of an APNG to standalone PNG files. +### Display APNG to Image control -Component for [Microsoft XNA](http://en.wikipedia.org/wiki/Microsoft_XNA): +```xml + +``` -* **APNG Wrapper for XNA** -> A simple game which use an APNG as animation (NOT USING CONTENT PIPELINE). - -* **Content Pipeline for APNG Images** -> Compile .apng file into .xnb assets, which can significantly reduce the load time (We move those costs from **running** to **compiling**). - -* **Test Game that Use Content Pipeline for Loading APNG Images** -> As titled. - -To compile this project, you must have these components installed: - -* Visual Studio 2013. -* Microsoft XNA Game Studio 4.0 *or* Windows Phone SDK 7.1 - -## Useful links - -* [http://en.wikipedia.org/wiki/APNG](http://en.wikipedia.org/wiki/APNG) -* [PNG (Portable Network Graphics) Specification](http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html) -* [APNG (Animated Portable Network Graphics) Specification](https://wiki.mozilla.org/APNG_Specification) -* [APNG Anime Maker](https://sites.google.com/site/cphktool/apng-anime-maker) +```cs +var apng = new APNG("a.png"); +if (apng.IsSimplePNG) + PngImage.Source = BitmapFrame.Create( + apng.DefaultImage.GetStream(), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); +else + apng.ToAnimation().CreateStoryboardFor(PngImage).Begin(PngImage); +``` diff --git a/README_original.md b/README_original.md new file mode 100644 index 0000000..3d5c650 --- /dev/null +++ b/README_original.md @@ -0,0 +1,52 @@ +# APNG.NET +*A fully-managed APNG Parser* + +## Introduction +I've been searching for days looking for a simple, easy-to-use animation controller for my game engine until I found [this article](http://www.codeproject.com/Articles/36179/APNG-Viewer). Then I noticed I could use APNG to bundle multiply image into one single file and describe the animation process internally (no coding needed). In APNG format, each frame have an `fcTL` chunk (frame control chunk), which contains many useful information such as `frame_height`; `x_offset` and `delay_time`. So we can set all these up when we build an APNG and copy it directly to game folder - no any coding needed. + +## PNG and APNG specification support status + +* For simple PNG, All chunks but `IHDR`, `IDAT` and `IEND` are **unsupported**, and will be **ignored** during the parsing. +* For APNG, the library **can only** parse `IHDR`, `acTL`, `fcTL`, `IDAT`, `fdAT` and `IEND` chunks. +* Multiply frame sizes are **supported**. This means you can reduce the file size by using *Differential Frames*. (use [APNG Anime Maker](https://sites.google.com/site/cphktool/apng-anime-maker)) +* All `DISPOSE_OP` and `BLEND_OP` are **supported**. + +## What's next + +* *Differential frames* support in `LibAPNG.XNA.APNGPipelineExtension`. + +## About the code + +This repository contains 5 projects: + +Basic component: + +* **APNG Parser** +> An managed DLL which handle parsing APNG image file. +> This library is *backward-compatible*: It means you can use this library to read an simple PNG image, with no error produced. + +* **APNG Test Extractor** +> A test application which can extract each frame of an APNG to standalone PNG files. + +Component for [Microsoft XNA](http://en.wikipedia.org/wiki/Microsoft_XNA): + +* **APNG Wrapper for XNA** +> A simple game which use an APNG as animation (NOT USING CONTENT PIPELINE). + +* **Content Pipeline for APNG Images** +> Compile .apng file into .xnb assets, which can significantly reduce the load time (We move those costs from **running** to **compiling**). + +* **Test Game that Use Content Pipeline for Loading APNG Images** +> As titled. + +To compile this project, you must have these components installed: + +* Visual Studio 2013. +* Microsoft XNA Game Studio 4.0 *or* Windows Phone SDK 7.1 + +## Useful links + +* [http://en.wikipedia.org/wiki/APNG](http://en.wikipedia.org/wiki/APNG) +* [PNG (Portable Network Graphics) Specification](http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html) +* [APNG (Animated Portable Network Graphics) Specification](https://wiki.mozilla.org/APNG_Specification) +* [APNG Anime Maker](https://sites.google.com/site/cphktool/apng-anime-maker)