SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
7.6 KiB

4 years ago
  1. using System;
  2. using Unity.Jobs;
  3. using Unity.Collections;
  4. using UnityEngine.XR.ARSubsystems;
  5. namespace UnityEngine.XR.ARCore
  6. {
  7. internal struct FlipVerticalJob : IJobParallelFor
  8. {
  9. public int width;
  10. public int height;
  11. [ReadOnly]
  12. [NativeDisableParallelForRestriction]
  13. public NativeSlice<byte> grayscaleIn;
  14. [WriteOnly]
  15. [NativeDisableParallelForRestriction]
  16. public NativeArray<byte> grayscaleOut;
  17. public void Execute(int row)
  18. {
  19. int inputOffset = (height - 1 - row) * width;
  20. int outputOffset = row * width;
  21. int lastOffset = outputOffset + width;
  22. while (outputOffset < lastOffset)
  23. {
  24. grayscaleOut[outputOffset++] = grayscaleIn[inputOffset++];
  25. }
  26. }
  27. }
  28. internal struct ConvertRFloatToGrayscaleJob : IJobParallelFor
  29. {
  30. public int width;
  31. public int height;
  32. [ReadOnly]
  33. public NativeSlice<float> rfloatIn;
  34. [WriteOnly]
  35. public NativeArray<byte> grayscaleImageOut;
  36. public void Execute(int row)
  37. {
  38. int inputOffset = (height - 1 - row) * width;
  39. int outputOffset = row * width;
  40. int lastOffset = outputOffset + width;
  41. while (outputOffset < lastOffset)
  42. {
  43. grayscaleImageOut[outputOffset++] = (byte)(rfloatIn[inputOffset++] * 255);
  44. }
  45. }
  46. }
  47. internal struct ConvertBGRA32ToGrayscaleJob : IJobParallelFor
  48. {
  49. public int width;
  50. public int height;
  51. [ReadOnly]
  52. [NativeDisableParallelForRestriction]
  53. public NativeSlice<byte> colorImageIn;
  54. [WriteOnly]
  55. [NativeDisableParallelForRestriction]
  56. public NativeArray<byte> grayscaleImageOut;
  57. public void Execute(int row)
  58. {
  59. int colorImageOffset = (height - 1 - row) * width * 4;
  60. int grayImageOffset = row * width;
  61. int lastOffset = grayImageOffset + width;
  62. while (grayImageOffset < lastOffset)
  63. {
  64. grayscaleImageOut[grayImageOffset++] = (byte)(
  65. colorImageIn[colorImageOffset ] * 0.11f +
  66. colorImageIn[colorImageOffset + 1] * 0.59f +
  67. colorImageIn[colorImageOffset + 2] * 0.3f);
  68. colorImageOffset += 4;
  69. }
  70. }
  71. }
  72. internal struct ConvertARGB32ToGrayscaleJob : IJobParallelFor
  73. {
  74. public int width;
  75. public int height;
  76. [ReadOnly]
  77. [NativeDisableParallelForRestriction]
  78. public NativeSlice<byte> colorImageIn;
  79. [WriteOnly]
  80. [NativeDisableParallelForRestriction]
  81. public NativeArray<byte> grayscaleImageOut;
  82. public void Execute(int row)
  83. {
  84. int colorImageOffset = (height - 1 - row) * width * 4 + 1;
  85. int grayImageOffset = row * width + 1;
  86. int lastOffset = grayImageOffset + width;
  87. while (grayImageOffset < lastOffset)
  88. {
  89. grayscaleImageOut[grayImageOffset++] = (byte)(
  90. colorImageIn[colorImageOffset ] * 0.3f +
  91. colorImageIn[colorImageOffset + 1] * 0.59f +
  92. colorImageIn[colorImageOffset + 2] * 0.11f);
  93. colorImageOffset += 4;
  94. }
  95. }
  96. }
  97. internal struct ConvertStridedToGrayscaleJob : IJobParallelFor
  98. {
  99. public int stride;
  100. public int width;
  101. public int height;
  102. // NB: NativeDisableParallelForRestriction to allow
  103. // us to read and write to indices other than the
  104. // one passed into the Execute method. This is because
  105. // we interpret the index as the row number and process
  106. // and entire row at a time. This takes about 75% the
  107. // time of doing it one pixel at a time.
  108. [ReadOnly]
  109. [NativeDisableParallelForRestriction]
  110. public NativeSlice<byte> colorImageIn;
  111. [WriteOnly]
  112. [NativeDisableParallelForRestriction]
  113. public NativeArray<byte> grayscaleImageOut;
  114. public void Execute(int row)
  115. {
  116. int colorImageOffset = (height - 1 - row) * width * stride;
  117. int grayImageOffset = row * width;
  118. int lastOffset = grayImageOffset + width;
  119. while (grayImageOffset < lastOffset)
  120. {
  121. grayscaleImageOut[grayImageOffset++] = (byte)(
  122. colorImageIn[colorImageOffset ] * 0.3f +
  123. colorImageIn[colorImageOffset + 1] * 0.59f +
  124. colorImageIn[colorImageOffset + 2] * 0.11f);
  125. colorImageOffset += stride;
  126. }
  127. }
  128. }
  129. internal static class ConversionJob
  130. {
  131. public static JobHandle Schedule(
  132. NativeSlice<byte> inputImage,
  133. Vector2Int sizeInPixels,
  134. TextureFormat format,
  135. NativeArray<byte> grayscaleImage,
  136. JobHandle inputDeps)
  137. {
  138. int width = sizeInPixels.x;
  139. int height = sizeInPixels.y;
  140. if ((format == TextureFormat.R8) ||
  141. (format == TextureFormat.Alpha8))
  142. {
  143. return new FlipVerticalJob
  144. {
  145. width = width,
  146. height = height,
  147. grayscaleIn = inputImage,
  148. grayscaleOut = grayscaleImage
  149. }.Schedule(height, 1, inputDeps);
  150. }
  151. // We'll have to convert it. Create an output buffer.
  152. if (format == TextureFormat.RGB24)
  153. {
  154. return new ConvertStridedToGrayscaleJob
  155. {
  156. stride = 3,
  157. width = width,
  158. height = height,
  159. colorImageIn = inputImage,
  160. grayscaleImageOut = grayscaleImage
  161. }.Schedule(height, 1, inputDeps);
  162. }
  163. else if (format == TextureFormat.RGBA32)
  164. {
  165. return new ConvertStridedToGrayscaleJob
  166. {
  167. stride = 4,
  168. width = width,
  169. height = height,
  170. colorImageIn = inputImage,
  171. grayscaleImageOut = grayscaleImage
  172. }.Schedule(height, 1, inputDeps);
  173. }
  174. else if (format == TextureFormat.ARGB32)
  175. {
  176. return new ConvertARGB32ToGrayscaleJob
  177. {
  178. width = width,
  179. height = height,
  180. colorImageIn = inputImage,
  181. grayscaleImageOut = grayscaleImage
  182. }.Schedule(height, 1, inputDeps);
  183. }
  184. else if (format == TextureFormat.BGRA32)
  185. {
  186. return new ConvertBGRA32ToGrayscaleJob
  187. {
  188. width = width,
  189. height = height,
  190. colorImageIn = inputImage,
  191. grayscaleImageOut = grayscaleImage
  192. }.Schedule(height, 1, inputDeps);
  193. }
  194. else if (format == TextureFormat.RFloat)
  195. {
  196. return new ConvertRFloatToGrayscaleJob
  197. {
  198. width = width,
  199. height = height,
  200. rfloatIn = inputImage.SliceConvert<float>(),
  201. grayscaleImageOut = grayscaleImage
  202. }.Schedule(height, 1, inputDeps);
  203. }
  204. else
  205. {
  206. throw new InvalidOperationException($"Texture format {format} is not supported.");
  207. }
  208. }
  209. }
  210. }