diff --git a/.gitignore b/.gitignore
index 1350c51..163f6dc 100755
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ Debug
*.suo
packages
*.user
+.vs/
+*.lock.json
TestResults
*/App_Data/user_uploads
PublishProfiles
diff --git a/PNGDecrush/BinaryReaderNetworkHostOrderAdditions.cs b/PNGDecrush/BinaryReaderNetworkHostOrderAdditions.cs
index 5bda781..39e57e3 100755
--- a/PNGDecrush/BinaryReaderNetworkHostOrderAdditions.cs
+++ b/PNGDecrush/BinaryReaderNetworkHostOrderAdditions.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Web;
+using System.IO;
namespace PNGDecrush
{
diff --git a/PNGDecrush/CRC32.cs b/PNGDecrush/CRC32.cs
new file mode 100644
index 0000000..5d7c2bb
--- /dev/null
+++ b/PNGDecrush/CRC32.cs
@@ -0,0 +1,225 @@
+// CRC32.cs
+// ------------------------------------------------------------------
+//
+// Copyright (c) 2011 Dino Chiesa.
+// All rights reserved.
+//
+// This code module is part of DotNetZip, a zipfile class library.
+//
+// ------------------------------------------------------------------
+//
+// This code is licensed under the Microsoft Public License.
+// See the file License.txt for the license details.
+// More info on: http://dotnetzip.codeplex.com
+//
+// ------------------------------------------------------------------
+//
+// Last Saved: <2011-August-02 18:25:54>
+//
+// ------------------------------------------------------------------
+//
+// This module defines the CRC32 class, which can do the CRC32 algorithm, using
+// arbitrary starting polynomials, and bit reversal. The bit reversal is what
+// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP
+// files, or GZIP files. This class does both.
+//
+// ------------------------------------------------------------------
+
+
+using System;
+using Interop = System.Runtime.InteropServices;
+
+namespace Ionic.Crc
+{
+ ///
+ /// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
+ /// can set the polynomial and enable or disable bit
+ /// reversal. This can be used for GZIP, BZip2, or ZIP.
+ ///
+ ///
+ /// This type is used internally by DotNetZip; it is generally not used
+ /// directly by applications wishing to create, read, or manipulate zip
+ /// archive files.
+ ///
+
+ [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000C")]
+ [Interop.ComVisible(true)]
+#if !NETCF
+ [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
+#endif
+ public class CRC32
+ {
+ ///
+ /// Indicates the current CRC for all blocks slurped in.
+ ///
+ public Int32 Crc32Result
+ {
+ get
+ {
+ return unchecked((Int32)(~_register));
+ }
+ }
+
+ ///
+ /// Update the value for the running CRC32 using the given block of bytes.
+ /// This is useful when using the CRC32() class in a Stream.
+ ///
+ /// block of bytes to slurp
+ /// starting point in the block
+ /// how many bytes within the block to slurp
+ public void SlurpBlock(byte[] block, int offset, int count)
+ {
+ if (block == null)
+ throw new Exception("The data buffer must not be null.");
+
+ // bzip algorithm
+ for (int i = 0; i < count; i++)
+ {
+ int x = offset + i;
+ byte b = block[x];
+ if (this.reverseBits)
+ {
+ UInt32 temp = (_register >> 24) ^ b;
+ _register = (_register << 8) ^ crc32Table[temp];
+ }
+ else
+ {
+ UInt32 temp = (_register & 0x000000FF) ^ b;
+ _register = (_register >> 8) ^ crc32Table[temp];
+ }
+ }
+ _TotalBytesRead += count;
+ }
+
+ private static uint ReverseBits(uint data)
+ {
+ unchecked
+ {
+ uint ret = data;
+ ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555;
+ ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333;
+ ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F;
+ ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24);
+ return ret;
+ }
+ }
+
+ private static byte ReverseBits(byte data)
+ {
+ unchecked
+ {
+ uint u = (uint)data * 0x00020202;
+ uint m = 0x01044010;
+ uint s = u & m;
+ uint t = (u << 2) & (m << 1);
+ return (byte)((0x01001001 * (s + t)) >> 24);
+ }
+ }
+
+
+
+ private void GenerateLookupTable()
+ {
+ crc32Table = new UInt32[256];
+ unchecked
+ {
+ UInt32 dwCrc;
+ byte i = 0;
+ do
+ {
+ dwCrc = i;
+ for (byte j = 8; j > 0; j--)
+ {
+ if ((dwCrc & 1) == 1)
+ {
+ dwCrc = (dwCrc >> 1) ^ dwPolynomial;
+ }
+ else
+ {
+ dwCrc >>= 1;
+ }
+ }
+ if (reverseBits)
+ {
+ crc32Table[ReverseBits(i)] = ReverseBits(dwCrc);
+ }
+ else
+ {
+ crc32Table[i] = dwCrc;
+ }
+ i++;
+ } while (i!=0);
+ }
+ }
+
+ ///
+ /// Create an instance of the CRC32 class using the default settings: no
+ /// bit reversal, and a polynomial of 0xEDB88320.
+ ///
+ public CRC32() : this(false)
+ {
+ }
+
+ ///
+ /// Create an instance of the CRC32 class, specifying whether to reverse
+ /// data bits or not.
+ ///
+ ///
+ /// specify true if the instance should reverse data bits.
+ ///
+ ///
+ ///
+ /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
+ /// want a CRC32 with compatibility with BZip2, you should pass true
+ /// here. In the CRC-32 used by GZIP and PKZIP, the bits are not
+ /// reversed; Therefore if you want a CRC32 with compatibility with
+ /// those, you should pass false.
+ ///
+ ///
+ public CRC32(bool reverseBits) :
+ this( unchecked((int)0xEDB88320), reverseBits)
+ {
+ }
+
+
+ ///
+ /// Create an instance of the CRC32 class, specifying the polynomial and
+ /// whether to reverse data bits or not.
+ ///
+ ///
+ /// The polynomial to use for the CRC, expressed in the reversed (LSB)
+ /// format: the highest ordered bit in the polynomial value is the
+ /// coefficient of the 0th power; the second-highest order bit is the
+ /// coefficient of the 1 power, and so on. Expressed this way, the
+ /// polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320.
+ ///
+ ///
+ /// specify true if the instance should reverse data bits.
+ ///
+ ///
+ ///
+ ///
+ /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
+ /// want a CRC32 with compatibility with BZip2, you should pass true
+ /// here for the reverseBits parameter. In the CRC-32 used by
+ /// GZIP and PKZIP, the bits are not reversed; Therefore if you want a
+ /// CRC32 with compatibility with those, you should pass false for the
+ /// reverseBits parameter.
+ ///
+ ///
+ public CRC32(int polynomial, bool reverseBits)
+ {
+ this.reverseBits = reverseBits;
+ this.dwPolynomial = (uint) polynomial;
+ this.GenerateLookupTable();
+ }
+
+ // private member vars
+ private UInt32 dwPolynomial;
+ private Int64 _TotalBytesRead;
+ private bool reverseBits;
+ private UInt32[] crc32Table;
+ private const int BUFFER_SIZE = 8192;
+ private UInt32 _register = 0xFFFFFFFFU;
+ }
+}
\ No newline at end of file
diff --git a/PNGDecrush/NuGet.config b/PNGDecrush/NuGet.config
new file mode 100644
index 0000000..1cfaa82
--- /dev/null
+++ b/PNGDecrush/NuGet.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PNGDecrush/PNGChunk.cs b/PNGDecrush/PNGChunk.cs
index cae6365..ff5997f 100755
--- a/PNGDecrush/PNGChunk.cs
+++ b/PNGDecrush/PNGChunk.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-
-namespace PNGDecrush
+namespace PNGDecrush
{
public class PNGChunk
{
diff --git a/PNGDecrush/PNGChunkParser.cs b/PNGDecrush/PNGChunkParser.cs
index 67eeb47..b128b85 100755
--- a/PNGDecrush/PNGChunkParser.cs
+++ b/PNGDecrush/PNGChunkParser.cs
@@ -2,9 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Text;
-using System.Web;
namespace PNGDecrush
{
diff --git a/PNGDecrush/PNGDecrush.csproj b/PNGDecrush/PNGDecrush.csproj
old mode 100755
new mode 100644
index 5aebf89..3918d30
--- a/PNGDecrush/PNGDecrush.csproj
+++ b/PNGDecrush/PNGDecrush.csproj
@@ -1,63 +1,28 @@
-
-
-
+
+
- Debug
- AnyCPU
- {447066CB-DDC0-41C2-90F2-84F056786CC7}
- Library
- Properties
- PNGDecrush
- PNGDecrush
- v4.5
- 512
+ netcoreapp2.0;net45;netstandard1.3
+ PNGDecrush is a C# library for reversing the optimization process that is applied to PNG files in an iOS project.
+ Mike Weller
+ Mike Weller
+ PNGDecrush - Decrush iOS PNG files
+ PNGDecrush - Decrush iOS PNG files
+ https://github.com/MikeWeller/PNGDecrush/
+ https://github.com/MikeWeller/PNGDecrush/blob/master/LICENSE
+ true
+ PNGDecrush.snk
+ 1.0.1
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
-
-
\ No newline at end of file
+
diff --git a/PNGDecrush/PNGDecrush.snk b/PNGDecrush/PNGDecrush.snk
new file mode 100644
index 0000000..0d43480
Binary files /dev/null and b/PNGDecrush/PNGDecrush.snk differ
diff --git a/PNGDecrush/PNGDecrusher.cs b/PNGDecrush/PNGDecrusher.cs
index 460f068..cdd5567 100755
--- a/PNGDecrush/PNGDecrusher.cs
+++ b/PNGDecrush/PNGDecrusher.cs
@@ -1,4 +1,4 @@
-using Ionic.Zlib;
+using Ionic.Crc;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -6,8 +6,8 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
+using System.Net;
using System.Text;
-using System.Web;
namespace PNGDecrush
{
@@ -36,8 +36,8 @@ public static IEnumerable DecrushChunks(IEnumerable chunks)
{
throw new InvalidDataException("Could not find a CgBI chunk. Image wasn't crushed with Apple's -iohone option.");
}
-
- return ConvertIDATChunksFromDeflateToZlib(chunksWithoutAppleChunk);;
+
+ return ConvertIDATChunksFromDeflateToZlib(chunksWithoutAppleChunk); ;
}
private static IEnumerable ConvertIDATChunksFromDeflateToZlib(IEnumerable inputChunks)
@@ -135,14 +135,72 @@ private static byte[] CombinedDataFromChunks(IEnumerable chunks)
private static byte[] ConvertDeflateToZlib(byte[] input)
{
- using (MemoryStream deflateData = new MemoryStream(input))
- using (System.IO.Compression.DeflateStream deflateStream = new System.IO.Compression.DeflateStream(deflateData, System.IO.Compression.CompressionMode.Decompress))
- using (ZlibStream zlibStream = new ZlibStream(deflateStream, Ionic.Zlib.CompressionMode.Compress))
- using (MemoryStream zlibData = new MemoryStream())
+ // Basically, we wrap the deflate stram in a zlib format.
+ // Because zlib includes a checksum of the decompressed data,
+ // we need to decompress all data.
+
+ // The zlib format is as follows:
+ // zlib format (wrapper around the deflate format):
+ // +---+---+
+ // |CMF|FLG| (2 bytes)
+ // +---+---+
+ // +---+---+---+---+
+ // | DICTID | (4 bytes. Present only when FLG.FDICT is set.) - Mostly not set
+ // +---+---+---+---+
+ // +=====================+
+ // |...compressed data...| (variable size of data)
+ // +=====================+
+ // +---+---+---+---+
+ // | ADLER32 | (4 bytes of checksum)
+ // +---+---+---+---+
+ //
+ // +---+---+
+ // |CMF|FLG|
+ // +---+---+
+ //
+ // 78 01 - No Compression/low
+ // 78 9C - Default Compression
+ // 78 DA - Best Compression
+
+ byte[] bytes;
+
+ using (MemoryStream compressedData = new MemoryStream(input))
+ using (DeflateStream deflateStream = new DeflateStream(compressedData, CompressionMode.Decompress))
+ using (MemoryStream decompressedData = new MemoryStream())
+ {
+ // Decompress all data
+ deflateStream.CopyTo(decompressedData);
+ bytes = decompressedData.ToArray();
+ }
+
+ using (MemoryStream recompressedData = new MemoryStream())
+ {
+ recompressedData.WriteByte(0x78);
+ recompressedData.WriteByte(0x9C);
+ using (var compressor = new DeflateStream(recompressedData, CompressionMode.Compress, true))
+ {
+ compressor.Write(bytes, 0, bytes.Length);
+ compressor.Flush();
+ }
+
+ recompressedData.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Adler32(bytes))), 0, sizeof(uint));
+
+ return recompressedData.ToArray();
+ }
+ }
+
+
+ // naive implementation of adler-32 checksum
+ static int Adler32(byte[] bytes)
+ {
+ const uint a32mod = 65521;
+ uint s1 = 1, s2 = 0;
+ foreach (byte b in bytes)
{
- zlibStream.CopyTo(zlibData);
- return zlibData.ToArray();
+ s1 = (s1 + b) % a32mod;
+ s2 = (s2 + s1) % a32mod;
}
+ return unchecked((int)((s2 << 16) + s1));
}
private static IEnumerable ChunksByRemovingAppleCgBIChunks(IEnumerable chunks)
@@ -154,7 +212,7 @@ public static uint CalculateCRCForChunk(string chunkType, byte[] chunkData)
{
byte[] chunkTypeBytes = Encoding.UTF8.GetBytes(chunkType);
- Ionic.Crc.CRC32 crc32calculator = new Ionic.Crc.CRC32();
+ CRC32 crc32calculator = new CRC32();
crc32calculator.SlurpBlock(chunkTypeBytes, 0, chunkTypeBytes.Length);
crc32calculator.SlurpBlock(chunkData, 0, chunkData.Length);
@@ -260,4 +318,4 @@ private static void ReversePremultipliedAlpha(byte[] pixelData, uint startOffset
pixelData[startOffset + 2] = (byte)((pixelData[startOffset + 2] * 255) / alpha);
}
}
-}
\ No newline at end of file
+}
diff --git a/PNGDecrush/Properties/AssemblyInfo.cs b/PNGDecrush/Properties/AssemblyInfo.cs
deleted file mode 100755
index beee41d..0000000
--- a/PNGDecrush/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-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("PNGDecrush")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PNGDecrush")]
-[assembly: AssemblyCopyright("Copyright © 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("4a3f1a2a-4d23-4f20-a67a-d411b0a7f457")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PNGDecrush/packages.config b/PNGDecrush/packages.config
deleted file mode 100755
index 2a946e0..0000000
--- a/PNGDecrush/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/PNGDecrush/project.json b/PNGDecrush/project.json
new file mode 100644
index 0000000..c0e68b0
--- /dev/null
+++ b/PNGDecrush/project.json
@@ -0,0 +1,42 @@
+{
+ "version": "1.0.0-*",
+
+ "authors": [ "Mike Weller" ],
+ "title": "PNGDecrush - Decrush iOS PNG files",
+ "description": "PNGDecrush is a C# library for reversing the optimization process that is applied to PNG files in an iOS project.",
+
+ "packOptions": {
+ "licenseUrl": "https://github.com/MikeWeller/PNGDecrush/blob/master/LICENSE",
+ "owners": [ "Mike Weller" ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/MikeWeller/PNGDecrush/"
+ },
+ },
+
+ "dependencies": {
+ },
+
+ "buildOptions": {
+ "keyFile": "PNGDecrush.snk",
+ "strongName": true
+ },
+
+
+ "frameworks": {
+ "netstandard1.3": {
+ "dependencies": {
+ "CoreCompat.System.Drawing": "1.0.0-beta006",
+ "System.IO.Compression": "4.1.0",
+ "System.Linq": "4.1.0",
+ "System.Net.Primitives": "4.0.11"
+ }
+ },
+
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Drawing": "4.0.0.0"
+ }
+ }
+ }
+}
diff --git a/PNGDecrushTests/PNGDecrushTests.csproj b/PNGDecrushTests/PNGDecrushTests.csproj
index 1d76a85..aa52e67 100755
--- a/PNGDecrushTests/PNGDecrushTests.csproj
+++ b/PNGDecrushTests/PNGDecrushTests.csproj
@@ -1,96 +1,23 @@
-
-
+
+
- Debug
- AnyCPU
- {B58EE7E0-77FE-44B3-9867-898D23408804}
- Library
- Properties
- PNGDecrushTests
- PNGDecrushTests
- v4.5
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
- $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
- False
- UnitTest
+ netcoreapp2.0
+
+ false
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\PNGDecrush\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
+
+
-
+
+
-
- {447066cb-ddc0-41c2-90f2-84f056786cc7}
- PNGDecrush
-
+
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/PNGDecrushTests/Properties/AssemblyInfo.cs b/PNGDecrushTests/Properties/AssemblyInfo.cs
deleted file mode 100755
index d021f23..0000000
--- a/PNGDecrushTests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-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("PNGDecrushTests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PNGDecrushTests")]
-[assembly: AssemblyCopyright("Copyright © 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("51e51633-f7af-47ca-806b-cfa2256ad6d7")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PNGDecrushTests/packages.config b/PNGDecrushTests/packages.config
deleted file mode 100755
index 2a946e0..0000000
--- a/PNGDecrushTests/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..2f05c32
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,8 @@
+image: Previous Visual Studio 2017
+
+build_script:
+ - cmd: cd PNGDecrush
+ - cmd: dotnet restore
+ - cmd: dotnet build -c Release --version-suffix r%APPVEYOR_BUILD_NUMBER%
+ - cmd: dotnet pack -c Release --version-suffix r%APPVEYOR_BUILD_NUMBER%
+ - ps: Push-AppveyorArtifact "bin\Release\PNGDecrush.1.0.1-r$($env:APPVEYOR_BUILD_NUMBER).nupkg"