ZipPredict16Image.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Photoshop PSD FileType Plugin for Paint.NET
  4. // http://psdplugin.codeplex.com/
  5. //
  6. // This software is provided under the MIT License:
  7. // Copyright (c) 2006-2007 Frank Blumenberg
  8. // Copyright (c) 2010-2016 Tao Yue
  9. //
  10. // See LICENSE.txt for complete licensing and attribution information.
  11. //
  12. /////////////////////////////////////////////////////////////////////////////////
  13. using System;
  14. using PDNWrapper;
  15. using System.IO.Compression;
  16. namespace PhotoshopFile.Compression
  17. {
  18. internal class ZipPredict16Image : ImageData
  19. {
  20. private ImageData zipImage;
  21. protected override bool AltersWrittenData
  22. {
  23. get { return true; }
  24. }
  25. public ZipPredict16Image(byte[] zipData, Size size)
  26. : base(size, 16)
  27. {
  28. // 16-bitdepth images are delta-encoded word-by-word. The deltas
  29. // are thus big-endian and must be reversed for further processing.
  30. var zipRawImage = new ZipImage(zipData, size, 16);
  31. zipImage = new EndianReverser(zipRawImage);
  32. }
  33. internal override void Read(byte[] buffer)
  34. {
  35. if (buffer.Length == 0)
  36. {
  37. return;
  38. }
  39. zipImage.Read(buffer);
  40. {
  41. {
  42. Unpredict(buffer);
  43. }
  44. }
  45. }
  46. public override byte[] ReadCompressed()
  47. {
  48. return zipImage.ReadCompressed();
  49. }
  50. private void Predict(/*UInt16**/ byte[] ptrData)
  51. {
  52. int size = sizeof(UInt16);
  53. // Delta-encode each row
  54. for (int i = 0; i < Size.Height; i++)
  55. {
  56. int rowOffset = Size.Width * i * size;
  57. //UInt16* ptrDataRow = ptrData;
  58. var ptrDataRowEnd = Size.Width - 1;
  59. // Start with the last column in the row
  60. while (ptrDataRowEnd > 0)
  61. {
  62. var v = BitConverter.ToUInt16(ptrData, ptrDataRowEnd * size + rowOffset);
  63. var v1 = BitConverter.ToUInt16(ptrData, (ptrDataRowEnd - 1) * size + rowOffset);
  64. v -= v1;
  65. var b = BitConverter.GetBytes(v);
  66. for (int c = 0; c < b.Length; ++c)
  67. {
  68. ptrData[ptrDataRowEnd * size + rowOffset + c] = b[c];
  69. }
  70. ptrDataRowEnd--;
  71. }
  72. }
  73. }
  74. /// <summary>
  75. /// Unpredicts the decompressed, native-endian image data.
  76. /// </summary>
  77. private void Unpredict(byte[] ptrData)
  78. {
  79. int size = sizeof(UInt16);
  80. // Delta-decode each row
  81. for (int i = 0; i < Size.Height; i++)
  82. {
  83. //UInt16* ptrDataRowEnd = ptrData + Size.Width;
  84. int rowOffset = Size.Width * i * size;
  85. // Start with column index 1 on each row
  86. int start = 1;
  87. while (start < Size.Width)
  88. {
  89. var v = BitConverter.ToUInt16(ptrData, start * size + rowOffset);
  90. var v1 = BitConverter.ToUInt16(ptrData, (start - 1) * size + rowOffset);
  91. v += v1;
  92. var b = BitConverter.GetBytes(v);
  93. for (int c = 0; c < b.Length; ++c)
  94. {
  95. ptrData[start * size + rowOffset + c] = b[c];
  96. }
  97. start++;
  98. }
  99. }
  100. }
  101. }
  102. }