ZipPredict32Image.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. namespace PhotoshopFile.Compression
  16. {
  17. internal class ZipPredict32Image : ImageData
  18. {
  19. private ZipImage zipImage;
  20. protected override bool AltersWrittenData
  21. {
  22. // Prediction will pack the data into a temporary buffer, so the
  23. // original data will remain unchanged.
  24. get { return false; }
  25. }
  26. public ZipPredict32Image(byte[] zipData, Size size)
  27. : base(size, 32)
  28. {
  29. zipImage = new ZipImage(zipData, size, 32);
  30. }
  31. internal override void Read(byte[] buffer)
  32. {
  33. if (buffer.Length == 0)
  34. {
  35. return;
  36. }
  37. var predictedData = new byte[buffer.Length];
  38. zipImage.Read(predictedData);
  39. {
  40. //fixed (byte* ptrData = &predictedData[0])
  41. //fixed (byte* ptrOutput = &buffer[0])
  42. {
  43. Unpredict(predictedData, buffer);
  44. }
  45. }
  46. }
  47. public override byte[] ReadCompressed()
  48. {
  49. return zipImage.ReadCompressed();
  50. }
  51. private void Predict(byte[] ptrData, byte[] ptrOutput /*Int32* ptrData, byte* ptrOutput*/)
  52. {
  53. int size = sizeof(Int32);
  54. int inputIndex = 0;
  55. int outputIndex = 0;
  56. for (int i = 0; i < Size.Height; i++)
  57. {
  58. // Pack together the individual bytes of the 32-bit words, high-order
  59. // bytes before low-order bytes.
  60. int offset1 = Size.Width;
  61. int offset2 = 2 * offset1;
  62. int offset3 = 3 * offset1;
  63. //Int32* ptrDataRow = ptrData;
  64. //Int32* ptrDataRowEnd = ptrDataRow + Size.Width;
  65. int start = 0, end = Size.Width;
  66. //while (ptrData < ptrDataRowEnd)
  67. while (start < end)
  68. {
  69. Int32 data = BitConverter.ToInt32(ptrData, inputIndex);
  70. ptrOutput[start + outputIndex] = (byte)(data >> 24);
  71. ptrOutput[start + outputIndex + offset1] = (byte)(data >> 16);
  72. ptrOutput[start + outputIndex + offset2] = (byte)(data >> 8);
  73. ptrOutput[start + outputIndex + offset3] = (byte)(data);
  74. //ptrData++;
  75. //ptrOutput++;
  76. start++;
  77. inputIndex += size;
  78. }
  79. // Delta-encode the row
  80. //byte* ptrOutputRow = ptrOutput;
  81. //byte* ptrOutputRowEnd = ptrOutputRow + BytesPerRow;
  82. //ptrOutput = ptrOutputRowEnd - 1;
  83. start = BytesPerRow - 1;
  84. while (start > 0)
  85. {
  86. ptrOutput[start + outputIndex] -= ptrOutput[start + outputIndex - 1];
  87. start--;
  88. }
  89. outputIndex += BytesPerRow;
  90. // Advance pointer to next row
  91. //ptrOutput = ptrOutputRowEnd;
  92. //Debug.Assert(ptrData == ptrDataRowEnd);
  93. }
  94. }
  95. /// <summary>
  96. /// Unpredicts the raw decompressed image data into a 32-bpp bitmap with
  97. /// native endianness.
  98. /// </summary>
  99. private void Unpredict(byte[] ptrData, byte[] ptrOutput /*byte* ptrData, Int32* ptrOutput*/)
  100. {
  101. int inputIndex = 0;
  102. int outputIndex = 0;
  103. for (int i = 0; i < Size.Height; i++)
  104. {
  105. //byte* ptrDataRow = ptrData;
  106. //byte* ptrDataRowEnd = ptrDataRow + BytesPerRow;
  107. // Delta-decode each row
  108. //ptrData++;
  109. //while (ptrData < ptrDataRowEnd)
  110. int startIndex = 1;
  111. while (startIndex < BytesPerRow)
  112. {
  113. //*ptrData += *(ptrData - 1);
  114. //ptrData++;
  115. ptrData[inputIndex + startIndex] += ptrData[inputIndex + startIndex - 1];
  116. startIndex++;
  117. }
  118. // Within each row, the individual bytes of the 32-bit words are
  119. // packed together, high-order bytes before low-order bytes.
  120. // We now unpack them into words.
  121. int offset1 = Size.Width;
  122. int offset2 = 2 * offset1;
  123. int offset3 = 3 * offset1;
  124. //ptrData = ptrDataRow;
  125. //Int32* ptrOutputRowEnd = ptrOutput + Size.Width;
  126. //while (ptrOutput < ptrOutputRowEnd)
  127. startIndex = 0;
  128. while (startIndex < Size.Width)
  129. {
  130. Int32 pp = (Int32)ptrData[inputIndex + startIndex] << 24;
  131. pp |= (Int32)ptrData[inputIndex + startIndex + offset1] << 16;
  132. pp |= (Int32)ptrData[inputIndex + startIndex + offset2] << 8;
  133. pp |= (Int32)ptrData[inputIndex + startIndex + offset3];
  134. byte[] rr = BitConverter.GetBytes(pp);
  135. for (int k = 0; k < rr.Length; ++k)
  136. {
  137. ptrOutput[outputIndex] = rr[k];
  138. outputIndex++;
  139. }
  140. startIndex++;
  141. //*ptrOutput = *(ptrData) << 24
  142. // | *(ptrData + offset1) << 16
  143. // | *(ptrData + offset2) << 8
  144. // | *(ptrData + offset3);
  145. //ptrData++;
  146. //ptrOutput++;
  147. }
  148. // Advance pointer to next row
  149. //ptrData = ptrDataRowEnd;
  150. //Debug.Assert(ptrOutput == ptrOutputRowEnd);
  151. inputIndex += BytesPerRow;
  152. }
  153. }
  154. }
  155. }