PngUtility.cs 1.8 KB

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