diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16161616TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16161616TiffColor{TPixel}.cs index c3a12363c..9ca497604 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16161616TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16161616TiffColor{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Numerics; using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Memory; @@ -50,7 +51,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation bool hasAssociatedAlpha = this.extraSamplesType.HasValue && this.extraSamplesType == TiffExtraSampleType.AssociatedAlphaData; int offset = 0; - using System.Buffers.IMemoryOwner vectors = hasAssociatedAlpha ? this.memoryAllocator.Allocate(width) : null; + using IMemoryOwner vectors = hasAssociatedAlpha ? this.memoryAllocator.Allocate(width) : null; Span vectorsSpan = hasAssociatedAlpha ? vectors.GetSpan() : Span.Empty; for (int y = top; y < top + height; y++) { @@ -86,7 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation if (hasAssociatedAlpha) { PixelOperations.Instance.ToVector4(this.configuration, pixelRow, vectorsSpan); - TiffUtils.UnPremultiplyRow(vectorsSpan, pixelRow, color); + PixelOperations.Instance.FromVector4Destructive(this.configuration, vectorsSpan, pixelRow, PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale); } offset += byteCount; diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba8888TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba8888TiffColor{TPixel}.cs index e21dcf27b..cac34dd06 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba8888TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba8888TiffColor{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Numerics; using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Memory; @@ -36,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var color = default(TPixel); color.FromVector4(TiffUtils.Vector4Default); - using System.Buffers.IMemoryOwner vectors = hasAssociatedAlpha ? this.memoryAllocator.Allocate(width) : null; + using IMemoryOwner vectors = hasAssociatedAlpha ? this.memoryAllocator.Allocate(width) : null; Span vectorsSpan = hasAssociatedAlpha ? vectors.GetSpan() : Span.Empty; for (int y = top; y < top + height; y++) { @@ -51,7 +52,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation if (hasAssociatedAlpha) { PixelOperations.Instance.ToVector4(this.configuration, pixelRow, vectorsSpan); - TiffUtils.UnPremultiplyRow(vectorsSpan, pixelRow, color); + PixelOperations.Instance.FromVector4Destructive(this.configuration, vectorsSpan, pixelRow, PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale); } offset += byteCount; diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaPlanarTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaPlanarTiffColor{TPixel}.cs index ecf957eab..f6bd5e6a9 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaPlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaPlanarTiffColor{TPixel}.cs @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var vec = new Vector4(r, g, b, a); if (hasAssociatedAlpha) { - color = TiffUtils.UnPremultiply(vec, color); + color = TiffUtils.UnPremultiply(ref vec, color); } else { diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaTiffColor{TPixel}.cs index c00557b10..0aa5ab685 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaTiffColor{TPixel}.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var vec = new Vector4(r, g, b, a); if (hasAssociatedAlpha) { - pixelRow[x] = TiffUtils.UnPremultiply(vec, color); + pixelRow[x] = TiffUtils.UnPremultiply(ref vec, color); } else { diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs index 13b63dedc..cff2e88f1 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils { rgba.PackedValue = r | (g << 16) | (b << 32) | (a << 48); var vec = rgba.ToVector4(); - return UnPremultiply(vec, color); + return UnPremultiply(ref vec, color); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils public static TPixel ColorScaleTo24Bit(ulong r, ulong g, ulong b, ulong a, TPixel color) where TPixel : unmanaged, IPixel { - var colorVector = new Vector4(r * Scale24Bit, g * Scale24Bit, b * Scale24Bit, a * Scale24Bit); + Vector4 colorVector = new Vector4(r, g, b, a) * Scale24Bit; color.FromVector4(colorVector); return color; } @@ -94,8 +94,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils public static TPixel ColorScaleTo24BitPremultiplied(ulong r, ulong g, ulong b, ulong a, TPixel color) where TPixel : unmanaged, IPixel { - var colorVector = new Vector4(r * Scale24Bit, g * Scale24Bit, b * Scale24Bit, a * Scale24Bit); - return UnPremultiply(colorVector, color); + Vector4 colorVector = new Vector4(r, g, b, a) * Scale24Bit; + return UnPremultiply(ref colorVector, color); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils public static TPixel ColorScaleTo32Bit(ulong r, ulong g, ulong b, ulong a, TPixel color) where TPixel : unmanaged, IPixel { - var colorVector = new Vector4(r * Scale32Bit, g * Scale32Bit, b * Scale32Bit, a * Scale32Bit); + Vector4 colorVector = new Vector4(r, g, b, a) * Scale32Bit; color.FromVector4(colorVector); return color; } @@ -120,8 +120,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils public static TPixel ColorScaleTo32BitPremultiplied(ulong r, ulong g, ulong b, ulong a, TPixel color) where TPixel : unmanaged, IPixel { - var colorVector = new Vector4(r * Scale32Bit, g * Scale32Bit, b * Scale32Bit, a * Scale32Bit); - return UnPremultiply(colorVector, color); + Vector4 colorVector = new Vector4(r, g, b, a) * Scale32Bit; + return UnPremultiply(ref colorVector, color); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -152,22 +152,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void UnPremultiplyRow(Span vectors, Span pixelRow, TPixel color) + public static TPixel UnPremultiply(ref Vector4 vector, TPixel color) where TPixel : unmanaged, IPixel { - for (int x = 0; x < vectors.Length; x++) - { - Vector4 vec = vectors[x]; - pixelRow[x] = UnPremultiply(vec, color); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TPixel UnPremultiply(Vector4 vec, TPixel color) - where TPixel : unmanaged, IPixel - { - float invW = 1.0f / vec.W; - color.FromVector4(new Vector4(vec.X * invW, vec.Y * invW, vec.Z * invW, vec.W)); + Numerics.UnPremultiply(ref vector); + color.FromVector4(vector); return color; } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 6e96d3c65..29d1cbdc5 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -362,7 +362,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff } // Note: Using tolerant comparer here, because there is a small difference to the reference decoder probably due to floating point rounding issues. - TestTiffDecoder(provider, useExactComparer: false); + TestTiffDecoder(provider, useExactComparer: false, compareTolerance: 0.004F); } [Theory]