From 55224ecad8e89a8f74d1164cbc5f0859015966bb Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 6 Jun 2025 21:24:11 +1000 Subject: [PATCH] Multiply > divide --- .../JpegColorConverter.TiffCmykScalar.cs | 7 ++++--- .../JpegColorConverter.TiffCmykVector128.cs | 8 ++++---- .../JpegColorConverter.TiffCmykVector256.cs | 8 ++++---- .../JpegColorConverter.TiffCmykVector512.cs | 8 ++++---- .../JpegColorConverter.TiffYccKScalar.cs | 18 ++++++++++-------- .../JpegColorConverter.TiffYccKVector128.cs | 16 ++++++++-------- .../JpegColorConverter.TiffYccKVector256.cs | 8 ++++---- .../JpegColorConverter.TiffYccKVector512.cs | 8 ++++---- .../JpegColorConverter.YccKVector512.cs | 2 +- 9 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykScalar.cs index 9406f0be8b..27449a368a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykScalar.cs @@ -76,9 +76,10 @@ internal abstract partial class JpegColorConverterBase } else { - ctmp = (ctmp - ktmp) / (255F - ktmp); - mtmp = (mtmp - ktmp) / (255F - ktmp); - ytmp = (ytmp - ktmp) / (255F - ktmp); + float divisor = 1 / (255F - ktmp); + ctmp = (ctmp - ktmp) * divisor; + mtmp = (mtmp - ktmp) * divisor; + ytmp = (ytmp - ktmp) * divisor; } c[i] = ctmp * maxValue; diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector128.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector128.cs index 652c536b8e..6d52d5c728 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector128.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector128.cs @@ -83,11 +83,11 @@ internal abstract partial class JpegColorConverterBase Vector128 ktmp = Vector128.Min(ctmp, Vector128.Min(mtmp, ytmp)); Vector128 kMask = ~Vector128.Equals(ktmp, scale); - Vector128 divisor = scale - ktmp; + Vector128 divisor = Vector128.One / (scale - ktmp); - ctmp = ((ctmp - ktmp) / divisor) & kMask; - mtmp = ((mtmp - ktmp) / divisor) & kMask; - ytmp = ((ytmp - ktmp) / divisor) & kMask; + ctmp = ((ctmp - ktmp) * divisor) & kMask; + mtmp = ((mtmp - ktmp) * divisor) & kMask; + ytmp = ((ytmp - ktmp) * divisor) & kMask; Unsafe.Add(ref destC, i) = ctmp * scale; Unsafe.Add(ref destM, i) = mtmp * scale; diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector256.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector256.cs index bfd44008c1..61b312a063 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector256.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector256.cs @@ -83,11 +83,11 @@ internal abstract partial class JpegColorConverterBase Vector256 ktmp = Vector256.Min(ctmp, Vector256.Min(mtmp, ytmp)); Vector256 kMask = ~Vector256.Equals(ktmp, scale); - Vector256 divisor = scale - ktmp; + Vector256 divisor = Vector256.One / (scale - ktmp); - ctmp = ((ctmp - ktmp) / divisor) & kMask; - mtmp = ((mtmp - ktmp) / divisor) & kMask; - ytmp = ((ytmp - ktmp) / divisor) & kMask; + ctmp = ((ctmp - ktmp) * divisor) & kMask; + mtmp = ((mtmp - ktmp) * divisor) & kMask; + ytmp = ((ytmp - ktmp) * divisor) & kMask; Unsafe.Add(ref destC, i) = ctmp * scale; Unsafe.Add(ref destM, i) = mtmp * scale; diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector512.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector512.cs index 19452a92f0..51d5cc76d3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector512.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffCmykVector512.cs @@ -92,11 +92,11 @@ internal abstract partial class JpegColorConverterBase Vector512 ktmp = Vector512.Min(ctmp, Vector512.Min(mtmp, ytmp)); Vector512 kMask = ~Vector512.Equals(ktmp, scale); - Vector512 divisor = scale - ktmp; + Vector512 divisor = Vector512.One / (scale - ktmp); - ctmp = ((ctmp - ktmp) / divisor) & kMask; - mtmp = ((mtmp - ktmp) / divisor) & kMask; - ytmp = ((ytmp - ktmp) / divisor) & kMask; + ctmp = ((ctmp - ktmp) * divisor) & kMask; + mtmp = ((mtmp - ktmp) * divisor) & kMask; + ytmp = ((ytmp - ktmp) * divisor) & kMask; Unsafe.Add(ref destC, i) = ctmp * scale; Unsafe.Add(ref destM, i) = mtmp * scale; diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs index 80f9891f22..495a208317 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs @@ -75,9 +75,10 @@ internal abstract partial class JpegColorConverterBase for (int i = 0; i < cr.Length; i++) { // Scale down to [0-1] - float r = rLane[i] / 255F; - float g = gLane[i] / 255F; - float b = bLane[i] / 255F; + const float divisor = 1F / 255F; + float r = rLane[i] * divisor; + float g = gLane[i] * divisor; + float b = bLane[i] * divisor; float ytmp; float cbtmp; @@ -87,15 +88,16 @@ internal abstract partial class JpegColorConverterBase if (ktmp >= 1F) { ytmp = 0F; - cbtmp = 0F; - crtmp = 0F; + cbtmp = 0.5F; + crtmp = 0.5F; ktmp = maxValue; } else { - r /= 1F - ktmp; - g /= 1F - ktmp; - b /= 1F - ktmp; + float kmask = 1F / (1F - ktmp); + r *= kmask; + g *= kmask; + b *= kmask; // Scale to [0-maxValue] ytmp = ((0.299f * r) + (0.587f * g) + (0.114f * b)) * maxValue; diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector128.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector128.cs index 2aaf0ae29a..b360c373ad 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector128.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector128.cs @@ -86,7 +86,7 @@ internal abstract partial class JpegColorConverterBase ref Vector128 destK = ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - Vector128 maxSourceValue = Vector128.Create(255F); + Vector128 maxSourceValue = Vector128.Create(1 / 255F); Vector128 maxSampleValue = Vector128.Create(this.MaximumValue); Vector128 chromaOffset = Vector128.Create(this.HalfValue); @@ -102,17 +102,17 @@ internal abstract partial class JpegColorConverterBase nuint n = values.Component0.Vector128Count(); for (nuint i = 0; i < n; i++) { - Vector128 r = Unsafe.Add(ref srcR, i) / maxSourceValue; - Vector128 g = Unsafe.Add(ref srcG, i) / maxSourceValue; - Vector128 b = Unsafe.Add(ref srcB, i) / maxSourceValue; + Vector128 r = Unsafe.Add(ref srcR, i) * maxSourceValue; + Vector128 g = Unsafe.Add(ref srcG, i) * maxSourceValue; + Vector128 b = Unsafe.Add(ref srcB, i) * maxSourceValue; Vector128 ktmp = Vector128.One - Vector128.Max(r, Vector128.Min(g, b)); Vector128 kMask = ~Vector128.Equals(ktmp, Vector128.One); - Vector128 divisor = Vector128.One - ktmp; + Vector128 divisor = Vector128.One / (Vector128.One - ktmp); - r /= divisor; - g /= divisor; - b /= divisor; + r = (r * divisor) & kMask; + g = (g * divisor) & kMask; + b = (b * divisor) & kMask; // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector256.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector256.cs index d7f66b323a..f996522d36 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector256.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector256.cs @@ -108,11 +108,11 @@ internal abstract partial class JpegColorConverterBase Vector256 ktmp = Vector256.One - Vector256.Max(r, Vector256.Min(g, b)); Vector256 kMask = ~Vector256.Equals(ktmp, Vector256.One); - Vector256 divisor = Vector256.One - ktmp; + Vector256 divisor = Vector256.One / (Vector256.One - ktmp); - r /= divisor; - g /= divisor; - b /= divisor; + r = (r * divisor) & kMask; + g = (g * divisor) & kMask; + b = (b * divisor) & kMask; // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector512.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector512.cs index eb27c9a6c0..47168a739d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector512.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKVector512.cs @@ -119,11 +119,11 @@ internal abstract partial class JpegColorConverterBase Vector512 ktmp = Vector512.One - Vector512.Max(r, Vector512.Min(g, b)); Vector512 kMask = ~Vector512.Equals(ktmp, Vector512.One); - Vector512 divisor = Vector512.One - ktmp; + Vector512 divisor = Vector512.One / (Vector512.One - ktmp); - r /= divisor; - g /= divisor; - b /= divisor; + r = (r * divisor) & kMask; + g = (g * divisor) & kMask; + b = (b * divisor) & kMask; // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKVector512.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKVector512.cs index 5378eb3a10..b81a833cde 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKVector512.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKVector512.cs @@ -138,6 +138,6 @@ internal abstract partial class JpegColorConverterBase /// protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span rLane, Span gLane, Span bLane) - => TiffYccKScalar.ConvertFromRgb(in values, this.HalfValue, this.MaximumValue, rLane, gLane, bLane); + => YccKScalar.ConvertFromRgb(in values, this.HalfValue, this.MaximumValue, rLane, gLane, bLane); } }