PngUtility.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using System;
  2. using System.IO;
  3. namespace MeidoPhotoStudio.Converter.Utility
  4. {
  5. internal static class PngUtility
  6. {
  7. private static readonly byte[] PngHeader = { 137, 80, 78, 71, 13, 10, 26, 10 };
  8. private static readonly byte[] PngEnd = System.Text.Encoding.ASCII.GetBytes("IEND");
  9. public static byte[]? ExtractPng(Stream stream)
  10. {
  11. var memoryStream = new MemoryStream();
  12. var headerBuffer = new byte[PngHeader.Length];
  13. stream.Read(headerBuffer, 0, headerBuffer.Length);
  14. if (!MeidoPhotoStudio.Plugin.Utility.BytesEqual(headerBuffer, PngHeader))
  15. return null;
  16. memoryStream.Write(headerBuffer, 0, headerBuffer.Length);
  17. var fourByteBuffer = new byte[4];
  18. var chunkBuffer = new byte[1024];
  19. try
  20. {
  21. do
  22. {
  23. // chunk length
  24. var read = stream.Read(fourByteBuffer, 0, 4);
  25. memoryStream.Write(fourByteBuffer, 0, read);
  26. if (BitConverter.IsLittleEndian)
  27. Array.Reverse(fourByteBuffer);
  28. var length = BitConverter.ToUInt32(fourByteBuffer, 0);
  29. // chunk type
  30. read = stream.Read(fourByteBuffer, 0, 4);
  31. memoryStream.Write(fourByteBuffer, 0, read);
  32. if (chunkBuffer.Length < length + 4L)
  33. chunkBuffer = new byte[length + 4L];
  34. // chunk data + CRC
  35. read = stream.Read(chunkBuffer, 0, (int)(length + 4L));
  36. memoryStream.Write(chunkBuffer, 0, read);
  37. } while (!MeidoPhotoStudio.Plugin.Utility.BytesEqual(fourByteBuffer, PngEnd));
  38. }
  39. catch
  40. {
  41. return null;
  42. }
  43. return memoryStream.ToArray();
  44. }
  45. }
  46. }