|
@@ -0,0 +1,53 @@
|
|
|
|
+using System;
|
|
|
|
+using System.IO;
|
|
|
|
+
|
|
|
|
+namespace MeidoPhotoStudio.Converter.Utility
|
|
|
|
+{
|
|
|
|
+ internal static class PngUtility
|
|
|
|
+ {
|
|
|
|
+ private static readonly byte[] PngHeader = { 137, 80, 78, 71, 13, 10, 26, 10 };
|
|
|
|
+ private static readonly byte[] PngEnd = System.Text.Encoding.ASCII.GetBytes("IEND");
|
|
|
|
+
|
|
|
|
+ public static byte[]? ExtractPng(Stream stream)
|
|
|
|
+ {
|
|
|
|
+ var memoryStream = new MemoryStream();
|
|
|
|
+
|
|
|
|
+ var headerBuffer = new byte[PngHeader.Length];
|
|
|
|
+
|
|
|
|
+ stream.Read(headerBuffer, 0, headerBuffer.Length);
|
|
|
|
+
|
|
|
|
+ if (!MeidoPhotoStudio.Plugin.Utility.BytesEqual(headerBuffer, PngHeader))
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ memoryStream.Write(headerBuffer, 0, headerBuffer.Length);
|
|
|
|
+
|
|
|
|
+ var fourByteBuffer = new byte[4];
|
|
|
|
+ var chunkBuffer = new byte[1024];
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ // chunk length
|
|
|
|
+ var read = stream.Read(fourByteBuffer, 0, 4);
|
|
|
|
+ memoryStream.Write(fourByteBuffer, 0, read);
|
|
|
|
+
|
|
|
|
+ if (BitConverter.IsLittleEndian)
|
|
|
|
+ Array.Reverse(fourByteBuffer);
|
|
|
|
+
|
|
|
|
+ var length = BitConverter.ToUInt32(fourByteBuffer, 0);
|
|
|
|
+
|
|
|
|
+ // chunk type
|
|
|
|
+ read = stream.Read(fourByteBuffer, 0, 4);
|
|
|
|
+ memoryStream.Write(fourByteBuffer, 0, read);
|
|
|
|
+
|
|
|
|
+ if (chunkBuffer.Length < length + 4L)
|
|
|
|
+ chunkBuffer = new byte[length + 4L];
|
|
|
|
+
|
|
|
|
+ // chunk data + CRC
|
|
|
|
+ read = stream.Read(chunkBuffer, 0, (int)(length + 4L));
|
|
|
|
+ memoryStream.Write(chunkBuffer, 0, read);
|
|
|
|
+ } while (!MeidoPhotoStudio.Plugin.Utility.BytesEqual(fourByteBuffer, PngEnd));
|
|
|
|
+
|
|
|
|
+ return memoryStream.ToArray();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|