From 984971e1d9aca406cfd41b742da96b2d8447fa1b Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 7 Nov 2021 16:48:10 +0100 Subject: [PATCH] Move yuv related methods to YuvConversion class --- .../Formats/Webp/Lossy/LossyUtils.cs | 31 ------------------- .../Formats/Webp/Lossy/WebpLossyDecoder.cs | 24 +++++++------- .../Formats/Webp/Lossy/YuvConversion.cs | 31 +++++++++++++++++++ 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs index c3f6e522a..b2513feb5 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs @@ -867,27 +867,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - [MethodImpl(InliningOptions.ShortMethod)] - public static uint LoadUv(byte u, byte v) => - (uint)(u | (v << 16)); // We process u and v together stashed into 32bit(16bit each). - - [MethodImpl(InliningOptions.ShortMethod)] - public static void YuvToBgr(int y, int u, int v, Span bgr) - { - bgr[0] = (byte)YuvToB(y, u); - bgr[1] = (byte)YuvToG(y, u, v); - bgr[2] = (byte)YuvToR(y, v); - } - - [MethodImpl(InliningOptions.ShortMethod)] - public static int YuvToB(int y, int u) => Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685); - - [MethodImpl(InliningOptions.ShortMethod)] - public static int YuvToG(int y, int u, int v) => Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708); - - [MethodImpl(InliningOptions.ShortMethod)] - public static int YuvToR(int y, int v) => Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234); - [MethodImpl(InliningOptions.ShortMethod)] public static byte Avg2(byte a, byte b) => (byte)((a + b + 1) >> 1); @@ -1092,9 +1071,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return WebpLookupTables.Abs0(p1 - p0) > thresh || WebpLookupTables.Abs0(q1 - q0) > thresh; } - [MethodImpl(InliningOptions.ShortMethod)] - private static int MultHi(int v, int coeff) => (v * coeff) >> 8; - [MethodImpl(InliningOptions.ShortMethod)] private static void Store(Span dst, int x, int y, int v) { @@ -1117,13 +1093,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [MethodImpl(InliningOptions.ShortMethod)] private static int Mul2(int a) => (a * 35468) >> 16; - [MethodImpl(InliningOptions.ShortMethod)] - private static byte Clip8(int v) - { - int yuvMask = (256 << 6) - 1; - return (byte)((v & ~yuvMask) == 0 ? v >> 6 : v < 0 ? 0 : 255); - } - [MethodImpl(InliningOptions.ShortMethod)] private static void Put8x8uv(byte value, Span dst) { diff --git a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs index 4f283f9f5..2f78842c6 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs @@ -747,21 +747,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { int xStep = 3; int lastPixelPair = (len - 1) >> 1; - uint tluv = LossyUtils.LoadUv(topU[0], topV[0]); // top-left sample - uint luv = LossyUtils.LoadUv(curU[0], curV[0]); // left-sample + uint tluv = YuvConversion.LoadUv(topU[0], topV[0]); // top-left sample + uint luv = YuvConversion.LoadUv(curU[0], curV[0]); // left-sample uint uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2; - LossyUtils.YuvToBgr(topY[0], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst); + YuvConversion.YuvToBgr(topY[0], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst); if (bottomY != null) { uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2; - LossyUtils.YuvToBgr(bottomY[0], (int)uv0 & 0xff, (int)(uv0 >> 16), bottomDst); + YuvConversion.YuvToBgr(bottomY[0], (int)uv0 & 0xff, (int)(uv0 >> 16), bottomDst); } for (int x = 1; x <= lastPixelPair; x++) { - uint tuv = LossyUtils.LoadUv(topU[x], topV[x]); // top sample - uint uv = LossyUtils.LoadUv(curU[x], curV[x]); // sample + uint tuv = YuvConversion.LoadUv(topU[x], topV[x]); // top sample + uint uv = YuvConversion.LoadUv(curU[x], curV[x]); // sample // Precompute invariant values associated with first and second diagonals. uint avg = tluv + tuv + luv + uv + 0x00080008u; @@ -770,15 +770,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uv0 = (diag12 + tluv) >> 1; uint uv1 = (diag03 + tuv) >> 1; int xMul2 = x * 2; - LossyUtils.YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep)); - LossyUtils.YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep)); + YuvConversion.YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep)); + YuvConversion.YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep)); if (bottomY != null) { uv0 = (diag03 + luv) >> 1; uv1 = (diag12 + uv) >> 1; - LossyUtils.YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep)); - LossyUtils.YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep)); + YuvConversion.YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep)); + YuvConversion.YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep)); } tluv = tuv; @@ -788,11 +788,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if ((len & 1) == 0) { uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2; - LossyUtils.YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep)); + YuvConversion.YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep)); if (bottomY != null) { uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2; - LossyUtils.YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep)); + YuvConversion.YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep)); } } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs index ed03c2e71..24143785a 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs @@ -299,5 +299,36 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uv = (uv + rounding + (128 << (YuvFix + 2))) >> (YuvFix + 2); return (uv & ~0xff) == 0 ? uv : uv < 0 ? 0 : 255; } + + [MethodImpl(InliningOptions.ShortMethod)] + public static uint LoadUv(byte u, byte v) => + (uint)(u | (v << 16)); // We process u and v together stashed into 32bit(16bit each). + + [MethodImpl(InliningOptions.ShortMethod)] + public static void YuvToBgr(int y, int u, int v, Span bgr) + { + bgr[0] = (byte)YuvToB(y, u); + bgr[1] = (byte)YuvToG(y, u, v); + bgr[2] = (byte)YuvToR(y, v); + } + + [MethodImpl(InliningOptions.ShortMethod)] + public static int YuvToB(int y, int u) => Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685); + + [MethodImpl(InliningOptions.ShortMethod)] + public static int YuvToG(int y, int u, int v) => Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708); + + [MethodImpl(InliningOptions.ShortMethod)] + public static int YuvToR(int y, int v) => Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234); + + [MethodImpl(InliningOptions.ShortMethod)] + private static int MultHi(int v, int coeff) => (v * coeff) >> 8; + + [MethodImpl(InliningOptions.ShortMethod)] + private static byte Clip8(int v) + { + int yuvMask = (256 << 6) - 1; + return (byte)((v & ~yuvMask) == 0 ? v >> 6 : v < 0 ? 0 : 255); + } } }