using System; namespace ScreenConnect; public class YuvDecoder : YuvCodecBase { public YuvDecoder(int streamCount, Func coderCreatorFunc) : base(streamCount, coderCreatorFunc) { } protected unsafe override void Process(byte* data, int width, int height, int stride, int lumaSize, int chromaSize, int yuvSize, byte* yuvPointer) { byte* ptr = yuvPointer; byte* ptr2 = ptr + lumaSize; byte* outputData = ptr2 + chromaSize; switch (base.StreamCount) { case 1: ReadThroughCoder(base.Coders[0], yuvPointer, yuvSize, isEndOfBlock: true); break; case 2: ReadThroughCoder(base.Coders[0], ptr, lumaSize, isEndOfBlock: true); ReadThroughCoder(base.Coders[1], ptr2, chromaSize * 2, isEndOfBlock: true); break; case 3: ReadThroughCoder(base.Coders[0], ptr, lumaSize, isEndOfBlock: true); ReadThroughCoder(base.Coders[1], ptr2, chromaSize, isEndOfBlock: true); ReadThroughCoder(base.Coders[2], outputData, chromaSize, isEndOfBlock: true); break; default: throw new ArgumentOutOfRangeException(); } byte* ptr3 = data; for (int i = 0; i < height; i++) { byte* ptr4 = ptr3; for (int j = 0; j < width; j++) { int num = 4096 * *(ptr++); int num2 = *(ptr2++) - 128; int num3 = *(outputData++) - 128; *(ptr4++) = Clamp(num + 7258 * num2 + 2048 >> 12); *(ptr4++) = Clamp(num - 1410 * num2 - 2925 * num3 + 2048 >> 12); *(ptr4++) = Clamp(num + 5743 * num3 + 2048 >> 12); *(ptr4++) = byte.MaxValue; } ptr3 += stride; } } protected static byte Clamp(int v) { return (byte)(((v & -256) == 0) ? ((uint)v) : ((v >= 0) ? 255u : 0u)); } }