This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
ARPlusSystem/ARPlusSystem-250418/Library/PackageCache/com.unity.xr.arcore@4.2.10/Runtime/ImageConversionJobs.cs

245 lines
7.6 KiB
C#
Raw Permalink Normal View History

using System;
using Unity.Jobs;
using Unity.Collections;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.ARCore
{
internal struct FlipVerticalJob : IJobParallelFor
{
public int width;
public int height;
[ReadOnly]
[NativeDisableParallelForRestriction]
public NativeSlice<byte> grayscaleIn;
[WriteOnly]
[NativeDisableParallelForRestriction]
public NativeArray<byte> grayscaleOut;
public void Execute(int row)
{
int inputOffset = (height - 1 - row) * width;
int outputOffset = row * width;
int lastOffset = outputOffset + width;
while (outputOffset < lastOffset)
{
grayscaleOut[outputOffset++] = grayscaleIn[inputOffset++];
}
}
}
internal struct ConvertRFloatToGrayscaleJob : IJobParallelFor
{
public int width;
public int height;
[ReadOnly]
public NativeSlice<float> rfloatIn;
[WriteOnly]
public NativeArray<byte> grayscaleImageOut;
public void Execute(int row)
{
int inputOffset = (height - 1 - row) * width;
int outputOffset = row * width;
int lastOffset = outputOffset + width;
while (outputOffset < lastOffset)
{
grayscaleImageOut[outputOffset++] = (byte)(rfloatIn[inputOffset++] * 255);
}
}
}
internal struct ConvertBGRA32ToGrayscaleJob : IJobParallelFor
{
public int width;
public int height;
[ReadOnly]
[NativeDisableParallelForRestriction]
public NativeSlice<byte> colorImageIn;
[WriteOnly]
[NativeDisableParallelForRestriction]
public NativeArray<byte> grayscaleImageOut;
public void Execute(int row)
{
int colorImageOffset = (height - 1 - row) * width * 4;
int grayImageOffset = row * width;
int lastOffset = grayImageOffset + width;
while (grayImageOffset < lastOffset)
{
grayscaleImageOut[grayImageOffset++] = (byte)(
colorImageIn[colorImageOffset ] * 0.11f +
colorImageIn[colorImageOffset + 1] * 0.59f +
colorImageIn[colorImageOffset + 2] * 0.3f);
colorImageOffset += 4;
}
}
}
internal struct ConvertARGB32ToGrayscaleJob : IJobParallelFor
{
public int width;
public int height;
[ReadOnly]
[NativeDisableParallelForRestriction]
public NativeSlice<byte> colorImageIn;
[WriteOnly]
[NativeDisableParallelForRestriction]
public NativeArray<byte> grayscaleImageOut;
public void Execute(int row)
{
int colorImageOffset = (height - 1 - row) * width * 4;
int grayImageOffset = row * width;
int lastOffset = grayImageOffset + width;
while (grayImageOffset < lastOffset)
{
//ARGB so need to account for ALPHA index.
grayscaleImageOut[grayImageOffset++] = (byte)(
colorImageIn[colorImageOffset + 1] * 0.3f +
colorImageIn[colorImageOffset + 2] * 0.59f +
colorImageIn[colorImageOffset + 3] * 0.11f);
colorImageOffset += 4;
}
}
}
internal struct ConvertStridedToGrayscaleJob : IJobParallelFor
{
public int stride;
public int width;
public int height;
// NB: NativeDisableParallelForRestriction to allow
// us to read and write to indices other than the
// one passed into the Execute method. This is because
// we interpret the index as the row number and process
// and entire row at a time. This takes about 75% the
// time of doing it one pixel at a time.
[ReadOnly]
[NativeDisableParallelForRestriction]
public NativeSlice<byte> colorImageIn;
[WriteOnly]
[NativeDisableParallelForRestriction]
public NativeArray<byte> grayscaleImageOut;
public void Execute(int row)
{
int colorImageOffset = (height - 1 - row) * width * stride;
int grayImageOffset = row * width;
int lastOffset = grayImageOffset + width;
while (grayImageOffset < lastOffset)
{
grayscaleImageOut[grayImageOffset++] = (byte)(
colorImageIn[colorImageOffset ] * 0.3f +
colorImageIn[colorImageOffset + 1] * 0.59f +
colorImageIn[colorImageOffset + 2] * 0.11f);
colorImageOffset += stride;
}
}
}
internal static class ConversionJob
{
public static JobHandle Schedule(
NativeSlice<byte> inputImage,
Vector2Int sizeInPixels,
TextureFormat format,
NativeArray<byte> grayscaleImage,
JobHandle inputDeps)
{
int width = sizeInPixels.x;
int height = sizeInPixels.y;
if ((format == TextureFormat.R8) ||
(format == TextureFormat.Alpha8))
{
return new FlipVerticalJob
{
width = width,
height = height,
grayscaleIn = inputImage,
grayscaleOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
// We'll have to convert it. Create an output buffer.
if (format == TextureFormat.RGB24)
{
return new ConvertStridedToGrayscaleJob
{
stride = 3,
width = width,
height = height,
colorImageIn = inputImage,
grayscaleImageOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
else if (format == TextureFormat.RGBA32)
{
return new ConvertStridedToGrayscaleJob
{
stride = 4,
width = width,
height = height,
colorImageIn = inputImage,
grayscaleImageOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
else if (format == TextureFormat.ARGB32)
{
return new ConvertARGB32ToGrayscaleJob
{
width = width,
height = height,
colorImageIn = inputImage,
grayscaleImageOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
else if (format == TextureFormat.BGRA32)
{
return new ConvertBGRA32ToGrayscaleJob
{
width = width,
height = height,
colorImageIn = inputImage,
grayscaleImageOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
else if (format == TextureFormat.RFloat)
{
return new ConvertRFloatToGrayscaleJob
{
width = width,
height = height,
rfloatIn = inputImage.SliceConvert<float>(),
grayscaleImageOut = grayscaleImage
}.Schedule(height, 1, inputDeps);
}
else
{
throw new InvalidOperationException($"Texture format {format} is not supported.");
}
}
}
}