From dba37fe5f68956e9b9c5e515b573e4252ebb083f Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 23:16:13 +0200 Subject: [PATCH 001/238] fix whitespacing in generated code --- .../PixelOperations{TPixel}.Generated.cs | 140 +++++++++--------- .../PixelOperations{TPixel}.Generated.tt | 29 ++-- 2 files changed, 85 insertions(+), 84 deletions(-) diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index e8908fe05..3ea4007d2 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -1,4 +1,13 @@ -// Copyright (c) Six Labors and contributors. + + + + + + + + + +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. // @@ -10,8 +19,7 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations { - - /// + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -19,7 +27,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -34,8 +42,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba64(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -47,8 +55,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -70,20 +78,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba64Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgba64(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -91,7 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -106,8 +114,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgb48(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -119,8 +127,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -142,20 +150,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb48Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgb48(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -163,7 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -178,8 +186,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -191,8 +199,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -214,20 +222,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgba32(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -235,7 +243,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -250,8 +258,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromBgra32(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -263,8 +271,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -286,20 +294,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgra32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToBgra32(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -307,7 +315,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -322,8 +330,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -335,8 +343,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -358,20 +366,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgb24(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -379,7 +387,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -394,8 +402,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -407,8 +415,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -430,20 +438,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgr24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToBgr24(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -451,7 +459,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -466,8 +474,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromArgb32(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -479,8 +487,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -502,19 +510,17 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToArgb32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToArgb32(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - } - + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index 5c762c7df..dbd30560e 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -14,8 +14,7 @@ void GeneratePackFromMethods(string pixelType, string tempPixelType, string assignToTempCode) { #> - - /// + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -23,7 +22,7 @@ /// The number of pixels to convert. internal virtual void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -38,8 +37,8 @@ dp.PackFrom<#=tempPixelType#>(temp); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -51,14 +50,13 @@ { this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); } - <# +<# } void GenerateToDestFormatMethods(string pixelType) { #> - - /// + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -80,19 +78,19 @@ } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void To<#=pixelType#>Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.To<#=pixelType#>(sourceColors, MemoryMarshal.Cast>(destBytes), count); } - <# +<# } #> @@ -107,8 +105,8 @@ namespace SixLabors.ImageSharp.PixelFormats using System.Runtime.InteropServices; public partial class PixelOperations - { - <# + {<# + GeneratePackFromMethods("Rgba64", "Rgba64", "temp = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Rgba64"); @@ -129,8 +127,5 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethods("Argb32", "Argb32", "temp = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Argb32"); - #> - - } - + #> } } \ No newline at end of file From 39b3cb708c3e9a95663faeef72fd36fc898571ed Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 15:19:11 +0200 Subject: [PATCH 002/238] #718: add pixel types Gray8 and Gray16 --- src/ImageSharp/PixelFormats/Gray16.cs | 270 ++++++++++++++++++ src/ImageSharp/PixelFormats/Gray8.cs | 265 +++++++++++++++++ .../PixelFormats/Gray8Tests.cs | 211 ++++++++++++++ 3 files changed, 746 insertions(+) create mode 100644 src/ImageSharp/PixelFormats/Gray16.cs create mode 100644 src/ImageSharp/PixelFormats/Gray8.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs new file mode 100644 index 000000000..a7e50e366 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -0,0 +1,270 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.PixelFormats +{ + /// + /// Packed pixel type containing a single 16 bit normalized gray values. + /// + /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. + /// + /// + public struct Gray16 : IPixel, IPackedVector + { + /// + /// RX as in ITU-R recommendation 709 to match libpng + /// + private const float Rx = .2126F; + + /// + /// GX as in ITU-R recommendation 709 to match libpng + /// + private const float Gx = .7152F; + + /// + /// BX as in ITU-R recommendation 709 to match libpng + /// + private const float Bx = .0722F; + + /// + /// Initializes a new instance of the struct. + /// + /// The gray component + public Gray16(byte gray) + { + this.PackedValue = gray; + } + + /// + public ushort PackedValue { get; set; } + + /// + /// Compares two objects for equality. + /// + /// + /// The on the left side of the operand. + /// + /// + /// The on the right side of the operand. + /// + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Gray16 left, Gray16 right) + { + return left.PackedValue == right.PackedValue; + } + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Gray16 left, Gray16 right) + { + return left.PackedValue != right.PackedValue; + } + + /// + public PixelOperations CreatePixelOperations() => new PixelOperations(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromScaledVector4(Vector4 vector) + { + this.PackFromVector4(vector); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToScaledVector4() + { + var scaledGray = this.PackedValue / 65535f; // ushort.Max as float + return new Vector4(scaledGray, scaledGray, scaledGray, 1.0f); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromVector4(Vector4 vector) + { + this.PackedValue = Pack(vector.X, vector.Y, vector.Z); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.PackedValue, this.PackedValue, this.PackedValue, 1.0f); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgba32(Rgba32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgb24(ref Rgb24 dest) + { + var scaledValue = this.PackedAsByte(); + + dest.R = scaledValue; + dest.G = scaledValue; + dest.B = scaledValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgba32(ref Rgba32 dest) + { + var scaledValue = this.PackedAsByte(); + + dest.R = scaledValue; + dest.G = scaledValue; + dest.B = scaledValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) + { + var scaledValue = this.PackedAsByte(); + + dest.R = scaledValue; + dest.G = scaledValue; + dest.B = scaledValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToBgr24(ref Bgr24 dest) + { + var scaledValue = this.PackedAsByte(); + + dest.R = scaledValue; + dest.G = scaledValue; + dest.B = scaledValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToBgra32(ref Bgra32 dest) + { + var scaledValue = this.PackedAsByte(); + + dest.R = scaledValue; + dest.G = scaledValue; + dest.B = scaledValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgb48(Rgb48 source) => + this.PackedValue = Pack(source.R, source.G, source.B); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgb48(ref Rgb48 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgba64(Rgba64 source) => + this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + /// Compares an object with the packed vector. + /// + /// The object to compare. + /// True if the object is equal to the packed vector. + public override bool Equals(object obj) + { + return obj is Gray16 other && this.Equals(other); + } + + /// + /// Compares another packed vector with the packed vector. + /// + /// The Gray8 packed vector to compare. + /// True if the packed vectors are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Gray16 other) + { + return this.PackedValue == other.PackedValue; + } + + /// + /// Gets a string representation of the packed vector. + /// + /// A string representation of the packed vector. + public override string ToString() + { + return (this.PackedValue / 65535f).ToString(); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); + + /// + /// Packs a into a byte. + /// + /// Red value of the color to pack. + /// Green value of the color to pack. + /// Blue value of the color to pack. + /// The containing the packed value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ushort Pack(float r, float g, float b) + { + float sum = r + g + b; + float val = (r * Rx) + (g * Gx) + (b * Bx); + return (ushort)Math.Round(val * 65535f / sum); // TODO: if this is correct, Rx, Gx, Bx consts could be scaled by 65535f directly! + } + + /// + /// Packs the into a byte. + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private byte PackedAsByte() + { + return (byte)(this.PackedValue >> 8); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs new file mode 100644 index 000000000..db0539543 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -0,0 +1,265 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.PixelFormats +{ + /// + /// Packed pixel type containing a single 8 bit normalized gray values. + /// + /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. + /// + /// + public struct Gray8 : IPixel, IPackedVector + { + /// + /// RX as in ITU-R recommendation 709 to match libpng + /// + private const float Rx = .2126F; + + /// + /// GX as in ITU-R recommendation 709 to match libpng + /// + private const float Gx = .7152F; + + /// + /// BX as in ITU-R recommendation 709 to match libpng + /// + private const float Bx = .0722F; + + /// + /// Initializes a new instance of the struct. + /// + /// The gray component + public Gray8(byte gray) + { + this.PackedValue = gray; + } + + /// + public byte PackedValue { get; set; } + + /// + /// Compares two objects for equality. + /// + /// + /// The on the left side of the operand. + /// + /// + /// The on the right side of the operand. + /// + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Gray8 left, Gray8 right) + { + return left.PackedValue == right.PackedValue; + } + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Gray8 left, Gray8 right) + { + return left.PackedValue != right.PackedValue; + } + + /// + public PixelOperations CreatePixelOperations() => new PixelOperations(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromScaledVector4(Vector4 vector) + { + this.PackFromVector4(vector); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToScaledVector4() + { + var scaledGray = this.PackedValue / 255f; + return new Vector4(scaledGray, scaledGray, scaledGray, 1.0f); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromVector4(Vector4 vector) + { + this.PackedValue = Pack(vector.X, vector.Y, vector.Z); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.PackedValue, this.PackedValue, this.PackedValue, 1.0f); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgba32(Rgba32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackedValue = Pack(source.R, source.G, source.B); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgb24(ref Rgb24 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToBgr24(ref Bgr24 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToBgra32(ref Bgra32 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + dest.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgb48(Rgb48 source) => + this.PackedValue = Pack(source.R, source.G, source.B); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgb48(ref Rgb48 dest) + { + ushort gray = (ushort)(this.PackedValue * 255); + dest.R = gray; + dest.G = gray; + dest.B = gray; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromRgba64(Rgba64 source) => + this.PackFromScaledVector4(source.ToScaledVector4()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackedValue = (byte)(source.PackedValue / 255); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackedValue = this.PackedValue; + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackedValue = (ushort)(this.PackedValue * 255); + + /// + /// Compares an object with the packed vector. + /// + /// The object to compare. + /// True if the object is equal to the packed vector. + public override bool Equals(object obj) + { + return obj is Gray8 other && this.Equals(other); + } + + /// + /// Compares another packed vector with the packed vector. + /// + /// The Gray8 packed vector to compare. + /// True if the packed vectors are equal. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Gray8 other) + { + return this.PackedValue == other.PackedValue; + } + + /// + /// Gets a string representation of the packed vector. + /// + /// A string representation of the packed vector. + public override string ToString() + { + return (this.PackedValue / 255F).ToString(); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); + + /// + /// Packs a into a byte. + /// + /// Red value of the color to pack. + /// Green value of the color to pack. + /// Blue value of the color to pack. + /// The containing the packed value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static byte Pack(float r, float g, float b) + { + float sum = r + g + b; + float val = (r * Rx) + (g * Gx) + (b * Bx); + return (byte)Math.Round(val * 255 / sum); // TODO: if this is correct, Rx, Gx, Bx consts could be scaled by 255 directly! + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs new file mode 100644 index 000000000..c4ce7339d --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -0,0 +1,211 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public class Gray8Tests + { + [Theory] + [InlineData(0)] + [InlineData(255)] + [InlineData(10)] + [InlineData(42)] + public void Gray8_PackedValue_EqualsInput(byte input) + { + Assert.Equal(input, new Gray8(input).PackedValue); + } + + [Theory] + [InlineData(0)] + [InlineData(255)] + [InlineData(30)] + public void Gray8_ToVector4(byte input) + { + // arrange + var gray = new Gray8(input); + + // act + var actual = gray.ToVector4(); + + // assert + Assert.Equal(input, actual.X); + Assert.Equal(input, actual.Y); + Assert.Equal(input, actual.Z); + Assert.Equal(1, actual.W); + } + + [Theory] + [InlineData(0)] + [InlineData(255)] + [InlineData(30)] + public void Gray8_ToScaledVector4(byte input) + { + // arrange + var gray = new Gray8(input); + + // act + var actual = gray.ToScaledVector4(); + + // assert + float scaledInput = input / 255f; + Assert.Equal(scaledInput, actual.X); + Assert.Equal(scaledInput, actual.Y); + Assert.Equal(scaledInput, actual.Z); + Assert.Equal(1, actual.W); + } + + [Fact] + public void Gray8_PackFromScaledVector4() + { + // arrange + Gray8 gray = default; + int expected = 128; + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + byte actual = gray.PackedValue; + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToRgb24() + { + // arrange + Rgb24 actual = default; + Gray8 gray = default; + var expected = new Rgb24(0, 0, 0); + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgb24(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToRgba32() + { + // arrange + Rgba32 actual = default; + Gray8 gray = default; + var expected = new Rgba32(0, 0, 0, 128); + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgba32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToBgr24() + { + // arrange + Bgr24 actual = default; + Gray8 gray = default; + var expected = new Bgr24(128, 128, 128); + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToBgr24(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToBgra32() + { + // arrange + Bgra32 actual = default; + Gray8 gray = default; + var expected = new Bgra32(128,128,128); + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToBgra32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToArgb32() + { + // arrange + Gray8 gray = default; + Argb32 actual = default; + var expected = new Argb32(128, 128, 128); + Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToArgb32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromScaledVector4_ToRgba64() + { + // arrange + Gray8 gray = default; + Rgba64 actual = default; + var expected = new Rgba64(65535, 65535, 65535, 65535); + Vector4 scaled = new Gray8(255).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgba64(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromRgb48_ToRgb48() + { + // arrange + var gray = default(Gray8); + var actual = default(Rgb48); + var expected = new Rgb48(0, 0, 0); + + // act + gray.PackFromRgb48(expected); + gray.ToRgb48(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray8_PackFromRgba64_ToRgba64() + { + // arrange + var gray = default(Gray8); + var actual = default(Rgba64); + var expected = new Rgba64(0, 0, 0, 65535); + + // act + gray.PackFromRgba64(expected); + gray.ToRgba64(ref actual); + + // assert + Assert.Equal(expected, actual); + } + } +} From f5a331b914b09cfbf4d3cd75b53fa3c1d954f773 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 23:23:39 +0200 Subject: [PATCH 003/238] #718: fix merge conflicts, adapt changes from PR #727 to t4 script --- .../PixelOperations{TPixel}.Generated.cs | 72 +++++++++++++++++++ .../PixelOperations{TPixel}.Generated.tt | 5 +- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 3ea4007d2..50398eeb2 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -522,5 +522,77 @@ namespace SixLabors.ImageSharp.PixelFormats { this.ToArgb32(sourceColors, MemoryMarshal.Cast(destBytes), count); } + + /// + /// Converts 'count' elements in 'source` span of data to a span of -s. + /// + /// The source of data. + /// The to the destination pixels. + /// The number of pixels to convert. + internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! + var temp = NamedColors.Black; + + for (int i = 0; i < count; i++) + { + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + temp = Unsafe.Add(ref sourceRef, i); + dp.PackFromGray8(temp); + } + } + + /// + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// + /// The to the source bytes. + /// The to the destination pixels. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + { + this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); + } + + /// + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Bulk version of . + /// + /// The span of source pixels + /// The destination span of data. + /// The number of pixels to convert. + internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span dest, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); + sp.ToGray8(ref dp); + } + } + + /// + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void ToGray8Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + { + this.ToGray8(sourceColors, MemoryMarshal.Cast(destBytes), count); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index dbd30560e..b4b577e3a 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -127,5 +127,8 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethods("Argb32", "Argb32", "temp = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Argb32"); - #> } + + GeneratePackFromMethods("Gray8", "Gray8", "temp = Unsafe.Add(ref sourceRef, i);"); + GenerateToDestFormatMethods("Gray8"); +#> } } \ No newline at end of file From 6b70bd696f11dcb8d73f6dcecc94073a2f7915c1 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 19:19:58 +0200 Subject: [PATCH 004/238] #718: fix Gray8Tests --- tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index c4ce7339d..64ad0bff6 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // arrange Rgb24 actual = default; Gray8 gray = default; - var expected = new Rgb24(0, 0, 0); + var expected = new Rgb24(128, 128, 128); Vector4 scaled = new Gray8(128).ToScaledVector4(); // act @@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // arrange Rgba32 actual = default; Gray8 gray = default; - var expected = new Rgba32(0, 0, 0, 128); + var expected = new Rgba32(128, 128, 128, 255); Vector4 scaled = new Gray8(128).ToScaledVector4(); // act From 4c80b16f31834879bf2c6e3d0ad6919d05fe70c9 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 22:13:58 +0200 Subject: [PATCH 005/238] #718: extend IPixel interface and implement it everywhere, ... AND add unit tests AND fix Gray16 implementation (constructor takes ushort, not byte) AND fix Gray8 and Gray16 Pack (do not scale by sum) --- src/ImageSharp/PixelFormats/Alpha8.cs | 16 ++ src/ImageSharp/PixelFormats/Argb32.cs | 30 +++ src/ImageSharp/PixelFormats/Bgr24.cs | 27 +++ src/ImageSharp/PixelFormats/Bgr565.cs | 16 ++ src/ImageSharp/PixelFormats/Bgra32.cs | 29 +++ src/ImageSharp/PixelFormats/Bgra4444.cs | 16 ++ src/ImageSharp/PixelFormats/Bgra5551.cs | 16 ++ src/ImageSharp/PixelFormats/Byte4.cs | 16 ++ src/ImageSharp/PixelFormats/Gray16.cs | 33 ++- src/ImageSharp/PixelFormats/Gray8.cs | 3 +- src/ImageSharp/PixelFormats/HalfSingle.cs | 16 ++ src/ImageSharp/PixelFormats/HalfVector2.cs | 16 ++ src/ImageSharp/PixelFormats/HalfVector4.cs | 16 ++ src/ImageSharp/PixelFormats/IPixel.cs | 24 ++ .../PixelFormats/NormalizedByte2.cs | 16 ++ .../PixelFormats/NormalizedByte4.cs | 16 ++ .../PixelFormats/NormalizedShort2.cs | 16 ++ .../PixelFormats/NormalizedShort4.cs | 16 ++ src/ImageSharp/PixelFormats/Rg32.cs | 16 ++ src/ImageSharp/PixelFormats/Rgb24.cs | 27 +++ src/ImageSharp/PixelFormats/Rgb48.cs | 33 +++ src/ImageSharp/PixelFormats/Rgba1010102.cs | 16 ++ src/ImageSharp/PixelFormats/Rgba32.cs | 35 +++ src/ImageSharp/PixelFormats/Rgba64.cs | 29 +++ src/ImageSharp/PixelFormats/RgbaVector.cs | 16 ++ src/ImageSharp/PixelFormats/Short2.cs | 16 ++ src/ImageSharp/PixelFormats/Short4.cs | 16 ++ .../PixelFormats/Gray16Tests.cs | 211 ++++++++++++++++++ 28 files changed, 748 insertions(+), 5 deletions(-) create mode 100644 tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index a8d97d31a..d795931af 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -168,6 +168,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.B = 0; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackedValue = 255; + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackedValue = 0; + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackedValue = 255; + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackedValue = 0; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 51d3964ef..0249bb6af 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -289,6 +290,35 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.A = 255; + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); + this.R = val; + this.G = val; + this.B = val; + this.A = 255; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// /// Converts the pixel to format. /// diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index fc283b568..bc8e2324c 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -172,6 +172,33 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = byte.MaxValue; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); + this.R = val; + this.G = val; + this.B = val; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 570b975db..53f15ecb3 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -187,6 +187,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 233df2f29..304f81535 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -215,6 +215,35 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgra32(ref Bgra32 dest) => dest = this; + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.R = source.PackedValue; + this.R = source.PackedValue; + this.R = source.PackedValue; + this.A = byte.MaxValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); + this.R = val; + this.G = val; + this.B = val; + this.A = byte.MaxValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// /// Converts the pixel to format. /// diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index 90f967f89..f684bec33 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -178,6 +178,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 3a18c03e8..1044a0feb 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -178,6 +178,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index bb1b350f0..aea3aec65 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -179,6 +179,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index a7e50e366..6fda8b081 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Initializes a new instance of the struct. /// /// The gray component - public Gray16(byte gray) + public Gray16(ushort gray) { this.PackedValue = gray; } @@ -185,6 +185,34 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.PackedValue = (ushort)(source.PackedValue * 255); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) + { + dest.PackedValue = (byte)(((this.PackedValue * 255) + 32895) >> 16); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + this.PackedValue = source.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) + { + dest.PackedValue = this.PackedValue; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => @@ -252,9 +280,8 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ushort Pack(float r, float g, float b) { - float sum = r + g + b; float val = (r * Rx) + (g * Gx) + (b * Bx); - return (ushort)Math.Round(val * 65535f / sum); // TODO: if this is correct, Rx, Gx, Bx consts could be scaled by 65535f directly! + return (ushort)Math.Round(val * 65535f); } /// diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index db0539543..1509f8ea9 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -257,9 +257,8 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] private static byte Pack(float r, float g, float b) { - float sum = r + g + b; float val = (r * Rx) + (g * Gx) + (b * Bx); - return (byte)Math.Round(val * 255 / sum); // TODO: if this is correct, Rx, Gx, Bx consts could be scaled by 255 directly! + return (byte)Math.Round(val * 255); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 09b463649..b392910a6 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -192,6 +192,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index befa49736..ac70f4fbc 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -207,6 +207,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 885e02292..9bdae99ab 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -200,6 +200,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index ae09af626..382c8541d 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -126,5 +126,29 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The destination pixel to write to void ToBgra32(ref Bgra32 dest); + + /// + /// Packs the Pixel from an value. + /// + /// The value. + void PackFromGray8(Gray8 source); + + /// + /// Converts the pixel to format. + /// + /// The destination pixel to write to. + void ToGray8(ref Gray8 dest); + + /// + /// Packs the Pixel from an value. + /// + /// The value. + void PackFromGray16(Gray16 source); + + /// + /// Converts the pixel tgo value. + /// + /// The destination pixel to write to. + void ToGray16(ref Gray16 dest); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 8592fdd6a..cd9fa65fb 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -226,6 +226,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index 293d536e5..9b53adecc 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -219,6 +219,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 1ced412d0..3319a1092 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -213,6 +213,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 25b26fa7f..7a74a4434 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -221,6 +221,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index e5ceeacec..e4bed1275 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -191,6 +191,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index d7e1c47ec..4c5aef543 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -166,6 +166,33 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = byte.MaxValue; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); + this.R = val; + this.G = val; + this.B = val; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/Rgb48.cs index 2d92b0e4e..7784c49ff 100644 --- a/src/ImageSharp/PixelFormats/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/Rgb48.cs @@ -210,6 +210,39 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + var val = (ushort)(source.PackedValue * 255); + this.R = val; + this.G = val; + this.B = val; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) + { + dest.PackFromRgb48(this); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) + { + dest.PackFromRgb48(this); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this = source; diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 94fb7a41e..6dd5f7b54 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -185,6 +185,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index cf66538c5..aab9fad92 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -336,6 +336,41 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + this.A = 0; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) + { + dest.PackFromRgba32(this); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); + this.R = val; + this.G = val; + this.B = val; + this.A = 0; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) + { + dest.PackFromRgba32(this); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromScaledVector4(Vector4 vector) diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 8e6be1e8c..5c3187856 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -274,6 +274,35 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)(((this.A * 255) + 32895) >> 16); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) + { + ushort x = (ushort)(source.PackedValue * 255); + this.R = x; + this.G = x; + this.B = x; + this.A = ushort.MaxValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) + { + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + this.A = ushort.MaxValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// public override bool Equals(object obj) { diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index dd5f77b80..3ab45a66e 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -298,6 +298,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 9fc7618b9..331c5fb20 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -207,6 +207,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 641f154f9..4a3d89ad8 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -213,6 +213,22 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray8(ref Gray8 dest) => dest.PackFromVector4(this.ToVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToGray16(ref Gray16 dest) => dest.PackFromVector4(this.ToVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs new file mode 100644 index 000000000..2525ee379 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -0,0 +1,211 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public class Gray16Tests + { + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(32767)] + [InlineData(42)] + public void Gray16_PackedValue_EqualsInput(ushort input) + { + Assert.Equal(input, new Gray16(input).PackedValue); + } + + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(32767)] + public void Gray16_ToVector4(ushort input) + { + // arrange + var gray = new Gray16(input); + + // act + var actual = gray.ToVector4(); + + // assert + Assert.Equal(input, actual.X); + Assert.Equal(input, actual.Y); + Assert.Equal(input, actual.Z); + Assert.Equal(1, actual.W); + } + + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(32767)] + public void Gray16_ToScaledVector4(ushort input) + { + // arrange + var gray = new Gray16(input); + + // act + var actual = gray.ToScaledVector4(); + + // assert + float scaledInput = input / 65535f; + Assert.Equal(scaledInput, actual.X); + Assert.Equal(scaledInput, actual.Y); + Assert.Equal(scaledInput, actual.Z); + Assert.Equal(1, actual.W); + } + + [Fact] + public void Gray16_PackFromScaledVector4() + { + // arrange + Gray16 gray = default; + int expected = 32767; + Vector4 scaled = new Gray16((ushort)expected).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + ushort actual = gray.PackedValue; + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToRgb24() + { + // arrange + Rgb24 actual = default; + Gray16 gray = default; + var expected = new Rgb24(128, 128, 128); + Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgb24(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToRgba32() + { + // arrange + Rgba32 actual = default; + Gray16 gray = default; + var expected = new Rgba32(128, 128, 128, 255); + Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgba32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToBgr24() + { + // arrange + Bgr24 actual = default; + Gray16 gray = default; + var expected = new Bgr24(128, 128, 128); + Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToBgr24(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToBgra32() + { + // arrange + Bgra32 actual = default; + Gray16 gray = default; + var expected = new Bgra32(128,128,128); + Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToBgra32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToArgb32() + { + // arrange + Gray16 gray = default; + Argb32 actual = default; + var expected = new Argb32(128, 128, 128); + Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToArgb32(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromScaledVector4_ToRgba64() + { + // arrange + Gray16 gray = default; + Rgba64 actual = default; + var expected = new Rgba64(65535, 65535, 65535, 65535); + Vector4 scaled = new Gray16(65535).ToScaledVector4(); + + // act + gray.PackFromScaledVector4(scaled); + gray.ToRgba64(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromRgb48_ToRgb48() + { + // arrange + var gray = default(Gray16); + var actual = default(Rgb48); + var expected = new Rgb48(0, 0, 0); + + // act + gray.PackFromRgb48(expected); + gray.ToRgb48(ref actual); + + // assert + Assert.Equal(expected, actual); + } + + [Fact] + public void Gray16_PackFromRgba64_ToRgba64() + { + // arrange + var gray = default(Gray16); + var actual = default(Rgba64); + var expected = new Rgba64(0, 0, 0, 65535); + + // act + gray.PackFromRgba64(expected); + gray.ToRgba64(ref actual); + + // assert + Assert.Equal(expected, actual); + } + } +} From 845af5e2e7e18d75a6bd7e6bb217253d000db9a1 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sat, 6 Oct 2018 23:55:34 +0200 Subject: [PATCH 006/238] #718: add missing inheritdoc comments --- src/ImageSharp/PixelFormats/Gray8.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index 1509f8ea9..916e199d0 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -195,9 +195,11 @@ namespace SixLabors.ImageSharp.PixelFormats public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromGray16(Gray16 source) => this.PackedValue = (byte)(source.PackedValue / 255); From 1cec215596a0e830fbf8f8fc32eb72ee23686e8b Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 7 Oct 2018 00:08:42 +0200 Subject: [PATCH 007/238] #718: add missing documentation --- src/ImageSharp/PixelFormats/Gray16.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index 6fda8b081..06da2867a 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -287,7 +287,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Packs the into a byte. /// - /// + /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] private byte PackedAsByte() { From 1bd63b33b3aff7dccf7f58f9985a61607666e846 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 8 Oct 2018 19:00:01 +0100 Subject: [PATCH 008/238] Fix Gray8 --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 67 +++++++ src/ImageSharp/PixelFormats/Alpha8.cs | 105 +++-------- src/ImageSharp/PixelFormats/Gray8.cs | 188 +++++++++----------- 3 files changed, 176 insertions(+), 184 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index c15e0a732..f9ade4cfe 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -13,6 +13,73 @@ namespace SixLabors.ImageSharp /// internal static class ImageMaths { + /// + /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public static byte GetBT709LuminanceBytes(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F)); + + /// + /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public static ushort GetBT709Luminance(ushort r, ushort g, ushort b) => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F)); + + /// + /// Scales a value from a 16 bit to it's 8 bit equivalent. + /// + /// The 8 bit compoonent value. + /// The + [MethodImpl(InliningOptions.ShortMethod)] + public static byte DownScaleFrom16BitTo8Bit(ushort component) + { + // To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is: + // + // (V * 255) / 65535 + // + // This reduces to round(V / 257), or floor((V + 128.5)/257) + // + // Represent V as the two byte value vhi.vlo. Make a guess that the + // result is the top byte of V, vhi, then the correction to this value + // is: + // + // error = floor(((V-vhi.vhi) + 128.5) / 257) + // = floor(((vlo-vhi) + 128.5) / 257) + // + // This can be approximated using integer arithmetic (and a signed + // shift): + // + // error = (vlo-vhi+128) >> 8; + // + // The approximate differs from the exact answer only when (vlo-vhi) is + // 128; it then gives a correction of +1 when the exact correction is + // 0. This gives 128 errors. The exact answer (correct for all 16-bit + // input values) is: + // + // error = (vlo-vhi+128)*65535 >> 24; + // + // An alternative arithmetic calculation which also gives no errors is: + // + // (V * 255 + 32895) >> 16 + return (byte)(((component * 255) + 32895) >> 16); + } + + /// + /// Scales a value from an 8 bit to it's 16 bit equivalent. + /// + /// The 8 bit compoonent value. + /// The + [MethodImpl(InliningOptions.ShortMethod)] + public static ushort UpscaleFrom8BitTo16Bit(byte component) => (ushort)(component * 257); + /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index d795931af..177ce81ef 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -19,10 +19,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Initializes a new instance of the struct. /// /// The alpha component - public Alpha8(float alpha) - { - this.PackedValue = Pack(alpha); - } + public Alpha8(float alpha) => this.PackedValue = Pack(alpha); /// public byte PackedValue { get; set; } @@ -40,10 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// True if the parameter is equal to the parameter; otherwise, false. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Alpha8 left, Alpha8 right) - { - return left.PackedValue == right.PackedValue; - } + public static bool operator ==(Alpha8 left, Alpha8 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -54,77 +48,48 @@ namespace SixLabors.ImageSharp.PixelFormats /// True if the parameter is not equal to the parameter; otherwise, false. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Alpha8 left, Alpha8 right) - { - return left.PackedValue != right.PackedValue; - } + public static bool operator !=(Alpha8 left, Alpha8 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + public Vector4 ToScaledVector4() => this.ToVector4(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.W); - } + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(vector.W); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(0, 0, 0, this.PackedValue / 255F); - } + public Vector4 ToVector4() => new Vector4(0, 0, 0, this.PackedValue / 255F); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackedValue = source.A; - } + public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackedValue = source.A; - } + public void PackFromArgb32(Argb32 source) => this.PackedValue = source.A; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackedValue = source.A; - } + public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.A; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest = default(Rgb24); - } + public void ToRgb24(ref Rgb24 dest) => dest = default; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgba32(ref Rgba32 dest) { - dest.R = 0; - dest.G = 0; - dest.B = 0; + dest.Rgb = default; dest.A = this.PackedValue; } @@ -140,10 +105,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - dest = default(Bgr24); - } + public void ToBgr24(ref Bgr24 dest) => dest = default; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -161,28 +123,23 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) - { - dest.R = 0; - dest.G = 0; - dest.B = 0; - } + public void ToRgb48(ref Rgb48 dest) => dest = default; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray8(Gray8 source) => this.PackedValue = 255; + public void PackFromGray8(Gray8 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackedValue = 0; + public void ToGray8(ref Gray8 dest) => dest = default; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) => this.PackedValue = 255; + public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackedValue = 0; + public void ToGray16(ref Gray16 dest) => dest = default; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -190,17 +147,18 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + public void ToRgba64(ref Rgba64 dest) + { + dest.Rgb = default; + dest.A = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); + } /// /// Compares an object with the packed vector. /// /// The object to compare. /// True if the object is equal to the packed vector. - public override bool Equals(object obj) - { - return obj is Alpha8 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Alpha8 other && this.Equals(other); /// /// Compares another Alpha8 packed vector with the packed vector. @@ -208,19 +166,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// The Alpha8 packed vector to compare. /// True if the packed vectors are equal. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Alpha8 other) - { - return this.PackedValue == other.PackedValue; - } + public bool Equals(Alpha8 other) => this.PackedValue.Equals(other.PackedValue); /// /// Gets a string representation of the packed vector. /// /// A string representation of the packed vector. - public override string ToString() - { - return (this.PackedValue / 255F).ToString(); - } + public override string ToString() => (this.PackedValue / 255F).ToString(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -232,9 +184,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// The float containing the value to pack. /// The containing the packed values. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static byte Pack(float alpha) - { - return (byte)Math.Round(alpha.Clamp(0, 1) * 255F); - } + private static byte Pack(float alpha) => (byte)Math.Round(alpha.Clamp(0, 1) * 255F); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index 916e199d0..0a41a6ecc 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -30,14 +29,21 @@ namespace SixLabors.ImageSharp.PixelFormats /// private const float Bx = .0722F; + /// + /// The maximum byte value. + /// + private static readonly Vector4 MaxBytes = new Vector4(255F); + + /// + /// The half vector value. + /// + private static readonly Vector4 Half = new Vector4(0.5F); + /// /// Initializes a new instance of the struct. /// /// The gray component - public Gray8(byte gray) - { - this.PackedValue = gray; - } + public Gray8(byte gray) => this.PackedValue = gray; /// public byte PackedValue { get; set; } @@ -45,20 +51,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Gray8 left, Gray8 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Gray8 left, Gray8 right) => left.PackedValue.Equals(right.PackedValue); /// /// Compares two objects for equality. @@ -68,67 +67,54 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Gray8 left, Gray8 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Gray8 left, Gray8 right) => !left.PackedValue.Equals(right.PackedValue); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - var scaledGray = this.PackedValue / 255f; - return new Vector4(scaledGray, scaledGray, scaledGray, 1.0f); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z); + vector *= MaxBytes; + vector += Half; + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); + float luminance = (vector.X * Rx) + (vector.Y * Gx) + (vector.Z * Bx); + + this.PackedValue = (byte)luminance; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { - return new Vector4(this.PackedValue, this.PackedValue, this.PackedValue, 1.0f); + float rgb = this.PackedValue / 255F; + return new Vector4(rgb, rgb, rgb, 1F); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackedValue = Pack(source.R, source.G, source.B); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackedValue = Pack(source.R, source.G, source.B); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackedValue = Pack(source.R, source.G, source.B); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToRgb24(ref Rgb24 dest) { dest.R = this.PackedValue; @@ -137,27 +123,27 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { dest.R = this.PackedValue; dest.G = this.PackedValue; dest.B = this.PackedValue; - dest.A = 255; + dest.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToArgb32(ref Argb32 dest) { dest.R = this.PackedValue; dest.G = this.PackedValue; dest.B = this.PackedValue; - dest.A = 255; + dest.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToBgr24(ref Bgr24 dest) { dest.R = this.PackedValue; @@ -166,101 +152,91 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToBgra32(ref Bgra32 dest) { dest.R = this.PackedValue; dest.G = this.PackedValue; dest.B = this.PackedValue; - dest.A = 255; + dest.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => - this.PackedValue = Pack(source.R, source.G, source.B); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) + => this.PackedValue = ImageMaths.GetBT709LuminanceBytes( + ImageMaths.DownScaleFrom16BitTo8Bit(source.R), + ImageMaths.DownScaleFrom16BitTo8Bit(source.G), + ImageMaths.DownScaleFrom16BitTo8Bit(source.B)); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToRgb48(ref Rgb48 dest) { - ushort gray = (ushort)(this.PackedValue * 255); - dest.R = gray; - dest.G = gray; - dest.B = gray; + ushort luminance = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); + dest.R = luminance; + dest.G = luminance; + dest.B = luminance; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba64(Rgba64 source) => - this.PackFromScaledVector4(source.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba64(Rgba64 source) + => this.PackedValue = ImageMaths.GetBT709LuminanceBytes( + ImageMaths.DownScaleFrom16BitTo8Bit(source.R), + ImageMaths.DownScaleFrom16BitTo8Bit(source.G), + ImageMaths.DownScaleFrom16BitTo8Bit(source.B)); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) => this.PackedValue = (byte)(source.PackedValue / 255); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void ToRgba64(ref Rgba64 dest) + { + ushort luminance = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); + dest.R = luminance; + dest.G = luminance; + dest.B = luminance; + dest.A = ushort.MaxValue; + } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void ToGray8(ref Gray8 dest) => dest.PackedValue = this.PackedValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackedValue = (ushort)(this.PackedValue * 255); + [MethodImpl(InliningOptions.ShortMethod)] + public void ToGray16(ref Gray16 dest) => dest.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); /// /// Compares an object with the packed vector. /// /// The object to compare. /// True if the object is equal to the packed vector. - public override bool Equals(object obj) - { - return obj is Gray8 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Gray8 other && this.Equals(other); /// /// Compares another packed vector with the packed vector. /// /// The Gray8 packed vector to compare. /// True if the packed vectors are equal. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Gray8 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Gray8 other) => this.PackedValue.Equals(other.PackedValue); /// /// Gets a string representation of the packed vector. /// /// A string representation of the packed vector. - public override string ToString() - { - return (this.PackedValue / 255F).ToString(); - } + public override string ToString() => $"Gray8({this.PackedValue}"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - - /// - /// Packs a into a byte. - /// - /// Red value of the color to pack. - /// Green value of the color to pack. - /// Blue value of the color to pack. - /// The containing the packed value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static byte Pack(float r, float g, float b) - { - float val = (r * Rx) + (g * Gx) + (b * Bx); - return (byte)Math.Round(val * 255); - } } } \ No newline at end of file From d49d74aafc3e99727735a76b4f30ff6e20703e24 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 9 Oct 2018 23:57:23 +0100 Subject: [PATCH 009/238] Update and normalise pixel format + disable out of date tests --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 4 +- src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs | 4 +- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 34 +- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 116 +- src/ImageSharp/PixelFormats/Alpha8.cs | 102 +- src/ImageSharp/PixelFormats/Argb32.cs | 260 +--- src/ImageSharp/PixelFormats/Bgr24.cs | 191 +-- src/ImageSharp/PixelFormats/Bgr565.cs | 216 +-- src/ImageSharp/PixelFormats/Bgra32.cs | 230 +-- src/ImageSharp/PixelFormats/Bgra4444.cs | 200 +-- src/ImageSharp/PixelFormats/Bgra5551.cs | 209 +-- src/ImageSharp/PixelFormats/Byte4.cs | 182 +-- .../PixelOperations{TPixel}.Generated.cs | 113 +- .../PixelOperations{TPixel}.Generated.tt | 8 +- .../Rgba32.PixelOperations.Generated.cs | 12 +- .../Rgba32.PixelOperations.Generated.tt | 12 +- src/ImageSharp/PixelFormats/Gray16.cs | 262 +--- src/ImageSharp/PixelFormats/Gray8.cs | 136 +- src/ImageSharp/PixelFormats/HalfSingle.cs | 200 +-- src/ImageSharp/PixelFormats/HalfTypeHelper.cs | 12 +- src/ImageSharp/PixelFormats/HalfVector2.cs | 231 +-- src/ImageSharp/PixelFormats/HalfVector4.cs | 203 +-- src/ImageSharp/PixelFormats/IPixel.cs | 96 +- .../PixelFormats/NormalizedByte2.cs | 263 +--- .../PixelFormats/NormalizedByte4.cs | 244 +-- .../PixelFormats/NormalizedShort2.cs | 253 +-- .../PixelFormats/NormalizedShort4.cs | 257 +--- src/ImageSharp/PixelFormats/Rg32.cs | 230 +-- src/ImageSharp/PixelFormats/Rgb24.cs | 185 +-- src/ImageSharp/PixelFormats/Rgb48.cs | 206 +-- src/ImageSharp/PixelFormats/Rgba1010102.cs | 222 +-- src/ImageSharp/PixelFormats/Rgba32.cs | 306 +--- src/ImageSharp/PixelFormats/Rgba64.cs | 248 +-- src/ImageSharp/PixelFormats/RgbaVector.cs | 355 +---- src/ImageSharp/PixelFormats/Short2.cs | 250 +-- src/ImageSharp/PixelFormats/Short4.cs | 248 +-- .../BinaryErrorDiffusionProcessor.cs | 11 +- .../BinaryOrderedDitherProcessor.cs | 9 +- .../Binarization/BinaryThresholdProcessor.cs | 9 +- .../ErrorDiffusionPaletteProcessor.cs | 12 +- .../OrderedDitherPaletteProcessor.cs | 15 +- .../OctreeFrameQuantizer{TPixel}.cs | 49 +- .../Quantization/WuFrameQuantizer{TPixel}.cs | 48 +- .../ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs | 32 +- .../Color/Bulk/ToXyzw.cs | 14 +- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 8 +- tests/ImageSharp.Tests/Issues/Issue594.cs | 174 +-- .../PixelFormats/Alpha8Tests.cs | 266 ++-- .../PixelFormats/Argb32Tests.cs | 308 ++-- .../PixelFormats/Bgr24Tests.cs | 150 +- .../PixelFormats/Bgr565Tests.cs | 212 +-- .../PixelFormats/Bgra32Tests.cs | 150 +- .../PixelFormats/Bgra4444Tests.cs | 308 ++-- .../PixelFormats/Bgra5551Tests.cs | 308 ++-- .../PixelFormats/Byte4Tests.cs | 308 ++-- .../PixelFormats/ColorConstructorTests.cs | 151 -- .../PixelFormats/ColorEqualityTests.cs | 216 --- .../PixelFormats/ColorPackingTests.cs | 88 -- .../PixelFormats/Gray16Tests.cs | 376 ++--- .../PixelFormats/Gray8Tests.cs | 302 ++-- .../PixelFormats/HalfSingleTests.cs | 212 +-- .../PixelFormats/HalfVector2Tests.cs | 212 +-- .../PixelFormats/HalfVector4Tests.cs | 308 ++-- .../PixelFormats/NormalizedByte2Tests.cs | 244 +-- .../PixelFormats/NormalizedByte4Tests.cs | 278 ++-- .../PixelFormats/NormalizedShort2Tests.cs | 246 +-- .../PixelFormats/NormalizedShort4Tests.cs | 278 ++-- .../PixelFormats/PixelOperationsTests.cs | 1354 ++++++++--------- .../PixelFormats/Rg32Tests.cs | 182 +-- .../PixelFormats/Rgb24Tests.cs | 350 ++--- .../PixelFormats/Rgb48Tests.cs | 391 +++-- .../PixelFormats/Rgba1010102Tests.cs | 278 ++-- .../PixelFormats/Rgba32Tests.cs | 110 +- .../PixelFormats/Rgba64Tests.cs | 221 +-- .../PixelFormats/RgbaVectorTests.cs | 50 +- .../PixelFormats/Short2Tests.cs | 74 +- .../PixelFormats/Short4Tests.cs | 74 +- .../PixelFormats/UnPackedPixelTests.cs | 64 +- .../Transforms/AffineTransformTests.cs | 13 +- .../Quantization/QuantizedImageTests.cs | 5 +- .../TestUtilities/ImagingTestCaseUtility.cs | 12 +- .../TestUtilities/TestUtils.cs | 16 +- .../Tests/TestImageProviderTests.cs | 38 +- 83 files changed, 5479 insertions(+), 9355 deletions(-) delete mode 100644 tests/ImageSharp.Tests/PixelFormats/ColorConstructorTests.cs delete mode 100644 tests/ImageSharp.Tests/PixelFormats/ColorEqualityTests.cs delete mode 100644 tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index f9ade4cfe..7bf73245f 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp /// The blue component. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static byte GetBT709LuminanceBytes(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F)); + public static byte Get8BitBT709Luminance(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F)); /// /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709. @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp /// The blue component. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static ushort GetBT709Luminance(ushort r, ushort g, ushort b) => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F)); + public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F)); /// /// Scales a value from a 16 bit to it's 8 bit equivalent. diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 44e42528c..186ff812f 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -101,9 +101,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp var fileHeader = new BmpFileHeader( type: 19778, // BM - offset: 54, + fileSize: 54 + infoHeader.ImageSize, reserved: 0, - fileSize: 54 + infoHeader.ImageSize); + offset: 54); #if NETCOREAPP2_1 Span buffer = stackalloc byte[40]; diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index ae0366e6e..f00a6b61e 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -210,16 +211,20 @@ namespace SixLabors.ImageSharp.Formats.Gif { // Transparent pixels are much more likely to be found at the end of a palette int index = -1; - Rgba32 trans = default; + int length = quantized.Palette.Length; - ref TPixel paletteRef = ref MemoryMarshal.GetReference(quantized.Palette.AsSpan()); - for (int i = quantized.Palette.Length - 1; i >= 0; i--) + using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(length)) { - ref TPixel entry = ref Unsafe.Add(ref paletteRef, i); - entry.ToRgba32(ref trans); - if (trans.Equals(default)) + Span rgbaSpan = rgbaBuffer.GetSpan(); + ref Rgba32 paletteRef = ref MemoryMarshal.GetReference(rgbaSpan); + PixelOperations.Instance.ToRgba32(quantized.Palette, rgbaSpan, length); + + for (int i = quantized.Palette.Length - 1; i >= 0; i--) { - index = i; + if (Unsafe.Add(ref paletteRef, i).Equals(default)) + { + index = i; + } } } @@ -406,24 +411,13 @@ namespace SixLabors.ImageSharp.Formats.Gif private void WriteColorTable(QuantizedFrame image, Stream stream) where TPixel : struct, IPixel { - int pixelCount = image.Palette.Length; - // The maximium number of colors for the bit depth int colorTableLength = ImageMaths.GetColorCountForBitDepth(this.bitDepth) * 3; - Rgb24 rgb = default; + int pixelCount = image.Palette.Length; using (IManagedByteBuffer colorTable = this.memoryAllocator.AllocateManagedByteBuffer(colorTableLength)) { - ref TPixel paletteRef = ref MemoryMarshal.GetReference(image.Palette.AsSpan()); - ref Rgb24 rgb24Ref = ref Unsafe.As(ref MemoryMarshal.GetReference(colorTable.GetSpan())); - for (int i = 0; i < pixelCount; i++) - { - ref TPixel entry = ref Unsafe.Add(ref paletteRef, i); - entry.ToRgb24(ref rgb); - Unsafe.Add(ref rgb24Ref, i) = rgb; - } - - // Write the palette to the stream + PixelOperations.Instance.ToRgb24Bytes(image.Palette.AsSpan(), colorTable.GetSpan(), pixelCount); stream.Write(colorTable.Array, 0, colorTableLength); } } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index a46d83707..1e9dbc71a 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Buffers.Binary; using System.Collections.Generic; using System.IO; @@ -312,11 +313,6 @@ namespace SixLabors.ImageSharp.Formats.Png private void CollectGrayscaleBytes(ReadOnlySpan rowSpan) where TPixel : struct, IPixel { - // Use ITU-R recommendation 709 to match libpng. - const float RX = .2126F; - const float GX = .7152F; - const float BX = .0722F; - ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan); Span rawScanlineSpan = this.rawScanline.GetSpan(); ref byte rawScanlineSpanRef = ref MemoryMarshal.GetReference(rawScanlineSpan); @@ -327,12 +323,18 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.use16Bit) { // 16 bit grayscale - Rgb48 rgb = default; - for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 2) + using (IMemoryOwner luminanceBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { - Unsafe.Add(ref rowSpanRef, x).ToRgb48(ref rgb); - ushort luminance = (ushort)((RX * rgb.R) + (GX * rgb.G) + (BX * rgb.B)); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance); + Span luminanceSpan = luminanceBuffer.GetSpan(); + ref Gray16 luminanceRef = ref MemoryMarshal.GetReference(luminanceSpan); + PixelOperations.Instance.ToGray16(rowSpan, luminanceSpan, rowSpan.Length); + + // Can't map directly to byte array as it's big endian. + for (int x = 0, o = 0; x < luminanceSpan.Length; x++, o += 2) + { + Gray16 luminance = Unsafe.Add(ref luminanceRef, x); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance.PackedValue); + } } } else @@ -340,12 +342,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.bitDepth == 8) { // 8 bit grayscale - Rgb24 rgb = default; - for (int x = 0; x < rowSpan.Length; x++) - { - Unsafe.Add(ref rowSpanRef, x).ToRgb24(ref rgb); - Unsafe.Add(ref rawScanlineSpanRef, x) = (byte)((RX * rgb.R) + (GX * rgb.G) + (BX * rgb.B)); - } + PixelOperations.Instance.ToGray8Bytes(rowSpan, rawScanlineSpan, rowSpan.Length); } else { @@ -356,14 +353,9 @@ namespace SixLabors.ImageSharp.Formats.Png Span tempSpan = temp.GetSpan(); ref byte tempSpanRef = ref MemoryMarshal.GetReference(tempSpan); - Rgb24 rgb = default; - for (int x = 0; x < rowSpan.Length; x++) - { - Unsafe.Add(ref rowSpanRef, x).ToRgb24(ref rgb); - float luminance = ((RX * rgb.R) + (GX * rgb.G) + (BX * rgb.B)) / scaleFactor; - Unsafe.Add(ref tempSpanRef, x) = (byte)luminance; - this.ScaleDownFrom8BitArray(tempSpan, rawScanlineSpan, this.bitDepth); - } + // We need to first create an array of luminance bytes then scale them down to the correct bit depth. + PixelOperations.Instance.ToGray8Bytes(rowSpan, tempSpan, rowSpan.Length); + this.ScaleDownFrom8BitArray(tempSpan, rawScanlineSpan, this.bitDepth, scaleFactor); } } } @@ -373,23 +365,31 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.use16Bit) { // 16 bit grayscale + alpha - Rgba64 rgba = default; - for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 4) + // TODO: Should we consider in the future a GrayAlpha32 type. + using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { - Unsafe.Add(ref rowSpanRef, x).ToRgba64(ref rgba); - ushort luminance = (ushort)((RX * rgba.R) + (GX * rgba.G) + (BX * rgba.B)); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.A); + Span rgbaSpan = rgbaBuffer.GetSpan(); + ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); + PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan, rowSpan.Length); + + // Can't map directly to byte array as it's big endian. + for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4) + { + Rgba64 rgba = Unsafe.Add(ref rgbaRef, x); + ushort luminance = ImageMaths.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.A); + } } } else { // 8 bit grayscale + alpha - Rgba32 rgba = default; + // TODO: Should we consider in the future a GrayAlpha16 type. for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 2) { - Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba); - Unsafe.Add(ref rawScanlineSpanRef, o) = (byte)((RX * rgba.R) + (GX * rgba.G) + (BX * rgba.B)); + var rgba = Unsafe.Add(ref rowSpanRef, x).ToRgba32(); + Unsafe.Add(ref rawScanlineSpanRef, o) = ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A; } } @@ -425,15 +425,21 @@ namespace SixLabors.ImageSharp.Formats.Png case 8: { // 16 bit Rgba - Rgba64 rgba = default; - ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan); - for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 8) + using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { - Unsafe.Add(ref rowSpanRef, x).ToRgba64(ref rgba); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), rgba.R); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.G); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 4, 2), rgba.B); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 6, 2), rgba.A); + Span rgbaSpan = rgbaBuffer.GetSpan(); + ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); + PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan, rowSpan.Length); + + // Can't map directly to byte array as it's big endian. + for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 8) + { + Rgba64 rgba = Unsafe.Add(ref rgbaRef, x); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), rgba.R); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.G); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 4, 2), rgba.B); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 6, 2), rgba.A); + } } break; @@ -442,14 +448,20 @@ namespace SixLabors.ImageSharp.Formats.Png default: { // 16 bit Rgb - Rgb48 rgb = default; - ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan); - for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 6) + using (IMemoryOwner rgbBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { - Unsafe.Add(ref rowSpanRef, x).ToRgb48(ref rgb); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), rgb.R); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgb.G); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 4, 2), rgb.B); + Span rgbSpan = rgbBuffer.GetSpan(); + ref Rgb48 rgbRef = ref MemoryMarshal.GetReference(rgbSpan); + PixelOperations.Instance.ToRgb48(rowSpan, rgbSpan, rowSpan.Length); + + // Can't map directly to byte array as it's big endian. + for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 6) + { + Rgb48 rgb = Unsafe.Add(ref rgbRef, x); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), rgb.R); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgb.G); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 4, 2), rgb.B); + } } break; @@ -624,7 +636,6 @@ namespace SixLabors.ImageSharp.Formats.Png TPixel[] palette = quantized.Palette; int paletteLength = Math.Min(palette.Length, 256); int colorTableLength = paletteLength * 3; - Rgba32 rgba = default; bool anyAlpha = false; using (IManagedByteBuffer colorTable = this.memoryAllocator.AllocateManagedByteBuffer(colorTableLength)) @@ -639,7 +650,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (quantizedSpan.IndexOf((byte)i) > -1) { int offset = i * 3; - palette[i].ToRgba32(ref rgba); + var rgba = palette[i].ToRgba32(); byte alpha = rgba.A; @@ -851,7 +862,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// The source span in 8 bits. /// The resultant span in . /// The bit depth. - private void ScaleDownFrom8BitArray(ReadOnlySpan source, Span result, int bits) + /// The scaling factor. + private void ScaleDownFrom8BitArray(ReadOnlySpan source, Span result, int bits, float scale = 1) { ref byte sourceRef = ref MemoryMarshal.GetReference(source); ref byte resultRef = ref MemoryMarshal.GetReference(result); @@ -864,7 +876,7 @@ namespace SixLabors.ImageSharp.Formats.Png for (int i = 0; i < source.Length; i++) { - int value = Unsafe.Add(ref sourceRef, i) & mask; + int value = ((int)MathF.Round(Unsafe.Add(ref sourceRef, i) / scale)) & mask; v |= value << shift; if (shift == 0) diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 177ce81ef..91be2efdd 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static bool operator ==(Alpha8 left, Alpha8 right) => left.Equals(right); /// @@ -47,112 +47,60 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static bool operator !=(Alpha8 left, Alpha8 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(vector.W); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() => new Vector4(0, 0, 0, this.PackedValue / 255F); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = source.A; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.A; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) => dest = default; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest.Rgb = default; - dest.A = this.PackedValue; - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray8(Gray8 source) => this.PackedValue = byte.MaxValue; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = 0; - dest.G = 0; - dest.B = 0; - dest.A = this.PackedValue; - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) => dest = default; + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - dest.R = 0; - dest.G = 0; - dest.B = 0; - dest.A = this.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(0, 0, 0, this.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackedValue = byte.MaxValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest = default; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray8(Gray8 source) => this.PackedValue = byte.MaxValue; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest = default; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest = default; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) - { - dest.Rgb = default; - dest.A = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); - } - /// /// Compares an object with the packed vector. /// @@ -165,17 +113,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The Alpha8 packed vector to compare. /// True if the packed vectors are equal. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Alpha8 other) => this.PackedValue.Equals(other.PackedValue); /// /// Gets a string representation of the packed vector. /// /// A string representation of the packed vector. - public override string ToString() => (this.PackedValue / 255F).ToString(); + public override string ToString() => $"Alpha8({this.PackedValue})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); /// @@ -183,7 +131,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The float containing the value to pack. /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static byte Pack(float alpha) => (byte)Math.Round(alpha.Clamp(0, 1) * 255F); + [MethodImpl(InliningOptions.ShortMethod)] + private static byte Pack(float alpha) => (byte)Math.Round(alpha.Clamp(0, 1F) * 255F); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 0249bb6af..0da8516a3 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -58,7 +57,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(byte r, byte g, byte b) { this.R = r; @@ -74,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(byte r, byte g, byte b, byte a) { this.R = r; @@ -90,12 +89,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(float r, float g, float b, float a = 1) - : this() - { - this.Pack(r, g, b, a); - } + : this() => this.Pack(r, g, b, a); /// /// Initializes a new instance of the struct. @@ -103,12 +99,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(Vector3 vector) - : this() - { - this.Pack(ref vector); - } + : this() => this.Pack(ref vector); /// /// Initializes a new instance of the struct. @@ -116,12 +109,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(Vector4 vector) - : this() - { - this.Pack(ref vector); - } + : this() => this.Pack(ref vector); /// /// Initializes a new instance of the struct. @@ -129,22 +119,19 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The packed value. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Argb32(uint packed) - : this() - { - this.Argb = packed; - } + : this() => this.Argb = packed; /// /// Gets or sets the packed representation of the Argb32 struct. /// public uint Argb { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } @@ -158,20 +145,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Argb32 left, Argb32 right) - { - return left.Argb == right.Argb; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Argb32 left, Argb32 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -181,62 +161,34 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Argb32 left, Argb32 right) - { - return left.Argb != right.Argb; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.Pack(ref vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Argb32 left, Argb32 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.R = source.R; - this.G = source.G; - this.B = source.B; - this.A = source.A; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackedValue = source.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackedValue = source.PackedValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { this.R = source.R; @@ -245,164 +197,84 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest = this; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { - this.A = 255; this.R = source.PackedValue; this.G = source.PackedValue; this.B = source.PackedValue; + this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { - var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); - this.R = val; - this.G = val; - this.B = val; - this.A = 255; + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; + this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = source.A; + } - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A); - - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32 ToArgb32() => this; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); - this.A = (byte)(((source.A * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); + this.A = ImageMaths.DownScaleFrom16BitTo8Bit(source.A); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + public override bool Equals(object obj) => obj is Argb32 argb32 && this.Equals(argb32); /// - public override bool Equals(object obj) - { - return obj is Argb32 argb32 && this.Equals(argb32); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Argb32 other) - { - return this.Argb == other.Argb; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Argb32 other) => this.Argb == other.Argb; /// /// Gets a string representation of the packed vector. /// /// A string representation of the packed vector. - public override string ToString() - { - return $"({this.R},{this.G},{this.B},{this.A})"; - } + public override string ToString() => $"Argb({this.A}, {this.R}, {this.G}, {this.B})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.Argb.GetHashCode(); /// /// Gets the representation without normalizing to [0, 1] /// /// A of values in [0, 255] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Vector4 ToByteScaledVector4() - { - return new Vector4(this.R, this.G, this.B, this.A); - } + [MethodImpl(InliningOptions.ShortMethod)] + internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); /// /// Packs the four floats into a color. @@ -411,7 +283,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The y-component /// The z-component /// The w-component - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(float x, float y, float z, float w) { var value = new Vector4(x, y, z, w); @@ -422,7 +294,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs a into a uint. /// /// The vector containing the values to pack. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(ref Vector3 vector) { var value = new Vector4(vector, 1); @@ -433,7 +305,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs a into a color. /// /// The vector containing the values to pack. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(ref Vector4 vector) { vector *= MaxBytes; diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index e1bb8a0ce..063fed522 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Bgr24(byte r, byte g, byte b) { this.R = r; @@ -49,39 +49,54 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = b; } + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Bgr24 left, Bgr24 right) => left.Equals(right); + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Bgr24 left, Bgr24 right) => !left.Equals(right); + /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Bgr24 other) - { - return this.R == other.R && this.G == other.G && this.B == other.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - public override bool Equals(object obj) - { - return obj is Bgr24 other && this.Equals(other); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) { - int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + Rgba32 rgba = default; + rgba.PackFromVector4(vector); + this.PackFromRgba32(rgba); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this = source.Bgr; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { this.R = source.R; @@ -90,7 +105,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { this.R = source.R; @@ -99,81 +114,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - Rgba32 rgba = default; - rgba.PackFromVector4(vector); - this.PackFromRgba32(rgba); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Rgba32(this.R, this.G, this.B, 255).ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = byte.MaxValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = byte.MaxValue; - } - - /// - public void ToBgr24(ref Bgr24 dest) - { - dest = this; - } - - /// - public void ToBgra32(ref Bgra32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = byte.MaxValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { this.R = source.PackedValue; @@ -182,53 +123,57 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { - var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); - this.R = val; - this.G = val; - this.B = val; + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this = source.Bgr; + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, byte.MaxValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Bgr24 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B); + + /// + public override bool Equals(object obj) => obj is Bgr24 other && this.Equals(other); /// - public override string ToString() + public override string ToString() => $"Bgra({this.B}, {this.G}, {this.R})"; + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() { - return $"({this.B},{this.G},{this.R})"; + int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); + return HashHelpers.Combine(hash, this.B.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 53f15ecb3..5b19fb25c 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -8,7 +8,8 @@ using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.PixelFormats { /// - /// Packed pixel type containing unsigned normalized values ranging from 0 to 1. The x and z components use 5 bits, and the y component uses 6 bits. + /// Packed pixel type containing unsigned normalized values ranging from 0 to 1. + /// The x and z components use 5 bits, and the y component uses 6 bits. /// /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// @@ -22,8 +23,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// The y-component /// The z-component public Bgr565(float x, float y, float z) + : this(new Vector3(x, y, z)) { - this.PackedValue = Pack(x, y, z); } /// @@ -32,10 +33,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed value. /// - public Bgr565(Vector3 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z); - } + public Bgr565(Vector3 vector) => this.PackedValue = Pack(ref vector); /// public ushort PackedValue { get; set; } @@ -48,11 +46,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Bgr565 left, Bgr565 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Bgr565 left, Bgr565 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -62,199 +57,104 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Bgr565 left, Bgr565 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Bgr565 left, Bgr565 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); - /// - /// Expands the packed representation into a . - /// The vector components are typically expanded in least to greatest significance order. - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3 ToVector3() - { - return new Vector3( - ((this.PackedValue >> 11) & 0x1F) * (1F / 31F), - ((this.PackedValue >> 5) & 0x3F) * (1F / 63F), - (this.PackedValue & 0x1F) * (1F / 31F)); - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z); + var vector3 = new Vector3(vector.X, vector.Y, vector.Z); + this.PackedValue = Pack(ref vector3); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.ToVector3(), 1F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.ToVector3(), 1F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromVector4(source.ToVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - public override bool Equals(object obj) + /// + /// Expands the packed representation into a . + /// The vector components are typically expanded in least to greatest significance order. + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public Vector3 ToVector3() { - return obj is Bgr565 other && this.Equals(other); + return new Vector3( + ((this.PackedValue >> 11) & 0x1F) * (1F / 31F), + ((this.PackedValue >> 5) & 0x3F) * (1F / 63F), + (this.PackedValue & 0x1F) * (1F / 31F)); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Bgr565 other) - { - return this.PackedValue == other.PackedValue; - } + public override bool Equals(object obj) => obj is Bgr565 other && this.Equals(other); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Bgr565 other) => this.PackedValue.Equals(other.PackedValue); /// public override string ToString() { - return this.ToVector3().ToString(); + var vector = this.ToVector3(); + return $"Bgr565({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##})"; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort Pack(float x, float y, float z) + [MethodImpl(InliningOptions.ShortMethod)] + private static ushort Pack(ref Vector3 vector) { - return (ushort)((((int)Math.Round(x.Clamp(0, 1) * 31F) & 0x1F) << 11) - | (((int)Math.Round(y.Clamp(0, 1) * 63F) & 0x3F) << 5) - | ((int)Math.Round(z.Clamp(0, 1) * 31F) & 0x1F)); + vector = Vector3.Clamp(vector, Vector3.Zero, Vector3.One); + + return (ushort)((((int)Math.Round(vector.X * 31F) & 0x1F) << 11) + | (((int)Math.Round(vector.Y * 63F) & 0x3F) << 5) + | ((int)Math.Round(vector.Z * 31F) & 0x1F)); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index c6fa4cf67..6fd086779 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Bgra32(byte r, byte g, byte b) { this.R = r; @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Bgra32(byte r, byte g, byte b, byte a) { this.R = r; @@ -84,10 +84,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public uint Bgra { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } @@ -98,71 +98,49 @@ namespace SixLabors.ImageSharp.PixelFormats set => this.Bgra = value; } - /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); - - /// - public bool Equals(Bgra32 other) - { - return this.Bgra == other.Bgra; - } - - /// - public override bool Equals(object obj) => obj is Bgra32 other && this.Equals(other); - - /// - public override int GetHashCode() => this.Bgra.GetHashCode(); + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Bgra32 left, Bgra32 right) => left.Equals(right); /// - /// Gets the representation without normalizing to [0, 1] + /// Compares two objects for equality. /// - /// A of values in [0, 255] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Vector4 ToByteScaledVector4() - { - return new Vector4(this.R, this.G, this.B, this.A); - } + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Bgra32 left, Bgra32 right) => !left.Equals(right); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.Pack(ref vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.R = source.R; - this.G = source.G; - this.B = source.B; - this.A = source.A; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { this.R = source.R; @@ -172,132 +150,88 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackedValue = source.PackedValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.PackedValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) => dest = Unsafe.As(ref this); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) => dest = this; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { this.R = source.PackedValue; - this.R = source.PackedValue; - this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { - var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); - this.R = val; - this.G = val; - this.B = val; + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = source.A; + } - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A); - - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Bgra32 ToBgra32() => this; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); - this.A = (byte)(((source.A * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); + this.A = ImageMaths.DownScaleFrom16BitTo8Bit(source.A); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + public override bool Equals(object obj) => obj is Bgra32 other && this.Equals(other); + + /// + public bool Equals(Bgra32 other) => this.Bgra.Equals(other.Bgra); + + /// + public override int GetHashCode() => this.Bgra.GetHashCode(); + + /// + public override string ToString() => $"Bgra32({this.B}, {this.G}, {this.R}, {this.A})"; + + /// + /// Gets the representation without normalizing to [0, 1] + /// + /// A of values in [0, 255] + [MethodImpl(InliningOptions.ShortMethod)] + internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); /// /// Packs a into a color. /// /// The vector containing the values to pack. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(ref Vector4 vector) { vector *= MaxBytes; @@ -309,11 +243,5 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = (byte)vector.Z; this.A = (byte)vector.W; } - - /// - public override string ToString() - { - return $"({this.B},{this.G},{this.R},{this.A})"; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index f684bec33..8a5e3f76b 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -23,18 +23,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component /// The w-component public Bgra4444(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } /// /// Initializes a new instance of the struct. /// /// The vector containing the components for the packed vector. - public Bgra4444(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + public Bgra4444(Vector4 vector) => this.PackedValue = Pack(ref vector); /// public ushort PackedValue { get; set; } @@ -47,11 +44,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Bgra4444 left, Bgra4444 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Bgra4444 left, Bgra4444 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -61,193 +55,95 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Bgra4444 left, Bgra4444 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Bgra4444 left, Bgra4444 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { const float Max = 1 / 15F; return new Vector4( - ((this.PackedValue >> 8) & 0x0F) * Max, - ((this.PackedValue >> 4) & 0x0F) * Max, - (this.PackedValue & 0x0F) * Max, - ((this.PackedValue >> 12) & 0x0F) * Max); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; + (this.PackedValue >> 8) & 0x0F, + (this.PackedValue >> 4) & 0x0F, + this.PackedValue & 0x0F, + (this.PackedValue >> 12) & 0x0F) * Max; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is Bgra4444 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Bgra4444 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Bgra4444 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Bgra4444 other) => this.PackedValue.Equals(other.PackedValue); /// public override string ToString() { - return this.ToVector4().ToString(); + var vector = this.ToVector4(); + return $"Bgra4444({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static ushort Pack(ref Vector4 vector) { - return (ushort)((((int)Math.Round(w.Clamp(0, 1) * 15F) & 0x0F) << 12) | - (((int)Math.Round(x.Clamp(0, 1) * 15F) & 0x0F) << 8) | - (((int)Math.Round(y.Clamp(0, 1) * 15F) & 0x0F) << 4) | - ((int)Math.Round(z.Clamp(0, 1) * 15F) & 0x0F)); + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One); + return (ushort)((((int)Math.Round(vector.W * 15F) & 0x0F) << 12) + | (((int)Math.Round(vector.X * 15F) & 0x0F) << 8) + | (((int)Math.Round(vector.Y * 15F) & 0x0F) << 4) + | ((int)Math.Round(vector.Z * 15F) & 0x0F)); } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 1044a0feb..25f289b84 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -8,7 +8,8 @@ using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.PixelFormats { /// - /// Packed pixel type containing unsigned normalized values ranging from 0 to 1. The x , y and z components use 5 bits, and the w component uses 1 bit. + /// Packed pixel type containing unsigned normalized values ranging from 0 to 1. + /// The x , y and z components use 5 bits, and the w component uses 1 bit. /// /// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form. /// @@ -23,8 +24,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component /// The w-component public Bgra5551(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } /// @@ -33,10 +34,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - public Bgra5551(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + public Bgra5551(Vector4 vector) => this.PackedValue = Pack(ref vector); /// public ushort PackedValue { get; set; } @@ -49,11 +47,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Bgra5551 left, Bgra5551 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Bgra5551 left, Bgra5551 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -63,31 +58,26 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Bgra5551 left, Bgra5551 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Bgra5551 left, Bgra5551 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { return new Vector4( @@ -98,166 +88,67 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is Bgra5551 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Bgra5551 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Bgra5551 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Bgra5551 other) => this.PackedValue.Equals(other.PackedValue); - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. + /// public override string ToString() { - return this.ToVector4().ToString(); + var vector = this.ToVector4(); + return $"Bgra5551({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"; } - /// - /// Gets a hash code of the packed vector. - /// - /// The hash code for the packed vector. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static ushort Pack(ref Vector4 vector) { + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One); return (ushort)( - (((int)Math.Round(x.Clamp(0, 1) * 31F) & 0x1F) << 10) - | (((int)Math.Round(y.Clamp(0, 1) * 31F) & 0x1F) << 5) - | (((int)Math.Round(z.Clamp(0, 1) * 31F) & 0x1F) << 0) - | (((int)Math.Round(w.Clamp(0, 1)) & 0x1) << 15)); + (((int)Math.Round(vector.X * 31F) & 0x1F) << 10) + | (((int)Math.Round(vector.Y * 31F) & 0x1F) << 5) + | (((int)Math.Round(vector.Z * 31F) & 0x1F) << 0) + | (((int)Math.Round(vector.W) & 0x1) << 15)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() => this.ToVector4() * 255f; + [MethodImpl(InliningOptions.ShortMethod)] + private Vector4 ToByteScaledVector4() => this.ToVector4() * 255F; } -} +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index aea3aec65..fbdf4862d 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -21,10 +21,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// A vector containing the initial values for the components of the Byte4 structure. /// - public Byte4(Vector4 vector) - { - this.PackedValue = Pack(ref vector); - } + public Byte4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// /// Initializes a new instance of the struct. @@ -50,11 +47,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Byte4 left, Byte4 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Byte4 left, Byte4 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -64,38 +58,26 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Byte4 left, Byte4 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Byte4 left, Byte4 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector * 255F); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector * 255F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4() / 255F; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4() / 255F; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(ref vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { return new Vector4( @@ -106,135 +88,53 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToByteScaledVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToByteScaledVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToByteScaledVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - var vector = this.ToVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - var vector = this.ToVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - var vector = this.ToVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToByteScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - var vector = this.ToVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - var vector = this.ToVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToByteScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is Byte4 byte4 && this.Equals(byte4); - } + public override bool Equals(object obj) => obj is Byte4 byte4 && this.Equals(byte4); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Byte4 other) - { - return this == other; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Byte4 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Returns a string representation of the current instance. - /// - /// String that represents the object. + /// public override string ToString() { - return this.PackedValue.ToString("x8"); + var vector = this.ToVector4(); + return $"Bgra5551({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; } /// @@ -242,18 +142,18 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the values to pack. /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static uint Pack(ref Vector4 vector) { const float Max = 255F; - const float Min = 0F; // Clamp the value between min and max values - // TODO: Use Vector4.Clamp() here! - uint byte4 = (uint)Math.Round(vector.X.Clamp(Min, Max)) & 0xFF; - uint byte3 = ((uint)Math.Round(vector.Y.Clamp(Min, Max)) & 0xFF) << 0x8; - uint byte2 = ((uint)Math.Round(vector.Z.Clamp(Min, Max)) & 0xFF) << 0x10; - uint byte1 = ((uint)Math.Round(vector.W.Clamp(Min, Max)) & 0xFF) << 0x18; + vector = Vector4.Clamp(vector, Vector4.Zero, new Vector4(Max)); + + uint byte4 = (uint)Math.Round(vector.X) & 0xFF; + uint byte3 = ((uint)Math.Round(vector.Y) & 0xFF) << 0x8; + uint byte2 = ((uint)Math.Round(vector.Z) & 0xFF) << 0x10; + uint byte1 = ((uint)Math.Round(vector.W) & 0xFF) << 0x18; return byte4 | byte3 | byte2 | byte1; } diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 50398eeb2..852ff73e0 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -1,13 +1,4 @@ - - - - - - - - - -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. // @@ -55,10 +46,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -74,7 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToRgba64(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -127,10 +116,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -146,7 +133,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToRgb48(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -199,10 +186,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -218,7 +203,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToRgba32(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -271,10 +256,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -290,7 +273,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToBgra32(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -343,10 +326,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -362,7 +343,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToRgb24(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -415,10 +396,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -434,7 +413,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToBgr24(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -487,10 +466,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -506,7 +483,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToArgb32(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -559,10 +536,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -578,7 +553,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); - sp.ToGray8(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -594,5 +569,75 @@ namespace SixLabors.ImageSharp.PixelFormats { this.ToGray8(sourceColors, MemoryMarshal.Cast(destBytes), count); } + + /// + /// Converts 'count' elements in 'source` span of data to a span of -s. + /// + /// The source of data. + /// The to the destination pixels. + /// The number of pixels to convert. + internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! + var temp = NamedColors.Black; + + for (int i = 0; i < count; i++) + { + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + temp = Unsafe.Add(ref sourceRef, i); + dp.PackFromGray16(temp); + } + } + + /// + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// + /// The to the source bytes. + /// The to the destination pixels. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + { + this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); + } + /// + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// + /// The span of source pixels + /// The destination span of data. + /// The number of pixels to convert. + internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span dest, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); + } + } + + /// + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void ToGray16Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + { + this.ToGray16(sourceColors, MemoryMarshal.Cast(destBytes), count); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index b4b577e3a..9fbe57ed9 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -14,6 +14,7 @@ void GeneratePackFromMethods(string pixelType, string tempPixelType, string assignToTempCode) { #> + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// @@ -58,7 +59,6 @@ #> /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. - /// Bulk version of . /// /// The span of source pixels /// The destination span of data. @@ -74,7 +74,7 @@ { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i); - sp.To<#=pixelType#>(ref dp); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -130,5 +130,9 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethods("Gray8", "Gray8", "temp = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Gray8"); + + GeneratePackFromMethods("Gray16", "Gray16", "temp = Unsafe.Add(ref sourceRef, i);"); + GenerateToDestFormatMethods("Gray16"); + #> } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index e68efba25..962150595 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - Unsafe.As(ref dp) = sp; dp.A = 255; + Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue; } } @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.Bgr = sp; dp.A = 255; + dp.Bgr = sp; dp.A = byte.MaxValue; } } @@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToRgba32(); + dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; } } @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToBgra32(); + dp.PackFromRgba32(sp); } } @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToRgba32(); + dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; } } @@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToArgb32(); + dp.PackFromRgba32(sp); } } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt index a73433339..9d9145f0b 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt @@ -71,17 +71,17 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations { <# - GeneratePackFromMethod("Rgb24", "Unsafe.As(ref dp) = sp; dp.A = 255;"); + GeneratePackFromMethod("Rgb24", "Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue;"); GenerateConvertToMethod("Rgb24", "dp = Unsafe.As(ref sp);"); - GeneratePackFromMethod("Bgr24", "dp.Bgr = sp; dp.A = 255;"); + GeneratePackFromMethod("Bgr24", "dp.Bgr = sp; dp.A = byte.MaxValue;"); GenerateConvertToMethod("Bgr24", "dp = sp.Bgr;"); - GeneratePackFromMethod("Bgra32", "dp = sp.ToRgba32();"); - GenerateConvertToMethod("Bgra32", "dp = sp.ToBgra32();"); + GeneratePackFromMethod("Bgra32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); + GenerateConvertToMethod("Bgra32", "dp.PackFromRgba32(sp);"); - GeneratePackFromMethod("Argb32", "dp = sp.ToRgba32();"); - GenerateConvertToMethod("Argb32", "dp = sp.ToArgb32();"); + GeneratePackFromMethod("Argb32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); + GenerateConvertToMethod("Argb32", "dp.PackFromRgba32(sp);"); #> } diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index 06da2867a..f9aada937 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -15,29 +15,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Gray16 : IPixel, IPackedVector { - /// - /// RX as in ITU-R recommendation 709 to match libpng - /// - private const float Rx = .2126F; - - /// - /// GX as in ITU-R recommendation 709 to match libpng - /// - private const float Gx = .7152F; - - /// - /// BX as in ITU-R recommendation 709 to match libpng - /// - private const float Bx = .0722F; + private const float Max = ushort.MaxValue; /// /// Initializes a new instance of the struct. /// - /// The gray component - public Gray16(ushort gray) - { - this.PackedValue = gray; - } + /// The luminance component + public Gray16(ushort luminance) => this.PackedValue = luminance; /// public ushort PackedValue { get; set; } @@ -45,20 +29,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Gray16 left, Gray16 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Gray16 left, Gray16 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -68,230 +45,105 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Gray16 left, Gray16 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Gray16 left, Gray16 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - var scaledGray = this.PackedValue / 65535f; // ushort.Max as float - return new Vector4(scaledGray, scaledGray, scaledGray, 1.0f); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z); + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + (ushort)MathF.Round(vector.X), + (ushort)MathF.Round(vector.Y), + (ushort)MathF.Round(vector.Z)); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { - return new Vector4(this.PackedValue, this.PackedValue, this.PackedValue, 1.0f); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackedValue = Pack(source.R, source.G, source.B); + float scaled = this.PackedValue / Max; + return new Vector4(scaled, scaled, scaled, 1F); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { - this.PackedValue = Pack(source.R, source.G, source.B); + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { - this.PackedValue = Pack(source.R, source.G, source.B); + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - var scaledValue = this.PackedAsByte(); - - dest.R = scaledValue; - dest.G = scaledValue; - dest.B = scaledValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray8(Gray8 source) => this.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - var scaledValue = this.PackedAsByte(); - - dest.R = scaledValue; - dest.G = scaledValue; - dest.B = scaledValue; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray16(Gray16 source) => this.PackedValue = source.PackedValue; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) { - var scaledValue = this.PackedAsByte(); - - dest.R = scaledValue; - dest.G = scaledValue; - dest.B = scaledValue; - dest.A = 255; + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() { - var scaledValue = this.PackedAsByte(); - - dest.R = scaledValue; - dest.G = scaledValue; - dest.B = scaledValue; + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(this.PackedValue); + return new Rgba32(rgb, rgb, rgb, byte.MaxValue); } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - var scaledValue = this.PackedAsByte(); - - dest.R = scaledValue; - dest.G = scaledValue; - dest.B = scaledValue; - dest.A = 255; - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray8(Gray8 source) - { - this.PackedValue = (ushort)(source.PackedValue * 255); - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba64(Rgba64 source) => ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) - { - dest.PackedValue = (byte)(((this.PackedValue * 255) + 32895) >> 16); - } + public override bool Equals(object obj) => obj is Gray16 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) - { - this.PackedValue = source.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Gray16 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) - { - dest.PackedValue = this.PackedValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => - this.PackedValue = Pack(source.R, source.G, source.B); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba64(Rgba64 source) => - this.PackFromScaledVector4(source.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - /// Compares an object with the packed vector. - /// - /// The object to compare. - /// True if the object is equal to the packed vector. - public override bool Equals(object obj) - { - return obj is Gray16 other && this.Equals(other); - } - - /// - /// Compares another packed vector with the packed vector. - /// - /// The Gray8 packed vector to compare. - /// True if the packed vectors are equal. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Gray16 other) - { - return this.PackedValue == other.PackedValue; - } - - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. - public override string ToString() - { - return (this.PackedValue / 65535f).ToString(); - } + public override string ToString() => $"Gray16({this.PackedValue})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - - /// - /// Packs a into a byte. - /// - /// Red value of the color to pack. - /// Green value of the color to pack. - /// Blue value of the color to pack. - /// The containing the packed value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort Pack(float r, float g, float b) - { - float val = (r * Rx) + (g * Gx) + (b * Bx); - return (ushort)Math.Round(val * 65535f); - } - - /// - /// Packs the into a byte. - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private byte PackedAsByte() - { - return (byte)(this.PackedValue >> 8); - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index 0a41a6ecc..b1fa2b1e1 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -14,21 +14,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Gray8 : IPixel, IPackedVector { - /// - /// RX as in ITU-R recommendation 709 to match libpng - /// - private const float Rx = .2126F; - - /// - /// GX as in ITU-R recommendation 709 to match libpng - /// - private const float Gx = .7152F; - - /// - /// BX as in ITU-R recommendation 709 to match libpng - /// - private const float Bx = .0722F; - /// /// The maximum byte value. /// @@ -42,8 +27,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Initializes a new instance of the struct. /// - /// The gray component - public Gray8(byte gray) => this.PackedValue = gray; + /// The luminance component. + public Gray8(byte luminance) => this.PackedValue = luminance; /// public byte PackedValue { get; set; } @@ -57,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// True if the parameter is equal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] - public static bool operator ==(Gray8 left, Gray8 right) => left.PackedValue.Equals(right.PackedValue); + public static bool operator ==(Gray8 left, Gray8 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -68,7 +53,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// True if the parameter is not equal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] - public static bool operator !=(Gray8 left, Gray8 right) => !left.PackedValue.Equals(right.PackedValue); + public static bool operator !=(Gray8 left, Gray8 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); @@ -88,9 +73,8 @@ namespace SixLabors.ImageSharp.PixelFormats vector *= MaxBytes; vector += Half; vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - float luminance = (vector.X * Rx) + (vector.Y * Gx) + (vector.Z * Bx); - this.PackedValue = (byte)luminance; + this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z); } /// @@ -101,138 +85,54 @@ namespace SixLabors.ImageSharp.PixelFormats return new Vector4(rgb, rgb, rgb, 1F); } - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); - /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); + public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.GetBT709LuminanceBytes(source.R, source.G, source.B); - - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - } + public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); - /// + /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - dest.A = byte.MaxValue; - } + public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; - /// + /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - dest.A = byte.MaxValue; - } + public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToBgr24(ref Bgr24 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - } + public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToBgra32(ref Bgra32 dest) - { - dest.R = this.PackedValue; - dest.G = this.PackedValue; - dest.B = this.PackedValue; - dest.A = byte.MaxValue; - } + public Rgba32 ToRgba32() => new Rgba32(this.PackedValue, this.PackedValue, this.PackedValue, byte.MaxValue); /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) - => this.PackedValue = ImageMaths.GetBT709LuminanceBytes( + => this.PackedValue = ImageMaths.Get8BitBT709Luminance( ImageMaths.DownScaleFrom16BitTo8Bit(source.R), ImageMaths.DownScaleFrom16BitTo8Bit(source.G), ImageMaths.DownScaleFrom16BitTo8Bit(source.B)); - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgb48(ref Rgb48 dest) - { - ushort luminance = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); - dest.R = luminance; - dest.G = luminance; - dest.B = luminance; - } - /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) - => this.PackedValue = ImageMaths.GetBT709LuminanceBytes( + => this.PackedValue = ImageMaths.Get8BitBT709Luminance( ImageMaths.DownScaleFrom16BitTo8Bit(source.R), ImageMaths.DownScaleFrom16BitTo8Bit(source.G), ImageMaths.DownScaleFrom16BitTo8Bit(source.B)); - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; - - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); - - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba64(ref Rgba64 dest) - { - ushort luminance = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); - dest.R = luminance; - dest.G = luminance; - dest.B = luminance; - dest.A = ushort.MaxValue; - } - - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void ToGray8(ref Gray8 dest) => dest.PackedValue = this.PackedValue; - - /// - [MethodImpl(InliningOptions.ShortMethod)] - public void ToGray16(ref Gray16 dest) => dest.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(this.PackedValue); - - /// - /// Compares an object with the packed vector. - /// - /// The object to compare. - /// True if the object is equal to the packed vector. + /// public override bool Equals(object obj) => obj is Gray8 other && this.Equals(other); - /// - /// Compares another packed vector with the packed vector. - /// - /// The Gray8 packed vector to compare. - /// True if the packed vectors are equal. + /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Gray8 other) => this.PackedValue.Equals(other.PackedValue); - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. + /// public override string ToString() => $"Gray8({this.PackedValue}"; /// diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index b392910a6..8048a3825 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -28,10 +28,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Initializes a new instance of the struct. /// /// The single component. - public HalfSingle(float single) - { - this.PackedValue = HalfTypeHelper.Pack(single); - } + public HalfSingle(float single) => this.PackedValue = HalfTypeHelper.Pack(single); /// public ushort PackedValue { get; set; } @@ -39,222 +36,115 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(HalfSingle left, HalfSingle right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(HalfSingle left, HalfSingle right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(HalfSingle left, HalfSingle right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(HalfSingle left, HalfSingle right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); - /// - /// Expands the packed representation into a . - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float ToSingle() - { - return HalfTypeHelper.Unpack(this.PackedValue); - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { float scaled = vector.X; scaled *= 2F; - scaled -= 1F; + scaled--; this.PackedValue = HalfTypeHelper.Pack(scaled); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { float single = this.ToSingle() + 1F; single /= 2F; - return new Vector4(single, 0, 0, 1); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = HalfTypeHelper.Pack(vector.X); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.ToSingle(), 0, 0, 1); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; + return new Vector4(single, 0, 0, 1F); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = HalfTypeHelper.Pack(vector.X); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.ToSingle(), 0, 0, 1F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + /// Expands the packed representation into a . + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public float ToSingle() => HalfTypeHelper.Unpack(this.PackedValue); /// - public override bool Equals(object obj) - { - return obj is HalfSingle other && this.Equals(other); - } + public override bool Equals(object obj) => obj is HalfSingle other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(HalfSingle other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(HalfSingle other) => this.PackedValue.Equals(other.PackedValue); /// - public override string ToString() - { - return this.ToSingle().ToString(); - } + public override string ToString() => $"HalfSingle({this.ToSingle():#0.##})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private Vector4 ToByteScaledVector4() { var vector = this.ToVector4(); vector *= MaxBytes; vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; + return Vector4.Clamp(vector, Vector4.Zero, MaxBytes); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfTypeHelper.cs b/src/ImageSharp/PixelFormats/HalfTypeHelper.cs index cf8b9f4a2..e8cfaa462 100644 --- a/src/ImageSharp/PixelFormats/HalfTypeHelper.cs +++ b/src/ImageSharp/PixelFormats/HalfTypeHelper.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Helper methods for packing and unpacking floating point values /// - internal class HalfTypeHelper + internal static class HalfTypeHelper { /// /// Packs a into an @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.PixelFormats return (ushort)s; } - m = m | 0x00800000; + m |= 0x00800000; int t = 14 - e; int a = (1 << (t - 1)) - 1; @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.PixelFormats if ((m & 0x00800000) != 0) { m = 0; - e += 1; + e++; } if (e > 30) @@ -97,11 +97,11 @@ namespace SixLabors.ImageSharp.PixelFormats while ((mantissa & 1024) == 0) { exponent--; - mantissa = mantissa << 1; + mantissa <<= 1; } mantissa &= 0xfffffbff; - result = ((uint)((((uint)value & 0x8000) << 16) | ((exponent + 127) << 23))) | (mantissa << 13); + result = (((uint)value & 0x8000) << 16) | ((exponent + 127) << 23) | (mantissa << 13); } else { @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.PixelFormats } else { - result = ((((uint)value & 0x8000) << 16) | ((((((uint)value >> 10) & 0x1f) - 15) + 127) << 23)) | (mantissa << 13); + result = (((uint)value & 0x8000) << 16) | ((((((uint)value >> 10) & 0x1f) - 15) + 127) << 23) | (mantissa << 13); } var uif = new Uif { U = result }; diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index ac70f4fbc..f398f508b 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -15,34 +14,18 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct HalfVector2 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half vector value. - /// - private static readonly Vector4 Half = new Vector4(0.5F); - /// /// Initializes a new instance of the struct. /// /// The x-component. /// The y-component. - public HalfVector2(float x, float y) - { - this.PackedValue = Pack(x, y); - } + public HalfVector2(float x, float y) => this.PackedValue = Pack(x, y); /// /// Initializes a new instance of the struct. /// /// A vector containing the initial values for the components. - public HalfVector2(Vector2 vector) - { - this.PackedValue = Pack(vector.X, vector.Y); - } + public HalfVector2(Vector2 vector) => this.PackedValue = Pack(vector.X, vector.Y); /// public uint PackedValue { get; set; } @@ -50,57 +33,30 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(HalfVector2 left, HalfVector2 right) - { - return left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(HalfVector2 left, HalfVector2 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(HalfVector2 left, HalfVector2 right) - { - return !left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(HalfVector2 left, HalfVector2 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); - /// - /// Expands the packed representation into a . - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 ToVector2() - { - Vector2 vector; - vector.X = HalfTypeHelper.Unpack((ushort)this.PackedValue); - vector.Y = HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x10)); - return vector; - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; @@ -109,7 +65,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector2(); @@ -119,14 +75,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(vector.X, vector.Y); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { var vector = this.ToVector2(); @@ -134,156 +87,74 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - public override string ToString() + /// + /// Expands the packed representation into a . + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public Vector2 ToVector2() { - return this.ToVector2().ToString(); + Vector2 vector; + vector.X = HalfTypeHelper.Unpack((ushort)this.PackedValue); + vector.Y = HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x10)); + return vector; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => this.PackedValue.GetHashCode(); + public override bool Equals(object obj) => obj is HalfVector2 other && this.Equals(other); /// - public override bool Equals(object obj) - { - return obj is HalfVector2 other && this.Equals(other); - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(HalfVector2 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(HalfVector2 other) + public override string ToString() { - return this.PackedValue.Equals(other.PackedValue); + var vector = this.ToVector2(); + return $"HalfVector2({vector.X:#0.##}, {vector.Y:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); + + [MethodImpl(InliningOptions.ShortMethod)] private static uint Pack(float x, float y) { uint num2 = HalfTypeHelper.Pack(x); uint num = (uint)(HalfTypeHelper.Pack(y) << 0x10); return num2 | num; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= MaxBytes; - vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 9bdae99ab..45d93efc0 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -15,16 +14,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct HalfVector4 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half vector value. - /// - private static readonly Vector4 Half = new Vector4(0.5F); - /// /// Initializes a new instance of the struct. /// @@ -33,64 +22,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component. /// The w-component. public HalfVector4(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - var vector = new Vector4(x, y, z, w); - this.PackedValue = Pack(ref vector); } /// /// Initializes a new instance of the struct. /// /// A vector containing the initial values for the components - public HalfVector4(Vector4 vector) - { - this.PackedValue = Pack(ref vector); - } + public HalfVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// public ulong PackedValue { get; set; } /// - /// Compares two objects for equality. + /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(HalfVector4 left, HalfVector4 right) - { - return left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(HalfVector4 left, HalfVector4 right) => left.Equals(right); /// - /// Compares two objects for equality. + /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(HalfVector4 left, HalfVector4 right) - { - return !left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(HalfVector4 left, HalfVector4 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { vector *= 2F; @@ -99,7 +70,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector4(); @@ -109,14 +80,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(ref vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { return new Vector4( @@ -127,140 +95,61 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override string ToString() - { - return this.ToVector4().ToString(); - } + public override bool Equals(object obj) => obj is HalfVector4 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => this.PackedValue.GetHashCode(); + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(HalfVector4 other) => this.PackedValue.Equals(other.PackedValue); /// - public override bool Equals(object obj) + public override string ToString() { - return obj is HalfVector4 other && this.Equals(other); + var vector = this.ToVector4(); + return $"HalfVector4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(HalfVector4 other) - { - return this.PackedValue.Equals(other.PackedValue); - } + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); /// /// Packs a into a . /// /// The vector containing the values to pack. /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static ulong Pack(ref Vector4 vector) { ulong num4 = HalfTypeHelper.Pack(vector.X); @@ -269,15 +158,5 @@ namespace SixLabors.ImageSharp.PixelFormats ulong num1 = (ulong)HalfTypeHelper.Pack(vector.W) << 0x30; return num4 | num3 | num2 | num1; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= MaxBytes; - vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 382c8541d..a3017501c 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -28,12 +28,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public interface IPixel { - /// - /// Sets the packed representation from a . - /// - /// The vector to create the packed representation from. - void PackFromVector4(Vector4 vector); - /// /// Sets the packed representation from a scaled . /// @@ -48,6 +42,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . Vector4 ToScaledVector4(); + /// + /// Sets the packed representation from a . + /// + /// The vector to create the packed representation from. + void PackFromVector4(Vector4 vector); + /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. @@ -55,24 +55,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . Vector4 ToVector4(); - /// - /// Packs the pixel from an value. - /// - /// The value. - void PackFromRgba32(Rgba32 source); - - /// - /// Packs the pixel from an value. - /// - /// The value. - void PackFromRgb48(Rgb48 source); - - /// - /// Packs the pixel from an value. - /// - /// The value. - void PackFromRgba64(Rgba64 source); - /// /// Packs the pixel from an value. /// @@ -86,69 +68,39 @@ namespace SixLabors.ImageSharp.PixelFormats void PackFromBgra32(Bgra32 source); /// - /// Converts the pixel to format. - /// - /// The destination pixel to write to - void ToRgb24(ref Rgb24 dest); - - /// - /// Converts the pixel to format. - /// - /// The destination pixel to write to - void ToRgba32(ref Rgba32 dest); - - /// - /// Converts the pixel to format. - /// - /// The destination pixel to write to - void ToRgb48(ref Rgb48 dest); - - /// - /// Converts the pixel to format. - /// - /// The destination pixel to write to - void ToRgba64(ref Rgba64 dest); - - /// - /// Converts the pixel to format. - /// - /// The destination pixel to write to - void ToArgb32(ref Argb32 dest); - - /// - /// Converts the pixel to format. + /// Packs the Pixel from an value. /// - /// The destination pixel to write to - void ToBgr24(ref Bgr24 dest); + /// The value. + void PackFromGray8(Gray8 source); /// - /// Converts the pixel to format. + /// Packs the Pixel from an value. /// - /// The destination pixel to write to - void ToBgra32(ref Bgra32 dest); + /// The value. + void PackFromGray16(Gray16 source); /// - /// Packs the Pixel from an value. + /// Packs the pixel from an value. /// - /// The value. - void PackFromGray8(Gray8 source); + /// The value. + void PackFromRgba32(Rgba32 source); /// - /// Converts the pixel to format. + /// Expands the packed representation into an . /// - /// The destination pixel to write to. - void ToGray8(ref Gray8 dest); + /// The . + Rgba32 ToRgba32(); /// - /// Packs the Pixel from an value. + /// Packs the pixel from an value. /// - /// The value. - void PackFromGray16(Gray16 source); + /// The value. + void PackFromRgb48(Rgb48 source); /// - /// Converts the pixel tgo value. + /// Packs the pixel from an value. /// - /// The destination pixel to write to. - void ToGray16(ref Gray16 dest); + /// The value. + void PackFromRgba64(Rgba64 source); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index cd9fa65fb..86b528090 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -15,39 +15,24 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct NormalizedByte2 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half the maximum byte value. - /// - private static readonly Vector4 Half = new Vector4(127); - - /// - /// The vector value used for rounding. - /// - private static readonly Vector4 Round = new Vector4(.5F); + private static readonly Vector2 Half = new Vector2(127); + private static readonly Vector2 MinusOne = new Vector2(-1F); /// /// Initializes a new instance of the struct. /// - /// The vector containing the component values. - public NormalizedByte2(Vector2 vector) + /// The x-component. + /// The y-component. + public NormalizedByte2(float x, float y) + : this(new Vector2(x, y)) { - this.PackedValue = Pack(vector.X, vector.Y); } /// /// Initializes a new instance of the struct. /// - /// The x-component. - /// The y-component. - public NormalizedByte2(float x, float y) - { - this.PackedValue = Pack(x, y); - } + /// The vector containing the component values. + public NormalizedByte2(Vector2 vector) => this.PackedValue = Pack(vector); /// public ushort PackedValue { get; set; } @@ -55,66 +40,39 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(NormalizedByte2 left, NormalizedByte2 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(NormalizedByte2 left, NormalizedByte2 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(NormalizedByte2 left, NormalizedByte2 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(NormalizedByte2 left, NormalizedByte2 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); - /// - /// Expands the packed representation into a . - /// The vector components are typically expanded in least to greatest significance order. - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 ToVector2() - { - return new Vector2( - (sbyte)((this.PackedValue >> 0) & 0xFF) / 127F, - (sbyte)((this.PackedValue >> 8) & 0xFF) / 127F); - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; scaled -= Vector2.One; - this.PackedValue = Pack(scaled.X, scaled.Y); + this.PackedValue = Pack(scaled); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector2(); @@ -124,188 +82,89 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.ToVector2(), 0F, 1F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); + var vector2 = new Vector2(vector.X, vector.Y); + this.PackedValue = Pack(vector2); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.ToVector2(), 0F, 1F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = 0; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - public override bool Equals(object obj) + /// + /// Expands the packed representation into a . + /// The vector components are typically expanded in least to greatest significance order. + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public Vector2 ToVector2() { - return obj is NormalizedByte2 other && this.Equals(other); + return new Vector2( + (sbyte)((this.PackedValue >> 0) & 0xFF) / 127F, + (sbyte)((this.PackedValue >> 8) & 0xFF) / 127F); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(NormalizedByte2 other) - { - return this.PackedValue == other.PackedValue; - } + public override bool Equals(object obj) => obj is NormalizedByte2 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(NormalizedByte2 other) => this.PackedValue.Equals(other.PackedValue); + + /// + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); /// public override string ToString() { - return this.PackedValue.ToString("X"); + var vector = this.ToVector2(); + return $"NormalizedByte2({vector.X:#0.##}, {vector.Y:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort Pack(float x, float y) + [MethodImpl(InliningOptions.ShortMethod)] + private static ushort Pack(Vector2 vector) { - int byte2 = ((ushort)Math.Round(x.Clamp(-1F, 1F) * 127F) & 0xFF) << 0; - int byte1 = ((ushort)Math.Round(y.Clamp(-1F, 1F) * 127F) & 0xFF) << 8; + vector = Vector2.Clamp(vector, MinusOne, Vector2.One) * Half; - return (ushort)(byte2 | byte1); - } + int byte2 = ((ushort)Math.Round(vector.X) & 0xFF) << 0; + int byte1 = ((ushort)Math.Round(vector.Y) & 0xFF) << 8; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= Half; - vector += Round; - vector += Half; - vector += Round; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; + return (ushort)(byte2 | byte1); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index 9b53adecc..b538e4a44 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -15,29 +15,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct NormalizedByte4 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half the maximum byte value. - /// private static readonly Vector4 Half = new Vector4(127); - - /// - /// The vector value used for rounding. - /// - private static readonly Vector4 Round = new Vector4(.5F); - - /// - /// Initializes a new instance of the struct. - /// - /// The vector containing the component values. - public NormalizedByte4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + private static readonly Vector4 MinusOne = new Vector4(-1F); /// /// Initializes a new instance of the struct. @@ -47,54 +26,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component. /// The w-component. public NormalizedByte4(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } + /// + /// Initializes a new instance of the struct. + /// + /// The vector containing the component values. + public NormalizedByte4(Vector4 vector) => this.PackedValue = Pack(ref vector); + /// public uint PackedValue { get; set; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(NormalizedByte4 left, NormalizedByte4 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(NormalizedByte4 left, NormalizedByte4 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(NormalizedByte4 left, NormalizedByte4 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(NormalizedByte4 left, NormalizedByte4 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { vector *= 2F; @@ -103,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector4(); @@ -113,14 +84,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { return new Vector4( @@ -131,178 +99,66 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is NormalizedByte4 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is NormalizedByte4 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(NormalizedByte4 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(NormalizedByte4 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); /// public override string ToString() { - return this.PackedValue.ToString("X"); + var vector = this.ToVector4(); + return $"NormalizedByte4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static uint Pack(ref Vector4 vector) { - uint byte4 = ((uint)Math.Round(x.Clamp(-1F, 1F) * 127F) & 0xFF) << 0; - uint byte3 = ((uint)Math.Round(y.Clamp(-1F, 1F) * 127F) & 0xFF) << 8; - uint byte2 = ((uint)Math.Round(z.Clamp(-1F, 1F) * 127F) & 0xFF) << 16; - uint byte1 = ((uint)Math.Round(w.Clamp(-1F, 1F) * 127F) & 0xFF) << 24; + vector = Vector4.Clamp(vector, MinusOne, Vector4.One) * Half; - return byte4 | byte3 | byte2 | byte1; - } + uint byte4 = ((uint)Math.Round(vector.X) & 0xFF) << 0; + uint byte3 = ((uint)Math.Round(vector.Y) & 0xFF) << 8; + uint byte2 = ((uint)Math.Round(vector.Z) & 0xFF) << 16; + uint byte1 = ((uint)Math.Round(vector.W) & 0xFF) << 24; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= Half; - vector += Round; - vector += Half; - vector += Round; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; + return byte4 | byte3 | byte2 | byte1; } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 3319a1092..6135826f4 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -15,39 +15,24 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct NormalizedShort2 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half the maximum byte value. - /// - private static readonly Vector4 Half = new Vector4(127); - - /// - /// The vector value used for rounding. - /// - private static readonly Vector4 Round = new Vector4(.5F); + private static readonly Vector2 Max = new Vector2(0x7FFF); + private static readonly Vector2 Min = Vector2.Negate(Max); /// /// Initializes a new instance of the struct. /// - /// The vector containing the component values. - public NormalizedShort2(Vector2 vector) + /// The x-component. + /// The y-component. + public NormalizedShort2(float x, float y) + : this(new Vector2(x, y)) { - this.PackedValue = Pack(vector.X, vector.Y); } /// /// Initializes a new instance of the struct. /// - /// The x-component. - /// The y-component. - public NormalizedShort2(float x, float y) - { - this.PackedValue = Pack(x, y); - } + /// The vector containing the component values. + public NormalizedShort2(Vector2 vector) => this.PackedValue = Pack(vector); /// public uint PackedValue { get; set; } @@ -55,53 +40,39 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(NormalizedShort2 left, NormalizedShort2 right) - { - return left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(NormalizedShort2 left, NormalizedShort2 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(NormalizedShort2 left, NormalizedShort2 right) - { - return !left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(NormalizedShort2 left, NormalizedShort2 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; scaled -= Vector2.One; - this.PackedValue = Pack(scaled.X, scaled.Y); + this.PackedValue = Pack(scaled); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector2(); @@ -111,146 +82,55 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.ToVector2(), 0, 1); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); + var vector2 = new Vector2(vector.X, vector.Y); + this.PackedValue = Pack(vector2); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.ToVector2(), 0, 1); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. /// /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector2 ToVector2() { const float MaxVal = 0x7FFF; @@ -261,61 +141,34 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - public override bool Equals(object obj) - { - return obj is NormalizedShort2 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is NormalizedShort2 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(NormalizedShort2 other) - { - return this.PackedValue.Equals(other.PackedValue); - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(NormalizedShort2 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return this.PackedValue.GetHashCode(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); /// public override string ToString() { - return this.PackedValue.ToString("X"); + var vector = this.ToVector2(); + return $"NormalizedShort2({vector.X:#0.##}, {vector.Y:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y) + [MethodImpl(InliningOptions.ShortMethod)] + private static uint Pack(Vector2 vector) { - const float MaxPos = 0x7FFF; - const float MinNeg = -MaxPos; + vector *= Max; + vector = Vector2.Clamp(vector, Min, Max); - // Clamp the value between min and max values // Round rather than truncate. - uint word2 = (uint)((int)MathF.Round(x * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF); - uint word1 = (uint)(((int)MathF.Round(y * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF) << 0x10); + uint word2 = (uint)((int)MathF.Round(vector.X) & 0xFFFF); + uint word1 = (uint)(((int)MathF.Round(vector.Y) & 0xFFFF) << 0x10); return word2 | word1; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= Half; - vector += Round; - vector += Half; - vector += Round; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 7a74a4434..9717829a2 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -15,29 +15,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct NormalizedShort4 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half the maximum byte value. - /// - private static readonly Vector4 Half = new Vector4(127); - - /// - /// The vector value used for rounding. - /// - private static readonly Vector4 Round = new Vector4(.5F); - - /// - /// Initializes a new instance of the struct. - /// - /// The vector containing the component values. - public NormalizedShort4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + private static readonly Vector4 Max = new Vector4(0x7FFF); + private static readonly Vector4 Min = Vector4.Negate(Max); /// /// Initializes a new instance of the struct. @@ -47,54 +26,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component. /// The w-component. public NormalizedShort4(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } + /// + /// Initializes a new instance of the struct. + /// + /// The vector containing the component values. + public NormalizedShort4(Vector4 vector) => this.PackedValue = Pack(ref vector); + /// public ulong PackedValue { get; set; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(NormalizedShort4 left, NormalizedShort4 right) - { - return left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(NormalizedShort4 left, NormalizedShort4 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(NormalizedShort4 left, NormalizedShort4 right) - { - return !left.Equals(right); - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(NormalizedShort4 left, NormalizedShort4 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { vector *= 2F; @@ -103,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector4(); @@ -113,14 +84,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { const float MaxVal = 0x7FFF; @@ -133,185 +101,68 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - Vector4 vector = source.ToByteScaledVector4(); - vector -= Round; - vector -= Half; - vector -= Round; - vector /= Half; - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is NormalizedShort4 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is NormalizedShort4 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(NormalizedShort4 other) - { - return this.PackedValue.Equals(other.PackedValue); - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(NormalizedShort4 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return this.PackedValue.GetHashCode(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); /// public override string ToString() { - return this.PackedValue.ToString("X"); + var vector = this.ToVector4(); + return $"NormalizedShort4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static ulong Pack(ref Vector4 vector) { - const float MaxPos = 0x7FFF; - const float MinNeg = -MaxPos; + vector *= Max; + vector = Vector4.Clamp(vector, Min, Max); - // Clamp the value between min and max values - ulong word4 = ((ulong)MathF.Round(x * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF) << 0x00; - ulong word3 = ((ulong)MathF.Round(y * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF) << 0x10; - ulong word2 = ((ulong)MathF.Round(z * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF) << 0x20; - ulong word1 = ((ulong)MathF.Round(w * MaxPos).Clamp(MinNeg, MaxPos) & 0xFFFF) << 0x30; + // Round rather than truncate. + ulong word4 = ((ulong)MathF.Round(vector.X) & 0xFFFF) << 0x00; + ulong word3 = ((ulong)MathF.Round(vector.Y) & 0xFFFF) << 0x10; + ulong word2 = ((ulong)MathF.Round(vector.Z) & 0xFFFF) << 0x20; + ulong word1 = ((ulong)MathF.Round(vector.W) & 0xFFFF) << 0x30; return word4 | word3 | word2 | word1; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= Half; - vector += Round; - vector += Half; - vector += Round; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return vector; - } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index e4bed1275..3375a9753 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -15,24 +15,23 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Rg32 : IPixel, IPackedVector { + private static readonly Vector2 Max = new Vector2(ushort.MaxValue); + /// /// Initializes a new instance of the struct. /// /// The x-component /// The y-component public Rg32(float x, float y) + : this(new Vector2(x, y)) { - this.PackedValue = Pack(x, y); } /// /// Initializes a new instance of the struct. /// /// The vector containing the component values. - public Rg32(Vector2 vector) - { - this.PackedValue = Pack(vector.X, vector.Y); - } + public Rg32(Vector2 vector) => this.PackedValue = Pack(vector); /// public uint PackedValue { get; set; } @@ -40,230 +39,111 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Rg32 left, Rg32 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rg32 left, Rg32 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Rg32 left, Rg32 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rg32 left, Rg32 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); - /// - /// Expands the packed representation into a . - /// The vector components are typically expanded in least to greatest significance order. - /// - /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 ToVector2() - { - return new Vector2( - (this.PackedValue & 0xFFFF) / 65535F, - ((this.PackedValue >> 16) & 0xFFFF) / 65535F); - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.ToVector2(), 0F, 1F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; + var vector2 = new Vector2(vector.X, vector.Y); + this.PackedValue = Pack(vector2); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.ToVector2(), 0F, 1F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)vector.X; - dest.G = (byte)vector.Y; - dest.B = (byte)vector.Z; - dest.A = (byte)vector.W; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + /// Expands the packed representation into a . + /// The vector components are typically expanded in least to greatest significance order. + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public Vector2 ToVector2() => new Vector2(this.PackedValue & 0xFFFF, (this.PackedValue >> 16) & 0xFFFF) / Max; /// - public override bool Equals(object obj) - { - return obj is Rg32 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Rg32 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rg32 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rg32 other) => this.PackedValue.Equals(other.PackedValue); /// public override string ToString() { - return this.ToVector2().ToString(); + var vector = this.ToVector2(); + return $"Rg32({vector.X:#0.##}, {vector.Y:#0.##})"; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return this.PackedValue.GetHashCode(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y) + [MethodImpl(InliningOptions.ShortMethod)] + private static uint Pack(Vector2 vector) { - return (uint)( - ((int)Math.Round(x.Clamp(0, 1) * 65535F) & 0xFFFF) | - (((int)Math.Round(y.Clamp(0, 1) * 65535F) & 0xFFFF) << 16)); + vector = Vector2.Clamp(vector, Vector2.Zero, Vector2.One) * Max; + return (uint)(((int)Math.Round(vector.X) & 0xFFFF) | (((int)Math.Round(vector.Y) & 0xFFFF) << 16)); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() => this.ToVector4() * 255F; } -} +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index 4c5aef543..0b2c39ab5 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -42,7 +41,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgb24(byte r, byte g, byte b) { this.R = r; @@ -50,39 +49,54 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = b; } + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rgb24 left, Rgb24 right) => left.Equals(right); + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rgb24 left, Rgb24 right) => !left.Equals(right); + /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rgb24 other) - { - return this.R == other.R && this.G == other.G && this.B == other.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - public override bool Equals(object obj) - { - return obj is Rgb24 other && this.Equals(other); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) { - int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + Rgba32 rgba = default; + rgba.PackFromVector4(vector); + this.PackFromRgba32(rgba); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this = Unsafe.As(ref source); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { this.R = source.R; @@ -91,7 +105,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { this.R = source.R; @@ -100,74 +114,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - Rgba32 rgba = default; - rgba.PackFromVector4(vector); - this.PackFromRgba32(rgba); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) => dest = this; - - /// - public void ToRgba32(ref Rgba32 dest) - { - dest.Rgb = this; - dest.A = byte.MaxValue; - } - - /// - public void ToArgb32(ref Argb32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = byte.MaxValue; - } - - /// - public void ToBgr24(ref Bgr24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } - - /// - public void ToBgra32(ref Bgra32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = byte.MaxValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { this.R = source.PackedValue; @@ -176,53 +123,57 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { - var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); - this.R = val; - this.G = val; - this.B = val; + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this = Unsafe.As(ref source); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, byte.MaxValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + public override bool Equals(object obj) => obj is Rgb24 other && this.Equals(other); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rgb24 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B); /// - public override string ToString() + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() { - return $"({this.R},{this.G},{this.B})"; + int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); + return HashHelpers.Combine(hash, this.B.GetHashCode()); } + + /// + public override string ToString() => $"Rgb24({this.R}, {this.G}, {this.B})"; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/Rgb48.cs index 7784c49ff..2ee1be6fe 100644 --- a/src/ImageSharp/PixelFormats/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/Rgb48.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.PixelFormats [StructLayout(LayoutKind.Sequential)] public struct Rgb48 : IPixel { - private const float Max = 65535F; + private const float Max = ushort.MaxValue; /// /// Gets or sets the red component. @@ -48,29 +48,6 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = b; } - /// - /// Initializes a new instance of the struct. - /// - /// The red component. - /// The green component. - /// The blue component. - public Rgb48(float r, float g, float b) - : this() - { - this.R = (ushort)MathF.Round(r.Clamp(0, 1) * Max); - this.G = (ushort)MathF.Round(g.Clamp(0, 1) * Max); - this.B = (ushort)MathF.Round(b.Clamp(0, 1) * Max); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The vector containing the components values. - public Rgb48(Vector3 vector) - : this(vector.X, vector.Y, vector.Z) - { - } - /// /// Compares two objects for equality. /// @@ -79,13 +56,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Rgb48 left, Rgb48 right) - { - return left.R == right.R - && left.G == right.G - && left.B == right.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rgb48 left, Rgb48 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -95,40 +67,22 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Rgb48 left, Rgb48 right) - { - return left.R != right.R - || left.G != right.G - || left.B != right.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rgb48 left, Rgb48 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.R / Max, this.G / Max, this.B / Max, 1); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; @@ -138,97 +92,43 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R / Max, this.G / Max, this.B / Max, 1F); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { - this.PackFromVector4(source.ToVector4()); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { - this.PackFromVector4(source.ToVector4()); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this = source.Rgb; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = 255; - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { - var val = (ushort)(source.PackedValue * 255); - this.R = val; - this.G = val; - this.B = val; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) - { - dest.PackFromRgb48(this); + ushort rgb = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { this.R = source.PackedValue; @@ -236,49 +136,41 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.PackedValue; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) { - dest.PackFromRgb48(this); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this = source; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest = this; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() { - dest.Rgb = this; - dest.A = ushort.MaxValue; + byte r = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); + byte g = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); + byte b = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); + return new Rgba32(r, g, b, byte.MaxValue); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this = source; + /// - public override bool Equals(object obj) - { - return obj is Rgb48 rgb48 && this.Equals(rgb48); - } + public override bool Equals(object obj) => obj is Rgb48 rgb48 && this.Equals(rgb48); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rgb48 other) - { - return this.R == other.R - && this.G == other.G - && this.B == other.B; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rgb48 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B); /// - public override string ToString() => this.ToVector4().ToString(); + public override string ToString() => $"Rgb48({this.R}, {this.G}, {this.B})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { return HashHelpers.Combine( diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 6dd5f7b54..8bcf34f30 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -16,6 +16,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Rgba1010102 : IPixel, IPackedVector { + private static readonly Vector4 Multiplier = new Vector4(1023F, 1023F, 1023F, 3F); + /// /// Initializes a new instance of the struct. /// @@ -24,18 +26,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component /// The w-component public Rgba1010102(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } /// /// Initializes a new instance of the struct. /// /// The vector containing the component values. - public Rgba1010102(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + public Rgba1010102(Vector4 vector) => this.PackedValue = Pack(ref vector); /// public uint PackedValue { get; set; } @@ -43,222 +42,107 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Rgba1010102 left, Rgba1010102 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rgba1010102 left, Rgba1010102 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Rgba1010102 left, Rgba1010102 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rgba1010102 left, Rgba1010102 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4( - ((this.PackedValue >> 0) & 0x03FF) / 1023F, - ((this.PackedValue >> 10) & 0x03FF) / 1023F, - ((this.PackedValue >> 20) & 0x03FF) / 1023F, - ((this.PackedValue >> 30) & 0x03) / 3F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); + return new Vector4( + (this.PackedValue >> 0) & 0x03FF, + (this.PackedValue >> 10) & 0x03FF, + (this.PackedValue >> 20) & 0x03FF, + (this.PackedValue >> 30) & 0x03) / Multiplier; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToVector4() * 255F; - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is Rgba1010102 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Rgba1010102 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rgba1010102 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rgba1010102 other) => this.PackedValue == other.PackedValue; /// - public override string ToString() - { - return this.ToVector4().ToString(); - } + public override string ToString() => this.ToVector4().ToString(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return this.PackedValue.GetHashCode(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static uint Pack(ref Vector4 vector) { + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Multiplier; + return (uint)( - (((int)Math.Round(x.Clamp(0, 1) * 1023F) & 0x03FF) << 0) | - (((int)Math.Round(y.Clamp(0, 1) * 1023F) & 0x03FF) << 10) | - (((int)Math.Round(z.Clamp(0, 1) * 1023F) & 0x03FF) << 20) | - (((int)Math.Round(w.Clamp(0, 1) * 3F) & 0x03) << 30)); + (((int)Math.Round(vector.X) & 0x03FF) << 0) + | (((int)Math.Round(vector.Y) & 0x03FF) << 10) + | (((int)Math.Round(vector.Z) & 0x03FF) << 20) + | (((int)Math.Round(vector.W) & 0x03) << 30)); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index aab9fad92..e92da0266 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(byte r, byte g, byte b) { this.R = r; @@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(byte r, byte g, byte b, byte a) { this.R = r; @@ -109,12 +109,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(float r, float g, float b, float a = 1) - : this() - { - this.Pack(r, g, b, a); - } + : this() => this.Pack(r, g, b, a); /// /// Initializes a new instance of the struct. @@ -122,12 +119,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(Vector3 vector) - : this() - { - this.Pack(ref vector); - } + : this() => this.Pack(ref vector); /// /// Initializes a new instance of the struct. @@ -135,12 +129,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(Vector4 vector) - : this() - { - this = PackNew(ref vector); - } + : this() => this = PackNew(ref vector); /// /// Initializes a new instance of the struct. @@ -148,22 +139,19 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The packed value. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32(uint packed) - : this() - { - this.Rgba = packed; - } + : this() => this.Rgba = packed; /// /// Gets or sets the packed representation of the Rgba32 struct. /// public uint Rgba { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } @@ -172,10 +160,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public Rgb24 Rgb { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } @@ -184,10 +172,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public Bgr24 Bgr { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => new Bgr24(this.R, this.G, this.B); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set { this.R = value.R; @@ -199,30 +187,23 @@ namespace SixLabors.ImageSharp.PixelFormats /// public uint PackedValue { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => this.Rgba; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => this.Rgba = value; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Rgba32 left, Rgba32 right) - { - return left.Rgba == right.Rgba; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rgba32 left, Rgba32 right) => left.Equals(right); /// /// Compares two objects for equality. @@ -232,11 +213,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Rgba32 left, Rgba32 right) - { - return left.Rgba != right.Rgba; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rgba32 left, Rgba32 right) => !left.Equals(right); /// /// Creates a new instance of the struct. @@ -248,23 +226,29 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . /// - public static Rgba32 FromHex(string hex) - { - return ColorBuilder.FromHex(hex); - } + public static Rgba32 FromHex(string hex) => ColorBuilder.FromHex(hex); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this = source; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; + + /// + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { this.R = source.R; @@ -274,7 +258,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { this.R = source.R; @@ -283,213 +267,85 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } - /// - /// Converts the value of this instance to a hexadecimal string. - /// - /// A hexadecimal string representation of the value. - public string ToHex() - { - uint hexOrder = (uint)(this.A << 0 | this.B << 8 | this.G << 16 | this.R << 24); - return hexOrder.ToString("X8"); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest = Unsafe.As(ref this); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - dest = this; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - dest.R = this.R; - dest.G = this.G; - dest.B = this.B; - dest.A = this.A; - } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; this.B = source.PackedValue; - this.A = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) - { - dest.PackFromRgba32(this); + this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) { - var val = (byte)(((source.PackedValue * 255) + 32895) >> 16); - this.R = val; - this.G = val; - this.B = val; - this.A = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) - { - dest.PackFromRgba32(this); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.Pack(ref vector); + byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; + this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; - } - - /// - /// Gets the value of this struct as . - /// Useful for changing the component order. - /// - /// A value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A); - - /// - /// Gets the value of this struct as . - /// Useful for changing the component order. - /// - /// A value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this = source; - /// - /// Converts the pixel to format. - /// - /// The RGBA value - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => this; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) { - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); this.A = byte.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) { - // Taken from libpng pngtran.c line: 2419 - this.R = (byte)(((source.R * 255) + 32895) >> 16); - this.G = (byte)(((source.G * 255) + 32895) >> 16); - this.B = (byte)(((source.B * 255) + 32895) >> 16); - this.A = (byte)(((source.A * 255) + 32895) >> 16); + this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); + this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); + this.B = ImageMaths.DownScaleFrom16BitTo8Bit(source.B); + this.A = ImageMaths.DownScaleFrom16BitTo8Bit(source.A); } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - public override bool Equals(object obj) + /// + /// Converts the value of this instance to a hexadecimal string. + /// + /// A hexadecimal string representation of the value. + public string ToHex() { - return obj is Rgba32 rgba32 && this.Equals(rgba32); + uint hexOrder = (uint)(this.A << 0 | this.B << 8 | this.G << 16 | this.R << 24); + return hexOrder.ToString("X8"); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rgba32 other) - { - return this.Rgba == other.Rgba; - } + public override bool Equals(object obj) => obj is Rgba32 rgba32 && this.Equals(rgba32); /// - public override string ToString() - { - return $"({this.R},{this.G},{this.B},{this.A})"; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rgba32 other) => this.Rgba.Equals(other.Rgba); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => this.Rgba.GetHashCode(); + public override string ToString() => $"Rgba32({this.R}, {this.G}, {this.B}, {this.A})"; - /// - /// Gets the representation without normalizing to [0, 1] - /// - /// A of values in [0, 255] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Vector4 ToByteScaledVector4() - { - return new Vector4(this.R, this.G, this.B, this.A); - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public override int GetHashCode() => this.Rgba.GetHashCode(); /// /// Packs a into a color returning a new instance as a result. /// /// The vector containing the values to pack. /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static Rgba32 PackNew(ref Vector4 vector) { vector *= MaxBytes; @@ -506,7 +362,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The y-component /// The z-component /// The w-component - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(float x, float y, float z, float w) { var value = new Vector4(x, y, z, w); @@ -517,10 +373,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs a into a uint. /// /// The vector containing the values to pack. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(ref Vector3 vector) { - var value = new Vector4(vector, 1); + var value = new Vector4(vector, 1F); this.Pack(ref value); } @@ -528,7 +384,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs a into a color. /// /// The vector containing the values to pack. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void Pack(ref Vector4 vector) { vector *= MaxBytes; diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 5c3187856..623f7051a 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.PixelFormats [StructLayout(LayoutKind.Sequential)] public struct Rgba64 : IPixel, IPackedVector { - private const float Max = 65535F; + private const float Max = ushort.MaxValue; /// /// Gets or sets the red component. @@ -47,7 +47,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// The blue component. /// The alpha component. public Rgba64(ushort r, ushort g, ushort b, ushort a) - : this() { this.R = r; this.G = g; @@ -55,126 +54,63 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = a; } - /// - /// Initializes a new instance of the struct. - /// - /// The red component. - /// The green component. - /// The blue component. - /// The alpha component. - public Rgba64(float r, float g, float b, float a) - : this() - { - this.R = (ushort)MathF.Round(r.Clamp(0, 1) * Max); - this.G = (ushort)MathF.Round(g.Clamp(0, 1) * Max); - this.B = (ushort)MathF.Round(b.Clamp(0, 1) * Max); - this.A = (ushort)MathF.Round(a.Clamp(0, 1) * Max); - } - - /// - /// Initializes a new instance of the struct. - /// - /// The vector containing the components values. - public Rgba64(Vector4 vector) - : this(vector.X, vector.Y, vector.Z, vector.W) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// The packed value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Rgba64(ulong packed) - : this() - { - this.PackedValue = packed; - } - /// /// Gets or sets the RGB components of this struct as /// public Rgb48 Rgb { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } /// public ulong PackedValue { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get => Unsafe.As(ref this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set => Unsafe.As(ref this) = value; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Rgba64 left, Rgba64 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Rgba64 left, Rgba64 right) => left.PackedValue == right.PackedValue; /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Rgba64 left, Rgba64 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Rgba64 left, Rgba64 right) => left.PackedValue != right.PackedValue; /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4(this.R, this.G, this.B, this.A) / Max; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; @@ -185,145 +121,95 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.PackFromVector4(source.ToVector4()); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / Max; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) { - this.PackFromVector4(source.ToVector4()); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) { - this.PackFromVector4(source.ToVector4()); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba64(Rgba64 source) => this = source; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - // Taken from libpng pngtran.c line: 2419 - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = (byte)(((this.A * 255) + 32895) >> 16); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray8(Gray8 source) { - this.Rgb = source; + ushort rgb = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); + this.R = rgb; + this.G = rgb; + this.B = rgb; this.A = ushort.MaxValue; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest = this.Rgb; - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest = this; - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromGray16(Gray16 source) { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = (byte)(((this.A * 255) + 32895) >> 16); + this.R = source.PackedValue; + this.G = source.PackedValue; + this.B = source.PackedValue; + this.A = ushort.MaxValue; } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() { - dest.R = (byte)(((this.R * 255) + 32895) >> 16); - dest.G = (byte)(((this.G * 255) + 32895) >> 16); - dest.B = (byte)(((this.B * 255) + 32895) >> 16); - dest.A = (byte)(((this.A * 255) + 32895) >> 16); + byte r = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); + byte g = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); + byte b = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); + byte a = ImageMaths.DownScaleFrom16BitTo8Bit(this.A); + return new Rgba32(r, g, b, a); } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray8(Gray8 source) - { - ushort x = (ushort)(source.PackedValue * 255); - this.R = x; - this.G = x; - this.B = x; - this.A = ushort.MaxValue; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromGray16(Gray16 source) + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) { - this.R = source.PackedValue; - this.G = source.PackedValue; - this.B = source.PackedValue; + this.Rgb = source; this.A = ushort.MaxValue; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba64(Rgba64 source) => this = source; /// - public override bool Equals(object obj) - { - return obj is Rgba64 rgba64 && this.Equals(rgba64); - } + public override bool Equals(object obj) => obj is Rgba64 rgba64 && this.Equals(rgba64); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Rgba64 other) - { - return this.PackedValue == other.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Rgba64 other) => this.PackedValue.Equals(other.PackedValue); /// - public override string ToString() - { - return $"({this.R},{this.G},{this.B},{this.A})"; - } + public override string ToString() => $"Rgba64({this.R}, {this.G}, {this.B}, {this.A})"; /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index 3ab45a66e..5ca0ce406 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -1,9 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.PixelFormats { @@ -18,36 +18,32 @@ namespace SixLabors.ImageSharp.PixelFormats /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, /// as it avoids the need to create new values for modification operations. /// + [StructLayout(LayoutKind.Sequential)] public partial struct RgbaVector : IPixel { /// - /// The maximum byte value. + /// Gets or sets the red component. /// - private static readonly Vector4 MaxBytes = new Vector4(255); + public float R; /// - /// The half vector value. + /// Gets or sets the green component. /// - private static readonly Vector4 Half = new Vector4(0.5F); + public float G; /// - /// The backing vector for SIMD support. + /// Gets or sets the blue component. /// - private Vector4 backingVector; + public float B; /// - /// Initializes a new instance of the struct. + /// Gets or sets the alpha component. /// - /// The red component. - /// The green component. - /// The blue component. - /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RgbaVector(byte r, byte g, byte b, byte a = 255) - : this() - { - this.backingVector = new Vector4(r, g, b, a) / MaxBytes; - } + public float A; + + private const float MaxBytes = byte.MaxValue; + private static readonly Vector4 Max = new Vector4(MaxBytes); + private static readonly Vector4 Half = new Vector4(0.5F); /// /// Initializes a new instance of the struct. @@ -56,128 +52,25 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public RgbaVector(float r, float g, float b, float a = 1) - : this() - { - this.backingVector = new Vector4(r, g, b, a); - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The vector containing the components for the packed vector. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RgbaVector(Vector3 vector) - : this() - { - this.backingVector = new Vector4(vector, 1); - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The vector containing the components for the packed vector. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RgbaVector(Vector4 vector) - : this() - { - this.backingVector = vector; - } - - /// - /// Gets or sets the red component. - /// - public float R - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return this.backingVector.X; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.backingVector.X = value; - } - } - - /// - /// Gets or sets the green component. - /// - public float G - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return this.backingVector.Y; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.backingVector.Y = value; - } - } - - /// - /// Gets or sets the blue component. - /// - public float B { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return this.backingVector.Z; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.backingVector.Z = value; - } - } - - /// - /// Gets or sets the alpha component. - /// - public float A - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return this.backingVector.W; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.backingVector.W = value; - } + this.R = r; + this.G = g; + this.B = b; + this.A = a; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(RgbaVector left, RgbaVector right) - { - return left.backingVector == right.backingVector; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(RgbaVector left, RgbaVector right) => left.Equals(right); /// /// Compares two objects for equality. @@ -187,11 +80,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(RgbaVector left, RgbaVector right) - { - return left.backingVector != right.backingVector; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(RgbaVector left, RgbaVector right) => !left.Equals(right); /// /// Creates a new instance of the struct. @@ -203,190 +93,103 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . /// - public static RgbaVector FromHex(string hex) - { - return ColorBuilder.FromHex(hex); - } + public static RgbaVector FromHex(string hex) => ColorBuilder.FromHex(hex); /// - public PixelOperations CreatePixelOperations() => new RgbaVector.PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - this.backingVector = source.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - this.backingVector = source.ToVector4(); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToScaledVector4() => this.ToVector4(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - this.backingVector = source.ToVector4(); - } - - /// - /// Converts the value of this instance to a hexadecimal string. - /// - /// A hexadecimal string representation of the value. - public string ToHex() - { - // Hex is RRGGBBAA - Vector4 vector = this.backingVector * MaxBytes; - vector += Half; - uint hexOrder = (uint)((byte)vector.W | (byte)vector.Z << 8 | (byte)vector.Y << 16 | (byte)vector.X << 24); - return hexOrder.ToString("X8"); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One); + this.R = vector.X; + this.G = vector.Y; + this.B = vector.Z; + this.A = vector.W; } - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromScaledVector4(Vector4 vector) - { - this.PackFromVector4(vector); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToScaledVector4() - { - return this.ToVector4(); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) + /// + /// Converts the value of this instance to a hexadecimal string. + /// + /// A hexadecimal string representation of the value. + public string ToHex() { - this.backingVector = vector; + // Hex is RRGGBBAA + Vector4 vector = this.ToVector4() * Max; + vector += Half; + uint hexOrder = (uint)((byte)vector.W | (byte)vector.Z << 8 | (byte)vector.Y << 16 | (byte)vector.X << 24); + return hexOrder.ToString("X8"); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return this.backingVector; - } + public override bool Equals(object obj) => obj is RgbaVector other && this.Equals(other); /// - public override bool Equals(object obj) - { - return obj is RgbaVector other && this.Equals(other); - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(RgbaVector other) => + this.R.Equals(other.R) + && this.G.Equals(other.G) + && this.B.Equals(other.B) + && this.A.Equals(other.A); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(RgbaVector other) - { - return this.backingVector == other.backingVector; - } - - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. public override string ToString() { - return this.ToVector4().ToString(); + var vector = this.ToVector4(); + return $"RgbaVector({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"; } /// public override int GetHashCode() { - return this.backingVector.GetHashCode(); + int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); + hash = HashHelpers.Combine(hash, this.B.GetHashCode()); + return HashHelpers.Combine(hash, this.A.GetHashCode()); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() => Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 331c5fb20..24430a5d9 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -15,39 +15,30 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Short2 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector2 MaxBytes = new Vector2(255); + // Largest two byte positive number 0xFFFF >> 1; + private const float MaxPos = 0x7FFF; - /// - /// The half the maximum byte value. - /// - private static readonly Vector2 Half = new Vector2(127); + // Two's complement + private const float MinNeg = ~(int)MaxPos; - /// - /// The vector value used for rounding. - /// - private static readonly Vector2 Round = new Vector2(.5F); + private static readonly Vector2 Max = new Vector2(MaxPos); + private static readonly Vector2 Min = new Vector2(MinNeg); /// /// Initializes a new instance of the struct. /// - /// The vector containing the component values. - public Short2(Vector2 vector) + /// The x-component. + /// The y-component. + public Short2(float x, float y) + : this(new Vector2(x, y)) { - this.PackedValue = Pack(vector.X, vector.Y); } /// /// Initializes a new instance of the struct. /// - /// The x-component. - /// The y-component. - public Short2(float x, float y) - { - this.PackedValue = Pack(x, y); - } + /// The vector containing the component values. + public Short2(Vector2 vector) => this.PackedValue = Pack(vector); /// public uint PackedValue { get; set; } @@ -55,53 +46,39 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// - /// True if the parameter is equal to the parameter; otherwise, false. + /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Short2 left, Short2 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Short2 left, Short2 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Short2 left, Short2 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Short2 left, Short2 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 65534F; scaled -= new Vector2(32767F); - this.PackedValue = Pack(scaled.X, scaled.Y); + this.PackedValue = Pack(scaled); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector2(); @@ -111,198 +88,83 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(vector.X, vector.Y); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4 ToVector4() - { - return new Vector4((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0, 1); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - Vector2 vector = new Vector2(source.R, source.G) / 255; - vector *= 65534; - vector -= new Vector2(32767); - this.PackedValue = Pack(vector.X, vector.Y); + var vector2 = new Vector2(vector.X, vector.Y); + this.PackedValue = Pack(vector2); } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - Vector2 vector = new Vector2(source.R, source.G) / 255; - vector *= 65534; - vector -= new Vector2(32767); - this.PackedValue = Pack(vector.X, vector.Y); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector4 ToVector4() => new Vector4((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0, 1); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - Vector2 vector = new Vector2(source.R, source.G) / 255; - vector *= 65534; - vector -= new Vector2(32767); - this.PackedValue = Pack(vector.X, vector.Y); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector2 vector = this.ToByteScaledVector2(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector2 vector = this.ToByteScaledVector2(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector2 vector = this.ToByteScaledVector2(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector2 vector = this.ToByteScaledVector2(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector2 vector = this.ToByteScaledVector2(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = 0; - dest.A = 255; - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. /// /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 ToVector2() - { - return new Vector2((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10)); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Vector2 ToVector2() => new Vector2((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10)); /// - public override bool Equals(object obj) - { - return obj is Short2 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Short2 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Short2 other) - { - return this == other; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Short2 other) => this.PackedValue.Equals(other.PackedValue); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); /// public override string ToString() { - return this.PackedValue.ToString("x8"); + var vector = this.ToVector2(); + return $"Short2({vector.X:#0.##}, {vector.Y:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y) + [MethodImpl(InliningOptions.ShortMethod)] + private static uint Pack(Vector2 vector) { - // Largest two byte positive number 0xFFFF >> 1; - const float MaxPos = 0x7FFF; - const float MinNeg = ~(int)MaxPos; - - // Clamp the value between min and max values - uint word2 = (uint)Math.Round(x.Clamp(MinNeg, MaxPos)) & 0xFFFF; - uint word1 = ((uint)Math.Round(y.Clamp(MinNeg, MaxPos)) & 0xFFFF) << 0x10; + vector = Vector2.Clamp(vector, Min, Max); + uint word2 = (uint)Math.Round(vector.X) & 0xFFFF; + uint word1 = ((uint)Math.Round(vector.Y) & 0xFFFF) << 0x10; return word2 | word1; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector2 ToByteScaledVector2() - { - var vector = this.ToVector2(); - vector /= 65534; - vector *= 255; - vector += Half; - vector += Round; - vector = Vector2.Clamp(vector, Vector2.Zero, MaxBytes); - return vector; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 4a3d89ad8..492513747 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -15,29 +15,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct Short4 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); + // Largest two byte positive number 0xFFFF >> 1; + private const float MaxPos = 0x7FFF; - /// - /// The half the maximum byte value. - /// - private static readonly Vector4 Half = new Vector4(127); + // Two's complement + private const float MinNeg = ~(int)MaxPos; - /// - /// The vector value used for rounding. - /// - private static readonly Vector4 Round = new Vector4(.5F); - - /// - /// Initializes a new instance of the struct. - /// - /// A vector containing the initial values for the components. - public Short4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + private static readonly Vector4 Max = new Vector4(MaxPos); + private static readonly Vector4 Min = new Vector4(MinNeg); /// /// Initializes a new instance of the struct. @@ -47,54 +32,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// The z-component. /// The w-component. public Short4(float x, float y, float z, float w) + : this(new Vector4(x, y, z, w)) { - this.PackedValue = Pack(x, y, z, w); } + /// + /// Initializes a new instance of the struct. + /// + /// A vector containing the initial values for the components. + public Short4(Vector4 vector) => this.PackedValue = Pack(ref vector); + /// public ulong PackedValue { get; set; } /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Short4 left, Short4 right) - { - return left.PackedValue == right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator ==(Short4 left, Short4 right) => left.Equals(right); /// /// Compares two objects for equality. /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Short4 left, Short4 right) - { - return left.PackedValue != right.PackedValue; - } + [MethodImpl(InliningOptions.ShortMethod)] + public static bool operator !=(Short4 left, Short4 right) => !left.Equals(right); /// public PixelOperations CreatePixelOperations() => new PixelOperations(); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromScaledVector4(Vector4 vector) { vector *= 65534F; @@ -103,7 +80,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToScaledVector4() { var scaled = this.ToVector4(); @@ -113,14 +90,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromVector4(Vector4 vector) - { - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ToVector4() { return new Vector4( @@ -131,184 +105,70 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgba32(Rgba32 source) - { - var vector = source.ToVector4(); - vector *= 65534; - vector -= new Vector4(32767); - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) - { - var vector = source.ToVector4(); - vector *= 65534; - vector -= new Vector4(32767); - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBgra32(Bgra32 source) - { - var vector = source.ToVector4(); - vector *= 65534; - vector -= new Vector4(32767); - this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb24(ref Rgb24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba32(ref Rgba32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgr24(ref Bgr24 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToBgra32(ref Bgra32 dest) - { - Vector4 vector = this.ToByteScaledVector4(); - dest.R = (byte)MathF.Round(vector.X); - dest.G = (byte)MathF.Round(vector.Y); - dest.B = (byte)MathF.Round(vector.Z); - dest.A = (byte)MathF.Round(vector.W); - } + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray8(ref Gray8 dest) => dest.PackFromVector4(this.ToVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToGray16(ref Gray16 dest) => dest.PackFromVector4(this.ToVector4()); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgb48(ref Rgb48 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToRgba64(ref Rgba64 dest) => dest.PackFromScaledVector4(this.ToScaledVector4()); - /// - public override bool Equals(object obj) - { - return obj is Short4 other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Short4 other && this.Equals(other); /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Short4 other) - { - return this == other; - } + [MethodImpl(InliningOptions.ShortMethod)] + public bool Equals(Short4 other) => this.PackedValue.Equals(other); /// /// Gets the hash code for the current instance. /// /// Hash code for the instance. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - /// - /// Returns a string representation of the current instance. - /// - /// String that represents the object. + /// public override string ToString() { - return this.PackedValue.ToString("x16"); + var vector = this.ToVector4(); + return $"Short4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; } - /// - /// Packs the components into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The containing the packed values. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Pack(float x, float y, float z, float w) + [MethodImpl(InliningOptions.ShortMethod)] + private static ulong Pack(ref Vector4 vector) { - // Largest two byte positive number 0xFFFF >> 1; - const float MaxPos = 0x7FFF; - - // Two's complement - const float MinNeg = ~(int)MaxPos; + vector = Vector4.Clamp(vector, Min, Max); // Clamp the value between min and max values - ulong word4 = ((ulong)Math.Round(x.Clamp(MinNeg, MaxPos)) & 0xFFFF) << 0x00; - ulong word3 = ((ulong)Math.Round(y.Clamp(MinNeg, MaxPos)) & 0xFFFF) << 0x10; - ulong word2 = ((ulong)Math.Round(z.Clamp(MinNeg, MaxPos)) & 0xFFFF) << 0x20; - ulong word1 = ((ulong)Math.Round(w.Clamp(MinNeg, MaxPos)) & 0xFFFF) << 0x30; + ulong word4 = ((ulong)Math.Round(vector.X) & 0xFFFF) << 0x00; + ulong word3 = ((ulong)Math.Round(vector.Y) & 0xFFFF) << 0x10; + ulong word2 = ((ulong)Math.Round(vector.Z) & 0xFFFF) << 0x20; + ulong word1 = ((ulong)Math.Round(vector.W) & 0xFFFF) << 0x30; return word4 | word3 | word2 | word1; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector /= 65534; - vector *= 255; - vector += Half; - vector += Round; - return Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs index 5041dcf5a..b338ff446 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs @@ -76,8 +76,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - float threshold = this.Threshold * 255F; - Rgba32 rgba = default; + byte threshold = (byte)MathF.Round(this.Threshold * 255F); bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8); var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); @@ -89,10 +88,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // Collect the values before looping so we can reduce our calculation count for identical sibling pixels TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; - sourcePixel.ToRgba32(ref rgba); + var rgba = sourcePixel.ToRgba32(); // Convert to grayscale using ITU-R Recommendation BT.709 if required - float luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); for (int y = startY; y < endY; y++) { @@ -106,8 +105,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // rather than calculating it again. This is an inexpensive optimization. if (!previousPixel.Equals(sourcePixel)) { - sourcePixel.ToRgba32(ref rgba); - luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + rgba = sourcePixel.ToRgba32(); + luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer previousPixel = sourcePixel; diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs index 048af8261..0b28a1574 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs @@ -56,7 +56,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - Rgba32 rgba = default; bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8); var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); @@ -68,10 +67,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // Collect the values before looping so we can reduce our calculation count for identical sibling pixels TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; - sourcePixel.ToRgba32(ref rgba); + var rgba = sourcePixel.ToRgba32(); // Convert to grayscale using ITU-R Recommendation BT.709 if required - float luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); for (int y = startY; y < endY; y++) { @@ -85,8 +84,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // rather than calculating it again. This is an inexpensive optimization. if (!previousPixel.Equals(sourcePixel)) { - sourcePixel.ToRgba32(ref rgba); - luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + rgba = sourcePixel.ToRgba32(); + luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer previousPixel = sourcePixel; diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs index 60754b3bf..03b7f73e9 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization Rectangle sourceRectangle, Configuration configuration) { - float threshold = this.Threshold * 255F; + byte threshold = (byte)MathF.Round(this.Threshold * 255F); TPixel upper = this.UpperColor; TPixel lower = this.LowerColor; @@ -83,17 +83,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization for (int y = rows.Min; y < rows.Max; y++) { Span row = source.GetPixelRowSpan(y); - Rgba32 rgba = default; for (int x = startX; x < endX; x++) { ref TPixel color = ref row[x]; - color.ToRgba32(ref rgba); + var rgba = color.ToRgba32(); // Convert to grayscale using ITU-R Recommendation BT.709 if required - float luminance = isAlphaOnly - ? rgba.A - : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); color = luminance >= threshold ? upper : lower; } } diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs index 8e2b2a5a8..b60322799 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs @@ -4,7 +4,6 @@ using System; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Dithering @@ -64,8 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - float threshold = this.Threshold * 255F; - Rgba32 rgba = default; + byte threshold = (byte)MathF.Round(this.Threshold * 255F); bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8); var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); @@ -78,10 +76,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; PixelPair pair = this.GetClosestPixelPair(ref sourcePixel); - sourcePixel.ToRgba32(ref rgba); + var rgba = sourcePixel.ToRgba32(); // Convert to grayscale using ITU-R Recommendation BT.709 if required - float luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); for (int y = startY; y < endY; y++) { @@ -103,8 +101,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering continue; } - sourcePixel.ToRgba32(ref rgba); - luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + rgba = sourcePixel.ToRgba32(); + luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer previousPixel = sourcePixel; diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs index b5e2eebc2..149c7170a 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs @@ -4,7 +4,6 @@ using System; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Dithering @@ -32,10 +31,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// The ordered ditherer. /// The palette to select substitute colors from. public OrderedDitherPaletteProcessor(IOrderedDither dither, TPixel[] palette) - : base(palette) - { - this.Dither = dither ?? throw new ArgumentNullException(nameof(dither)); - } + : base(palette) => this.Dither = dither ?? throw new ArgumentNullException(nameof(dither)); /// /// Gets the ditherer. @@ -45,7 +41,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - Rgba32 rgba = default; bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8); var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); @@ -58,10 +53,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; PixelPair pair = this.GetClosestPixelPair(ref sourcePixel); - sourcePixel.ToRgba32(ref rgba); + var rgba = sourcePixel.ToRgba32(); // Convert to grayscale using ITU-R Recommendation BT.709 if required - float luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); for (int y = startY; y < endY; y++) { @@ -83,8 +78,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering continue; } - sourcePixel.ToRgba32(ref rgba); - luminance = isAlphaOnly ? rgba.A : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B); + rgba = sourcePixel.ToRgba32(); + luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer previousPixel = sourcePixel; diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 39546d63f..552aa8af8 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -73,14 +73,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization ref TPixel scanBaseRef = ref MemoryMarshal.GetReference(row); // And loop through each column - Rgba32 rgba = default; for (int x = 0; x < width; x++) { ref TPixel pixel = ref Unsafe.Add(ref scanBaseRef, x); - pixel.ToRgba32(ref rgba); // Add the color to the Octree - this.octree.AddColor(ref pixel, ref rgba); + this.octree.AddColor(ref pixel); } } } @@ -97,9 +95,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // pass of the algorithm by avoiding transforming rows of identical color. TPixel sourcePixel = source[0, 0]; TPixel previousPixel = sourcePixel; - Rgba32 rgba = default; this.transparentIndex = this.GetTransparentIndex(); - byte pixelValue = this.QuantizePixel(ref sourcePixel, ref rgba); + byte pixelValue = this.QuantizePixel(ref sourcePixel); TPixel transformedPixel = palette[pixelValue]; for (int y = 0; y < height; y++) @@ -117,7 +114,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization if (!previousPixel.Equals(sourcePixel)) { // Quantize the pixel - pixelValue = this.QuantizePixel(ref sourcePixel, ref rgba); + pixelValue = this.QuantizePixel(ref sourcePixel); // And setup the previous pointer previousPixel = sourcePixel; @@ -146,10 +143,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Process the pixel in the second pass of the algorithm. /// /// The pixel to quantize. - /// The color to compare against. /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] - private byte QuantizePixel(ref TPixel pixel, ref Rgba32 rgba) + private byte QuantizePixel(ref TPixel pixel) { if (this.Dither) { @@ -158,13 +154,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization return this.GetClosestPixel(ref pixel); } - pixel.ToRgba32(ref rgba); + var rgba = pixel.ToRgba32(); if (rgba.Equals(default)) { return this.transparentIndex; } - return (byte)this.octree.GetPaletteIndex(ref pixel, ref rgba); + return (byte)this.octree.GetPaletteIndex(ref pixel); } /// @@ -239,8 +235,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Add a given color value to the Octree /// /// The pixel data. - /// The color. - public void AddColor(ref TPixel pixel, ref Rgba32 rgba) + public void AddColor(ref TPixel pixel) { // Check if this request is for the same color as the last if (this.previousColor.Equals(pixel)) @@ -250,18 +245,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization if (this.previousNode is null) { this.previousColor = pixel; - this.root.AddColor(ref pixel, this.maxColorBits, 0, this, ref rgba); + this.root.AddColor(ref pixel, this.maxColorBits, 0, this); } else { // Just update the previous node - this.previousNode.Increment(ref pixel, ref rgba); + this.previousNode.Increment(ref pixel); } } else { this.previousColor = pixel; - this.root.AddColor(ref pixel, this.maxColorBits, 0, this, ref rgba); + this.root.AddColor(ref pixel, this.maxColorBits, 0, this); } } @@ -294,12 +289,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Get the palette index for the passed color /// /// The pixel data. - /// The color to map to. /// /// The . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetPaletteIndex(ref TPixel pixel, ref Rgba32 rgba) => this.root.GetPaletteIndex(ref pixel, 0, ref rgba); + public int GetPaletteIndex(ref TPixel pixel) => this.root.GetPaletteIndex(ref pixel, 0); /// /// Keep track of the previous node that was quantized @@ -426,13 +420,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// The number of significant color bits /// The level in the tree /// The tree to which this node belongs - /// The color to map to. - public void AddColor(ref TPixel pixel, int colorBits, int level, Octree octree, ref Rgba32 rgba) + public void AddColor(ref TPixel pixel, int colorBits, int level, Octree octree) { // Update the color information if this is a leaf if (this.leaf) { - this.Increment(ref pixel, ref rgba); + this.Increment(ref pixel); // Setup the previous node octree.TrackPrevious(this); @@ -441,7 +434,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization { // Go to the next level down in the tree int shift = 7 - level; - pixel.ToRgba32(ref rgba); + var rgba = pixel.ToRgba32(); int index = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) @@ -456,7 +449,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } // Add the color to the child node - child.AddColor(ref pixel, colorBits, level + 1, octree, ref rgba); + child.AddColor(ref pixel, colorBits, level + 1, octree); } } @@ -525,19 +518,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The pixel data. /// The level. - /// The color to map to. /// /// The representing the index of the pixel in the palette. /// [MethodImpl(MethodImplOptions.NoInlining)] - public int GetPaletteIndex(ref TPixel pixel, int level, ref Rgba32 rgba) + public int GetPaletteIndex(ref TPixel pixel, int level) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; - pixel.ToRgba32(ref rgba); + var rgba = pixel.ToRgba32(); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) @@ -546,7 +538,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization OctreeNode child = this.children[pixelIndex]; if (child != null) { - index = child.GetPaletteIndex(ref pixel, level + 1, ref rgba); + index = child.GetPaletteIndex(ref pixel, level + 1); } else { @@ -561,11 +553,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Increment the pixel count and add to the color information /// /// The pixel to add. - /// The color to map to. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Increment(ref TPixel pixel, ref Rgba32 rgba) + public void Increment(ref TPixel pixel) { - pixel.ToRgba32(ref rgba); + var rgba = pixel.ToRgba32(); this.pixelCount++; this.red += rgba.R; this.green += rgba.G; diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index 13bc057da..f3b5da320 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -442,33 +442,36 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Build up the 3-D color histogram // Loop through each row - for (int y = 0; y < height; y++) + using (IMemoryOwner rgbaBuffer = source.MemoryAllocator.Allocate(source.Width)) { - Span row = source.GetPixelRowSpan(y); - ref TPixel scanBaseRef = ref MemoryMarshal.GetReference(row); - - // And loop through each column - Rgba32 rgba = default; - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - ref TPixel pixel = ref Unsafe.Add(ref scanBaseRef, x); - pixel.ToRgba32(ref rgba); + Span row = source.GetPixelRowSpan(y); + Span rgbaSpan = rgbaBuffer.GetSpan(); + PixelOperations.Instance.ToRgba32(row, rgbaSpan, source.Width); + ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan); + + // And loop through each column + for (int x = 0; x < width; x++) + { + ref Rgba32 rgba = ref Unsafe.Add(ref scanBaseRef, x); - int r = rgba.R >> (8 - IndexBits); - int g = rgba.G >> (8 - IndexBits); - int b = rgba.B >> (8 - IndexBits); - int a = rgba.A >> (8 - IndexAlphaBits); + int r = rgba.R >> (8 - IndexBits); + int g = rgba.G >> (8 - IndexBits); + int b = rgba.B >> (8 - IndexBits); + int a = rgba.A >> (8 - IndexAlphaBits); - int index = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1); + int index = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1); - vwtSpan[index]++; - vmrSpan[index] += rgba.R; - vmgSpan[index] += rgba.G; - vmbSpan[index] += rgba.B; - vmaSpan[index] += rgba.A; + vwtSpan[index]++; + vmrSpan[index] += rgba.R; + vmgSpan[index] += rgba.G; + vmbSpan[index] += rgba.B; + vmaSpan[index] += rgba.A; - var vector = new Vector4(rgba.R, rgba.G, rgba.B, rgba.A); - m2Span[index] += Vector4.Dot(vector, vector); + var vector = new Vector4(rgba.R, rgba.G, rgba.B, rgba.A); + m2Span[index] += Vector4.Dot(vector, vector); + } } } } @@ -876,8 +879,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } // Expected order r->g->b->a - Rgba32 rgba = default; - pixel.ToRgba32(ref rgba); + var rgba = pixel.ToRgba32(); int r = rgba.R >> (8 - IndexBits); int g = rgba.G >> (8 - IndexBits); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs index 4e9c6d10a..f96023f00 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs @@ -4,10 +4,7 @@ // ReSharper disable InconsistentNaming using System.Buffers; -using System; - using BenchmarkDotNet.Attributes; - using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -38,35 +35,10 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark(Baseline = true)] - public void PerElement() - { - Span s = this.source.GetSpan(); - Span d = this.destination.GetSpan(); - - var rgb = default(Rgb24); - - for (int i = 0; i < this.Count; i++) - { - TPixel c = s[i]; - int i3 = i * 3; - c.ToRgb24(ref rgb); - d[i3] = rgb.R; - d[i3 + 1] = rgb.G; - d[i3 + 2] = rgb.B; - } - } + public void CommonBulk() => new PixelOperations().ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); [Benchmark] - public void CommonBulk() - { - new PixelOperations().ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); - } - - [Benchmark] - public void OptimizedBulk() - { - PixelOperations.Instance.ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); - } + public void OptimizedBulk() => PixelOperations.Instance.ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } public class ToXyz_Rgba32 : ToXyz diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs index 8166c8f46..740287e85 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs @@ -42,13 +42,11 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk Span s = this.source.GetSpan(); Span d = this.destination.GetSpan(); - var rgba = default(Rgba32); - for (int i = 0; i < this.Count; i++) { TPixel c = s[i]; int i4 = i * 4; - c.ToRgba32(ref rgba); + var rgba = c.ToRgba32(); d[i4] = rgba.R; d[i4 + 1] = rgba.G; d[i4 + 2] = rgba.B; @@ -57,16 +55,10 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark] - public void CommonBulk() - { - new PixelOperations().ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); - } + public void CommonBulk() => new PixelOperations().ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); [Benchmark] - public void OptimizedBulk() - { - PixelOperations.Instance.ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); - } + public void OptimizedBulk() => PixelOperations.Instance.ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } public class ToXyzw_Rgba32 : ToXyzw diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 5ef8f0111..5d163917c 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -2,7 +2,7 @@ net462;net471;netcoreapp2.1 True - 7.3 + latest full portable True @@ -11,15 +11,15 @@ AnyCPU;x64;x86 - true + false - true + false - true + false diff --git a/tests/ImageSharp.Tests/Issues/Issue594.cs b/tests/ImageSharp.Tests/Issues/Issue594.cs index 81fd59885..4a0683fba 100644 --- a/tests/ImageSharp.Tests/Issues/Issue594.cs +++ b/tests/ImageSharp.Tests/Issues/Issue594.cs @@ -48,46 +48,46 @@ namespace SixLabors.ImageSharp.Tests.Issues Assert.Equal((uint)958796544, new NormalizedByte4(0.0008f, 0.15f, 0.30f, 0.45f).PackedValue); - var rgb = default(Rgb24); - var rgba = default(Rgba32); - var bgr = default(Bgr24); - var bgra = default(Bgra32); - var argb = default(Argb32); + //var rgb = default(Rgb24); + //var rgba = default(Rgba32); + //var bgr = default(Bgr24); + //var bgra = default(Bgra32); + //var argb = default(Argb32); - new NormalizedByte4(x, y, z, w).ToRgb24(ref rgb); - Assert.Equal(rgb, new Rgb24(141, 90, 192)); + //new NormalizedByte4(x, y, z, w).ToRgb24(ref rgb); + //Assert.Equal(rgb, new Rgb24(141, 90, 192)); - new NormalizedByte4(x, y, z, w).ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(141, 90, 192, 39)); + //new NormalizedByte4(x, y, z, w).ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(141, 90, 192, 39)); - new NormalizedByte4(x, y, z, w).ToBgr24(ref bgr); - Assert.Equal(bgr, new Bgr24(141, 90, 192)); + //new NormalizedByte4(x, y, z, w).ToBgr24(ref bgr); + //Assert.Equal(bgr, new Bgr24(141, 90, 192)); - new NormalizedByte4(x, y, z, w).ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); // this assert fails in Release build on linux (#594) + //new NormalizedByte4(x, y, z, w).ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); // this assert fails in Release build on linux (#594) - new NormalizedByte4(x, y, z, w).ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(141, 90, 192, 39)); + //new NormalizedByte4(x, y, z, w).ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(141, 90, 192, 39)); // http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8 - var r = default(NormalizedByte4); - r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); - r.ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); - - r.PackedValue = 0xff4af389; - r.ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); - - r = default(NormalizedByte4); - r.PackFromArgb32(new Argb32(9, 115, 202, 127)); - r.ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(9, 115, 202, 127)); - - r = default(NormalizedByte4); - r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); - r.ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); + //var r = default(NormalizedByte4); + //r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); + //r.ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); + + //r.PackedValue = 0xff4af389; + //r.ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); + + //r = default(NormalizedByte4); + //r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + //r.ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(9, 115, 202, 127)); + + //r = default(NormalizedByte4); + //r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + //r.ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); } // This test fails for unknown reason in Release mode on linux and is meant to help reproducing the issue @@ -127,41 +127,41 @@ namespace SixLabors.ImageSharp.Tests.Issues Assert.Equal(0xa6674000d99a0ccd, new NormalizedShort4(x, y, z, w).PackedValue); Assert.Equal((ulong)4150390751449251866, new NormalizedShort4(0.0008f, 0.15f, 0.30f, 0.45f).PackedValue); - var rgb = default(Rgb24); - var rgba = default(Rgba32); - var bgr = default(Bgr24); - var bgra = default(Bgra32); - var argb = default(Argb32); + //var rgb = default(Rgb24); + //var rgba = default(Rgba32); + //var bgr = default(Bgr24); + //var bgra = default(Bgra32); + //var argb = default(Argb32); - new NormalizedShort4(x, y, z, w).ToRgb24(ref rgb); - Assert.Equal(rgb, new Rgb24(141, 90, 192)); + //new NormalizedShort4(x, y, z, w).ToRgb24(ref rgb); + //Assert.Equal(rgb, new Rgb24(141, 90, 192)); - new NormalizedShort4(x, y, z, w).ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(141, 90, 192, 39)); // this assert fails in Release build on linux (#594) + //new NormalizedShort4(x, y, z, w).ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(141, 90, 192, 39)); // this assert fails in Release build on linux (#594) - new NormalizedShort4(x, y, z, w).ToBgr24(ref bgr); - Assert.Equal(bgr, new Bgr24(141, 90, 192)); + //new NormalizedShort4(x, y, z, w).ToBgr24(ref bgr); + //Assert.Equal(bgr, new Bgr24(141, 90, 192)); - new NormalizedShort4(x, y, z, w).ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); + //new NormalizedShort4(x, y, z, w).ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); - new NormalizedShort4(x, y, z, w).ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(141, 90, 192, 39)); + //new NormalizedShort4(x, y, z, w).ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(141, 90, 192, 39)); - var r = default(NormalizedShort4); - r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); - r.ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); + //var r = default(NormalizedShort4); + //r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); + //r.ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); - r = default(NormalizedShort4); - r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); - r.ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); + //r = default(NormalizedShort4); + //r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + //r.ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); - r = default(NormalizedShort4); - r.PackFromArgb32(new Argb32(9, 115, 202, 127)); - r.ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(9, 115, 202, 127)); + //r = default(NormalizedShort4); + //r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + //r.ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(9, 115, 202, 127)); } // This test fails for unknown reason in Release mode on linux and is meant to help reproducing the issue @@ -212,41 +212,41 @@ namespace SixLabors.ImageSharp.Tests.Issues w = 193; Assert.Equal((ulong)0x00c173b7316d2d1b, new Short4(x, y, z, w).PackedValue); - var rgb = default(Rgb24); - var rgba = default(Rgba32); - var bgr = default(Bgr24); - var bgra = default(Bgra32); - var argb = default(Argb32); + //var rgb = default(Rgb24); + //var rgba = default(Rgba32); + //var bgr = default(Bgr24); + //var bgra = default(Bgra32); + //var argb = default(Argb32); - new Short4(x, y, z, w).ToRgb24(ref rgb); - Assert.Equal(rgb, new Rgb24(172, 177, 243)); // this assert fails in Release build on linux (#594) + //new Short4(x, y, z, w).ToRgb24(ref rgb); + //Assert.Equal(rgb, new Rgb24(172, 177, 243)); // this assert fails in Release build on linux (#594) - new Short4(x, y, z, w).ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(172, 177, 243, 128)); + //new Short4(x, y, z, w).ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(172, 177, 243, 128)); - new Short4(x, y, z, w).ToBgr24(ref bgr); - Assert.Equal(bgr, new Bgr24(172, 177, 243)); + //new Short4(x, y, z, w).ToBgr24(ref bgr); + //Assert.Equal(bgr, new Bgr24(172, 177, 243)); - new Short4(x, y, z, w).ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(172, 177, 243, 128)); + //new Short4(x, y, z, w).ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(172, 177, 243, 128)); - new Short4(x, y, z, w).ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(172, 177, 243, 128)); + //new Short4(x, y, z, w).ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(172, 177, 243, 128)); - var r = default(Short4); - r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); - r.ToRgba32(ref rgba); - Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); + //var r = default(Short4); + //r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); + //r.ToRgba32(ref rgba); + //Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); - r = default(Short4); - r.PackFromBgra32(new Bgra32(20, 38, 0, 255)); - r.ToBgra32(ref bgra); - Assert.Equal(bgra, new Bgra32(20, 38, 0, 255)); + //r = default(Short4); + //r.PackFromBgra32(new Bgra32(20, 38, 0, 255)); + //r.ToBgra32(ref bgra); + //Assert.Equal(bgra, new Bgra32(20, 38, 0, 255)); - r = default(Short4); - r.PackFromArgb32(new Argb32(20, 38, 0, 255)); - r.ToArgb32(ref argb); - Assert.Equal(argb, new Argb32(20, 38, 0, 255)); + //r = default(Short4); + //r.PackFromArgb32(new Argb32(20, 38, 0, 255)); + //r.ToArgb32(ref argb); + //Assert.Equal(argb, new Argb32(20, 38, 0, 255)); } // Comparison helpers with small tolerance to allow for floating point rounding during computations. diff --git a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs index 9a29236db..d5b7d9b2b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs @@ -73,138 +73,138 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void Alpha8_PackFromScaledVector4_ToRgb24() - { - // arrange - Rgb24 actual = default; - Alpha8 alpha = default; - var expected = new Rgb24(0, 0, 0); - Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromScaledVector4_ToRgba32() - { - // arrange - Rgba32 actual = default; - Alpha8 alpha = default; - var expected = new Rgba32(0, 0, 0, 128); - Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromScaledVector4_ToBgr24() - { - // arrange - Bgr24 actual = default; - Alpha8 alpha = default; - var expected = new Bgr24(0, 0, 0); - Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromScaledVector4_ToBgra32() - { - // arrange - Bgra32 actual = default; - Alpha8 alpha = default; - var expected = new Bgra32(0, 0, 0, 128); - Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromScaledVector4_ToArgb32() - { - // arrange - Alpha8 alpha = default; - Argb32 actual = default; - var expected = new Argb32(0, 0, 0, 128); - Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromScaledVector4_ToRgba64() - { - // arrange - Alpha8 alpha = default; - Rgba64 actual = default; - var expected = new Rgba64(0, 0, 0, 65535); - Vector4 scaled = new Alpha8(1F).ToScaledVector4(); - - // act - alpha.PackFromScaledVector4(scaled); - alpha.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromRgb48_ToRgb48() - { - // arrange - var alpha = default(Alpha8); - var actual = default(Rgb48); - var expected = new Rgb48(0, 0, 0); - - // act - alpha.PackFromRgb48(expected); - alpha.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Alpha8_PackFromRgba64_ToRgba64() - { - // arrange - var alpha = default(Alpha8); - var actual = default(Rgba64); - var expected = new Rgba64(0, 0, 0, 65535); - - // act - alpha.PackFromRgba64(expected); - alpha.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToRgb24() + //{ + // // arrange + // Rgb24 actual = default; + // Alpha8 alpha = default; + // var expected = new Rgb24(0, 0, 0); + // Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToRgba32() + //{ + // // arrange + // Rgba32 actual = default; + // Alpha8 alpha = default; + // var expected = new Rgba32(0, 0, 0, 128); + // Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToBgr24() + //{ + // // arrange + // Bgr24 actual = default; + // Alpha8 alpha = default; + // var expected = new Bgr24(0, 0, 0); + // Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToBgra32() + //{ + // // arrange + // Bgra32 actual = default; + // Alpha8 alpha = default; + // var expected = new Bgra32(0, 0, 0, 128); + // Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToArgb32() + //{ + // // arrange + // Alpha8 alpha = default; + // Argb32 actual = default; + // var expected = new Argb32(0, 0, 0, 128); + // Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromScaledVector4_ToRgba64() + //{ + // // arrange + // Alpha8 alpha = default; + // Rgba64 actual = default; + // var expected = new Rgba64(0, 0, 0, 65535); + // Vector4 scaled = new Alpha8(1F).ToScaledVector4(); + + // // act + // alpha.PackFromScaledVector4(scaled); + // alpha.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var alpha = default(Alpha8); + // var actual = default(Rgb48); + // var expected = new Rgb48(0, 0, 0); + + // // act + // alpha.PackFromRgb48(expected); + // alpha.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Alpha8_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var alpha = default(Alpha8); + // var actual = default(Rgba64); + // var expected = new Rgba64(0, 0, 0, 65535); + + // // act + // alpha.PackFromRgba64(expected); + // alpha.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs index 5817b5c32..53545f517 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs @@ -67,159 +67,159 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Argb32(Vector4.One * +1234.0f).ToVector4()); } - [Fact] - public void Argb32_ToRgb24() - { - // arrange - var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(0x1a, 0, 0x80); - - // act - argb.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_ToRgba32() - { - // arrange - var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(0x1a, 0, 0x80, 0); - - // act - argb.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_ToBgr24() - { - // arrange - var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(0x1a, 0, 0x80); - - // act - argb.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_ToBgra32() - { - // arrange - var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(0x1a, 0, 0x80, 0); - - // act - argb.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_ToArgb32() - { - // arrange - var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(0x1a, 0, 0x80, 0); - - // act - argb.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_PackFromRgba32_ToRgba32() - { - // arrange - var argb = default(Argb32); - var actual = default(Rgba32); - var expected = new Rgba32(0x1a, 0, 0x80, 0); - - // act - argb.PackFromRgba32(expected); - argb.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_PackFromBgra32_ToBgra32() - { - // arrange - var argb = default(Argb32); - var actual = default(Bgra32); - var expected = new Bgra32(0x1a, 0, 0x80, 0); - - // act - argb.PackFromBgra32(expected); - argb.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_PackFromArgb32_ToArgb32() - { - // arrange - var argb = default(Argb32); - var actual = default(Argb32); - var expected = new Argb32(0x1a, 0, 0x80, 0); - - // act - argb.PackFromArgb32(expected); - argb.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_PackFromRgb48_ToRgb48() - { - // arrange - var argb = default(Argb32); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - argb.PackFromRgb48(expected); - argb.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Argb32_PackFromRgba64_ToRgba64() - { - // arrange - var argb = default(Argb32); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - argb.PackFromRgba64(expected); - argb.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Argb32_ToRgb24() + //{ + // // arrange + // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(0x1a, 0, 0x80); + + // // act + // argb.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_ToRgba32() + //{ + // // arrange + // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(0x1a, 0, 0x80, 0); + + // // act + // argb.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_ToBgr24() + //{ + // // arrange + // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(0x1a, 0, 0x80); + + // // act + // argb.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_ToBgra32() + //{ + // // arrange + // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); + // var actual = default(Bgra32); + // var expected = new Bgra32(0x1a, 0, 0x80, 0); + + // // act + // argb.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_ToArgb32() + //{ + // // arrange + // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(0x1a, 0, 0x80, 0); + + // // act + // argb.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var argb = default(Argb32); + // var actual = default(Rgba32); + // var expected = new Rgba32(0x1a, 0, 0x80, 0); + + // // act + // argb.PackFromRgba32(expected); + // argb.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var argb = default(Argb32); + // var actual = default(Bgra32); + // var expected = new Bgra32(0x1a, 0, 0x80, 0); + + // // act + // argb.PackFromBgra32(expected); + // argb.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var argb = default(Argb32); + // var actual = default(Argb32); + // var expected = new Argb32(0x1a, 0, 0x80, 0); + + // // act + // argb.PackFromArgb32(expected); + // argb.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var argb = default(Argb32); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // argb.PackFromRgb48(expected); + // argb.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Argb32_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var argb = default(Argb32); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // argb.PackFromRgba64(expected); + // argb.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index 048a38380..e742789e4 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -96,80 +96,80 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); } - [Fact] - public void ToRgb24() - { - var rgb = new Bgr24(1, 2, 3); - var dest = default(Rgb24); - - rgb.ToRgb24(ref dest); - - Assert.Equal(new Rgb24(1, 2, 3), dest); - } - - [Fact] - public void ToRgba32() - { - var rgb = new Bgr24(1, 2, 3); - var rgba = default(Rgba32); - - rgb.ToRgba32(ref rgba); - - Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); - } - - [Fact] - public void ToBgr24() - { - var rgb = new Bgr24(1, 2, 3); - var bgr = default(Bgr24); - - rgb.ToBgr24(ref bgr); - - Assert.Equal(new Bgr24(1, 2, 3), bgr); - } - - [Fact] - public void ToBgra32() - { - var rgb = new Bgr24(1, 2, 3); - var bgra = default(Bgra32); - - rgb.ToBgra32(ref bgra); - - Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); - } - - [Fact] - public void Bgr24_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Bgr24); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr24_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Bgr24); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void ToRgb24() + //{ + // var rgb = new Bgr24(1, 2, 3); + // var dest = default(Rgb24); + + // rgb.ToRgb24(ref dest); + + // Assert.Equal(new Rgb24(1, 2, 3), dest); + //} + + //[Fact] + //public void ToRgba32() + //{ + // var rgb = new Bgr24(1, 2, 3); + // var rgba = default(Rgba32); + + // rgb.ToRgba32(ref rgba); + + // Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); + //} + + //[Fact] + //public void ToBgr24() + //{ + // var rgb = new Bgr24(1, 2, 3); + // var bgr = default(Bgr24); + + // rgb.ToBgr24(ref bgr); + + // Assert.Equal(new Bgr24(1, 2, 3), bgr); + //} + + //[Fact] + //public void ToBgra32() + //{ + // var rgb = new Bgr24(1, 2, 3); + // var bgra = default(Bgra32); + + // rgb.ToBgra32(ref bgra); + + // Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); + //} + + //[Fact] + //public void Bgr24_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Bgr24); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr24_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Bgr24); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs index b66cac9ca..6954067a3 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs @@ -70,111 +70,111 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector3.One, new Bgr565(Vector3.One * 1234F).ToVector3()); } - [Fact] - public void Bgr565_ToRgb24() - { - // arrange - var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - var actual = default(Rgb24); - var expected = new Rgb24(25, 0, 132); - - // act - bgra.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_ToRgba32() - { - // arrange - var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - var actual = default(Rgba32); - var expected = new Rgba32(25, 0, 132, 255); - - // act - bgra.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_ToBgr24() - { - // arrange - var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - var actual = default(Bgr24); - var expected = new Bgr24(25, 0, 132); - - // act - bgra.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_ToBgra32() - { - // arrange - var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - var actual = default(Bgra32); - var expected = new Bgra32(25, 0, 132, 255); - - // act - bgra.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_ToArgb32() - { - // arrange - var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - var actual = default(Argb32); - var expected = new Argb32(25, 0, 132, 255); - - // act - bgra.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Bgr565); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgr565_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Bgr565); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Bgr565_ToRgb24() + //{ + // // arrange + // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); + // var actual = default(Rgb24); + // var expected = new Rgb24(25, 0, 132); + + // // act + // bgra.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_ToRgba32() + //{ + // // arrange + // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); + // var actual = default(Rgba32); + // var expected = new Rgba32(25, 0, 132, 255); + + // // act + // bgra.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_ToBgr24() + //{ + // // arrange + // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); + // var actual = default(Bgr24); + // var expected = new Bgr24(25, 0, 132); + + // // act + // bgra.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_ToBgra32() + //{ + // // arrange + // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); + // var actual = default(Bgra32); + // var expected = new Bgra32(25, 0, 132, 255); + + // // act + // bgra.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_ToArgb32() + //{ + // // arrange + // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); + // var actual = default(Argb32); + // var expected = new Argb32(25, 0, 132, 255); + + // // act + // bgra.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Bgr565); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgr565_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Bgr565); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs index 70f8c35df..9ff84a88c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -103,80 +103,80 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vec(1, 2, 3, 4), rgb.ToVector4()); } - [Fact] - public void ToRgb24() - { - var c = new Bgra32(1, 2, 3, 4); - var dest = default(Rgb24); - - c.ToRgb24(ref dest); - - Assert.Equal(new Rgb24(1, 2, 3), dest); - } - - [Fact] - public void ToRgba32() - { - var c = new Bgra32(1, 2, 3, 4); - var rgba = default(Rgba32); - - c.ToRgba32(ref rgba); - - Assert.Equal(new Rgba32(1, 2, 3, 4), rgba); - } - - [Fact] - public void ToBgr24() - { - var rgb = new Bgra32(1, 2, 3, 4); - var bgr = default(Bgr24); - - rgb.ToBgr24(ref bgr); - - Assert.Equal(new Bgr24(1, 2, 3), bgr); - } - - [Fact] - public void ToBgra32() - { - var rgb = new Bgra32(1, 2, 3, 4); - var bgra = default(Bgra32); - - rgb.ToBgra32(ref bgra); - - Assert.Equal(new Bgra32(1, 2, 3, 4), bgra); - } - - [Fact] - public void Bgra32_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Bgra32); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra32_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Bgra32); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void ToRgb24() + //{ + // var c = new Bgra32(1, 2, 3, 4); + // var dest = default(Rgb24); + + // c.ToRgb24(ref dest); + + // Assert.Equal(new Rgb24(1, 2, 3), dest); + //} + + //[Fact] + //public void ToRgba32() + //{ + // var c = new Bgra32(1, 2, 3, 4); + // var rgba = default(Rgba32); + + // c.ToRgba32(ref rgba); + + // Assert.Equal(new Rgba32(1, 2, 3, 4), rgba); + //} + + //[Fact] + //public void ToBgr24() + //{ + // var rgb = new Bgra32(1, 2, 3, 4); + // var bgr = default(Bgr24); + + // rgb.ToBgr24(ref bgr); + + // Assert.Equal(new Bgr24(1, 2, 3), bgr); + //} + + //[Fact] + //public void ToBgra32() + //{ + // var rgb = new Bgra32(1, 2, 3, 4); + // var bgra = default(Bgra32); + + // rgb.ToBgra32(ref bgra); + + // Assert.Equal(new Bgra32(1, 2, 3, 4), bgra); + //} + + //[Fact] + //public void Bgra32_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Bgra32); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra32_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Bgra32); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs index f643d152e..2e6e339b6 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs @@ -71,159 +71,159 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Bgra4444(Vector4.One * 1234.0f).ToVector4()); } - [Fact] - public void Bgra4444_ToRgb24() - { - // arrange - var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(34, 0, 136); - - // act - bgra.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_ToRgba32() - { - // arrange - var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(34, 0, 136, 0); - - // act - bgra.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_ToBgr24() - { - // arrange - var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(34, 0, 136); - - // act - bgra.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_ToBgra32() - { - // arrange - var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(34, 0, 136, 0); - - // act - bgra.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_ToArgb32() - { - // arrange - var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(34, 0, 136, 0); - - // act - bgra.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_PackFromRgba32_ToRgba32() - { - // arrange - var bgra = default(Bgra4444); - var actual = default(Rgba32); - var expected = new Rgba32(34, 0, 136, 0); - - // act - bgra.PackFromRgba32(expected); - bgra.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_PackFromBgra32_ToBgra32() - { - // arrange - var bgra = default(Bgra4444); - var actual = default(Bgra32); - var expected = new Bgra32(34, 0, 136, 0); - - // act - bgra.PackFromBgra32(expected); - bgra.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_PackFromArgb32_ToArgb32() - { - // arrange - var bgra = default(Bgra4444); - var actual = default(Argb32); - var expected = new Argb32(34, 0, 136, 0); - - // act - bgra.PackFromArgb32(expected); - bgra.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Bgra4444); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra4444_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Bgra4444); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Bgra4444_ToRgb24() + //{ + // // arrange + // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(34, 0, 136); + + // // act + // bgra.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_ToRgba32() + //{ + // // arrange + // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(34, 0, 136, 0); + + // // act + // bgra.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_ToBgr24() + //{ + // // arrange + // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(34, 0, 136); + + // // act + // bgra.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_ToBgra32() + //{ + // // arrange + // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgra32); + // var expected = new Bgra32(34, 0, 136, 0); + + // // act + // bgra.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_ToArgb32() + //{ + // // arrange + // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(34, 0, 136, 0); + + // // act + // bgra.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var bgra = default(Bgra4444); + // var actual = default(Rgba32); + // var expected = new Rgba32(34, 0, 136, 0); + + // // act + // bgra.PackFromRgba32(expected); + // bgra.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var bgra = default(Bgra4444); + // var actual = default(Bgra32); + // var expected = new Bgra32(34, 0, 136, 0); + + // // act + // bgra.PackFromBgra32(expected); + // bgra.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var bgra = default(Bgra4444); + // var actual = default(Argb32); + // var expected = new Argb32(34, 0, 136, 0); + + // // act + // bgra.PackFromArgb32(expected); + // bgra.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Bgra4444); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra4444_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Bgra4444); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs index b6a078031..3a0aec320 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs @@ -70,159 +70,159 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Bgra5551(Vector4.One * 1234.0f).ToVector4()); } - [Fact] - public void Bgra5551_ToRgb24() - { - // arrange - var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(24, 0, 131); - - // act - bgra.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_Rgba32() - { - // arrange - var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(24, 0, 131, 0); - - // act - bgra.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_ToBgr24() - { - // arrange - var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(24, 0, 131); - - // act - bgra.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_Bgra32() - { - // arrange - var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(24, 0, 131, 0); - - // act - bgra.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_ToArgb32() - { - // arrange - var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(24, 0, 131, 0); - - // act - bgra.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_PackFromRgba32_ToRgba32() - { - // arrange - var bgra = default(Bgra5551); - var expected = new Rgba32(24, 0, 131, 0); - var actual = default(Rgba32); - - // act - bgra.PackFromRgba32(expected); - bgra.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_PackFromBgra32_ToBgra32() - { - // arrange - var bgra = default(Bgra5551); - var expected = new Bgra32(24, 0, 131, 0); - var actual = default(Bgra32); - - // act - bgra.PackFromBgra32(expected); - bgra.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_PackFromArgb32_ToArgb32() - { - // arrange - var bgra = default(Bgra5551); - var expected = new Argb32(24, 0, 131, 0); - var actual = default(Argb32); - - // act - bgra.PackFromArgb32(expected); - bgra.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Bgra5551); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Bgra5551_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Bgra5551); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Bgra5551_ToRgb24() + //{ + // // arrange + // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(24, 0, 131); + + // // act + // bgra.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_Rgba32() + //{ + // // arrange + // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(24, 0, 131, 0); + + // // act + // bgra.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_ToBgr24() + //{ + // // arrange + // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(24, 0, 131); + + // // act + // bgra.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_Bgra32() + //{ + // // arrange + // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgra32); + // var expected = new Bgra32(24, 0, 131, 0); + + // // act + // bgra.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_ToArgb32() + //{ + // // arrange + // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(24, 0, 131, 0); + + // // act + // bgra.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var bgra = default(Bgra5551); + // var expected = new Rgba32(24, 0, 131, 0); + // var actual = default(Rgba32); + + // // act + // bgra.PackFromRgba32(expected); + // bgra.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var bgra = default(Bgra5551); + // var expected = new Bgra32(24, 0, 131, 0); + // var actual = default(Bgra32); + + // // act + // bgra.PackFromBgra32(expected); + // bgra.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var bgra = default(Bgra5551); + // var expected = new Argb32(24, 0, 131, 0); + // var actual = default(Argb32); + + // // act + // bgra.PackFromArgb32(expected); + // bgra.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Bgra5551); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Bgra5551_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Bgra5551); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs index 28555a7df..d1e8cceaa 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs @@ -68,159 +68,159 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One * 255, new Byte4(Vector4.One * 1234.0f).ToVector4()); } - [Fact] - public void Byte4_ToRgb24() - { - // arrange - var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(128, 0, 0); - - // act - byte4.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_Rgba32() - { - // arrange - var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(128, 0, 0, 0); - - // act - byte4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_ToBgr24() - { - // arrange - var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(128, 0, 0); - - // act - byte4.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_Bgra32() - { - // arrange - var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(128, 0, 0, 0); - - // act - byte4.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_Argb32() - { - // arrange - var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(128, 0, 0, 0); - - // act - byte4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_PackFromRgba32_ToRgba32() - { - // arrange - var byte4 = default(Byte4); - var actual = default(Rgba32); - var expected = new Rgba32(20, 38, 0, 255); - - // act - byte4.PackFromRgba32(expected); - byte4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_PackFromBgra32_ToBgra32() - { - // arrange - var byte4 = default(Byte4); - var actual = default(Bgra32); - var expected = new Bgra32(20, 38, 0, 255); - - // act - byte4.PackFromBgra32(expected); - byte4.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_PackFromArgb32_ToArgb32() - { - // arrange - var byte4 = default(Byte4); - var actual = default(Argb32); - var expected = new Argb32(20, 38, 0, 255); - - // act - byte4.PackFromArgb32(expected); - byte4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Byte4); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Byte4_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Byte4); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Byte4_ToRgb24() + //{ + // // arrange + // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(128, 0, 0); + + // // act + // byte4.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_Rgba32() + //{ + // // arrange + // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(128, 0, 0, 0); + + // // act + // byte4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_ToBgr24() + //{ + // // arrange + // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(128, 0, 0); + + // // act + // byte4.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_Bgra32() + //{ + // // arrange + // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); + // var actual = default(Bgra32); + // var expected = new Bgra32(128, 0, 0, 0); + + // // act + // byte4.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_Argb32() + //{ + // // arrange + // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(128, 0, 0, 0); + + // // act + // byte4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var byte4 = default(Byte4); + // var actual = default(Rgba32); + // var expected = new Rgba32(20, 38, 0, 255); + + // // act + // byte4.PackFromRgba32(expected); + // byte4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var byte4 = default(Byte4); + // var actual = default(Bgra32); + // var expected = new Bgra32(20, 38, 0, 255); + + // // act + // byte4.PackFromBgra32(expected); + // byte4.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var byte4 = default(Byte4); + // var actual = default(Argb32); + // var expected = new Argb32(20, 38, 0, 255); + + // // act + // byte4.PackFromArgb32(expected); + // byte4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Byte4); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Byte4_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Byte4); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/ColorConstructorTests.cs b/tests/ImageSharp.Tests/PixelFormats/ColorConstructorTests.cs deleted file mode 100644 index b0d5929f4..000000000 --- a/tests/ImageSharp.Tests/PixelFormats/ColorConstructorTests.cs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Collections.Generic; -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.Colors -{ - public class ColorConstructorTests - { - public static IEnumerable Vector4Data - { - get - { - Vector4[] vector4Values = new Vector4[] - { - Vector4.Zero, - Vector4.One, - Vector4.UnitX, - Vector4.UnitY, - Vector4.UnitZ, - Vector4.UnitW, - }; - - foreach (Vector4 vector4 in vector4Values) - { - // using float array to work around a bug in xunit corruptint the state of any Vector4 passed as MemberData - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { new Argb32(vector4), vector4Components }; - yield return new object[] { new Bgra4444(vector4), vector4Components }; - yield return new object[] { new Bgra5551(vector4), vector4Components }; - yield return new object[] { new Byte4(vector4), vector4Components }; - yield return new object[] { new HalfVector4(vector4), vector4Components }; - yield return new object[] { new NormalizedByte4(vector4), vector4Components }; - yield return new object[] { new NormalizedShort4(vector4), vector4Components }; - yield return new object[] { new Rgba1010102(vector4), vector4Components }; - yield return new object[] { new Rgba64(vector4), vector4Components }; - yield return new object[] { new Short4(vector4), vector4Components }; - } - } - } - - public static IEnumerable Vector3Data - { - get - { - Dictionary vector3Values = new Dictionary() - { - { Vector3.One, Vector4.One }, - { Vector3.Zero, new Vector4(0, 0, 0, 1) }, - { Vector3.UnitX, new Vector4(1, 0, 0, 1) }, - { Vector3.UnitY, new Vector4(0, 1, 0, 1) }, - { Vector3.UnitZ, new Vector4(0, 0, 1, 1) }, - }; - - foreach (Vector3 vector3 in vector3Values.Keys) - { - Vector4 vector4 = vector3Values[vector3]; - // using float array to work around a bug in xunit corruptint the state of any Vector4 passed as MemberData - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { new Argb32(vector3), vector4Components }; - yield return new object[] { new Bgr565(vector3), vector4Components }; - } - } - } - - public static IEnumerable Float4Data - { - get - { - Vector4[] vector4Values = new Vector4[] - { - Vector4.Zero, - Vector4.One, - Vector4.UnitX, - Vector4.UnitY, - Vector4.UnitZ, - Vector4.UnitW, - }; - - foreach (Vector4 vector4 in vector4Values) - { - // using float array to work around a bug in xunit corruptint the state of any Vector4 passed as MemberData - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { new Argb32(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Bgra4444(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Bgra5551(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Byte4(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new HalfVector4(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new NormalizedByte4(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new NormalizedShort4(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Rgba1010102(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Rgba64(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - yield return new object[] { new Short4(vector4.X, vector4.Y, vector4.Z, vector4.W), vector4Components }; - } - } - } - - public static IEnumerable Float3Data - { - get - { - Dictionary vector3Values = new Dictionary() - { - { Vector3.One, Vector4.One }, - { Vector3.Zero, new Vector4(0, 0, 0, 1) }, - { Vector3.UnitX, new Vector4(1, 0, 0, 1) }, - { Vector3.UnitY, new Vector4(0, 1, 0, 1) }, - { Vector3.UnitZ, new Vector4(0, 0, 1, 1) }, - }; - - foreach (Vector3 vector3 in vector3Values.Keys) - { - Vector4 vector4 = vector3Values[vector3]; - // using float array to work around a bug in xunit corruptint the state of any Vector4 passed as MemberData - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { new Argb32(vector3.X, vector3.Y, vector3.Z), vector4Components }; - yield return new object[] { new Bgr565(vector3.X, vector3.Y, vector3.Z), vector4Components }; - } - } - } - - [Theory] - [MemberData(nameof(Vector4Data))] - [MemberData(nameof(Vector3Data))] - [MemberData(nameof(Float4Data))] - [MemberData(nameof(Float3Data))] - public void ConstructorToVector4(IPixel packedVector, float[] expectedVector4Components) - { - // Arrange - int precision = 2; - // using float array to work around a bug in xunit corruptint the state of any Vector4 passed as MemberData - Vector4 expectedVector4 = new Vector4(expectedVector4Components[0], expectedVector4Components[1], expectedVector4Components[2], expectedVector4Components[3]); - - // Act - Vector4 vector4 = packedVector.ToVector4(); - - // Assert - Assert.Equal(expectedVector4.X, vector4.X, precision); - Assert.Equal(expectedVector4.Y, vector4.Y, precision); - Assert.Equal(expectedVector4.Z, vector4.Z, precision); - Assert.Equal(expectedVector4.W, vector4.W, precision); - } - } -} diff --git a/tests/ImageSharp.Tests/PixelFormats/ColorEqualityTests.cs b/tests/ImageSharp.Tests/PixelFormats/ColorEqualityTests.cs deleted file mode 100644 index d3815f2eb..000000000 --- a/tests/ImageSharp.Tests/PixelFormats/ColorEqualityTests.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.Colors -{ - /// - /// Test implementations of IEquatable - /// - public class ColorEqualityTests - { - public static readonly TheoryData EqualityData = - new TheoryData() - { - { new Alpha8(.5F), new Alpha8(.5F), typeof(Alpha8) }, - { new Argb32(Vector4.One), new Argb32(Vector4.One), typeof(Argb32) }, - { new Bgr565(Vector3.One), new Bgr565(Vector3.One), typeof(Bgr565) }, - { new Bgra4444(Vector4.One), new Bgra4444(Vector4.One), typeof(Bgra4444) }, - { new Bgra5551(Vector4.One), new Bgra5551(Vector4.One), typeof(Bgra5551) }, - { new Byte4(Vector4.One * 255), new Byte4(Vector4.One * 255), typeof(Byte4) }, - { new HalfSingle(-1F), new HalfSingle(-1F), typeof(HalfSingle) }, - { new HalfVector2(0.1f, -0.3f), new HalfVector2(0.1f, -0.3f), typeof(HalfVector2) }, - { new HalfVector4(Vector4.One), new HalfVector4(Vector4.One), typeof(HalfVector4) }, - { new NormalizedByte2(-Vector2.One), new NormalizedByte2(-Vector2.One), typeof(NormalizedByte2) }, - { new NormalizedByte4(Vector4.One), new NormalizedByte4(Vector4.One), typeof(NormalizedByte4) }, - { new NormalizedShort2(Vector2.One), new NormalizedShort2(Vector2.One), typeof(NormalizedShort2) }, - { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.One), typeof(NormalizedShort4) }, - { new Rg32(Vector2.One), new Rg32(Vector2.One), typeof(Rg32) }, - { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.One), typeof(Rgba1010102) }, - { new Rgba32(Vector4.One), new Rgba32(Vector4.One), typeof(Rgba32) }, - { new Rgba64(Vector4.One), new Rgba64(Vector4.One), typeof(Rgba64) }, - { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.One * 0x7FFF), typeof(Short2) }, - { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF), typeof(Short4) }, - }; - - public static readonly TheoryData NotEqualityDataNulls = - new TheoryData() - { - // Valid object against null - { new Alpha8(.5F), null, typeof(Alpha8) }, - { new Argb32(Vector4.One), null, typeof(Argb32) }, - { new Bgr565(Vector3.One), null, typeof(Bgr565) }, - { new Bgra4444(Vector4.One), null, typeof(Bgra4444) }, - { new Bgra5551(Vector4.One), null, typeof(Bgra5551) }, - { new Byte4(Vector4.One * 255), null, typeof(Byte4) }, - { new HalfSingle(-1F), null, typeof(HalfSingle) }, - { new HalfVector2(0.1f, -0.3f), null, typeof(HalfVector2) }, - { new HalfVector4(Vector4.One), null, typeof(HalfVector4) }, - { new NormalizedByte2(-Vector2.One), null, typeof(NormalizedByte2) }, - { new NormalizedByte4(Vector4.One), null, typeof(NormalizedByte4) }, - { new NormalizedShort2(Vector2.One), null, typeof(NormalizedShort2) }, - { new NormalizedShort4(Vector4.One), null, typeof(NormalizedShort4) }, - { new Rg32(Vector2.One), null, typeof(Rg32) }, - { new Rgba1010102(Vector4.One), null, typeof(Rgba1010102) }, - { new Rgba64(Vector4.One), null, typeof(Rgba64) }, - { new Short2(Vector2.One * 0x7FFF), null, typeof(Short2) }, - { new Short4(Vector4.One * 0x7FFF), null, typeof(Short4) }, - }; - - public static readonly TheoryData NotEqualityDataDifferentObjects = - new TheoryData() - { - // Valid objects of different types but not equal - { new Alpha8(.5F), new Argb32(Vector4.Zero), null }, - { new HalfSingle(-1F), new NormalizedShort2(Vector2.Zero), null }, - { new Rgba1010102(Vector4.One), new Bgra5551(Vector4.Zero), null }, - }; - - public static readonly TheoryData NotEqualityData = - new TheoryData() - { - // Valid objects of the same type but not equal - { new Alpha8(.5F), new Alpha8(.8F), typeof(Alpha8) }, - { new Argb32(Vector4.One), new Argb32(Vector4.Zero), typeof(Argb32) }, - { new Bgr565(Vector3.One), new Bgr565(Vector3.Zero), typeof(Bgr565) }, - { new Bgra4444(Vector4.One), new Bgra4444(Vector4.Zero), typeof(Bgra4444) }, - { new Bgra5551(Vector4.One), new Bgra5551(Vector4.Zero), typeof(Bgra5551) }, - { new Byte4(Vector4.One * 255), new Byte4(Vector4.Zero), typeof(Byte4) }, - { new HalfSingle(-1F), new HalfSingle(1F), typeof(HalfSingle) }, - { new HalfVector2(0.1f, -0.3f), new HalfVector2(0.1f, 0.3f), typeof(HalfVector2) }, - { new HalfVector4(Vector4.One), new HalfVector4(Vector4.Zero), typeof(HalfVector4) }, - { new NormalizedByte2(-Vector2.One), new NormalizedByte2(-Vector2.Zero), typeof(NormalizedByte2) }, - { new NormalizedByte4(Vector4.One), new NormalizedByte4(Vector4.Zero), typeof(NormalizedByte4) }, - { new NormalizedShort2(Vector2.One), new NormalizedShort2(Vector2.Zero), typeof(NormalizedShort2) }, - { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.Zero), typeof(NormalizedShort4) }, - { new Rg32(Vector2.One), new Rg32(Vector2.Zero), typeof(Rg32) }, - { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.Zero), typeof(Rgba1010102) }, - { new Rgba32(Vector4.One), new Rgba32(Vector4.Zero), typeof(Rgba32) }, - { new Rgba64(Vector4.One), new Rgba64(Vector4.Zero), typeof(Rgba64) }, - { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.Zero), typeof(Short2) }, - { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero), typeof(Short4) }, - }; - - [Theory] - [MemberData(nameof(EqualityData))] - public void Equality(object first, object second, Type type) - { - // Act - bool equal = first.Equals(second); - - // Assert - Assert.True(equal); - } - - [Theory] - [MemberData(nameof(NotEqualityDataNulls))] - [MemberData(nameof(NotEqualityDataDifferentObjects))] - [MemberData(nameof(NotEqualityData))] - public void NotEquality(object first, object second, Type type) - { - // Act - bool equal = first.Equals(second); - - // Assert - Assert.False(equal); - } - - [Theory] - [MemberData(nameof(EqualityData))] - public void HashCodeEqual(object first, object second, Type type) - { - // Act - bool equal = first.GetHashCode() == second.GetHashCode(); - - // Assert - Assert.True(equal); - } - - [Theory] - [MemberData(nameof(NotEqualityDataDifferentObjects))] - public void HashCodeNotEqual(object first, object second, Type type) - { - // Act - bool equal = first.GetHashCode() == second.GetHashCode(); - - // Assert - Assert.False(equal); - } - - [Theory] - [MemberData(nameof(EqualityData))] - public void EqualityObject(object first, object second, Type type) - { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) - dynamic firstObject = Convert.ChangeType(first, type); - dynamic secondObject = Convert.ChangeType(second, type); - - // Act - dynamic equal = firstObject.Equals(secondObject); - - // Assert - Assert.True(equal); - } - - [Theory] - [MemberData(nameof(NotEqualityData))] - public void NotEqualityObject(object first, object second, Type type) - { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) - dynamic firstObject = Convert.ChangeType(first, type); - dynamic secondObject = Convert.ChangeType(second, type); - - // Act - dynamic equal = firstObject.Equals(secondObject); - - // Assert - Assert.False(equal); - } - - [Theory] - [MemberData(nameof(EqualityData))] - public void EqualityOperator(object first, object second, Type type) - { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) - dynamic firstObject = Convert.ChangeType(first, type); - dynamic secondObject = Convert.ChangeType(second, type); - - // Act - dynamic equal = firstObject == secondObject; - - // Assert - Assert.True(equal); - } - - [Theory] - [MemberData(nameof(NotEqualityData))] - public void NotEqualityOperator(object first, object second, Type type) - { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) - dynamic firstObject = Convert.ChangeType(first, type); - dynamic secondObject = Convert.ChangeType(second, type); - - // Act - dynamic notEqual = firstObject != secondObject; - - // Assert - Assert.True(notEqual); - } - } -} diff --git a/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs b/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs deleted file mode 100644 index c9a1c8fe7..000000000 --- a/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Collections.Generic; -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.Colors -{ - public class ColorPackingTests - { - public static IEnumerable Vector4PackData - { - get - { - Vector4[] vector4Values = new Vector4[] - { - Vector4.Zero, - Vector4.One, - Vector4.UnitX, - Vector4.UnitY, - Vector4.UnitZ, - Vector4.UnitW, - }; - - foreach (Vector4 vector4 in vector4Values) - { - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { default(Argb32), vector4Components }; - yield return new object[] { default(Bgra4444), vector4Components }; - yield return new object[] { default(Bgra5551), vector4Components }; - yield return new object[] { default(Byte4), vector4Components }; - yield return new object[] { default(HalfVector4), vector4Components }; - yield return new object[] { default(NormalizedByte4), vector4Components }; - yield return new object[] { default(NormalizedShort4), vector4Components }; - yield return new object[] { default(Rgba1010102), vector4Components }; - yield return new object[] { default(Rgba64), vector4Components }; - yield return new object[] { default(Short4), vector4Components }; - } - } - } - - public static IEnumerable Vector3PackData - { - get - { - Vector4[] vector4Values = new Vector4[] - { - Vector4.One, - new Vector4(0, 0, 0, 1), - new Vector4(1, 0, 0, 1), - new Vector4(0, 1, 0, 1), - new Vector4(0, 0, 1, 1), - }; - - foreach (Vector4 vector4 in vector4Values) - { - float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - - yield return new object[] { default(Argb32), vector4Components }; - yield return new object[] { new Bgr565(), vector4Components }; - } - } - } - - [Theory] - [MemberData(nameof(Vector4PackData))] - [MemberData(nameof(Vector3PackData))] - public void FromVector4ToVector4(IPixel packedVector, float[] vector4ComponentsToPack) - { - // Arrange - int precision = 2; - Vector4 vector4ToPack = new Vector4(vector4ComponentsToPack[0], vector4ComponentsToPack[1], vector4ComponentsToPack[2], vector4ComponentsToPack[3]); - packedVector.PackFromVector4(vector4ToPack); - - // Act - Vector4 vector4 = packedVector.ToVector4(); - - // Assert - Assert.Equal(vector4ToPack.X, vector4.X, precision); - Assert.Equal(vector4ToPack.Y, vector4.Y, precision); - Assert.Equal(vector4ToPack.Z, vector4.Z, precision); - Assert.Equal(vector4ToPack.W, vector4.W, precision); - } - } -} diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs index 2525ee379..166fb230a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -19,193 +19,193 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(input, new Gray16(input).PackedValue); } - [Theory] - [InlineData(0)] - [InlineData(65535)] - [InlineData(32767)] - public void Gray16_ToVector4(ushort input) - { - // arrange - var gray = new Gray16(input); - - // act - var actual = gray.ToVector4(); - - // assert - Assert.Equal(input, actual.X); - Assert.Equal(input, actual.Y); - Assert.Equal(input, actual.Z); - Assert.Equal(1, actual.W); - } - - [Theory] - [InlineData(0)] - [InlineData(65535)] - [InlineData(32767)] - public void Gray16_ToScaledVector4(ushort input) - { - // arrange - var gray = new Gray16(input); - - // act - var actual = gray.ToScaledVector4(); - - // assert - float scaledInput = input / 65535f; - Assert.Equal(scaledInput, actual.X); - Assert.Equal(scaledInput, actual.Y); - Assert.Equal(scaledInput, actual.Z); - Assert.Equal(1, actual.W); - } - - [Fact] - public void Gray16_PackFromScaledVector4() - { - // arrange - Gray16 gray = default; - int expected = 32767; - Vector4 scaled = new Gray16((ushort)expected).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - ushort actual = gray.PackedValue; - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToRgb24() - { - // arrange - Rgb24 actual = default; - Gray16 gray = default; - var expected = new Rgb24(128, 128, 128); - Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToRgba32() - { - // arrange - Rgba32 actual = default; - Gray16 gray = default; - var expected = new Rgba32(128, 128, 128, 255); - Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToBgr24() - { - // arrange - Bgr24 actual = default; - Gray16 gray = default; - var expected = new Bgr24(128, 128, 128); - Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToBgra32() - { - // arrange - Bgra32 actual = default; - Gray16 gray = default; - var expected = new Bgra32(128,128,128); - Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToArgb32() - { - // arrange - Gray16 gray = default; - Argb32 actual = default; - var expected = new Argb32(128, 128, 128); - Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromScaledVector4_ToRgba64() - { - // arrange - Gray16 gray = default; - Rgba64 actual = default; - var expected = new Rgba64(65535, 65535, 65535, 65535); - Vector4 scaled = new Gray16(65535).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromRgb48_ToRgb48() - { - // arrange - var gray = default(Gray16); - var actual = default(Rgb48); - var expected = new Rgb48(0, 0, 0); - - // act - gray.PackFromRgb48(expected); - gray.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray16_PackFromRgba64_ToRgba64() - { - // arrange - var gray = default(Gray16); - var actual = default(Rgba64); - var expected = new Rgba64(0, 0, 0, 65535); - - // act - gray.PackFromRgba64(expected); - gray.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Theory] + //[InlineData(0)] + //[InlineData(65535)] + //[InlineData(32767)] + //public void Gray16_ToVector4(ushort input) + //{ + // // arrange + // var gray = new Gray16(input); + + // // act + // var actual = gray.ToVector4(); + + // // assert + // Assert.Equal(input, actual.X); + // Assert.Equal(input, actual.Y); + // Assert.Equal(input, actual.Z); + // Assert.Equal(1, actual.W); + //} + + //[Theory] + //[InlineData(0)] + //[InlineData(65535)] + //[InlineData(32767)] + //public void Gray16_ToScaledVector4(ushort input) + //{ + // // arrange + // var gray = new Gray16(input); + + // // act + // var actual = gray.ToScaledVector4(); + + // // assert + // float scaledInput = input / 65535f; + // Assert.Equal(scaledInput, actual.X); + // Assert.Equal(scaledInput, actual.Y); + // Assert.Equal(scaledInput, actual.Z); + // Assert.Equal(1, actual.W); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4() + //{ + // // arrange + // Gray16 gray = default; + // int expected = 32767; + // Vector4 scaled = new Gray16((ushort)expected).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // ushort actual = gray.PackedValue; + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToRgb24() + //{ + // // arrange + // Rgb24 actual = default; + // Gray16 gray = default; + // var expected = new Rgb24(128, 128, 128); + // Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToRgba32() + //{ + // // arrange + // Rgba32 actual = default; + // Gray16 gray = default; + // var expected = new Rgba32(128, 128, 128, 255); + // Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToBgr24() + //{ + // // arrange + // Bgr24 actual = default; + // Gray16 gray = default; + // var expected = new Bgr24(128, 128, 128); + // Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToBgra32() + //{ + // // arrange + // Bgra32 actual = default; + // Gray16 gray = default; + // var expected = new Bgra32(128,128,128); + // Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToArgb32() + //{ + // // arrange + // Gray16 gray = default; + // Argb32 actual = default; + // var expected = new Argb32(128, 128, 128); + // Vector4 scaled = new Gray16(32768).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromScaledVector4_ToRgba64() + //{ + // // arrange + // Gray16 gray = default; + // Rgba64 actual = default; + // var expected = new Rgba64(65535, 65535, 65535, 65535); + // Vector4 scaled = new Gray16(65535).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var gray = default(Gray16); + // var actual = default(Rgb48); + // var expected = new Rgb48(0, 0, 0); + + // // act + // gray.PackFromRgb48(expected); + // gray.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray16_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var gray = default(Gray16); + // var actual = default(Rgba64); + // var expected = new Rgba64(0, 0, 0, 65535); + + // // act + // gray.PackFromRgba64(expected); + // gray.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index 64ad0bff6..ae114a0e2 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -19,24 +19,24 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(input, new Gray8(input).PackedValue); } - [Theory] - [InlineData(0)] - [InlineData(255)] - [InlineData(30)] - public void Gray8_ToVector4(byte input) - { - // arrange - var gray = new Gray8(input); - - // act - var actual = gray.ToVector4(); - - // assert - Assert.Equal(input, actual.X); - Assert.Equal(input, actual.Y); - Assert.Equal(input, actual.Z); - Assert.Equal(1, actual.W); - } + //[Theory] + //[InlineData(0, 0)] + //[InlineData(255, 1)] + //[InlineData(30)] + //public void Gray8_ToVector4(byte input) + //{ + // // arrange + // var gray = new Gray8(input); + + // // act + // var actual = gray.ToVector4(); + + // // assert + // Assert.Equal(input, actual.X); + // Assert.Equal(input, actual.Y); + // Assert.Equal(input, actual.Z); + // Assert.Equal(1, actual.W); + //} [Theory] [InlineData(0)] @@ -74,138 +74,138 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void Gray8_PackFromScaledVector4_ToRgb24() - { - // arrange - Rgb24 actual = default; - Gray8 gray = default; - var expected = new Rgb24(128, 128, 128); - Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromScaledVector4_ToRgba32() - { - // arrange - Rgba32 actual = default; - Gray8 gray = default; - var expected = new Rgba32(128, 128, 128, 255); - Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromScaledVector4_ToBgr24() - { - // arrange - Bgr24 actual = default; - Gray8 gray = default; - var expected = new Bgr24(128, 128, 128); - Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromScaledVector4_ToBgra32() - { - // arrange - Bgra32 actual = default; - Gray8 gray = default; - var expected = new Bgra32(128,128,128); - Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromScaledVector4_ToArgb32() - { - // arrange - Gray8 gray = default; - Argb32 actual = default; - var expected = new Argb32(128, 128, 128); - Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromScaledVector4_ToRgba64() - { - // arrange - Gray8 gray = default; - Rgba64 actual = default; - var expected = new Rgba64(65535, 65535, 65535, 65535); - Vector4 scaled = new Gray8(255).ToScaledVector4(); - - // act - gray.PackFromScaledVector4(scaled); - gray.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromRgb48_ToRgb48() - { - // arrange - var gray = default(Gray8); - var actual = default(Rgb48); - var expected = new Rgb48(0, 0, 0); - - // act - gray.PackFromRgb48(expected); - gray.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Gray8_PackFromRgba64_ToRgba64() - { - // arrange - var gray = default(Gray8); - var actual = default(Rgba64); - var expected = new Rgba64(0, 0, 0, 65535); - - // act - gray.PackFromRgba64(expected); - gray.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Gray8_PackFromScaledVector4_ToRgb24() + //{ + // // arrange + // Rgb24 actual = default; + // Gray8 gray = default; + // var expected = new Rgb24(128, 128, 128); + // Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromScaledVector4_ToRgba32() + //{ + // // arrange + // Rgba32 actual = default; + // Gray8 gray = default; + // var expected = new Rgba32(128, 128, 128, 255); + // Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromScaledVector4_ToBgr24() + //{ + // // arrange + // Bgr24 actual = default; + // Gray8 gray = default; + // var expected = new Bgr24(128, 128, 128); + // Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromScaledVector4_ToBgra32() + //{ + // // arrange + // Bgra32 actual = default; + // Gray8 gray = default; + // var expected = new Bgra32(128,128,128); + // Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromScaledVector4_ToArgb32() + //{ + // // arrange + // Gray8 gray = default; + // Argb32 actual = default; + // var expected = new Argb32(128, 128, 128); + // Vector4 scaled = new Gray8(128).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromScaledVector4_ToRgba64() + //{ + // // arrange + // Gray8 gray = default; + // Rgba64 actual = default; + // var expected = new Rgba64(65535, 65535, 65535, 65535); + // Vector4 scaled = new Gray8(255).ToScaledVector4(); + + // // act + // gray.PackFromScaledVector4(scaled); + // gray.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var gray = default(Gray8); + // var actual = default(Rgb48); + // var expected = new Rgb48(0, 0, 0); + + // // act + // gray.PackFromRgb48(expected); + // gray.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Gray8_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var gray = default(Gray8); + // var actual = default(Rgba64); + // var expected = new Rgba64(0, 0, 0, 65535); + + // // act + // gray.PackFromRgba64(expected); + // gray.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs index 3376645f3..1c3905854 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs @@ -67,111 +67,111 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void HalfSingle_ToRgb24() - { - // arrange - var halfVector = new HalfSingle(.5F); - var actual = default(Rgb24); - var expected = new Rgb24(128, 0, 0); - - // act - halfVector.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_Rgba32() - { - // arrange - var halfVector = new HalfSingle(.5F); - var actual = default(Rgba32); - var expected = new Rgba32(128, 0, 0, 255); - - // act - halfVector.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_ToBgr24() - { - // arrange - var halfVector = new HalfSingle(.5F); - var actual = default(Bgr24); - var expected = new Bgr24(128, 0, 0); - - // act - halfVector.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_Bgra32() - { - // arrange - var halfVector = new HalfSingle(.5F); - var actual = default(Bgra32); - var expected = new Bgra32(128, 0, 0, 255); - - // act - halfVector.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_Argb32() - { - // arrange - var halfVector = new HalfSingle(.5F); - var actual = default(Argb32); - var expected = new Argb32(128, 0, 0, 255); - - // act - halfVector.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(HalfSingle); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfSingle_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(HalfSingle); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void HalfSingle_ToRgb24() + //{ + // // arrange + // var halfVector = new HalfSingle(.5F); + // var actual = default(Rgb24); + // var expected = new Rgb24(128, 0, 0); + + // // act + // halfVector.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_Rgba32() + //{ + // // arrange + // var halfVector = new HalfSingle(.5F); + // var actual = default(Rgba32); + // var expected = new Rgba32(128, 0, 0, 255); + + // // act + // halfVector.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_ToBgr24() + //{ + // // arrange + // var halfVector = new HalfSingle(.5F); + // var actual = default(Bgr24); + // var expected = new Bgr24(128, 0, 0); + + // // act + // halfVector.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_Bgra32() + //{ + // // arrange + // var halfVector = new HalfSingle(.5F); + // var actual = default(Bgra32); + // var expected = new Bgra32(128, 0, 0, 255); + + // // act + // halfVector.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_Argb32() + //{ + // // arrange + // var halfVector = new HalfSingle(.5F); + // var actual = default(Argb32); + // var expected = new Argb32(128, 0, 0, 255); + + // // act + // halfVector.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(HalfSingle); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfSingle_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(HalfSingle); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs index c2a524f0d..1ceb224e5 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs @@ -72,111 +72,111 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void HalfVector2_ToRgb24() - { - // arrange - var halfVector = new HalfVector2(.5F, .25F); - var actual = default(Rgb24); - var expected = new Rgb24(128, 64, 0); - - // act - halfVector.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_Rgba32() - { - // arrange - var halfVector = new HalfVector2(.5F, .25F); - var actual = default(Rgba32); - var expected = new Rgba32(128, 64, 0, 255); - - // act - halfVector.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_ToBgr24() - { - // arrange - var halfVector = new HalfVector2(.5F, .25F); - var actual = default(Bgr24); - var expected = new Bgr24(128, 64, 0); - - // act - halfVector.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_Bgra32() - { - // arrange - var halfVector = new HalfVector2(.5F, .25F); - var actual = default(Bgra32); - var expected = new Bgra32(128, 64, 0, 255); - - // act - halfVector.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_Argb32() - { - // arrange - var halfVector = new HalfVector2(.5F, .25F); - var actual = default(Argb32); - var expected = new Argb32(128, 64, 0, 255); - - // act - halfVector.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(HalfVector2); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector2_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(HalfVector2); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void HalfVector2_ToRgb24() + //{ + // // arrange + // var halfVector = new HalfVector2(.5F, .25F); + // var actual = default(Rgb24); + // var expected = new Rgb24(128, 64, 0); + + // // act + // halfVector.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_Rgba32() + //{ + // // arrange + // var halfVector = new HalfVector2(.5F, .25F); + // var actual = default(Rgba32); + // var expected = new Rgba32(128, 64, 0, 255); + + // // act + // halfVector.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_ToBgr24() + //{ + // // arrange + // var halfVector = new HalfVector2(.5F, .25F); + // var actual = default(Bgr24); + // var expected = new Bgr24(128, 64, 0); + + // // act + // halfVector.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_Bgra32() + //{ + // // arrange + // var halfVector = new HalfVector2(.5F, .25F); + // var actual = default(Bgra32); + // var expected = new Bgra32(128, 64, 0, 255); + + // // act + // halfVector.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_Argb32() + //{ + // // arrange + // var halfVector = new HalfVector2(.5F, .25F); + // var actual = default(Argb32); + // var expected = new Argb32(128, 64, 0, 255); + + // // act + // halfVector.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(HalfVector2); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector2_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(HalfVector2); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs index 8b28dd827..3ba571850 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs @@ -66,159 +66,159 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void HalfVector4_ToRgb24() - { - // arrange - var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - var actual = default(Rgb24); - var expected = new Rgb24(64, 128, 191); - - // act - halfVector.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_Rgba32() - { - // arrange - var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - var actual = default(Rgba32); - var expected = new Rgba32(64, 128, 191, 255); - - // act - halfVector.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_ToBgr24() - { - // arrange - var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - var actual = default(Bgr24); - var expected = new Bgr24(64, 128, 191); - - // act - halfVector.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_Bgra32() - { - // arrange - var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - var actual = default(Bgra32); - var expected = new Bgra32(64, 128, 191, 255); - - // act - halfVector.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_Argb32() - { - // arrange - var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - var actual = default(Argb32); - var expected = new Argb32(64, 128, 191, 255); - - // act - halfVector.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_PackFromRgba32_ToRgba32() - { - // arrange - var halVector = default(HalfVector4); - var actual = default(Rgba32); - var expected = new Rgba32(64, 128, 191, 255); - - // act - halVector.PackFromRgba32(expected); - halVector.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_PackFromBgra32_ToBgra32() - { - // arrange - var halVector = default(HalfVector4); - var actual = default(Bgra32); - var expected = new Bgra32(64, 128, 191, 255); - - // act - halVector.PackFromBgra32(expected); - halVector.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_PackFromArgb32_ToArgb32() - { - // arrange - var halVector = default(HalfVector4); - var actual = default(Argb32); - var expected = new Argb32(64, 128, 191, 255); - - // act - halVector.PackFromArgb32(expected); - halVector.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(HalfVector4); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void HalfVector4_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(HalfVector4); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void HalfVector4_ToRgb24() + //{ + // // arrange + // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); + // var actual = default(Rgb24); + // var expected = new Rgb24(64, 128, 191); + + // // act + // halfVector.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_Rgba32() + //{ + // // arrange + // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); + // var actual = default(Rgba32); + // var expected = new Rgba32(64, 128, 191, 255); + + // // act + // halfVector.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_ToBgr24() + //{ + // // arrange + // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); + // var actual = default(Bgr24); + // var expected = new Bgr24(64, 128, 191); + + // // act + // halfVector.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_Bgra32() + //{ + // // arrange + // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); + // var actual = default(Bgra32); + // var expected = new Bgra32(64, 128, 191, 255); + + // // act + // halfVector.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_Argb32() + //{ + // // arrange + // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); + // var actual = default(Argb32); + // var expected = new Argb32(64, 128, 191, 255); + + // // act + // halfVector.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var halVector = default(HalfVector4); + // var actual = default(Rgba32); + // var expected = new Rgba32(64, 128, 191, 255); + + // // act + // halVector.PackFromRgba32(expected); + // halVector.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var halVector = default(HalfVector4); + // var actual = default(Bgra32); + // var expected = new Bgra32(64, 128, 191, 255); + + // // act + // halVector.PackFromBgra32(expected); + // halVector.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var halVector = default(HalfVector4); + // var actual = default(Argb32); + // var expected = new Argb32(64, 128, 191, 255); + + // // act + // halVector.PackFromArgb32(expected); + // halVector.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(HalfVector4); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void HalfVector4_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(HalfVector4); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs index 83f22e2aa..3ab36853b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs @@ -67,127 +67,127 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void NormalizedByte2_PackFromRgba32() - { - // arrange - var byte2 = new NormalizedByte2(); - var rgba = new Rgba32(141, 90, 0, 0); - int expected = 0xda0d; - - // act - byte2.PackFromRgba32(rgba); - ushort actual = byte2.PackedValue; - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_ToRgb24() - { - // arrange - var short4 = new NormalizedByte2(0.1f, -0.3f); - var actual = default(Rgb24); - var expected = new Rgb24(141, 90, 0); - - // act - short4.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_ToRgba32() - { - // arrange - var short4 = new NormalizedByte2(0.1f, -0.3f); - var actual = default(Rgba32); - var expected = new Rgba32(141, 90, 0, 255); - - // act - short4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_ToBgr24() - { - // arrange - var short4 = new NormalizedByte2(0.1f, -0.3f); - var actual = default(Bgr24); - var expected = new Bgr24(141, 90, 0); - - // act - short4.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_ToBgra32() - { - // arrange - var short4 = new NormalizedByte2(0.1f, -0.3f); - var actual = default(Bgra32); - var expected = new Bgra32(141, 90, 0, 255); - - // act - short4.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_ToArgb32() - { - // arrange - var short4 = new NormalizedByte2(0.1f, -0.3f); - var actual = default(Argb32); - var expected = new Argb32(141, 90, 0, 255); - - // act - short4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(NormalizedByte2); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte2_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(NormalizedByte2); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void NormalizedByte2_PackFromRgba32() + //{ + // // arrange + // var byte2 = new NormalizedByte2(); + // var rgba = new Rgba32(141, 90, 0, 0); + // int expected = 0xda0d; + + // // act + // byte2.PackFromRgba32(rgba); + // ushort actual = byte2.PackedValue; + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_ToRgb24() + //{ + // // arrange + // var short4 = new NormalizedByte2(0.1f, -0.3f); + // var actual = default(Rgb24); + // var expected = new Rgb24(141, 90, 0); + + // // act + // short4.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_ToRgba32() + //{ + // // arrange + // var short4 = new NormalizedByte2(0.1f, -0.3f); + // var actual = default(Rgba32); + // var expected = new Rgba32(141, 90, 0, 255); + + // // act + // short4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_ToBgr24() + //{ + // // arrange + // var short4 = new NormalizedByte2(0.1f, -0.3f); + // var actual = default(Bgr24); + // var expected = new Bgr24(141, 90, 0); + + // // act + // short4.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_ToBgra32() + //{ + // // arrange + // var short4 = new NormalizedByte2(0.1f, -0.3f); + // var actual = default(Bgra32); + // var expected = new Bgra32(141, 90, 0, 255); + + // // act + // short4.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_ToArgb32() + //{ + // // arrange + // var short4 = new NormalizedByte2(0.1f, -0.3f); + // var actual = default(Argb32); + // var expected = new Argb32(141, 90, 0, 255); + + // // act + // short4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(NormalizedByte2); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte2_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(NormalizedByte2); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs index 16516496f..acac04853 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs @@ -61,144 +61,144 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void NormalizedByte4_ToRgb24() - { - // arrange - var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(141, 90, 192); - - // act - short4.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_ToRgba32() - { - // arrange - var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(141, 90, 192, 39); - - // act - short4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_ToBgr24() - { - // arrange - var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(141, 90, 192); - - // act - short4.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_ToArgb32() - { - // arrange - var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(141, 90, 192, 39); - - // act - short4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_PackFromRgba32_ToRgba32() - { - // arrange - var short4 = default(NormalizedByte4); - var actual = default(Rgba32); - var expected = new Rgba32(9, 115, 202, 127); - - // act - short4.PackFromRgba32(new Rgba32(9, 115, 202, 127)); - short4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_PackFromBgra32_ToRgba32() - { - // arrange - var actual = default(Bgra32); - var short4 = default(NormalizedByte4); - var expected = new Bgra32(9, 115, 202, 127); - - // act - short4.PackFromBgra32(expected); - short4.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_PackFromArgb32_ToRgba32() - { - // arrange - var short4 = default(NormalizedByte4); - var actual = default(Argb32); - var expected = new Argb32(9, 115, 202, 127); - - // act - short4.PackFromArgb32(expected); - short4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(NormalizedByte4); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedByte4_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(NormalizedByte4); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void NormalizedByte4_ToRgb24() + //{ + // // arrange + // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(141, 90, 192); + + // // act + // short4.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_ToRgba32() + //{ + // // arrange + // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(141, 90, 192, 39); + + // // act + // short4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_ToBgr24() + //{ + // // arrange + // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(141, 90, 192); + + // // act + // short4.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_ToArgb32() + //{ + // // arrange + // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(141, 90, 192, 39); + + // // act + // short4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var short4 = default(NormalizedByte4); + // var actual = default(Rgba32); + // var expected = new Rgba32(9, 115, 202, 127); + + // // act + // short4.PackFromRgba32(new Rgba32(9, 115, 202, 127)); + // short4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_PackFromBgra32_ToRgba32() + //{ + // // arrange + // var actual = default(Bgra32); + // var short4 = default(NormalizedByte4); + // var expected = new Bgra32(9, 115, 202, 127); + + // // act + // short4.PackFromBgra32(expected); + // short4.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_PackFromArgb32_ToRgba32() + //{ + // // arrange + // var short4 = default(NormalizedByte4); + // var actual = default(Argb32); + // var expected = new Argb32(9, 115, 202, 127); + + // // act + // short4.PackFromArgb32(expected); + // short4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(NormalizedByte4); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedByte4_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(NormalizedByte4); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs index 2fb7f05ac..e02d513c2 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs @@ -70,128 +70,128 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void NormalizedShort2_PackFromRgba32_ToRgb24() - { - // arrange - var actual = default(Rgb24); - var short2 = new NormalizedShort2(); - var rgba = new Rgba32(141, 90, 0, 0); - var expected = new Rgb24(141, 90, 0); - - // act - short2.PackFromRgba32(rgba); - short2.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_ToRgb24() - { - // arrange - var short2 = new NormalizedShort2(0.1f, -0.3f); - var actual = default(Rgb24); - var expected = new Rgb24(141, 90, 0); - - // act - short2.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_ToRgba32() - { - // arrange - var short2 = new NormalizedShort2(0.1f, -0.3f); - var actual = default(Rgba32); - var expected = new Rgba32(141, 90, 0, 255); - - // act - short2.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_ToBgr24() - { - // arrange - var short2 = new NormalizedShort2(0.1f, -0.3f); - var actual = default(Bgr24); - var expected = new Bgr24(141, 90, 0); - - // act - short2.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_ToBgra32() - { - // arrange - var short2 = new NormalizedShort2(0.1f, -0.3f); - var actual = default(Bgra32); - var expected = new Bgra32(141, 90, 0, 255); - - // act - short2.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_ToArgb32() - { - // arrange - var short2 = new NormalizedShort2(0.1f, -0.3f); - var actual = default(Argb32); - var expected = new Argb32(141, 90, 0, 255); - - // act - short2.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(NormalizedShort2); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort2_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(NormalizedShort2); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void NormalizedShort2_PackFromRgba32_ToRgb24() + //{ + // // arrange + // var actual = default(Rgb24); + // var short2 = new NormalizedShort2(); + // var rgba = new Rgba32(141, 90, 0, 0); + // var expected = new Rgb24(141, 90, 0); + + // // act + // short2.PackFromRgba32(rgba); + // short2.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_ToRgb24() + //{ + // // arrange + // var short2 = new NormalizedShort2(0.1f, -0.3f); + // var actual = default(Rgb24); + // var expected = new Rgb24(141, 90, 0); + + // // act + // short2.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_ToRgba32() + //{ + // // arrange + // var short2 = new NormalizedShort2(0.1f, -0.3f); + // var actual = default(Rgba32); + // var expected = new Rgba32(141, 90, 0, 255); + + // // act + // short2.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_ToBgr24() + //{ + // // arrange + // var short2 = new NormalizedShort2(0.1f, -0.3f); + // var actual = default(Bgr24); + // var expected = new Bgr24(141, 90, 0); + + // // act + // short2.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_ToBgra32() + //{ + // // arrange + // var short2 = new NormalizedShort2(0.1f, -0.3f); + // var actual = default(Bgra32); + // var expected = new Bgra32(141, 90, 0, 255); + + // // act + // short2.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_ToArgb32() + //{ + // // arrange + // var short2 = new NormalizedShort2(0.1f, -0.3f); + // var actual = default(Argb32); + // var expected = new Argb32(141, 90, 0, 255); + + // // act + // short2.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(NormalizedShort2); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort2_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(NormalizedShort2); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs index 7dcdd9c88..25ffbb348 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs @@ -62,144 +62,144 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void NormalizedShort4_ToRgb24() - { - // arrange - var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(141, 90, 192); - - // act - short4.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_ToRgba32() - { - // arrange - var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(141, 90, 192, 39); - - // act - short4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_ToBgr24() - { - // arrange - var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(141, 90, 192); - - // act - short4.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_ToArgb32() - { - // arrange - var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(141, 90, 192, 39); - - // act - short4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_PackFromRgba32_ToRgba32() - { - // arrange - var short4 = default(NormalizedShort4); - var expected = new Rgba32(9, 115, 202, 127); - var actual = default(Rgba32); - - // act - short4.PackFromRgba32(expected); - short4.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_PackFromBgra32_ToRgba32() - { - // arrange - var short4 = default(NormalizedShort4); - var actual = default(Bgra32); - var expected = new Bgra32(9, 115, 202, 127); - - // act - short4.PackFromBgra32(expected); - short4.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_PackFromArgb32_ToRgba32() - { - // arrange - var short4 = default(NormalizedShort4); - var actual = default(Argb32); - var expected = new Argb32(9, 115, 202, 127); - - // act - short4.PackFromArgb32(expected); - short4.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(NormalizedShort4); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NormalizedShort4_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(NormalizedShort4); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void NormalizedShort4_ToRgb24() + //{ + // // arrange + // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(141, 90, 192); + + // // act + // short4.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_ToRgba32() + //{ + // // arrange + // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(141, 90, 192, 39); + + // // act + // short4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_ToBgr24() + //{ + // // arrange + // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(141, 90, 192); + + // // act + // short4.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_ToArgb32() + //{ + // // arrange + // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Argb32); + // var expected = new Argb32(141, 90, 192, 39); + + // // act + // short4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var short4 = default(NormalizedShort4); + // var expected = new Rgba32(9, 115, 202, 127); + // var actual = default(Rgba32); + + // // act + // short4.PackFromRgba32(expected); + // short4.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_PackFromBgra32_ToRgba32() + //{ + // // arrange + // var short4 = default(NormalizedShort4); + // var actual = default(Bgra32); + // var expected = new Bgra32(9, 115, 202, 127); + + // // act + // short4.PackFromBgra32(expected); + // short4.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_PackFromArgb32_ToRgba32() + //{ + // // arrange + // var short4 = default(NormalizedShort4); + // var actual = default(Argb32); + // var expected = new Argb32(9, 115, 202, 127); + + // // act + // short4.PackFromArgb32(expected); + // short4.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(NormalizedShort4); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void NormalizedShort4_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(NormalizedShort4); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 9e41fd94f..92b04f587 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -1,95 +1,89 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; -using Xunit.Abstractions; - -namespace SixLabors.ImageSharp.Tests.PixelFormats -{ - public partial class PixelOperationsTests - { - public class Rgba32 : PixelOperationsTests - { - public Rgba32(ITestOutputHelper output) - : base(output) - { - } - - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - - [Fact] - public void IsSpecialImplementation() - { - Assert.IsType(PixelOperations.Instance); - } - - [Fact] - public void ToVector4SimdAligned() - { - if (!Vector.IsHardwareAccelerated) - { - return; - } - - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) - ); - } - - - // [Fact] // Profiling benchmark - enable manually! -#pragma warning disable xUnit1013 // Public method should be marked as test - public void Benchmark_ToVector4() -#pragma warning restore xUnit1013 // Public method should be marked as test - { - int times = 200000; - int count = 1024; - - using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) - using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) - { - this.Measure( - times, - () => - { - PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); - }); - } - } - } - - public class Argb32 : PixelOperationsTests - { - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public Argb32(ITestOutputHelper output) - : base(output) - { - } - - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - } - - [Theory] - [WithBlankImages(1, 1, PixelTypes.All)] - public void GetGlobalInstance(TestImageProvider dummy) - where TPixel : struct, IPixel - { - Assert.NotNull(PixelOperations.Instance); +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Buffers; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public partial class PixelOperationsTests + { + public class Rgba32 : PixelOperationsTests + { + public Rgba32(ITestOutputHelper output) + : base(output) + { + } + + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Fact] + public void ToVector4SimdAligned() + { + if (!Vector.IsHardwareAccelerated) + { + return; + } + + ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) + ); + } + + + // [Fact] // Profiling benchmark - enable manually! +#pragma warning disable xUnit1013 // Public method should be marked as test + public void Benchmark_ToVector4() +#pragma warning restore xUnit1013 // Public method should be marked as test + { + int times = 200000; + int count = 1024; + + using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) + using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) + { + this.Measure( + times, + () => + { + PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); + }); + } + } } + public class Argb32 : PixelOperationsTests + { + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public Argb32(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + } + + [Theory] + [WithBlankImages(1, 1, PixelTypes.All)] + public void GetGlobalInstance(TestImageProvider dummy) + where TPixel : struct, IPixel => Assert.NotNull(PixelOperations.Instance); + [Fact] public void IsOpaqueColor() { @@ -98,595 +92,593 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Transparent)); Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal,PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - } - } - - public abstract class PixelOperationsTests : MeasureFixture - where TPixel : struct, IPixel - { - protected PixelOperationsTests(ITestOutputHelper output) - : base(output) - { - } - - public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - - private static PixelOperations Operations => PixelOperations.Instance; - - internal static TPixel[] CreateExpectedPixelData(Vector4[] source) - { - var expected = new TPixel[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i].PackFromVector4(source[i]); - } - return expected; - } - - internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source) - { - var expected = new TPixel[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i].PackFromScaledVector4(source[i]); - } - return expected; - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromVector4(int count) - { - Vector4[] source = CreateVector4TestData(count); - TPixel[] expected = CreateExpectedPixelData(source); - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromScaledVector4(int count) - { - Vector4[] source = CreateVector4TestData(count); - TPixel[] expected = CreateScaledExpectedPixelData(source); - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromScaledVector4(s, d.GetSpan(), count) - ); - } - - internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToVector4(); - } - return expected; - } - - internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToScaledVector4(); - } - return expected; - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToVector4(int count) - { - TPixel[] source = CreatePixelTestData(count); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => Operations.ToVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToScaledVector4(int count) - { - TPixel[] source = CreateScaledPixelTestData(count); - Vector4[] expected = CreateExpectedScaledVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => Operations.ToScaledVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgb24Bytes(int count) - { - byte[] source = CreateByteTestData(count * 3); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - - expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgb24Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var rgb = default(Rgb24); - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - source[i].ToRgb24(ref rgb); - expected[i3] = rgb.R; - expected[i3 + 1] = rgb.G; - expected[i3 + 2] = rgb.B; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgba32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgba32Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var rgba = default(Rgba32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToRgba32(ref rgba); - expected[i4] = rgba.R; - expected[i4 + 1] = rgba.G; - expected[i4 + 2] = rgba.B; - expected[i4 + 3] = rgba.A; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgb48Bytes(int count) - { - byte[] source = CreateByteTestData(count * 6); - Span sourceSpan = source.AsSpan(); - var expected = new TPixel[count]; - - var rgba64 = new Rgba64(0, 0, 0, 65535); - for (int i = 0; i < count; i++) - { - int i6 = i * 6; - rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; - expected[i].PackFromRgba64(rgba64); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgb48Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 6]; - Rgb48 rgb = default; - - for (int i = 0; i < count; i++) - { - int i6 = i * 6; - source[i].ToRgb48(ref rgb); - Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); - expected[i6] = rgb48Bytes[0]; - expected[i6 + 1] = rgb48Bytes[1]; - expected[i6 + 2] = rgb48Bytes[2]; - expected[i6 + 3] = rgb48Bytes[3]; - expected[i6 + 4] = rgb48Bytes[4]; - expected[i6 + 5] = rgb48Bytes[5]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgba64Bytes(int count) - { - byte[] source = CreateByteTestData(count * 8); - Span sourceSpan = source.AsSpan(); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i8 = i * 8; - expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgba64Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 8]; - Rgba64 rgba = default; - - for (int i = 0; i < count; i++) - { - int i8 = i * 8; - source[i].ToRgba64(ref rgba); - Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); - expected[i8] = rgba64Bytes[0]; - expected[i8 + 1] = rgba64Bytes[1]; - expected[i8 + 2] = rgba64Bytes[2]; - expected[i8 + 3] = rgba64Bytes[3]; - expected[i8 + 4] = rgba64Bytes[4]; - expected[i8 + 5] = rgba64Bytes[5]; - expected[i8 + 6] = rgba64Bytes[6]; - expected[i8 + 7] = rgba64Bytes[7]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromBgr24Bytes(int count) - { - byte[] source = CreateByteTestData(count * 3); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - - expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToBgr24Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var bgr = default(Bgr24); - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - source[i].ToBgr24(ref bgr); - expected[i3] = bgr.B; - expected[i3 + 1] = bgr.G; - expected[i3 + 2] = bgr.R; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromBgra32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToZyxwBytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var bgra = default(Bgra32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToBgra32(ref bgra); - expected[i4] = bgra.B; - expected[i4 + 1] = bgra.G; - expected[i4 + 2] = bgra.R; - expected[i4 + 3] = bgra.A; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromArgb32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToArgb32Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var argb = default(Argb32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToArgb32(ref argb); - expected[i4] = argb.A; - expected[i4 + 1] = argb.R; - expected[i4 + 2] = argb.G; - expected[i4 + 3] = argb.B; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) - ); - } - - private class TestBuffers : IDisposable - where TSource : struct - where TDest : struct - { - public TSource[] SourceBuffer { get; } - public IMemoryOwner ActualDestBuffer { get; } - public TDest[] ExpectedDestBuffer { get; } - - public TestBuffers(TSource[] source, TDest[] expectedDest) - { - this.SourceBuffer = source; - this.ExpectedDestBuffer = expectedDest; - this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); - } - - public void Dispose() - { - this.ActualDestBuffer.Dispose(); - } - - private const float Tolerance = 0.0001f; - - public void Verify() - { - int count = this.ExpectedDestBuffer.Length; - - if (typeof(TDest) == typeof(Vector4)) - { - - Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); - Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); - - for (int i = 0; i < count; i++) - { - // ReSharper disable PossibleNullReferenceException - Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); - // ReSharper restore PossibleNullReferenceException - } - } - else - { - Span expected = this.ExpectedDestBuffer.AsSpan(); - Span actual = this.ActualDestBuffer.GetSpan(); - for (int i = 0; i < count; i++) - { - Assert.Equal(expected[i], actual[i]); - } - } - } - } - - internal static void TestOperation( - TSource[] source, - TDest[] expected, - Action> action) - where TSource : struct - where TDest : struct - { - using (var buffers = new TestBuffers(source, expected)) - { - action(buffers.SourceBuffer, buffers.ActualDestBuffer); - buffers.Verify(); - } - } - - internal static Vector4[] CreateVector4TestData(int length) - { - var result = new Vector4[length]; - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - result[i] = GetVector(rnd); - } - return result; - } - - internal static TPixel[] CreatePixelTestData(int length) - { - var result = new TPixel[length]; - - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - Vector4 v = GetVector(rnd); - result[i].PackFromVector4(v); - } - - return result; - } - - internal static TPixel[] CreateScaledPixelTestData(int length) - { - var result = new TPixel[length]; - - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - Vector4 v = GetVector(rnd); - result[i].PackFromScaledVector4(v); - } - - return result; - } - - internal static byte[] CreateByteTestData(int length) - { - byte[] result = new byte[length]; - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - result[i] = (byte)rnd.Next(255); - } - return result; - } - - internal static Vector4 GetVector(Random rnd) - { - return new Vector4( - (float)rnd.NextDouble(), - (float)rnd.NextDouble(), - (float)rnd.NextDouble(), - (float)rnd.NextDouble() - ); - } - - [StructLayout(LayoutKind.Sequential)] - private unsafe struct Rgba64Bytes - { - public fixed byte Data[8]; - - public byte this[int idx] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ref byte self = ref Unsafe.As(ref this); - return Unsafe.Add(ref self, idx); - } - } - } - } + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); + } + } + + public abstract class PixelOperationsTests : MeasureFixture + where TPixel : struct, IPixel + { + protected PixelOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + private static PixelOperations Operations => PixelOperations.Instance; + + internal static TPixel[] CreateExpectedPixelData(Vector4[] source) + { + var expected = new TPixel[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i].PackFromVector4(source[i]); + } + return expected; + } + + internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source) + { + var expected = new TPixel[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i].PackFromScaledVector4(source[i]); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromVector4(int count) + { + Vector4[] source = CreateVector4TestData(count); + TPixel[] expected = CreateExpectedPixelData(source); + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromScaledVector4(int count) + { + Vector4[] source = CreateVector4TestData(count); + TPixel[] expected = CreateScaledExpectedPixelData(source); + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromScaledVector4(s, d.GetSpan(), count) + ); + } + + internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToVector4(); + } + return expected; + } + + internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToScaledVector4(); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToVector4(int count) + { + TPixel[] source = CreatePixelTestData(count); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToScaledVector4(int count) + { + TPixel[] source = CreateScaledPixelTestData(count); + Vector4[] expected = CreateExpectedScaledVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => Operations.ToScaledVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgb24Bytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgb24Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + var rgb = default(Rgb24); + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = rgb.R; + expected[i3 + 1] = rgb.G; + expected[i3 + 2] = rgb.B; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgba32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgba32Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var rgba = default(Rgba32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = rgba.R; + expected[i4 + 1] = rgba.G; + expected[i4 + 2] = rgba.B; + expected[i4 + 3] = rgba.A; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgb48Bytes(int count) + { + byte[] source = CreateByteTestData(count * 6); + Span sourceSpan = source.AsSpan(); + var expected = new TPixel[count]; + + var rgba64 = new Rgba64(0, 0, 0, 65535); + for (int i = 0; i < count; i++) + { + int i6 = i * 6; + rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; + expected[i].PackFromRgba64(rgba64); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgb48Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 6]; + Rgb48 rgb = default; + + for (int i = 0; i < count; i++) + { + int i6 = i * 6; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); + expected[i6] = rgb48Bytes[0]; + expected[i6 + 1] = rgb48Bytes[1]; + expected[i6 + 2] = rgb48Bytes[2]; + expected[i6 + 3] = rgb48Bytes[3]; + expected[i6 + 4] = rgb48Bytes[4]; + expected[i6 + 5] = rgb48Bytes[5]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgba64Bytes(int count) + { + byte[] source = CreateByteTestData(count * 8); + Span sourceSpan = source.AsSpan(); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i8 = i * 8; + expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgba64Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 8]; + Rgba64 rgba = default; + + for (int i = 0; i < count; i++) + { + int i8 = i * 8; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); + expected[i8] = rgba64Bytes[0]; + expected[i8 + 1] = rgba64Bytes[1]; + expected[i8 + 2] = rgba64Bytes[2]; + expected[i8 + 3] = rgba64Bytes[3]; + expected[i8 + 4] = rgba64Bytes[4]; + expected[i8 + 5] = rgba64Bytes[5]; + expected[i8 + 6] = rgba64Bytes[6]; + expected[i8 + 7] = rgba64Bytes[7]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromBgr24Bytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToBgr24Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + var bgr = default(Bgr24); + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + bgr.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = bgr.B; + expected[i3 + 1] = bgr.G; + expected[i3 + 2] = bgr.R; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromBgra32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToBgra32Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var bgra = default(Bgra32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + bgra.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = bgra.B; + expected[i4 + 1] = bgra.G; + expected[i4 + 2] = bgra.R; + expected[i4 + 3] = bgra.A; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromArgb32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToArgb32Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var argb = default(Argb32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + argb.PackFromScaledVector4(source[i].ToScaledVector4()); + + expected[i4] = argb.A; + expected[i4 + 1] = argb.R; + expected[i4 + 2] = argb.G; + expected[i4 + 3] = argb.B; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) + ); + } + + private class TestBuffers : IDisposable + where TSource : struct + where TDest : struct + { + public TSource[] SourceBuffer { get; } + public IMemoryOwner ActualDestBuffer { get; } + public TDest[] ExpectedDestBuffer { get; } + + public TestBuffers(TSource[] source, TDest[] expectedDest) + { + this.SourceBuffer = source; + this.ExpectedDestBuffer = expectedDest; + this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); + } + + public void Dispose() => this.ActualDestBuffer.Dispose(); + + private const float Tolerance = 0.0001f; + + public void Verify() + { + int count = this.ExpectedDestBuffer.Length; + + if (typeof(TDest) == typeof(Vector4)) + { + + Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); + Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); + + for (int i = 0; i < count; i++) + { + // ReSharper disable PossibleNullReferenceException + Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); + // ReSharper restore PossibleNullReferenceException + } + } + else + { + Span expected = this.ExpectedDestBuffer.AsSpan(); + Span actual = this.ActualDestBuffer.GetSpan(); + for (int i = 0; i < count; i++) + { + Assert.Equal(expected[i], actual[i]); + } + } + } + } + + internal static void TestOperation( + TSource[] source, + TDest[] expected, + Action> action) + where TSource : struct + where TDest : struct + { + using (var buffers = new TestBuffers(source, expected)) + { + action(buffers.SourceBuffer, buffers.ActualDestBuffer); + buffers.Verify(); + } + } + + internal static Vector4[] CreateVector4TestData(int length) + { + var result = new Vector4[length]; + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = GetVector(rnd); + } + return result; + } + + internal static TPixel[] CreatePixelTestData(int length) + { + var result = new TPixel[length]; + + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + Vector4 v = GetVector(rnd); + result[i].PackFromVector4(v); + } + + return result; + } + + internal static TPixel[] CreateScaledPixelTestData(int length) + { + var result = new TPixel[length]; + + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + Vector4 v = GetVector(rnd); + result[i].PackFromScaledVector4(v); + } + + return result; + } + + internal static byte[] CreateByteTestData(int length) + { + byte[] result = new byte[length]; + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = (byte)rnd.Next(255); + } + return result; + } + + internal static Vector4 GetVector(Random rnd) + { + return new Vector4( + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble() + ); + } + + [StructLayout(LayoutKind.Sequential)] + private unsafe struct Rgba64Bytes + { + public fixed byte Data[8]; + + public byte this[int idx] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ref byte self = ref Unsafe.As(ref this); + return Unsafe.Add(ref self, idx); + } + } + } + } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs index 3a80c3436..69ecc553e 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs @@ -69,96 +69,96 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector2.One, new Rg32(Vector2.One * 1234.0f).ToVector2()); } - [Fact] - public void Rg32_ToRgb24() - { - // arrange - var rg32 = new Rg32(0.1f, -0.3f); - var actual = default(Rgb24); - var expected = new Rgb24(25, 0, 0); - - // act - rg32.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rg32_ToRgba32() - { - // arrange - var rg32 = new Rg32(0.1f, -0.3f); - var actual = default(Rgba32); - var expected = new Rgba32(25, 0, 0, 255); - - // act - rg32.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rg32_ToBgr24() - { - // arrange - var rg32 = new Rg32(0.1f, -0.3f); - var actual = default(Bgr24); - var expected = new Bgr24(25, 0, 0); - - // act - rg32.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rg32_ToArgb32() - { - // arrange - var rg32 = new Rg32(0.1f, -0.3f); - var actual = default(Argb32); - var expected = new Argb32(25, 0, 0, 255); - - // act - rg32.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rg32_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Rg32); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 65535, 0); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rg32_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Rg32); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 65535, 0, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Rg32_ToRgb24() + //{ + // // arrange + // var rg32 = new Rg32(0.1f, -0.3f); + // var actual = default(Rgb24); + // var expected = new Rgb24(25, 0, 0); + + // // act + // rg32.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rg32_ToRgba32() + //{ + // // arrange + // var rg32 = new Rg32(0.1f, -0.3f); + // var actual = default(Rgba32); + // var expected = new Rgba32(25, 0, 0, 255); + + // // act + // rg32.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rg32_ToBgr24() + //{ + // // arrange + // var rg32 = new Rg32(0.1f, -0.3f); + // var actual = default(Bgr24); + // var expected = new Bgr24(25, 0, 0); + + // // act + // rg32.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rg32_ToArgb32() + //{ + // // arrange + // var rg32 = new Rg32(0.1f, -0.3f); + // var actual = default(Argb32); + // var expected = new Argb32(25, 0, 0, 255); + + // // act + // rg32.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rg32_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Rg32); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 65535, 0); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rg32_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Rg32); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 65535, 0, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index d056bf30d..fcbef1374 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -1,175 +1,175 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.PixelFormats -{ - public class Rgb24Tests - { - public static readonly TheoryData ColorData = - new TheoryData() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; - - [Theory] - [MemberData(nameof(ColorData))] - public void Constructor(byte r, byte g, byte b) - { - var p = new Rgb24(r, g, b); - - Assert.Equal(r, p.R); - Assert.Equal(g, p.G); - Assert.Equal(b, p.B); - } - - [Fact] - public unsafe void ByteLayoutIsSequentialRgb() - { - var color = new Rgb24(1, 2, 3); - byte* ptr = (byte*)&color; - - Assert.Equal(1, ptr[0]); - Assert.Equal(2, ptr[1]); - Assert.Equal(3, ptr[2]); - } - - [Theory] - [MemberData(nameof(ColorData))] - public void Equals_WhenTrue(byte r, byte g, byte b) - { - var x = new Rgb24(r, g, b); - var y = new Rgb24(r, g, b); - - Assert.True(x.Equals(y)); - Assert.True(x.Equals((object)y)); - Assert.Equal(x.GetHashCode(), y.GetHashCode()); - } - - [Theory] - [InlineData(1, 2, 3, 1, 2, 4)] - [InlineData(0, 255, 0, 0, 244, 0)] - [InlineData(1, 255, 0, 0, 255, 0)] - public void Equals_WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) - { - var a = new Rgb24(r1, g1, b1); - var b = new Rgb24(r2, g2, b2); - - Assert.False(a.Equals(b)); - Assert.False(a.Equals((object)b)); - } - - [Fact] - public void PackFromRgba32() - { - var rgb = default(Rgb24); - rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); - - Assert.Equal(1, rgb.R); - Assert.Equal(2, rgb.G); - Assert.Equal(3, rgb.B); - } - - private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( - r / 255f, - g / 255f, - b / 255f, - a / 255f); - - [Fact] - public void PackFromVector4() - { - var rgb = default(Rgb24); - rgb.PackFromVector4(Vec(1, 2, 3, 4)); - - Assert.Equal(1, rgb.R); - Assert.Equal(2, rgb.G); - Assert.Equal(3, rgb.B); - } - - [Fact] - public void ToVector4() - { - var rgb = new Rgb24(1, 2, 3); - - Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); - } - - [Fact] - public void ToRgb24() - { - var rgb = new Rgb24(1, 2, 3); - var dest = default(Rgb24); - - rgb.ToRgb24(ref dest); - - Assert.Equal(rgb, dest); - } - - [Fact] - public void ToRgba32() - { - var rgb = new Rgb24(1, 2, 3); - var rgba = default(Rgba32); - - rgb.ToRgba32(ref rgba); - - Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); - } - - [Fact] - public void ToBgr24() - { - var rgb = new Rgb24(1, 2, 3); - var bgr = default(Bgr24); - - rgb.ToBgr24(ref bgr); - - Assert.Equal(new Bgr24(1, 2, 3), bgr); - } - - [Fact] - public void ToBgra32() - { - var rgb = new Rgb24(1, 2, 3); - var bgra = default(Bgra32); - - rgb.ToBgra32(ref bgra); - - Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); - } - - [Fact] - public void Rgb24_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Rgb24); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb24_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Rgb24); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } - } -} \ No newline at end of file +//// Copyright (c) Six Labors and contributors. +//// Licensed under the Apache License, Version 2.0. + +//using System; +//using System.Numerics; +//using SixLabors.ImageSharp.PixelFormats; +//using Xunit; + +//namespace SixLabors.ImageSharp.Tests.PixelFormats +//{ +// public class Rgb24Tests +// { +// public static readonly TheoryData ColorData = +// new TheoryData() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; + +// [Theory] +// [MemberData(nameof(ColorData))] +// public void Constructor(byte r, byte g, byte b) +// { +// var p = new Rgb24(r, g, b); + +// Assert.Equal(r, p.R); +// Assert.Equal(g, p.G); +// Assert.Equal(b, p.B); +// } + +// [Fact] +// public unsafe void ByteLayoutIsSequentialRgb() +// { +// var color = new Rgb24(1, 2, 3); +// byte* ptr = (byte*)&color; + +// Assert.Equal(1, ptr[0]); +// Assert.Equal(2, ptr[1]); +// Assert.Equal(3, ptr[2]); +// } + +// [Theory] +// [MemberData(nameof(ColorData))] +// public void Equals_WhenTrue(byte r, byte g, byte b) +// { +// var x = new Rgb24(r, g, b); +// var y = new Rgb24(r, g, b); + +// Assert.True(x.Equals(y)); +// Assert.True(x.Equals((object)y)); +// Assert.Equal(x.GetHashCode(), y.GetHashCode()); +// } + +// [Theory] +// [InlineData(1, 2, 3, 1, 2, 4)] +// [InlineData(0, 255, 0, 0, 244, 0)] +// [InlineData(1, 255, 0, 0, 255, 0)] +// public void Equals_WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) +// { +// var a = new Rgb24(r1, g1, b1); +// var b = new Rgb24(r2, g2, b2); + +// Assert.False(a.Equals(b)); +// Assert.False(a.Equals((object)b)); +// } + +// [Fact] +// public void PackFromRgba32() +// { +// var rgb = default(Rgb24); +// rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); + +// Assert.Equal(1, rgb.R); +// Assert.Equal(2, rgb.G); +// Assert.Equal(3, rgb.B); +// } + +// private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( +// r / 255f, +// g / 255f, +// b / 255f, +// a / 255f); + +// [Fact] +// public void PackFromVector4() +// { +// var rgb = default(Rgb24); +// rgb.PackFromVector4(Vec(1, 2, 3, 4)); + +// Assert.Equal(1, rgb.R); +// Assert.Equal(2, rgb.G); +// Assert.Equal(3, rgb.B); +// } + +// [Fact] +// public void ToVector4() +// { +// var rgb = new Rgb24(1, 2, 3); + +// Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); +// } + +// [Fact] +// public void ToRgb24() +// { +// var rgb = new Rgb24(1, 2, 3); +// var dest = default(Rgb24); + +// rgb.ToRgb24(ref dest); + +// Assert.Equal(rgb, dest); +// } + +// [Fact] +// public void ToRgba32() +// { +// var rgb = new Rgb24(1, 2, 3); +// var rgba = default(Rgba32); + +// rgb.ToRgba32(ref rgba); + +// Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); +// } + +// [Fact] +// public void ToBgr24() +// { +// var rgb = new Rgb24(1, 2, 3); +// var bgr = default(Bgr24); + +// rgb.ToBgr24(ref bgr); + +// Assert.Equal(new Bgr24(1, 2, 3), bgr); +// } + +// [Fact] +// public void ToBgra32() +// { +// var rgb = new Rgb24(1, 2, 3); +// var bgra = default(Bgra32); + +// rgb.ToBgra32(ref bgra); + +// Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); +// } + +// [Fact] +// public void Rgb24_PackFromRgb48_ToRgb48() +// { +// // arrange +// var input = default(Rgb24); +// var actual = default(Rgb48); +// var expected = new Rgb48(65535, 0, 65535); + +// // act +// input.PackFromRgb48(expected); +// input.ToRgb48(ref actual); + +// // assert +// Assert.Equal(expected, actual); +// } + +// [Fact] +// public void Rgb24_PackFromRgba64_ToRgba64() +// { +// // arrange +// var input = default(Rgb24); +// var actual = default(Rgba64); +// var expected = new Rgba64(65535, 0, 65535, 65535); + +// // act +// input.PackFromRgba64(expected); +// input.ToRgba64(ref actual); + +// // assert +// Assert.Equal(expected, actual); +// } +// } +//} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs index 77d6544f0..2af488e3c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs @@ -1,199 +1,192 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.PixelFormats -{ - public class Rgb48Tests - { - [Fact] - public void Rgb48_Values() - { - var rgb = new Rgba64(5243, 9830, 19660, 29491); - - Assert.Equal(5243, rgb.R); - Assert.Equal(9830, rgb.G); - Assert.Equal(19660, rgb.B); - Assert.Equal(29491, rgb.A); - - rgb = new Rgba64(5243 / 65535F, 9830 / 65535F, 19660 / 65535F, 29491 / 65535F); - - Assert.Equal(5243, rgb.R); - Assert.Equal(9830, rgb.G); - Assert.Equal(19660, rgb.B); - Assert.Equal(29491, rgb.A); - } - - [Fact] - public void Rgb48_ToVector4() - { - Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(Vector3.Zero).ToVector4()); - Assert.Equal(Vector4.One, new Rgb48(Vector3.One).ToVector4()); - } - - [Fact] - public void Rgb48_ToScaledVector4() - { - // arrange - var short2 = new Rgb48(Vector3.One); - - // act - Vector4 actual = short2.ToScaledVector4(); - - // assert - Assert.Equal(1, actual.X); - Assert.Equal(1, actual.Y); - Assert.Equal(1, actual.Z); - Assert.Equal(1, actual.W); - } - - [Fact] - public void Rgb48_PackFromScaledVector4() - { - // arrange - var pixel = default(Rgb48); - var short3 = new Rgb48(Vector3.One); - var expected = new Rgb48(Vector3.One); - - // act - Vector4 scaled = short3.ToScaledVector4(); - pixel.PackFromScaledVector4(scaled); - - // assert - Assert.Equal(expected, pixel); - } - - [Fact] - public void Rgb48_Clamping() - { - Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(Vector3.One * -1234.0f).ToVector4()); - Assert.Equal(Vector4.One, new Rgb48(Vector3.One * 1234.0f).ToVector4()); - } - - [Fact] - public void Rgb48_ToRgb24() - { - // arrange - var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); - var actual = default(Rgb24); - var expected = new Rgb24(20, 38, 76); - - // act - rgba48.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_ToRgba32() - { - // arrange - var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); - var actual = default(Rgba32); - var expected = new Rgba32(20, 38, 76, 255); - - // act - rgba48.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_ToArgb32() - { - // arrange - var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); - var actual = default(Argb32); - var expected = new Argb32(20, 38, 76, 255); - - // act - rgba48.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_ToBgr24() - { - // arrange - var rgb48 = new Rgb48(0.08f, 0.15f, 0.30f); - var actual = default(Bgr24); - var expected = new Bgr24(20, 38, 76); - - // act - rgb48.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_ToBgra32() - { - // arrange - var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); - var actual = default(Bgra32); - var expected = new Bgra32(20, 38, 76, 255); - - // act - rgba48.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_PackFromRgba32_ToRgba32() - { - // arrange - var rgb48 = default(Rgb48); - var actual = default(Rgba32); - var expected = new Rgba32(20, 38, 76, 255); - - // act - rgb48.PackFromRgba32(expected); - rgb48.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Rgb48); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Rgb48); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } - } -} +//// Copyright (c) Six Labors and contributors. +//// Licensed under the Apache License, Version 2.0. + +//using System.Numerics; +//using SixLabors.ImageSharp.PixelFormats; +//using Xunit; + +//namespace SixLabors.ImageSharp.Tests.PixelFormats +//{ +// public class Rgb48Tests +// { +// [Fact] +// public void Rgb48_Values() +// { +// var rgb = new Rgba64(5243, 9830, 19660, 29491); + +// Assert.Equal(5243, rgb.R); +// Assert.Equal(9830, rgb.G); +// Assert.Equal(19660, rgb.B); +// Assert.Equal(29491, rgb.A); +// } + +// [Fact] +// public void Rgb48_ToVector4() +// { +// Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(0, 0, 0, 0).ToVector4()); +// Assert.Equal(Vector4.One, new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); +// } + +// [Fact] +// public void Rgb48_ToScaledVector4() +// { +// // arrange +// var short2 = new Rgb48(Vector3.One); + +// // act +// Vector4 actual = short2.ToScaledVector4(); + +// // assert +// Assert.Equal(1, actual.X); +// Assert.Equal(1, actual.Y); +// Assert.Equal(1, actual.Z); +// Assert.Equal(1, actual.W); +// } + +// [Fact] +// public void Rgb48_PackFromScaledVector4() +// { +// // arrange +// var pixel = default(Rgb48); +// var short3 = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); +// var expected = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); + +// // act +// Vector4 scaled = short3.ToScaledVector4(); +// pixel.PackFromScaledVector4(scaled); + +// // assert +// Assert.Equal(expected, pixel); +// } + +// //[Fact] +// //public void Rgb48_Clamping() +// //{ +// // Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(Vector3.One * -1234.0f).ToVector4()); +// // Assert.Equal(Vector4.One, new Rgb48(Vector3.One * 1234.0f).ToVector4()); +// //} + +// //[Fact] +// //public void Rgb48_ToRgb24() +// //{ +// // // arrange +// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); +// // var actual = default(Rgb24); +// // var expected = new Rgb24(20, 38, 76); + +// // // act +// // rgba48.ToRgb24(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_ToRgba32() +// //{ +// // // arrange +// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); +// // var actual = default(Rgba32); +// // var expected = new Rgba32(20, 38, 76, 255); + +// // // act +// // rgba48.ToRgba32(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_ToArgb32() +// //{ +// // // arrange +// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); +// // var actual = default(Argb32); +// // var expected = new Argb32(20, 38, 76, 255); + +// // // act +// // rgba48.ToArgb32(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgba64_ToBgr24() +// //{ +// // // arrange +// // var rgb48 = new Rgb48(0.08f, 0.15f, 0.30f); +// // var actual = default(Bgr24); +// // var expected = new Bgr24(20, 38, 76); + +// // // act +// // rgb48.ToBgr24(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_ToBgra32() +// //{ +// // // arrange +// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); +// // var actual = default(Bgra32); +// // var expected = new Bgra32(20, 38, 76, 255); + +// // // act +// // rgba48.ToBgra32(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_PackFromRgba32_ToRgba32() +// //{ +// // // arrange +// // var rgb48 = default(Rgb48); +// // var actual = default(Rgba32); +// // var expected = new Rgba32(20, 38, 76, 255); + +// // // act +// // rgb48.PackFromRgba32(expected); +// // rgb48.ToRgba32(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_PackFromRgb48_ToRgb48() +// //{ +// // // arrange +// // var input = default(Rgb48); +// // var actual = default(Rgb48); +// // var expected = new Rgb48(65535, 0, 65535); + +// // // act +// // input.PackFromRgb48(expected); +// // input.ToRgb48(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} + +// //[Fact] +// //public void Rgb48_PackFromRgba64_ToRgba64() +// //{ +// // // arrange +// // var input = default(Rgb48); +// // var actual = default(Rgba64); +// // var expected = new Rgba64(65535, 0, 65535, 65535); + +// // // act +// // input.PackFromRgba64(expected); +// // input.ToRgba64(ref actual); + +// // // assert +// // Assert.Equal(expected, actual); +// //} +// } +//} diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs index fcb3b6c7c..d8ad6d3f1 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs @@ -71,144 +71,144 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Rgba1010102(Vector4.One * 1234.0f).ToVector4()); } - [Fact] - public void Rgba1010102_ToRgb24() - { - // arrange - var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(25, 0, 128); - - // act - rgba.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_ToRgba32() - { - // arrange - var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Rgba32); - var expected = new Rgba32(25, 0, 128, 0); - - // act - rgba.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_ToBgr24() - { - // arrange - var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(25, 0, 128); - - // act - rgba.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_ToBgra32() - { - // arrange - var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(25, 0, 128, 0); - - // act - rgba.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_PackFromRgba32_ToRgba32() - { - // arrange - var rgba = default(Rgba1010102); - var expected = new Rgba32(25, 0, 128, 0); - var actual = default(Rgba32); - - // act - rgba.PackFromRgba32(expected); - rgba.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_PackFromBgra32_ToBgra32() - { - // arrange - var rgba = default(Rgba1010102); - var expected = new Bgra32(25, 0, 128, 0); - var actual = default(Bgra32); - - // act - rgba.PackFromBgra32(expected); - rgba.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_PackFromArgb32_ToArgb32() - { - // arrange - var rgba = default(Rgba1010102); - var expected = new Argb32(25, 0, 128, 0); - var actual = default(Argb32); - - // act - rgba.PackFromArgb32(expected); - rgba.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Rgba1010102); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba1010102_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Rgba1010102); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 65535); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Rgba1010102_ToRgb24() + //{ + // // arrange + // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgb24); + // var expected = new Rgb24(25, 0, 128); + + // // act + // rgba.ToRgb24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_ToRgba32() + //{ + // // arrange + // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Rgba32); + // var expected = new Rgba32(25, 0, 128, 0); + + // // act + // rgba.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_ToBgr24() + //{ + // // arrange + // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgr24); + // var expected = new Bgr24(25, 0, 128); + + // // act + // rgba.ToBgr24(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_ToBgra32() + //{ + // // arrange + // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); + // var actual = default(Bgra32); + // var expected = new Bgra32(25, 0, 128, 0); + + // // act + // rgba.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var rgba = default(Rgba1010102); + // var expected = new Rgba32(25, 0, 128, 0); + // var actual = default(Rgba32); + + // // act + // rgba.PackFromRgba32(expected); + // rgba.ToRgba32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_PackFromBgra32_ToBgra32() + //{ + // // arrange + // var rgba = default(Rgba1010102); + // var expected = new Bgra32(25, 0, 128, 0); + // var actual = default(Bgra32); + + // // act + // rgba.PackFromBgra32(expected); + // rgba.ToBgra32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_PackFromArgb32_ToArgb32() + //{ + // // arrange + // var rgba = default(Rgba1010102); + // var expected = new Argb32(25, 0, 128, 0); + // var actual = default(Argb32); + + // // act + // rgba.PackFromArgb32(expected); + // rgba.ToArgb32(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_PackFromRgb48_ToRgb48() + //{ + // // arrange + // var input = default(Rgba1010102); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + // input.ToRgb48(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba1010102_PackFromRgba64_ToRgba64() + //{ + // // arrange + // var input = default(Rgba1010102); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 65535); + + // // act + // input.PackFromRgba64(expected); + // input.ToRgba64(ref actual); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs index 4b2c18776..30a5f961b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs @@ -19,12 +19,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void AreEqual() { - Rgba32 color1 = new Rgba32(0, 0, 0); - Rgba32 color2 = new Rgba32(0, 0, 0, 1F); - Rgba32 color3 = Rgba32.FromHex("#000"); - Rgba32 color4 = Rgba32.FromHex("#000F"); - Rgba32 color5 = Rgba32.FromHex("#000000"); - Rgba32 color6 = Rgba32.FromHex("#000000FF"); + var color1 = new Rgba32(0, 0, 0); + var color2 = new Rgba32(0, 0, 0, 1F); + var color3 = Rgba32.FromHex("#000"); + var color4 = Rgba32.FromHex("#000F"); + var color5 = Rgba32.FromHex("#000000"); + var color6 = Rgba32.FromHex("#000000FF"); Assert.Equal(color1, color2); Assert.Equal(color1, color3); @@ -39,11 +39,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void AreNotEqual() { - Rgba32 color1 = new Rgba32(255, 0, 0, 255); - Rgba32 color2 = new Rgba32(0, 0, 0, 255); - Rgba32 color3 = Rgba32.FromHex("#000"); - Rgba32 color4 = Rgba32.FromHex("#000000"); - Rgba32 color5 = Rgba32.FromHex("#FF000000"); + var color1 = new Rgba32(255, 0, 0, 255); + var color2 = new Rgba32(0, 0, 0, 255); + var color3 = Rgba32.FromHex("#000"); + var color4 = Rgba32.FromHex("#000000"); + var color5 = Rgba32.FromHex("#FF000000"); Assert.NotEqual(color1, color2); Assert.NotEqual(color1, color3); @@ -57,25 +57,25 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void ConstructorAssignsProperties() { - Rgba32 color1 = new Rgba32(1, .1f, .133f, .864f); + var color1 = new Rgba32(1, .1f, .133f, .864f); Assert.Equal(255, color1.R); Assert.Equal((byte)Math.Round(.1f * 255), color1.G); Assert.Equal((byte)Math.Round(.133f * 255), color1.B); Assert.Equal((byte)Math.Round(.864f * 255), color1.A); - Rgba32 color2 = new Rgba32(1, .1f, .133f); + var color2 = new Rgba32(1, .1f, .133f); Assert.Equal(255, color2.R); Assert.Equal(Math.Round(.1f * 255), color2.G); Assert.Equal(Math.Round(.133f * 255), color2.B); Assert.Equal(255, color2.A); - Rgba32 color4 = new Rgba32(new Vector3(1, .1f, .133f)); + var color4 = new Rgba32(new Vector3(1, .1f, .133f)); Assert.Equal(255, color4.R); Assert.Equal(Math.Round(.1f * 255), color4.G); Assert.Equal(Math.Round(.133f * 255), color4.B); Assert.Equal(255, color4.A); - Rgba32 color5 = new Rgba32(new Vector4(1, .1f, .133f, .5f)); + var color5 = new Rgba32(new Vector4(1, .1f, .133f, .5f)); Assert.Equal(255, color5.R); Assert.Equal(Math.Round(.1f * 255), color5.G); Assert.Equal(Math.Round(.133f * 255), color5.B); @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public unsafe void ByteLayout() { - Rgba32 color = new Rgba32(1, 2, 3, 4); + var color = new Rgba32(1, 2, 3, 4); byte* colorBase = (byte*)&color; Assert.Equal(1, colorBase[0]); Assert.Equal(2, colorBase[1]); @@ -181,23 +181,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Rgba32(Vector4.One * +1234.0f).ToVector4()); } - [Fact] - public void Rgba32_ToRgb24() - { - // arrange - var rgba = new Rgba32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Rgb24); - var expected = new Rgb24(0x1a, 0, 0x80); - - // act - rgba.ToRgb24(ref actual); - - // assert - Assert.Equal(expected.R, actual.R); - Assert.Equal(expected.G, actual.G); - Assert.Equal(expected.B, actual.B); - } - [Fact] public void Rgba32_ToRgba32() { @@ -207,52 +190,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(0x1a, 0, 0x80, 0); // act - rgba.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba32_ToBgr24() - { - // arrange - var rgba = new Rgba32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Bgr24); - var expected = new Bgr24(0x1a, 0, 0x80); - - // act - rgba.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba32_ToBgra32() - { - // arrange - var rgba = new Rgba32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Bgra32); - var expected = new Bgra32(0x1a, 0, 0x80, 0); - - // act - rgba.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba32_ToArgb32() - { - // arrange - var rgba = new Rgba32(+0.1f, -0.3f, +0.5f, -0.7f); - var actual = default(Argb32); - var expected = new Argb32(0x1a, 0, 0x80, 0); - - // act - rgba.ToArgb32(ref actual); + actual.PackFromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -268,7 +206,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act rgba.PackFromRgba32(expected); - rgba.ToRgba32(ref actual); + actual.PackFromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -284,7 +222,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act rgba.PackFromBgra32(expected); - rgba.ToBgra32(ref actual); + actual.PackFromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -300,14 +238,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act rgba.PackFromArgb32(expected); - rgba.ToArgb32(ref actual); + actual.PackFromRgba32(rgba); // assert Assert.Equal(expected, actual); } [Fact] - public void Rgba32_PackFromRgb48_ToRgb48() + public void Rgba32_PackFromRgb48() { // arrange var input = default(Rgba32); @@ -316,14 +254,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgb48(expected); - input.ToRgb48(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); } [Fact] - public void Rgba32_PackFromRgba64_ToRgba64() + public void Rgba32_PackFromRgba64() { // arrange var input = default(Rgba32); @@ -332,7 +270,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgba64(expected); - input.ToRgba64(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs index 92b36a1c6..185fc5635 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs @@ -13,33 +13,31 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void Rgba64_PackedValues() { Assert.Equal((ulong)0x73334CCC2666147B, new Rgba64(5243, 9830, 19660, 29491).PackedValue); - Assert.Equal((ulong)0x73334CCC2666147B, new Rgba64(0.08f, 0.15f, 0.30f, 0.45f).PackedValue); - var rgba = new Rgba64(0x73334CCC2666147B); - Assert.Equal(5243, rgba.R); - Assert.Equal(9830, rgba.G); - Assert.Equal(19660, rgba.B); - Assert.Equal(29491, rgba.A); // Test the limits. - Assert.Equal((ulong)0x0, new Rgba64(Vector4.Zero).PackedValue); - Assert.Equal(0xFFFFFFFFFFFFFFFF, new Rgba64(Vector4.One).PackedValue); + Assert.Equal((ulong)0x0, new Rgba64(0, 0, 0, 0).PackedValue); + Assert.Equal(0xFFFFFFFFFFFFFFFF, new Rgba64( + ushort.MaxValue, + ushort.MaxValue, + ushort.MaxValue, + ushort.MaxValue).PackedValue); + // Test data ordering - Assert.Equal(0xC7AD8F5C570A1EB8, new Rgba64(((float)0x1EB8) / 0xffff, ((float)0x570A) / 0xffff, ((float)0x8F5C) / 0xffff, ((float)0xC7AD) / 0xffff).PackedValue); - Assert.Equal(0xC7AD8F5C570A1EB8, new Rgba64(0.12f, 0.34f, 0.56f, 0.78f).PackedValue); + Assert.Equal(0xC7AD8F5C570A1EB8, new Rgba64(0x1EB8, 0x570A, 0x8F5C, 0xC7AD).PackedValue); } [Fact] public void Rgba64_ToVector4() { - Assert.Equal(Vector4.Zero, new Rgba64(Vector4.Zero).ToVector4()); - Assert.Equal(Vector4.One, new Rgba64(Vector4.One).ToVector4()); + Assert.Equal(Vector4.Zero, new Rgba64(0, 0, 0, 0).ToVector4()); + Assert.Equal(Vector4.One, new Rgba64(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); } [Fact] public void Rgba64_ToScaledVector4() { // arrange - var short2 = new Rgba64(Vector4.One); + var short2 = new Rgba64(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); // act Vector4 actual = short2.ToScaledVector4(); @@ -56,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { // arrange var pixel = default(Rgba64); - var short4 = new Rgba64(Vector4.One); + var short4 = new Rgba64(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); const ulong expected = 0xFFFFFFFFFFFFFFFF; // act @@ -71,131 +69,78 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void Rgba64_Clamping() { - Assert.Equal(Vector4.Zero, new Rgba64(Vector4.One * -1234.0f).ToVector4()); - Assert.Equal(Vector4.One, new Rgba64(Vector4.One * 1234.0f).ToVector4()); - } - - [Fact] - public void Rgba64_ToRgb24() - { - // arrange - var rgba64 = new Rgba64(0.08f, 0.15f, 0.30f, 0.45f); - var actual = default(Rgb24); - var expected = new Rgb24(20, 38, 76); - - // act - rgba64.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_ToRgba32() - { - // arrange - var rgba64 = new Rgba64(0.08f, 0.15f, 0.30f, 0.45f); - var actual = default(Rgba32); - var expected = new Rgba32(20, 38, 76, 115); - - // act - rgba64.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_ToArgb32() - { - // arrange - var rgba64 = new Rgba64(0.08f, 0.15f, 0.30f, 0.45f); - var actual = default(Argb32); - var expected = new Argb32(20, 38, 76, 115); - - // act - rgba64.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_ToBgr24() - { - // arrange - var rgba64 = new Rgba64(0.08f, 0.15f, 0.30f, 0.45f); - var actual = default(Bgr24); - var expected = new Bgr24(20, 38, 76); - - // act - rgba64.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_ToBgra32() - { - // arrange - var rgba64 = new Rgba64(0.08f, 0.15f, 0.30f, 0.45f); - var actual = default(Bgra32); - var expected = new Bgra32(20, 38, 76, 115); - - // act - rgba64.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgba64_PackFromRgba32_ToRgba32() - { - // arrange - var rgba64 = default(Rgba64); - var actual = default(Rgba32); - var expected = new Rgba32(20, 38, 76, 115); - - // act - rgba64.PackFromRgba32(expected); - rgba64.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Rgb48_PackFromRgb48_ToRgb48() - { - // arrange - var input = default(Rgba64); - var actual = default(Rgb48); - var expected = new Rgb48(65535, 0, 65535); - - // act - input.PackFromRgb48(expected); - input.ToRgb48(ref actual); - - // assert - Assert.Equal(expected, actual); + var zero = default(Rgba64); + var one = default(Rgba64); + zero.PackFromVector4(Vector4.One * -1234.0f); + one.PackFromVector4(Vector4.One * 1234.0f); + Assert.Equal(Vector4.Zero, zero.ToVector4()); + Assert.Equal(Vector4.One, one.ToVector4()); } - [Fact] - public void Rgba64_PackFromRgba64_ToRgba64() - { - // arrange - var input = default(Rgba64); - var actual = default(Rgba64); - var expected = new Rgba64(65535, 0, 65535, 0); - - // act - input.PackFromRgba64(expected); - input.ToRgba64(ref actual); - - // assert - Assert.Equal(expected, actual); - } + //[Fact] + //public void Rgba64_ToRgba32() + //{ + // // arrange + // var rgba64 = new Rgba64( + // (ushort)(0.08f * ushort.MaxValue), + // (ushort)(0.15f * ushort.MaxValue), + // (ushort)(0.30f * ushort.MaxValue), + // (ushort)(0.45f * ushort.MaxValue)); + // var actual = default(Rgba32); + // var expected = new Rgba32(20, 38, 76, 115); + + // // act + // actual = rgba64.ToRgba32(); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba64_PackFromRgba32_ToRgba32() + //{ + // // arrange + // var rgba64 = default(Rgba64); + // var actual = default(Rgba32); + // var expected = new Rgba32(20, 38, 76, 115); + + // // act + // rgba64.PackFromRgba32(expected); + // actual = rgba64.ToRgba32(); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgb48_PackFromRgb48() + //{ + // // arrange + // var input = default(Rgba64); + // var actual = default(Rgb48); + // var expected = new Rgb48(65535, 0, 65535); + + // // act + // input.PackFromRgb48(expected); + + // // assert + // Assert.Equal(expected, actual); + //} + + //[Fact] + //public void Rgba64_PackFromRgba64() + //{ + // // arrange + // var input = default(Rgba64); + // var actual = default(Rgba64); + // var expected = new Rgba64(65535, 0, 65535, 0); + + // // act + // input.PackFromRgba64(expected); + // actual.PackFromScaledVector4(input.ToScaledVector4()); + + // // assert + // Assert.Equal(expected, actual); + //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs index a21b647a7..9b5fceac7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs @@ -19,12 +19,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void AreEqual() { - RgbaVector color1 = new RgbaVector(0, 0, 0F); - RgbaVector color2 = new RgbaVector(0, 0, 0, 1F); - RgbaVector color3 = RgbaVector.FromHex("#000"); - RgbaVector color4 = RgbaVector.FromHex("#000F"); - RgbaVector color5 = RgbaVector.FromHex("#000000"); - RgbaVector color6 = RgbaVector.FromHex("#000000FF"); + var color1 = new RgbaVector(0, 0, 0F); + var color2 = new RgbaVector(0, 0, 0, 1F); + var color3 = RgbaVector.FromHex("#000"); + var color4 = RgbaVector.FromHex("#000F"); + var color5 = RgbaVector.FromHex("#000000"); + var color6 = RgbaVector.FromHex("#000000FF"); Assert.Equal(color1, color2); Assert.Equal(color1, color3); @@ -39,11 +39,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void AreNotEqual() { - RgbaVector color1 = new RgbaVector(1, 0, 0, 1); - RgbaVector color2 = new RgbaVector(0, 0, 0, 1); - RgbaVector color3 = RgbaVector.FromHex("#000"); - RgbaVector color4 = RgbaVector.FromHex("#000000"); - RgbaVector color5 = RgbaVector.FromHex("#FF000000"); + var color1 = new RgbaVector(1, 0, 0, 1); + var color2 = new RgbaVector(0, 0, 0, 1); + var color3 = RgbaVector.FromHex("#000"); + var color4 = RgbaVector.FromHex("#000000"); + var color5 = RgbaVector.FromHex("#FF000000"); Assert.NotEqual(color1, color2); Assert.NotEqual(color1, color3); @@ -57,29 +57,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void ConstructorAssignsProperties() { - RgbaVector color1 = new RgbaVector(1, .1F, .133F, .864F); + var color1 = new RgbaVector(1, .1F, .133F, .864F); Assert.Equal(1F, color1.R); Assert.Equal(.1F, color1.G); Assert.Equal(.133F, color1.B); Assert.Equal(.864F, color1.A); - RgbaVector color2 = new RgbaVector(1, .1f, .133f); + var color2 = new RgbaVector(1, .1f, .133f); Assert.Equal(1F, color2.R); Assert.Equal(.1F, color2.G); Assert.Equal(.133F, color2.B); Assert.Equal(1F, color2.A); - - RgbaVector color4 = new RgbaVector(new Vector3(1, .1f, .133f)); - Assert.Equal(1F, color4.R); - Assert.Equal(.1F, color4.G); - Assert.Equal(.133F, color4.B); - Assert.Equal(1F, color4.A); - - RgbaVector color5 = new RgbaVector(new Vector4(1, .1f, .133f, .5f)); - Assert.Equal(1F, color5.R); - Assert.Equal(.1F, color5.G); - Assert.Equal(.133F, color5.B); - Assert.Equal(.5F, color5.A); } /// @@ -88,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void FromAndToHex() { - RgbaVector color = RgbaVector.FromHex("#AABBCCDD"); + var color = RgbaVector.FromHex("#AABBCCDD"); Assert.Equal(170 / 255F, color.R); Assert.Equal(187 / 255F, color.G); Assert.Equal(204 / 255F, color.B); @@ -116,7 +104,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] public void FloatLayout() { - RgbaVector color = new RgbaVector(1F, 2, 3, 4); + var color = new RgbaVector(1F, 2, 3, 4); Vector4 colorBase = Unsafe.As(ref Unsafe.Add(ref color, 0)); float[] ordered = new float[4]; colorBase.CopyTo(ordered); @@ -128,7 +116,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void RgbaVector_PackFromRgb48_ToRgb48() + public void RgbaVector_PackFromRgb48() { // arrange var input = default(RgbaVector); @@ -137,14 +125,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgb48(expected); - input.ToRgb48(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); } [Fact] - public void RgbaVector_PackFromRgba64_ToRgba64() + public void RgbaVector_PackFromRgba64() { // arrange var input = default(RgbaVector); @@ -153,7 +141,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgba64(expected); - input.ToRgba64(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs index 5c75fcbbb..5f2f45b3b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // arrange var pixel = default(Short2); var short2 = new Short2(Vector2.One * 0x7FFF); - ulong expected = 0x7FFF7FFF; + const ulong expected = 0x7FFF7FFF; // act Vector4 scaled = short2.ToScaledVector4(); @@ -79,21 +79,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } - [Fact] - public void Short2_ToRgb24() - { - // arrange - var short2 = new Short2(127.5f, -5.3f); - var actual = default(Rgb24); - var expected = new Rgb24(128, 127, 0); - - // act - short2.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - [Fact] public void Short2_ToRgba32() { @@ -103,52 +88,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(128, 127, 0, 255); // act - short2.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short2_ToBgr24() - { - // arrange - var short2 = new Short2(127.5f, -5.3f); - var actual = default(Bgr24); - var expected = new Bgr24(128, 127, 0); - - // act - short2.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short2_ToArgb32() - { - // arrange - var short2 = new Short2(127.5f, -5.3f); - var actual = default(Argb32); - var expected = new Argb32(128, 127, 0, 255); - - // act - short2.ToArgb32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short2_ToBgra32() - { - // arrange - var short2 = new Short2(127.5f, -5.3f); - var actual = default(Bgra32); - var expected = new Bgra32(128, 127, 0, 255); - - // act - short2.ToBgra32(ref actual); + actual = short2.ToRgba32(); // assert Assert.Equal(expected, actual); @@ -164,14 +104,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short2.PackFromRgba32(expected); - short2.ToRgba32(ref actual); + actual = short2.ToRgba32(); // assert Assert.Equal(expected, actual); } [Fact] - public void Short2_PackFromRgb48_ToRgb48() + public void Short2_PackFromRgb48() { // arrange var input = default(Short2); @@ -180,14 +120,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgb48(expected); - input.ToRgb48(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); } [Fact] - public void Short2_PackFromRgba64_ToRgba64() + public void Short2_PackFromRgba64() { // arrange var input = default(Short2); @@ -196,7 +136,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgba64(expected); - input.ToRgba64(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs index 59dc385d4..4245fcf38 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // arrange var short4 = new Short4(Vector4.One * 0x7FFF); Vector4 scaled = short4.ToScaledVector4(); - long expected = 0x7FFF7FFF7FFF7FFF; + const long expected = 0x7FFF7FFF7FFF7FFF; // act var pixel = default(Short4); @@ -83,36 +83,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One * -0x8000, vector2); } - [Fact] - public void Short4_ToRgb24() - { - // arrange - var shortValue = new Short4(11547, 12653, 29623, 193); - var actual = default(Rgb24); - var expected = new Rgb24(172, 177, 243); - - // act - shortValue.ToRgb24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short4_ToBgr24() - { - // arrange - var shortValue = new Short4(11547, 12653, 29623, 193); - var actual = default(Bgr24); - var expected = new Bgr24(172, 177, 243); - - // act - shortValue.ToBgr24(ref actual); - - // assert - Assert.Equal(expected, actual); - } - [Fact] public void Short4_ToRgba32() { @@ -122,37 +92,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(172, 177, 243, 128); // act - shortValue.ToRgba32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short4_ToBgra32() - { - // arrange - var shortValue = new Short4(11547, 12653, 29623, 193); - var actual = default(Bgra32); - var expected = new Bgra32(172, 177, 243, 128); - - // act - shortValue.ToBgra32(ref actual); - - // assert - Assert.Equal(expected, actual); - } - - [Fact] - public void Short4_ToArgb32() - { - // arrange - var shortValue = new Short4(11547, 12653, 29623, 193); - var actual = default(Argb32); - var expected = new Argb32(172, 177, 243, 128); - - // act - shortValue.ToArgb32(ref actual); + actual = shortValue.ToRgba32(); // assert Assert.Equal(expected, actual); @@ -168,7 +108,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.PackFromRgba32(expected); - short4.ToRgba32(ref actual); + actual = short4.ToRgba32(); // assert Assert.Equal(expected, actual); @@ -184,7 +124,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.PackFromBgra32(expected); - short4.ToBgra32(ref actual); + actual.PackFromRgba32(short4.ToRgba32()); // assert Assert.Equal(expected, actual); @@ -200,7 +140,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.PackFromArgb32(expected); - short4.ToArgb32(ref actual); + actual.PackFromRgba32(short4.ToRgba32()); // assert Assert.Equal(expected, actual); @@ -216,7 +156,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgb48(expected); - input.ToRgb48(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); @@ -232,7 +172,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act input.PackFromRgba64(expected); - input.ToRgba64(ref actual); + actual.PackFromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs index 1fca398fc..29c97ce35 100644 --- a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Tests.Colors public void Color_Types_From_Bytes_Produce_Equal_Scaled_Component_OutPut() { var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); Assert.Equal(color.R, (byte)(colorVector.R * 255)); Assert.Equal(color.G, (byte)(colorVector.G * 255)); @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Tests.Colors public void Color_Types_From_Vector4_Produce_Equal_Scaled_Component_OutPut() { var color = new Rgba32(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); - var colorVector = new RgbaVector(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); Assert.Equal(color.R, (byte)(colorVector.R * 255)); Assert.Equal(color.G, (byte)(colorVector.G * 255)); @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Colors public void Color_Types_From_Vector3_Produce_Equal_Scaled_Component_OutPut() { var color = new Rgba32(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); - var colorVector = new RgbaVector(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F); Assert.Equal(color.R, (byte)(colorVector.R * 255)); Assert.Equal(color.G, (byte)(colorVector.G * 255)); @@ -73,76 +73,28 @@ namespace SixLabors.ImageSharp.Tests.Colors public void Color_Types_To_Vector4_Produce_Equal_OutPut() { var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); Assert.Equal(color.ToVector4(), colorVector.ToVector4()); } - [Fact] - public void Color_Types_To_RgbBytes_Produce_Equal_OutPut() - { - var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); - - var rgb = default(Rgb24); - var rgbVector = default(Rgb24); - - color.ToRgb24(ref rgb); - colorVector.ToRgb24(ref rgbVector); - - Assert.Equal(rgb, rgbVector); - } - [Fact] public void Color_Types_To_RgbaBytes_Produce_Equal_OutPut() { var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); - - var rgba = default(Rgba32); - var rgbaVector = default(Rgba32); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); - color.ToRgba32(ref rgba); - colorVector.ToRgba32(ref rgbaVector); + var rgba = color.ToRgba32(); + var rgbaVector = colorVector.ToRgba32(); Assert.Equal(rgba, rgbaVector); } - [Fact] - public void Color_Types_To_BgrBytes_Produce_Equal_OutPut() - { - var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); - - var bgr = default(Bgr24); - var bgrVector = default(Bgr24); - - color.ToBgr24(ref bgr); - colorVector.ToBgr24(ref bgrVector); - - Assert.Equal(bgr, bgrVector); - } - - [Fact] - public void Color_Types_To_BgraBytes_Produce_Equal_OutPut() - { - var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); - - var bgra = default(Bgra32); - var bgraVector = default(Bgra32); - - color.ToBgra32(ref bgra); - colorVector.ToBgra32(ref bgraVector); - - Assert.Equal(bgra, bgraVector); - } - [Fact] public void Color_Types_To_Hex_Produce_Equal_OutPut() { var color = new Rgba32(24, 48, 96, 192); - var colorVector = new RgbaVector(24, 48, 96, 192); + var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); // 183060C0 Assert.Equal(color.ToHex(), colorVector.ToHex()); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index edc6994e7..17240839d 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -65,10 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms nameof(KnownResamplers.Lanczos8), }; - public AffineTransformTests(ITestOutputHelper output) - { - this.Output = output; - } + public AffineTransformTests(ITestOutputHelper output) => this.Output = output; /// /// The output of an "all white" image should be "all white" or transparent, regardless of the transformation and the resampler. @@ -240,12 +237,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms where TPixel : struct, IPixel { Span data = image.Frames.RootFrame.GetPixelSpan(); - var rgba = default(Rgba32); var white = new Rgb24(255, 255, 255); foreach (TPixel pixel in data) { - pixel.ToRgba32(ref rgba); - if (rgba.A == 0) continue; + var rgba = pixel.ToRgba32(); + if (rgba.A == 0) + { + continue; + } Assert.Equal(white, rgba.Rgb); } diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index c2b1c26c5..719e9793a 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -97,12 +97,11 @@ namespace SixLabors.ImageSharp.Tests { // Transparent pixels are much more likely to be found at the end of a palette int index = -1; - var trans = default(Rgba32); for (int i = quantized.Palette.Length - 1; i >= 0; i--) { - quantized.Palette[i].ToRgba32(ref trans); + var trans = quantized.Palette[i].ToRgba32(); - if (trans.Equals(default(Rgba32))) + if (trans.Equals(default)) { index = i; } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs index 65b32e088..70b630adf 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs @@ -72,7 +72,10 @@ namespace SixLabors.ImageSharp.Tests extension = '.' + extension; } - if (fn != string.Empty) fn = '_' + fn; + if (fn != string.Empty) + { + fn = '_' + fn; + } string pixName = ""; @@ -274,17 +277,14 @@ namespace SixLabors.ImageSharp.Tests } public static void ModifyPixel(Image img, int x, int y, byte perChannelChange) - where TPixel : struct, IPixel - { - ModifyPixel(img.Frames.RootFrame, x, y, perChannelChange); - } + where TPixel : struct, IPixel => ModifyPixel(img.Frames.RootFrame, x, y, perChannelChange); public static void ModifyPixel(ImageFrame img, int x, int y, byte perChannelChange) where TPixel : struct, IPixel { TPixel pixel = img[x, y]; Rgba64 rgbaPixel = default; - pixel.ToRgba64(ref rgbaPixel); + rgbaPixel.PackFromScaledVector4(pixel.ToScaledVector4()); ushort change = (ushort)Math.Round((perChannelChange / 255F) * 65535F); if (rgbaPixel.R + perChannelChange <= 255) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index 5a14f2e26..e6a5ffc84 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -80,10 +80,10 @@ namespace SixLabors.ImageSharp.Tests } else { - ca.ToRgb24(ref rgb1); - cb.ToRgb24(ref rgb2); + rgb1 = ca.ToRgba32().Rgb; + rgb2 = cb.ToRgba32().Rgb; - if (rgb1.R != rgb2.R || rgb1.G != rgb2.G || rgb1.B != rgb2.B) + if (!rgb1.Equals(rgb2)) { return false; } @@ -94,10 +94,7 @@ namespace SixLabors.ImageSharp.Tests return true; } - public static string ToCsv(this IEnumerable items, string separator = ",") - { - return String.Join(separator, items.Select(o => String.Format(CultureInfo.InvariantCulture, "{0}", o))); - } + public static string ToCsv(this IEnumerable items, string separator = ",") => string.Join(separator, items.Select(o => string.Format(CultureInfo.InvariantCulture, "{0}", o))); public static Type GetClrType(this PixelTypes pixelType) => PixelTypes2ClrTypes[pixelType]; @@ -141,10 +138,7 @@ namespace SixLabors.ImageSharp.Tests internal static PixelTypes[] GetAllPixelTypes() => (PixelTypes[])Enum.GetValues(typeof(PixelTypes)); internal static TPixel GetPixelOfNamedColor(string colorName) - where TPixel : struct, IPixel - { - return (TPixel)typeof(NamedColors).GetTypeInfo().GetField(colorName).GetValue(null); - } + where TPixel : struct, IPixel => (TPixel)typeof(NamedColors).GetTypeInfo().GetField(colorName).GetValue(null); /// /// Utility for testing image processor extension methods: diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 5305eb2ba..1d284af15 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -2,36 +2,26 @@ // Licensed under the Apache License, Version 2.0. using System; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; -using Xunit.Abstractions; - using System.Collections.Concurrent; using System.IO; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; +using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests { - using SixLabors.Memory; - public class TestImageProviderTests { - public TestImageProviderTests(ITestOutputHelper output) - { - this.Output = output; - } + public TestImageProviderTests(ITestOutputHelper output) => this.Output = output; private ITestOutputHelper Output { get; } [Theory] [WithBlankImages(1, 1, PixelTypes.Rgba32)] public void NoOutputSubfolderIsPresentByDefault(TestImageProvider provider) - where TPixel : struct, IPixel - { - Assert.Empty(provider.Utility.OutputSubfolderName); - } + where TPixel : struct, IPixel => Assert.Empty(provider.Utility.OutputSubfolderName); [Theory] [WithBlankImages(42, 666, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.HalfSingle, "hello")] @@ -64,10 +54,7 @@ namespace SixLabors.ImageSharp.Tests [WithBlankImages(1, 1, PixelTypes.Alpha8, PixelTypes.Alpha8)] [WithBlankImages(1, 1, PixelTypes.Argb32, PixelTypes.Argb32)] public void PixelType_PropertyValueIsCorrect(TestImageProvider provider, PixelTypes expected) - where TPixel : struct, IPixel - { - Assert.Equal(expected, provider.PixelType); - } + where TPixel : struct, IPixel => Assert.Equal(expected, provider.PixelType); [Theory] [WithFile(TestImages.Bmp.Car, PixelTypes.All, 88)] @@ -96,7 +83,7 @@ namespace SixLabors.ImageSharp.Tests // Couldn't make xUnit happy without this hackery: - private static ConcurrentDictionary invocationCounts = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary invocationCounts = new ConcurrentDictionary(); private string callerName = null; @@ -160,7 +147,7 @@ namespace SixLabors.ImageSharp.Tests return new Image(42, 42); } - private static ConcurrentDictionary invocationCounts = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary invocationCounts = new ConcurrentDictionary(); private string callerName = null; @@ -287,14 +274,12 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(10, img.Width); Assert.Equal(20, img.Height); - var rgba = default(Rgba32); - Buffer2D pixels = img.GetRootFramePixelBuffer(); for (int y = 0; y < pixels.Height; y++) { for (int x = 0; x < pixels.Width; x++) { - pixels[x, y].ToRgba32(ref rgba); + var rgba = pixels[x, y].ToRgba32(); Assert.Equal(255, rgba.R); Assert.Equal(100, rgba.G); @@ -311,10 +296,7 @@ namespace SixLabors.ImageSharp.Tests /// /// public static Image CreateTestImage() - where TPixel : struct, IPixel - { - return new Image(3, 3); - } + where TPixel : struct, IPixel => new Image(3, 3); [Theory] [WithMemberFactory(nameof(CreateTestImage), PixelTypes.All)] From b7bd7a98baed3b5bfd40f855d815a936a05e1053 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 10 Oct 2018 08:58:22 +0100 Subject: [PATCH 010/238] Fix linear gradient brush test. --- .../Drawing/FillLinearGradientBrushTests.cs | 37 ++++++++++--------- tests/Images/External | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs index 3522ade7c..74a61dfba 100644 --- a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs +++ b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs @@ -283,10 +283,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing { // it's diagonal, so for any (a, a) on the gradient line, for all (a-x, b+x) - +/- depending on the diagonal direction - must be the same color) TPixel colorOnDiagonal = image[i, i]; + + // TODO: This is incorrect. from -0 to < 0 ?? int orthoCount = 0; for (int offset = -orthoCount; offset < orthoCount; offset++) { - Assert.Equal(colorOnDiagonal, image[i + horizontalSign * offset, i + verticalSign * offset]); + Assert.Equal(colorOnDiagonal, image[i + (horizontalSign * offset), i + (verticalSign * offset)]); } } @@ -302,8 +304,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing [Theory] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })] - [WithBlankImages(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f}, new[] { 0, 1, 2, 0 })] - [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f}, new[]{0, 1, 3})] + [WithBlankImages(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f }, new[] { 0, 1, 2, 0 })] + [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f }, new[] { 0, 1, 3 })] public void ArbitraryGradients( TestImageProvider provider, int startX, int startY, @@ -312,35 +314,36 @@ namespace SixLabors.ImageSharp.Tests.Drawing int[] stopColorCodes) where TPixel : struct, IPixel { - TPixel[] colors = { - NamedColors.Navy, NamedColors.LightGreen, NamedColors.Yellow, - NamedColors.Red - }; + TPixel[] colors = + { + NamedColors.Navy, NamedColors.LightGreen, NamedColors.Yellow, + NamedColors.Red + }; var coloringVariant = new StringBuilder(); - ColorStop[] colorStops = new ColorStop[stopPositions.Length]; + var colorStops = new ColorStop[stopPositions.Length]; for (int i = 0; i < stopPositions.Length; i++) { TPixel color = colors[stopColorCodes[i % colors.Length]]; float position = stopPositions[i]; colorStops[i] = new ColorStop(position, color); - coloringVariant.AppendFormat(CultureInfo.InvariantCulture, "{0}@{1};", color, position); + coloringVariant.AppendFormat(CultureInfo.InvariantCulture, "{0}@{1};", color.ToRgba32().ToHex(), position); } FormattableString variant = $"({startX},{startY})_TO_({endX},{endY})__[{coloringVariant}]"; provider.VerifyOperation( image => - { - var unicolorLinearGradientBrush = new LinearGradientBrush( - new SixLabors.Primitives.Point(startX, startY), - new SixLabors.Primitives.Point(endX, endY), - GradientRepetitionMode.None, - colorStops); + { + var unicolorLinearGradientBrush = new LinearGradientBrush( + new SixLabors.Primitives.Point(startX, startY), + new SixLabors.Primitives.Point(endX, endY), + GradientRepetitionMode.None, + colorStops); - image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); - }, + image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); + }, variant, false, false); diff --git a/tests/Images/External b/tests/Images/External index 03c7fa758..1a807d17b 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 03c7fa7582dea75cea0d49514ccb7e1b6dc9e780 +Subproject commit 1a807d17b4cf5ab50558983d4137614cabe96ce3 From 86ba2b8843507b8f71bdb12c44fc91d17eb247df Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 13 Oct 2018 16:55:17 +0100 Subject: [PATCH 011/238] Fix up Gray8 and Gary16 tests --- .../PixelFormats/Gray16Tests.cs | 296 +++++++----------- .../PixelFormats/Gray8Tests.cs | 248 +++++---------- 2 files changed, 189 insertions(+), 355 deletions(-) diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs index 166fb230a..db4fa7019 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -15,197 +15,115 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [InlineData(32767)] [InlineData(42)] public void Gray16_PackedValue_EqualsInput(ushort input) + => Assert.Equal(input, new Gray16(input).PackedValue); + + [Fact] + public void Gray16_PackFromScaledVector4() + { + // Arrange + Gray16 gray = default; + const ushort expected = 32767; + Vector4 scaled = new Gray16(expected).ToScaledVector4(); + + // Act + gray.PackFromScaledVector4(scaled); + ushort actual = gray.PackedValue; + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(32767)] + public void Gray16_ToScaledVector4(ushort input) + { + // Arrange + var gray = new Gray16(input); + + // Act + Vector4 actual = gray.ToScaledVector4(); + + // Assert + float vectorInput = input / 65535F; + Assert.Equal(vectorInput, actual.X); + Assert.Equal(vectorInput, actual.Y); + Assert.Equal(vectorInput, actual.Z); + Assert.Equal(1F, actual.W); + } + + [Fact] + public void Gray16_PackFromVector4() + { + // Arrange + Gray16 gray = default; + const ushort expected = 32767; + var vector = new Gray16(expected).ToVector4(); + + // Act + gray.PackFromVector4(vector); + ushort actual = gray.PackedValue; + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(32767)] + public void Gray16_ToVector4(ushort input) { - Assert.Equal(input, new Gray16(input).PackedValue); + // Arrange + var gray = new Gray16(input); + + // Act + var actual = gray.ToVector4(); + + // Assert + float vectorInput = input / 65535F; + Assert.Equal(vectorInput, actual.X); + Assert.Equal(vectorInput, actual.Y); + Assert.Equal(vectorInput, actual.Z); + Assert.Equal(1F, actual.W); } - //[Theory] - //[InlineData(0)] - //[InlineData(65535)] - //[InlineData(32767)] - //public void Gray16_ToVector4(ushort input) - //{ - // // arrange - // var gray = new Gray16(input); - - // // act - // var actual = gray.ToVector4(); - - // // assert - // Assert.Equal(input, actual.X); - // Assert.Equal(input, actual.Y); - // Assert.Equal(input, actual.Z); - // Assert.Equal(1, actual.W); - //} - - //[Theory] - //[InlineData(0)] - //[InlineData(65535)] - //[InlineData(32767)] - //public void Gray16_ToScaledVector4(ushort input) - //{ - // // arrange - // var gray = new Gray16(input); - - // // act - // var actual = gray.ToScaledVector4(); - - // // assert - // float scaledInput = input / 65535f; - // Assert.Equal(scaledInput, actual.X); - // Assert.Equal(scaledInput, actual.Y); - // Assert.Equal(scaledInput, actual.Z); - // Assert.Equal(1, actual.W); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4() - //{ - // // arrange - // Gray16 gray = default; - // int expected = 32767; - // Vector4 scaled = new Gray16((ushort)expected).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // ushort actual = gray.PackedValue; - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToRgb24() - //{ - // // arrange - // Rgb24 actual = default; - // Gray16 gray = default; - // var expected = new Rgb24(128, 128, 128); - // Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToRgba32() - //{ - // // arrange - // Rgba32 actual = default; - // Gray16 gray = default; - // var expected = new Rgba32(128, 128, 128, 255); - // Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToBgr24() - //{ - // // arrange - // Bgr24 actual = default; - // Gray16 gray = default; - // var expected = new Bgr24(128, 128, 128); - // Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToBgra32() - //{ - // // arrange - // Bgra32 actual = default; - // Gray16 gray = default; - // var expected = new Bgra32(128,128,128); - // Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToArgb32() - //{ - // // arrange - // Gray16 gray = default; - // Argb32 actual = default; - // var expected = new Argb32(128, 128, 128); - // Vector4 scaled = new Gray16(32768).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromScaledVector4_ToRgba64() - //{ - // // arrange - // Gray16 gray = default; - // Rgba64 actual = default; - // var expected = new Rgba64(65535, 65535, 65535, 65535); - // Vector4 scaled = new Gray16(65535).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var gray = default(Gray16); - // var actual = default(Rgb48); - // var expected = new Rgb48(0, 0, 0); - - // // act - // gray.PackFromRgb48(expected); - // gray.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray16_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var gray = default(Gray16); - // var actual = default(Rgba64); - // var expected = new Rgba64(0, 0, 0, 65535); - - // // act - // gray.PackFromRgba64(expected); - // gray.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} + [Fact] + public void Gray16_PackFromRgba32() + { + // Arrange + Gray16 gray = default; + const byte rgb = 128; + ushort scaledRgb = ImageMaths.UpscaleFrom8BitTo16Bit(rgb); + ushort expected = ImageMaths.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb); + + // Act + gray.PackFromRgba32(new Rgba32(rgb, rgb, rgb)); + ushort actual = gray.PackedValue; + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0)] + [InlineData(65535)] + [InlineData(8100)] + public void Gray16_ToRgba32(ushort input) + { + // Arrange + ushort expected = ImageMaths.DownScaleFrom16BitTo8Bit(input); + var gray = new Gray16(input); + + // Act + var actual = gray.ToRgba32(); + + // Assert + Assert.Equal(expected, actual.R); + Assert.Equal(expected, actual.G); + Assert.Equal(expected, actual.B); + Assert.Equal(byte.MaxValue, actual.A); + } } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index ae114a0e2..aaca6c877 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -15,28 +15,23 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [InlineData(10)] [InlineData(42)] public void Gray8_PackedValue_EqualsInput(byte input) + => Assert.Equal(input, new Gray8(input).PackedValue); + + [Fact] + public void Gray8_PackFromScaledVector4() { - Assert.Equal(input, new Gray8(input).PackedValue); - } + // Arrange + Gray8 gray = default; + const byte expected = 128; + Vector4 scaled = new Gray8(expected).ToScaledVector4(); - //[Theory] - //[InlineData(0, 0)] - //[InlineData(255, 1)] - //[InlineData(30)] - //public void Gray8_ToVector4(byte input) - //{ - // // arrange - // var gray = new Gray8(input); - - // // act - // var actual = gray.ToVector4(); - - // // assert - // Assert.Equal(input, actual.X); - // Assert.Equal(input, actual.Y); - // Assert.Equal(input, actual.Z); - // Assert.Equal(1, actual.W); - //} + // Act + gray.PackFromScaledVector4(scaled); + byte actual = gray.PackedValue; + + // Assert + Assert.Equal(expected, actual); + } [Theory] [InlineData(0)] @@ -44,14 +39,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [InlineData(30)] public void Gray8_ToScaledVector4(byte input) { - // arrange + // Arrange var gray = new Gray8(input); - // act - var actual = gray.ToScaledVector4(); + // Act + Vector4 actual = gray.ToScaledVector4(); - // assert - float scaledInput = input / 255f; + // Assert + float scaledInput = input / 255F; Assert.Equal(scaledInput, actual.X); Assert.Equal(scaledInput, actual.Y); Assert.Equal(scaledInput, actual.Z); @@ -59,153 +54,74 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Gray8_PackFromScaledVector4() + public void Gray8_PackFromVector4() { - // arrange + // Arrange Gray8 gray = default; - int expected = 128; - Vector4 scaled = new Gray8(128).ToScaledVector4(); + const int expected = 128; + var vector = new Gray8(expected).ToVector4(); - // act - gray.PackFromScaledVector4(scaled); + // Act + gray.PackFromVector4(vector); + byte actual = gray.PackedValue; + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0)] + [InlineData(255)] + [InlineData(30)] + public void Gray8_ToVector4(byte input) + { + // Arrange + var gray = new Gray8(input); + + // Act + var actual = gray.ToVector4(); + + // Assert + float scaledInput = input / 255F; + Assert.Equal(scaledInput, actual.X); + Assert.Equal(scaledInput, actual.Y); + Assert.Equal(scaledInput, actual.Z); + Assert.Equal(1, actual.W); + } + + [Fact] + public void Gray8_PackFromRgba32() + { + // Arrange + Gray8 gray = default; + const byte rgb = 128; + byte expected = ImageMaths.Get8BitBT709Luminance(rgb, rgb, rgb); + + // Act + gray.PackFromRgba32(new Rgba32(rgb, rgb, rgb)); byte actual = gray.PackedValue; - // assert + // Assert Assert.Equal(expected, actual); } - //[Fact] - //public void Gray8_PackFromScaledVector4_ToRgb24() - //{ - // // arrange - // Rgb24 actual = default; - // Gray8 gray = default; - // var expected = new Rgb24(128, 128, 128); - // Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromScaledVector4_ToRgba32() - //{ - // // arrange - // Rgba32 actual = default; - // Gray8 gray = default; - // var expected = new Rgba32(128, 128, 128, 255); - // Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromScaledVector4_ToBgr24() - //{ - // // arrange - // Bgr24 actual = default; - // Gray8 gray = default; - // var expected = new Bgr24(128, 128, 128); - // Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromScaledVector4_ToBgra32() - //{ - // // arrange - // Bgra32 actual = default; - // Gray8 gray = default; - // var expected = new Bgra32(128,128,128); - // Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromScaledVector4_ToArgb32() - //{ - // // arrange - // Gray8 gray = default; - // Argb32 actual = default; - // var expected = new Argb32(128, 128, 128); - // Vector4 scaled = new Gray8(128).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromScaledVector4_ToRgba64() - //{ - // // arrange - // Gray8 gray = default; - // Rgba64 actual = default; - // var expected = new Rgba64(65535, 65535, 65535, 65535); - // Vector4 scaled = new Gray8(255).ToScaledVector4(); - - // // act - // gray.PackFromScaledVector4(scaled); - // gray.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var gray = default(Gray8); - // var actual = default(Rgb48); - // var expected = new Rgb48(0, 0, 0); - - // // act - // gray.PackFromRgb48(expected); - // gray.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Gray8_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var gray = default(Gray8); - // var actual = default(Rgba64); - // var expected = new Rgba64(0, 0, 0, 65535); - - // // act - // gray.PackFromRgba64(expected); - // gray.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} + [Theory] + [InlineData(0)] + [InlineData(255)] + [InlineData(30)] + public void Gray8_ToRgba32(byte input) + { + // Arrange + var gray = new Gray8(input); + + // Act + var actual = gray.ToRgba32(); + + // Assert + Assert.Equal(input, actual.R); + Assert.Equal(input, actual.G); + Assert.Equal(input, actual.B); + Assert.Equal(byte.MaxValue, actual.A); + } } -} +} \ No newline at end of file From 61ce88eb02330e0558e5ddf58e7e05b1e49b311c Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 13 Oct 2018 17:36:12 +0100 Subject: [PATCH 012/238] Fix up pixel format tests --- .../PixelFormats/Argb32Tests.cs | 155 ---------- .../PixelFormats/Bgr24Tests.cs | 76 ----- .../PixelFormats/Bgr565Tests.cs | 107 ------- .../PixelFormats/Bgra32Tests.cs | 76 ----- .../PixelFormats/Bgra4444Tests.cs | 155 ---------- .../PixelFormats/Bgra5551Tests.cs | 155 ---------- .../PixelFormats/Byte4Tests.cs | 155 ---------- .../PixelFormats/HalfSingleTests.cs | 107 ------- .../PixelFormats/HalfVector2Tests.cs | 107 ------- .../PixelFormats/HalfVector4Tests.cs | 155 ---------- .../PixelFormats/NormalizedByte2Tests.cs | 123 -------- .../PixelFormats/NormalizedByte4Tests.cs | 140 --------- .../PixelFormats/NormalizedShort2Tests.cs | 124 -------- .../PixelFormats/NormalizedShort4Tests.cs | 142 +-------- .../PixelFormats/Rg32Tests.cs | 92 ------ .../PixelFormats/Rgb24Tests.cs | 287 +++++++----------- .../PixelFormats/Rgb48Tests.cs | 253 ++++----------- .../PixelFormats/Rgba1010102Tests.cs | 148 +-------- .../PixelFormats/Rgba64Tests.cs | 75 +---- tests/Images/External | 2 +- 20 files changed, 198 insertions(+), 2436 deletions(-) diff --git a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs index 53545f517..6186793c5 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs @@ -66,160 +66,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.Zero, new Argb32(Vector4.One * -1234.0f).ToVector4()); Assert.Equal(Vector4.One, new Argb32(Vector4.One * +1234.0f).ToVector4()); } - - //[Fact] - //public void Argb32_ToRgb24() - //{ - // // arrange - // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(0x1a, 0, 0x80); - - // // act - // argb.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_ToRgba32() - //{ - // // arrange - // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(0x1a, 0, 0x80, 0); - - // // act - // argb.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_ToBgr24() - //{ - // // arrange - // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(0x1a, 0, 0x80); - - // // act - // argb.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_ToBgra32() - //{ - // // arrange - // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - // var actual = default(Bgra32); - // var expected = new Bgra32(0x1a, 0, 0x80, 0); - - // // act - // argb.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_ToArgb32() - //{ - // // arrange - // var argb = new Argb32(+0.1f, -0.3f, +0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(0x1a, 0, 0x80, 0); - - // // act - // argb.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var argb = default(Argb32); - // var actual = default(Rgba32); - // var expected = new Rgba32(0x1a, 0, 0x80, 0); - - // // act - // argb.PackFromRgba32(expected); - // argb.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var argb = default(Argb32); - // var actual = default(Bgra32); - // var expected = new Bgra32(0x1a, 0, 0x80, 0); - - // // act - // argb.PackFromBgra32(expected); - // argb.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var argb = default(Argb32); - // var actual = default(Argb32); - // var expected = new Argb32(0x1a, 0, 0x80, 0); - - // // act - // argb.PackFromArgb32(expected); - // argb.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var argb = default(Argb32); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // argb.PackFromRgb48(expected); - // argb.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Argb32_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var argb = default(Argb32); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // argb.PackFromRgba64(expected); - // argb.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index e742789e4..96589a03e 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -95,81 +95,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); } - - //[Fact] - //public void ToRgb24() - //{ - // var rgb = new Bgr24(1, 2, 3); - // var dest = default(Rgb24); - - // rgb.ToRgb24(ref dest); - - // Assert.Equal(new Rgb24(1, 2, 3), dest); - //} - - //[Fact] - //public void ToRgba32() - //{ - // var rgb = new Bgr24(1, 2, 3); - // var rgba = default(Rgba32); - - // rgb.ToRgba32(ref rgba); - - // Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); - //} - - //[Fact] - //public void ToBgr24() - //{ - // var rgb = new Bgr24(1, 2, 3); - // var bgr = default(Bgr24); - - // rgb.ToBgr24(ref bgr); - - // Assert.Equal(new Bgr24(1, 2, 3), bgr); - //} - - //[Fact] - //public void ToBgra32() - //{ - // var rgb = new Bgr24(1, 2, 3); - // var bgra = default(Bgra32); - - // rgb.ToBgra32(ref bgra); - - // Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); - //} - - //[Fact] - //public void Bgr24_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Bgr24); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr24_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Bgr24); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs index 6954067a3..8cbbf558d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs @@ -69,112 +69,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector3.Zero, new Bgr565(Vector3.One * -1234F).ToVector3()); Assert.Equal(Vector3.One, new Bgr565(Vector3.One * 1234F).ToVector3()); } - - //[Fact] - //public void Bgr565_ToRgb24() - //{ - // // arrange - // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - // var actual = default(Rgb24); - // var expected = new Rgb24(25, 0, 132); - - // // act - // bgra.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_ToRgba32() - //{ - // // arrange - // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - // var actual = default(Rgba32); - // var expected = new Rgba32(25, 0, 132, 255); - - // // act - // bgra.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_ToBgr24() - //{ - // // arrange - // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - // var actual = default(Bgr24); - // var expected = new Bgr24(25, 0, 132); - - // // act - // bgra.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_ToBgra32() - //{ - // // arrange - // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - // var actual = default(Bgra32); - // var expected = new Bgra32(25, 0, 132, 255); - - // // act - // bgra.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_ToArgb32() - //{ - // // arrange - // var bgra = new Bgr565(0.1F, -0.3F, 0.5F); - // var actual = default(Argb32); - // var expected = new Argb32(25, 0, 132, 255); - - // // act - // bgra.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Bgr565); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgr565_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Bgr565); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs index 9ff84a88c..1b890ac49 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -102,81 +102,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vec(1, 2, 3, 4), rgb.ToVector4()); } - - //[Fact] - //public void ToRgb24() - //{ - // var c = new Bgra32(1, 2, 3, 4); - // var dest = default(Rgb24); - - // c.ToRgb24(ref dest); - - // Assert.Equal(new Rgb24(1, 2, 3), dest); - //} - - //[Fact] - //public void ToRgba32() - //{ - // var c = new Bgra32(1, 2, 3, 4); - // var rgba = default(Rgba32); - - // c.ToRgba32(ref rgba); - - // Assert.Equal(new Rgba32(1, 2, 3, 4), rgba); - //} - - //[Fact] - //public void ToBgr24() - //{ - // var rgb = new Bgra32(1, 2, 3, 4); - // var bgr = default(Bgr24); - - // rgb.ToBgr24(ref bgr); - - // Assert.Equal(new Bgr24(1, 2, 3), bgr); - //} - - //[Fact] - //public void ToBgra32() - //{ - // var rgb = new Bgra32(1, 2, 3, 4); - // var bgra = default(Bgra32); - - // rgb.ToBgra32(ref bgra); - - // Assert.Equal(new Bgra32(1, 2, 3, 4), bgra); - //} - - //[Fact] - //public void Bgra32_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Bgra32); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra32_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Bgra32); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs index 2e6e339b6..a2fc1a052 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs @@ -70,160 +70,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.Zero, new Bgra4444(Vector4.One * -1234.0f).ToVector4()); Assert.Equal(Vector4.One, new Bgra4444(Vector4.One * 1234.0f).ToVector4()); } - - //[Fact] - //public void Bgra4444_ToRgb24() - //{ - // // arrange - // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(34, 0, 136); - - // // act - // bgra.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_ToRgba32() - //{ - // // arrange - // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(34, 0, 136, 0); - - // // act - // bgra.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_ToBgr24() - //{ - // // arrange - // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(34, 0, 136); - - // // act - // bgra.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_ToBgra32() - //{ - // // arrange - // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgra32); - // var expected = new Bgra32(34, 0, 136, 0); - - // // act - // bgra.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_ToArgb32() - //{ - // // arrange - // var bgra = new Bgra4444(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(34, 0, 136, 0); - - // // act - // bgra.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var bgra = default(Bgra4444); - // var actual = default(Rgba32); - // var expected = new Rgba32(34, 0, 136, 0); - - // // act - // bgra.PackFromRgba32(expected); - // bgra.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var bgra = default(Bgra4444); - // var actual = default(Bgra32); - // var expected = new Bgra32(34, 0, 136, 0); - - // // act - // bgra.PackFromBgra32(expected); - // bgra.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var bgra = default(Bgra4444); - // var actual = default(Argb32); - // var expected = new Argb32(34, 0, 136, 0); - - // // act - // bgra.PackFromArgb32(expected); - // bgra.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Bgra4444); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra4444_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Bgra4444); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs index 3a0aec320..084dfbd97 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs @@ -69,160 +69,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.Zero, new Bgra5551(Vector4.One * -1234.0f).ToVector4()); Assert.Equal(Vector4.One, new Bgra5551(Vector4.One * 1234.0f).ToVector4()); } - - //[Fact] - //public void Bgra5551_ToRgb24() - //{ - // // arrange - // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(24, 0, 131); - - // // act - // bgra.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_Rgba32() - //{ - // // arrange - // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(24, 0, 131, 0); - - // // act - // bgra.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_ToBgr24() - //{ - // // arrange - // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(24, 0, 131); - - // // act - // bgra.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_Bgra32() - //{ - // // arrange - // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgra32); - // var expected = new Bgra32(24, 0, 131, 0); - - // // act - // bgra.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_ToArgb32() - //{ - // // arrange - // var bgra = new Bgra5551(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(24, 0, 131, 0); - - // // act - // bgra.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var bgra = default(Bgra5551); - // var expected = new Rgba32(24, 0, 131, 0); - // var actual = default(Rgba32); - - // // act - // bgra.PackFromRgba32(expected); - // bgra.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var bgra = default(Bgra5551); - // var expected = new Bgra32(24, 0, 131, 0); - // var actual = default(Bgra32); - - // // act - // bgra.PackFromBgra32(expected); - // bgra.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var bgra = default(Bgra5551); - // var expected = new Argb32(24, 0, 131, 0); - // var actual = default(Argb32); - - // // act - // bgra.PackFromArgb32(expected); - // bgra.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Bgra5551); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Bgra5551_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Bgra5551); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs index d1e8cceaa..de1c749f6 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs @@ -67,160 +67,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.Zero, new Byte4(Vector4.One * -1234.0f).ToVector4()); Assert.Equal(Vector4.One * 255, new Byte4(Vector4.One * 1234.0f).ToVector4()); } - - //[Fact] - //public void Byte4_ToRgb24() - //{ - // // arrange - // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(128, 0, 0); - - // // act - // byte4.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_Rgba32() - //{ - // // arrange - // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(128, 0, 0, 0); - - // // act - // byte4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_ToBgr24() - //{ - // // arrange - // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(128, 0, 0); - - // // act - // byte4.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_Bgra32() - //{ - // // arrange - // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - // var actual = default(Bgra32); - // var expected = new Bgra32(128, 0, 0, 0); - - // // act - // byte4.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_Argb32() - //{ - // // arrange - // var byte4 = new Byte4(127.5f, -12.3f, 0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(128, 0, 0, 0); - - // // act - // byte4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var byte4 = default(Byte4); - // var actual = default(Rgba32); - // var expected = new Rgba32(20, 38, 0, 255); - - // // act - // byte4.PackFromRgba32(expected); - // byte4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var byte4 = default(Byte4); - // var actual = default(Bgra32); - // var expected = new Bgra32(20, 38, 0, 255); - - // // act - // byte4.PackFromBgra32(expected); - // byte4.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var byte4 = default(Byte4); - // var actual = default(Argb32); - // var expected = new Argb32(20, 38, 0, 255); - - // // act - // byte4.PackFromArgb32(expected); - // byte4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Byte4); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Byte4_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Byte4); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs index 1c3905854..fed55af6f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs @@ -66,112 +66,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void HalfSingle_ToRgb24() - //{ - // // arrange - // var halfVector = new HalfSingle(.5F); - // var actual = default(Rgb24); - // var expected = new Rgb24(128, 0, 0); - - // // act - // halfVector.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_Rgba32() - //{ - // // arrange - // var halfVector = new HalfSingle(.5F); - // var actual = default(Rgba32); - // var expected = new Rgba32(128, 0, 0, 255); - - // // act - // halfVector.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_ToBgr24() - //{ - // // arrange - // var halfVector = new HalfSingle(.5F); - // var actual = default(Bgr24); - // var expected = new Bgr24(128, 0, 0); - - // // act - // halfVector.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_Bgra32() - //{ - // // arrange - // var halfVector = new HalfSingle(.5F); - // var actual = default(Bgra32); - // var expected = new Bgra32(128, 0, 0, 255); - - // // act - // halfVector.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_Argb32() - //{ - // // arrange - // var halfVector = new HalfSingle(.5F); - // var actual = default(Argb32); - // var expected = new Argb32(128, 0, 0, 255); - - // // act - // halfVector.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(HalfSingle); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfSingle_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(HalfSingle); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs index 1ceb224e5..c775e3a0d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs @@ -71,112 +71,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void HalfVector2_ToRgb24() - //{ - // // arrange - // var halfVector = new HalfVector2(.5F, .25F); - // var actual = default(Rgb24); - // var expected = new Rgb24(128, 64, 0); - - // // act - // halfVector.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_Rgba32() - //{ - // // arrange - // var halfVector = new HalfVector2(.5F, .25F); - // var actual = default(Rgba32); - // var expected = new Rgba32(128, 64, 0, 255); - - // // act - // halfVector.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_ToBgr24() - //{ - // // arrange - // var halfVector = new HalfVector2(.5F, .25F); - // var actual = default(Bgr24); - // var expected = new Bgr24(128, 64, 0); - - // // act - // halfVector.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_Bgra32() - //{ - // // arrange - // var halfVector = new HalfVector2(.5F, .25F); - // var actual = default(Bgra32); - // var expected = new Bgra32(128, 64, 0, 255); - - // // act - // halfVector.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_Argb32() - //{ - // // arrange - // var halfVector = new HalfVector2(.5F, .25F); - // var actual = default(Argb32); - // var expected = new Argb32(128, 64, 0, 255); - - // // act - // halfVector.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(HalfVector2); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector2_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(HalfVector2); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs index 3ba571850..540a1ed08 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs @@ -65,160 +65,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void HalfVector4_ToRgb24() - //{ - // // arrange - // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - // var actual = default(Rgb24); - // var expected = new Rgb24(64, 128, 191); - - // // act - // halfVector.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_Rgba32() - //{ - // // arrange - // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - // var actual = default(Rgba32); - // var expected = new Rgba32(64, 128, 191, 255); - - // // act - // halfVector.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_ToBgr24() - //{ - // // arrange - // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - // var actual = default(Bgr24); - // var expected = new Bgr24(64, 128, 191); - - // // act - // halfVector.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_Bgra32() - //{ - // // arrange - // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - // var actual = default(Bgra32); - // var expected = new Bgra32(64, 128, 191, 255); - - // // act - // halfVector.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_Argb32() - //{ - // // arrange - // var halfVector = new HalfVector4(.25F, .5F, .75F, 1F); - // var actual = default(Argb32); - // var expected = new Argb32(64, 128, 191, 255); - - // // act - // halfVector.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var halVector = default(HalfVector4); - // var actual = default(Rgba32); - // var expected = new Rgba32(64, 128, 191, 255); - - // // act - // halVector.PackFromRgba32(expected); - // halVector.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var halVector = default(HalfVector4); - // var actual = default(Bgra32); - // var expected = new Bgra32(64, 128, 191, 255); - - // // act - // halVector.PackFromBgra32(expected); - // halVector.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var halVector = default(HalfVector4); - // var actual = default(Argb32); - // var expected = new Argb32(64, 128, 191, 255); - - // // act - // halVector.PackFromArgb32(expected); - // halVector.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(HalfVector4); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void HalfVector4_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(HalfVector4); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs index 3ab36853b..98b747a94 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs @@ -66,128 +66,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void NormalizedByte2_PackFromRgba32() - //{ - // // arrange - // var byte2 = new NormalizedByte2(); - // var rgba = new Rgba32(141, 90, 0, 0); - // int expected = 0xda0d; - - // // act - // byte2.PackFromRgba32(rgba); - // ushort actual = byte2.PackedValue; - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_ToRgb24() - //{ - // // arrange - // var short4 = new NormalizedByte2(0.1f, -0.3f); - // var actual = default(Rgb24); - // var expected = new Rgb24(141, 90, 0); - - // // act - // short4.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_ToRgba32() - //{ - // // arrange - // var short4 = new NormalizedByte2(0.1f, -0.3f); - // var actual = default(Rgba32); - // var expected = new Rgba32(141, 90, 0, 255); - - // // act - // short4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_ToBgr24() - //{ - // // arrange - // var short4 = new NormalizedByte2(0.1f, -0.3f); - // var actual = default(Bgr24); - // var expected = new Bgr24(141, 90, 0); - - // // act - // short4.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_ToBgra32() - //{ - // // arrange - // var short4 = new NormalizedByte2(0.1f, -0.3f); - // var actual = default(Bgra32); - // var expected = new Bgra32(141, 90, 0, 255); - - // // act - // short4.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_ToArgb32() - //{ - // // arrange - // var short4 = new NormalizedByte2(0.1f, -0.3f); - // var actual = default(Argb32); - // var expected = new Argb32(141, 90, 0, 255); - - // // act - // short4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(NormalizedByte2); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte2_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(NormalizedByte2); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs index acac04853..d9cca360b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs @@ -60,145 +60,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void NormalizedByte4_ToRgb24() - //{ - // // arrange - // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(141, 90, 192); - - // // act - // short4.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_ToRgba32() - //{ - // // arrange - // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(141, 90, 192, 39); - - // // act - // short4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_ToBgr24() - //{ - // // arrange - // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(141, 90, 192); - - // // act - // short4.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_ToArgb32() - //{ - // // arrange - // var short4 = new NormalizedByte4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(141, 90, 192, 39); - - // // act - // short4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var short4 = default(NormalizedByte4); - // var actual = default(Rgba32); - // var expected = new Rgba32(9, 115, 202, 127); - - // // act - // short4.PackFromRgba32(new Rgba32(9, 115, 202, 127)); - // short4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_PackFromBgra32_ToRgba32() - //{ - // // arrange - // var actual = default(Bgra32); - // var short4 = default(NormalizedByte4); - // var expected = new Bgra32(9, 115, 202, 127); - - // // act - // short4.PackFromBgra32(expected); - // short4.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_PackFromArgb32_ToRgba32() - //{ - // // arrange - // var short4 = default(NormalizedByte4); - // var actual = default(Argb32); - // var expected = new Argb32(9, 115, 202, 127); - - // // act - // short4.PackFromArgb32(expected); - // short4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(NormalizedByte4); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedByte4_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(NormalizedByte4); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs index e02d513c2..83eab82ac 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs @@ -69,129 +69,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void NormalizedShort2_PackFromRgba32_ToRgb24() - //{ - // // arrange - // var actual = default(Rgb24); - // var short2 = new NormalizedShort2(); - // var rgba = new Rgba32(141, 90, 0, 0); - // var expected = new Rgb24(141, 90, 0); - - // // act - // short2.PackFromRgba32(rgba); - // short2.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_ToRgb24() - //{ - // // arrange - // var short2 = new NormalizedShort2(0.1f, -0.3f); - // var actual = default(Rgb24); - // var expected = new Rgb24(141, 90, 0); - - // // act - // short2.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_ToRgba32() - //{ - // // arrange - // var short2 = new NormalizedShort2(0.1f, -0.3f); - // var actual = default(Rgba32); - // var expected = new Rgba32(141, 90, 0, 255); - - // // act - // short2.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_ToBgr24() - //{ - // // arrange - // var short2 = new NormalizedShort2(0.1f, -0.3f); - // var actual = default(Bgr24); - // var expected = new Bgr24(141, 90, 0); - - // // act - // short2.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_ToBgra32() - //{ - // // arrange - // var short2 = new NormalizedShort2(0.1f, -0.3f); - // var actual = default(Bgra32); - // var expected = new Bgra32(141, 90, 0, 255); - - // // act - // short2.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_ToArgb32() - //{ - // // arrange - // var short2 = new NormalizedShort2(0.1f, -0.3f); - // var actual = default(Argb32); - // var expected = new Argb32(141, 90, 0, 255); - - // // act - // short2.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(NormalizedShort2); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort2_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(NormalizedShort2); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs index 25ffbb348..40b2d05e3 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // arrange var pixel = default(NormalizedShort4); Vector4 scaled = new NormalizedShort4(Vector4.One).ToScaledVector4(); - ulong expected = (ulong)0x7FFF7FFF7FFF7FFF; + ulong expected = 0x7FFF7FFF7FFF7FFF; // act pixel.PackFromScaledVector4(scaled); @@ -61,145 +61,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // assert Assert.Equal(expected, actual); } - - //[Fact] - //public void NormalizedShort4_ToRgb24() - //{ - // // arrange - // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(141, 90, 192); - - // // act - // short4.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_ToRgba32() - //{ - // // arrange - // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(141, 90, 192, 39); - - // // act - // short4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_ToBgr24() - //{ - // // arrange - // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(141, 90, 192); - - // // act - // short4.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_ToArgb32() - //{ - // // arrange - // var short4 = new NormalizedShort4(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Argb32); - // var expected = new Argb32(141, 90, 192, 39); - - // // act - // short4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var short4 = default(NormalizedShort4); - // var expected = new Rgba32(9, 115, 202, 127); - // var actual = default(Rgba32); - - // // act - // short4.PackFromRgba32(expected); - // short4.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_PackFromBgra32_ToRgba32() - //{ - // // arrange - // var short4 = default(NormalizedShort4); - // var actual = default(Bgra32); - // var expected = new Bgra32(9, 115, 202, 127); - - // // act - // short4.PackFromBgra32(expected); - // short4.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_PackFromArgb32_ToRgba32() - //{ - // // arrange - // var short4 = default(NormalizedShort4); - // var actual = default(Argb32); - // var expected = new Argb32(9, 115, 202, 127); - - // // act - // short4.PackFromArgb32(expected); - // short4.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(NormalizedShort4); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void NormalizedShort4_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(NormalizedShort4); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs index 69ecc553e..135843e35 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs @@ -68,97 +68,5 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector2.Zero, new Rg32(Vector2.One * -1234.0f).ToVector2()); Assert.Equal(Vector2.One, new Rg32(Vector2.One * 1234.0f).ToVector2()); } - - //[Fact] - //public void Rg32_ToRgb24() - //{ - // // arrange - // var rg32 = new Rg32(0.1f, -0.3f); - // var actual = default(Rgb24); - // var expected = new Rgb24(25, 0, 0); - - // // act - // rg32.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rg32_ToRgba32() - //{ - // // arrange - // var rg32 = new Rg32(0.1f, -0.3f); - // var actual = default(Rgba32); - // var expected = new Rgba32(25, 0, 0, 255); - - // // act - // rg32.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rg32_ToBgr24() - //{ - // // arrange - // var rg32 = new Rg32(0.1f, -0.3f); - // var actual = default(Bgr24); - // var expected = new Bgr24(25, 0, 0); - - // // act - // rg32.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rg32_ToArgb32() - //{ - // // arrange - // var rg32 = new Rg32(0.1f, -0.3f); - // var actual = default(Argb32); - // var expected = new Argb32(25, 0, 0, 255); - - // // act - // rg32.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rg32_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Rg32); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 65535, 0); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rg32_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Rg32); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 65535, 0, 65535); - - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index fcbef1374..aa6d9024c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -1,175 +1,112 @@ -//// Copyright (c) Six Labors and contributors. -//// Licensed under the Apache License, Version 2.0. - -//using System; -//using System.Numerics; -//using SixLabors.ImageSharp.PixelFormats; -//using Xunit; - -//namespace SixLabors.ImageSharp.Tests.PixelFormats -//{ -// public class Rgb24Tests -// { -// public static readonly TheoryData ColorData = -// new TheoryData() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; - -// [Theory] -// [MemberData(nameof(ColorData))] -// public void Constructor(byte r, byte g, byte b) -// { -// var p = new Rgb24(r, g, b); - -// Assert.Equal(r, p.R); -// Assert.Equal(g, p.G); -// Assert.Equal(b, p.B); -// } - -// [Fact] -// public unsafe void ByteLayoutIsSequentialRgb() -// { -// var color = new Rgb24(1, 2, 3); -// byte* ptr = (byte*)&color; - -// Assert.Equal(1, ptr[0]); -// Assert.Equal(2, ptr[1]); -// Assert.Equal(3, ptr[2]); -// } - -// [Theory] -// [MemberData(nameof(ColorData))] -// public void Equals_WhenTrue(byte r, byte g, byte b) -// { -// var x = new Rgb24(r, g, b); -// var y = new Rgb24(r, g, b); - -// Assert.True(x.Equals(y)); -// Assert.True(x.Equals((object)y)); -// Assert.Equal(x.GetHashCode(), y.GetHashCode()); -// } - -// [Theory] -// [InlineData(1, 2, 3, 1, 2, 4)] -// [InlineData(0, 255, 0, 0, 244, 0)] -// [InlineData(1, 255, 0, 0, 255, 0)] -// public void Equals_WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) -// { -// var a = new Rgb24(r1, g1, b1); -// var b = new Rgb24(r2, g2, b2); - -// Assert.False(a.Equals(b)); -// Assert.False(a.Equals((object)b)); -// } - -// [Fact] -// public void PackFromRgba32() -// { -// var rgb = default(Rgb24); -// rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); - -// Assert.Equal(1, rgb.R); -// Assert.Equal(2, rgb.G); -// Assert.Equal(3, rgb.B); -// } - -// private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( -// r / 255f, -// g / 255f, -// b / 255f, -// a / 255f); - -// [Fact] -// public void PackFromVector4() -// { -// var rgb = default(Rgb24); -// rgb.PackFromVector4(Vec(1, 2, 3, 4)); - -// Assert.Equal(1, rgb.R); -// Assert.Equal(2, rgb.G); -// Assert.Equal(3, rgb.B); -// } - -// [Fact] -// public void ToVector4() -// { -// var rgb = new Rgb24(1, 2, 3); - -// Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); -// } - -// [Fact] -// public void ToRgb24() -// { -// var rgb = new Rgb24(1, 2, 3); -// var dest = default(Rgb24); - -// rgb.ToRgb24(ref dest); - -// Assert.Equal(rgb, dest); -// } - -// [Fact] -// public void ToRgba32() -// { -// var rgb = new Rgb24(1, 2, 3); -// var rgba = default(Rgba32); - -// rgb.ToRgba32(ref rgba); - -// Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); -// } - -// [Fact] -// public void ToBgr24() -// { -// var rgb = new Rgb24(1, 2, 3); -// var bgr = default(Bgr24); - -// rgb.ToBgr24(ref bgr); - -// Assert.Equal(new Bgr24(1, 2, 3), bgr); -// } - -// [Fact] -// public void ToBgra32() -// { -// var rgb = new Rgb24(1, 2, 3); -// var bgra = default(Bgra32); - -// rgb.ToBgra32(ref bgra); - -// Assert.Equal(new Bgra32(1, 2, 3, 255), bgra); -// } - -// [Fact] -// public void Rgb24_PackFromRgb48_ToRgb48() -// { -// // arrange -// var input = default(Rgb24); -// var actual = default(Rgb48); -// var expected = new Rgb48(65535, 0, 65535); - -// // act -// input.PackFromRgb48(expected); -// input.ToRgb48(ref actual); - -// // assert -// Assert.Equal(expected, actual); -// } - -// [Fact] -// public void Rgb24_PackFromRgba64_ToRgba64() -// { -// // arrange -// var input = default(Rgb24); -// var actual = default(Rgba64); -// var expected = new Rgba64(65535, 0, 65535, 65535); - -// // act -// input.PackFromRgba64(expected); -// input.ToRgba64(ref actual); - -// // assert -// Assert.Equal(expected, actual); -// } -// } -//} \ No newline at end of file +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public class Rgb24Tests + { + public static readonly TheoryData ColorData = + new TheoryData() + { + { 1, 2, 3 }, + { 4, 5, 6 }, + { 0, 255, 42 } + }; + + [Theory] + [MemberData(nameof(ColorData))] + public void Constructor(byte r, byte g, byte b) + { + var p = new Rgb24(r, g, b); + + Assert.Equal(r, p.R); + Assert.Equal(g, p.G); + Assert.Equal(b, p.B); + } + + [Fact] + public unsafe void ByteLayoutIsSequentialRgb() + { + var color = new Rgb24(1, 2, 3); + byte* ptr = (byte*)&color; + + Assert.Equal(1, ptr[0]); + Assert.Equal(2, ptr[1]); + Assert.Equal(3, ptr[2]); + } + + [Theory] + [MemberData(nameof(ColorData))] + public void Equals_WhenTrue(byte r, byte g, byte b) + { + var x = new Rgb24(r, g, b); + var y = new Rgb24(r, g, b); + + Assert.True(x.Equals(y)); + Assert.True(x.Equals((object)y)); + Assert.Equal(x.GetHashCode(), y.GetHashCode()); + } + + [Theory] + [InlineData(1, 2, 3, 1, 2, 4)] + [InlineData(0, 255, 0, 0, 244, 0)] + [InlineData(1, 255, 0, 0, 255, 0)] + public void Equals_WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) + { + var a = new Rgb24(r1, g1, b1); + var b = new Rgb24(r2, g2, b2); + + Assert.False(a.Equals(b)); + Assert.False(a.Equals((object)b)); + } + + [Fact] + public void PackFromRgba32() + { + var rgb = default(Rgb24); + rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); + + Assert.Equal(1, rgb.R); + Assert.Equal(2, rgb.G); + Assert.Equal(3, rgb.B); + } + + private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( + r / 255f, + g / 255f, + b / 255f, + a / 255f); + + [Fact] + public void PackFromVector4() + { + var rgb = default(Rgb24); + rgb.PackFromVector4(Vec(1, 2, 3, 4)); + + Assert.Equal(1, rgb.R); + Assert.Equal(2, rgb.G); + Assert.Equal(3, rgb.B); + } + + [Fact] + public void ToVector4() + { + var rgb = new Rgb24(1, 2, 3); + + Assert.Equal(Vec(1, 2, 3), rgb.ToVector4()); + } + + [Fact] + public void ToRgba32() + { + var rgb = new Rgb24(1, 2, 3); + var rgba = rgb.ToRgba32(); + + Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs index 2af488e3c..16dfd7f57 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs @@ -1,192 +1,61 @@ -//// Copyright (c) Six Labors and contributors. -//// Licensed under the Apache License, Version 2.0. - -//using System.Numerics; -//using SixLabors.ImageSharp.PixelFormats; -//using Xunit; - -//namespace SixLabors.ImageSharp.Tests.PixelFormats -//{ -// public class Rgb48Tests -// { -// [Fact] -// public void Rgb48_Values() -// { -// var rgb = new Rgba64(5243, 9830, 19660, 29491); - -// Assert.Equal(5243, rgb.R); -// Assert.Equal(9830, rgb.G); -// Assert.Equal(19660, rgb.B); -// Assert.Equal(29491, rgb.A); -// } - -// [Fact] -// public void Rgb48_ToVector4() -// { -// Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(0, 0, 0, 0).ToVector4()); -// Assert.Equal(Vector4.One, new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); -// } - -// [Fact] -// public void Rgb48_ToScaledVector4() -// { -// // arrange -// var short2 = new Rgb48(Vector3.One); - -// // act -// Vector4 actual = short2.ToScaledVector4(); - -// // assert -// Assert.Equal(1, actual.X); -// Assert.Equal(1, actual.Y); -// Assert.Equal(1, actual.Z); -// Assert.Equal(1, actual.W); -// } - -// [Fact] -// public void Rgb48_PackFromScaledVector4() -// { -// // arrange -// var pixel = default(Rgb48); -// var short3 = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); -// var expected = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); - -// // act -// Vector4 scaled = short3.ToScaledVector4(); -// pixel.PackFromScaledVector4(scaled); - -// // assert -// Assert.Equal(expected, pixel); -// } - -// //[Fact] -// //public void Rgb48_Clamping() -// //{ -// // Assert.Equal(new Vector4(0, 0, 0, 1), new Rgb48(Vector3.One * -1234.0f).ToVector4()); -// // Assert.Equal(Vector4.One, new Rgb48(Vector3.One * 1234.0f).ToVector4()); -// //} - -// //[Fact] -// //public void Rgb48_ToRgb24() -// //{ -// // // arrange -// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); -// // var actual = default(Rgb24); -// // var expected = new Rgb24(20, 38, 76); - -// // // act -// // rgba48.ToRgb24(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_ToRgba32() -// //{ -// // // arrange -// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); -// // var actual = default(Rgba32); -// // var expected = new Rgba32(20, 38, 76, 255); - -// // // act -// // rgba48.ToRgba32(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_ToArgb32() -// //{ -// // // arrange -// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); -// // var actual = default(Argb32); -// // var expected = new Argb32(20, 38, 76, 255); - -// // // act -// // rgba48.ToArgb32(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgba64_ToBgr24() -// //{ -// // // arrange -// // var rgb48 = new Rgb48(0.08f, 0.15f, 0.30f); -// // var actual = default(Bgr24); -// // var expected = new Bgr24(20, 38, 76); - -// // // act -// // rgb48.ToBgr24(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_ToBgra32() -// //{ -// // // arrange -// // var rgba48 = new Rgb48(0.08f, 0.15f, 0.30f); -// // var actual = default(Bgra32); -// // var expected = new Bgra32(20, 38, 76, 255); - -// // // act -// // rgba48.ToBgra32(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_PackFromRgba32_ToRgba32() -// //{ -// // // arrange -// // var rgb48 = default(Rgb48); -// // var actual = default(Rgba32); -// // var expected = new Rgba32(20, 38, 76, 255); - -// // // act -// // rgb48.PackFromRgba32(expected); -// // rgb48.ToRgba32(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_PackFromRgb48_ToRgb48() -// //{ -// // // arrange -// // var input = default(Rgb48); -// // var actual = default(Rgb48); -// // var expected = new Rgb48(65535, 0, 65535); - -// // // act -// // input.PackFromRgb48(expected); -// // input.ToRgb48(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} - -// //[Fact] -// //public void Rgb48_PackFromRgba64_ToRgba64() -// //{ -// // // arrange -// // var input = default(Rgb48); -// // var actual = default(Rgba64); -// // var expected = new Rgba64(65535, 0, 65535, 65535); - -// // // act -// // input.PackFromRgba64(expected); -// // input.ToRgba64(ref actual); - -// // // assert -// // Assert.Equal(expected, actual); -// //} -// } -//} +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public class Rgb48Tests + { + [Fact] + public void Rgb48_Values() + { + var rgb = new Rgba64(5243, 9830, 19660, 29491); + + Assert.Equal(5243, rgb.R); + Assert.Equal(9830, rgb.G); + Assert.Equal(19660, rgb.B); + Assert.Equal(29491, rgb.A); + } + + [Fact] + public void Rgb48_ToVector4() + => Assert.Equal(Vector4.One, new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); + + [Fact] + public void Rgb48_ToScaledVector4() + => Assert.Equal(Vector4.One, new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); + + [Fact] + public void Rgb48_PackFromScaledVector4() + { + // arrange + var pixel = default(Rgb48); + var short3 = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); + var expected = new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); + + // act + Vector4 scaled = short3.ToScaledVector4(); + pixel.PackFromScaledVector4(scaled); + + // assert + Assert.Equal(expected, pixel); + } + + [Fact] + public void Rgb48_ToRgba32() + { + // arrange + var rgba48 = new Rgb48(5140, 9766, 19532); + var expected = new Rgba32(20, 38, 76, 255); + + // act + var actual = rgba48.ToRgba32(); + + // assert + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs index d8ad6d3f1..243d4a44c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs @@ -71,144 +71,18 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, new Rgba1010102(Vector4.One * 1234.0f).ToVector4()); } - //[Fact] - //public void Rgba1010102_ToRgb24() - //{ - // // arrange - // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgb24); - // var expected = new Rgb24(25, 0, 128); - - // // act - // rgba.ToRgb24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_ToRgba32() - //{ - // // arrange - // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Rgba32); - // var expected = new Rgba32(25, 0, 128, 0); - - // // act - // rgba.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_ToBgr24() - //{ - // // arrange - // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgr24); - // var expected = new Bgr24(25, 0, 128); - - // // act - // rgba.ToBgr24(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_ToBgra32() - //{ - // // arrange - // var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); - // var actual = default(Bgra32); - // var expected = new Bgra32(25, 0, 128, 0); - - // // act - // rgba.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var rgba = default(Rgba1010102); - // var expected = new Rgba32(25, 0, 128, 0); - // var actual = default(Rgba32); - - // // act - // rgba.PackFromRgba32(expected); - // rgba.ToRgba32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_PackFromBgra32_ToBgra32() - //{ - // // arrange - // var rgba = default(Rgba1010102); - // var expected = new Bgra32(25, 0, 128, 0); - // var actual = default(Bgra32); - - // // act - // rgba.PackFromBgra32(expected); - // rgba.ToBgra32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_PackFromArgb32_ToArgb32() - //{ - // // arrange - // var rgba = default(Rgba1010102); - // var expected = new Argb32(25, 0, 128, 0); - // var actual = default(Argb32); - - // // act - // rgba.PackFromArgb32(expected); - // rgba.ToArgb32(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_PackFromRgb48_ToRgb48() - //{ - // // arrange - // var input = default(Rgba1010102); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - // input.ToRgb48(ref actual); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba1010102_PackFromRgba64_ToRgba64() - //{ - // // arrange - // var input = default(Rgba1010102); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 65535); + [Fact] + public void Rgba1010102_ToRgba32() + { + // arrange + var rgba = new Rgba1010102(0.1f, -0.3f, 0.5f, -0.7f); + var expected = new Rgba32(25, 0, 128, 0); - // // act - // input.PackFromRgba64(expected); - // input.ToRgba64(ref actual); + // act + var actual = rgba.ToRgba32(); - // // assert - // Assert.Equal(expected, actual); - //} + // assert + Assert.Equal(expected, actual); + } } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs index 185fc5635..e9ac5377d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs @@ -77,70 +77,19 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(Vector4.One, one.ToVector4()); } - //[Fact] - //public void Rgba64_ToRgba32() - //{ - // // arrange - // var rgba64 = new Rgba64( - // (ushort)(0.08f * ushort.MaxValue), - // (ushort)(0.15f * ushort.MaxValue), - // (ushort)(0.30f * ushort.MaxValue), - // (ushort)(0.45f * ushort.MaxValue)); - // var actual = default(Rgba32); - // var expected = new Rgba32(20, 38, 76, 115); - - // // act - // actual = rgba64.ToRgba32(); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba64_PackFromRgba32_ToRgba32() - //{ - // // arrange - // var rgba64 = default(Rgba64); - // var actual = default(Rgba32); - // var expected = new Rgba32(20, 38, 76, 115); - - // // act - // rgba64.PackFromRgba32(expected); - // actual = rgba64.ToRgba32(); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgb48_PackFromRgb48() - //{ - // // arrange - // var input = default(Rgba64); - // var actual = default(Rgb48); - // var expected = new Rgb48(65535, 0, 65535); - - // // act - // input.PackFromRgb48(expected); - - // // assert - // Assert.Equal(expected, actual); - //} - - //[Fact] - //public void Rgba64_PackFromRgba64() - //{ - // // arrange - // var input = default(Rgba64); - // var actual = default(Rgba64); - // var expected = new Rgba64(65535, 0, 65535, 0); + [Fact] + public void Rgba64_ToRgba32() + { + // arrange + var rgba64 = new Rgba64(5140, 9766, 19532, 29555); + var actual = default(Rgba32); + var expected = new Rgba32(20, 38, 76, 115); - // // act - // input.PackFromRgba64(expected); - // actual.PackFromScaledVector4(input.ToScaledVector4()); + // act + actual = rgba64.ToRgba32(); - // // assert - // Assert.Equal(expected, actual); - //} + // assert + Assert.Equal(expected, actual); + } } } diff --git a/tests/Images/External b/tests/Images/External index 1a807d17b..ee90e5f32 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 1a807d17b4cf5ab50558983d4137614cabe96ce3 +Subproject commit ee90e5f32218027744b5d40058b587cc1047b76f From 189d602fb728f4a1ca659021bac57455cdde0040 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 14 Oct 2018 22:43:02 +0200 Subject: [PATCH 013/238] BulkConvertByteToNormalizedFloat --- src/ImageSharp/Common/Extensions/SimdUtils.cs | 75 +- .../PixelFormats/Rgba32.PixelOperations.cs | 12 +- .../Color/Bulk/ToVector4.cs | 31 +- .../PixelFormats/PixelOperationsTests.cs | 1384 +++++++++-------- 4 files changed, 802 insertions(+), 700 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Extensions/SimdUtils.cs index 7b77fefca..db1e80dda 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.cs @@ -7,6 +7,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.PixelFormats; + namespace SixLabors.ImageSharp { /// @@ -103,6 +105,47 @@ namespace SixLabors.ImageSharp } } + internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + { + if (!Vector.IsHardwareAccelerated) + { + throw new InvalidOperationException( + "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); + } + + DebugGuard.IsTrue((dest.Length % Vector.Count) == 0, nameof(source), "dest.Length should be divisable by Vector.Count!"); + + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); + + ref Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); + + int n = dest.Length / 8; + Octet.OfUInt32 temp = default; + + for (int i = 0; i < n; i++) + { + Octet.OfByte sVal = Unsafe.Add(ref sourceBase, i); + + // This call is the bottleneck now: + temp.LoadFrom(ref sVal); + + Vector vi = Unsafe.As>(ref temp); + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + + Unsafe.Add(ref destBaseAsFloat, i) = vf; + } + } + /// /// Same as but clamps overflown values before conversion. /// @@ -181,6 +224,19 @@ namespace SixLabors.ImageSharp { return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; } + + [MethodImpl(InliningOptions.ShortMethod)] + public void LoadFrom(ref OfByte src) + { + this.V0 = src.V0; + this.V1 = src.V1; + this.V2 = src.V2; + this.V3 = src.V3; + this.V4 = src.V4; + this.V5 = src.V5; + this.V6 = src.V6; + this.V7 = src.V7; + } } [StructLayout(LayoutKind.Explicit, Size = 8)] @@ -215,16 +271,17 @@ namespace SixLabors.ImageSharp return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; } - public void LoadFrom(ref OfUInt32 i) + [MethodImpl(InliningOptions.ShortMethod)] + public void LoadFrom(ref OfUInt32 src) { - this.V0 = (byte)i.V0; - this.V1 = (byte)i.V1; - this.V2 = (byte)i.V2; - this.V3 = (byte)i.V3; - this.V4 = (byte)i.V4; - this.V5 = (byte)i.V5; - this.V6 = (byte)i.V6; - this.V7 = (byte)i.V7; + this.V0 = (byte)src.V0; + this.V1 = (byte)src.V1; + this.V2 = (byte)src.V2; + this.V3 = (byte)src.V3; + this.V4 = (byte)src.V4; + this.V5 = (byte)src.V5; + this.V6 = (byte)src.V6; + this.V7 = (byte)src.V7; } } } diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 2629ce3f7..76e119ba4 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -57,14 +57,14 @@ namespace SixLabors.ImageSharp.PixelFormats int unpackedRawCount = count * 4; ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(sourceColors)); - ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); - ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsUnpacked); - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsUnpacked); + ref WideRgba destBaseAsWide = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); + ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsWide); + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWide); for (int i = 0; i < count; i++) { uint sVal = Unsafe.Add(ref sourceBase, i); - ref UnpackedRGBA dst = ref Unsafe.Add(ref destBaseAsUnpacked, i); + ref WideRgba dst = ref Unsafe.Add(ref destBaseAsWide, i); // This call is the bottleneck now: dst.Load(sVal); @@ -174,10 +174,10 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Value type to store -s unpacked into multiple -s. + /// Value type to store -s widened into multiple -s. /// [StructLayout(LayoutKind.Sequential)] - private struct UnpackedRGBA + private struct WideRgba { private uint r; diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 50fac2513..7b6f902d8 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -6,8 +6,13 @@ using System.Buffers; using System; using System.Numerics; +using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Jobs; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Jobs; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -17,11 +22,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public abstract class ToVector4 where TPixel : struct, IPixel { - private IMemoryOwner source; + protected IMemoryOwner source; - private IMemoryOwner destination; + protected IMemoryOwner destination; - [Params(64, 300, 1024)] + [Params( + //64, + 1024)] public int Count { get; set; } [GlobalSetup] @@ -38,7 +45,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.destination.Dispose(); } - [Benchmark(Baseline = true)] + [Benchmark] public void PerElement() { Span s = this.source.GetSpan(); @@ -51,7 +58,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + [Benchmark(Baseline = true)] public void CommonBulk() { new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); @@ -64,7 +71,21 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } + [CoreJob] + //[ClrJob] public class ToVector4_Rgba32 : ToVector4 { + class Config : ManualConfig + { + } + + [Benchmark] + public void BulkConvertByteToNormalizedFloat() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 9e41fd94f..a96da03e7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -1,93 +1,117 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Buffers; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.PixelFormats; -using Xunit; -using Xunit.Abstractions; - -namespace SixLabors.ImageSharp.Tests.PixelFormats -{ - public partial class PixelOperationsTests - { - public class Rgba32 : PixelOperationsTests - { - public Rgba32(ITestOutputHelper output) - : base(output) - { - } - - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - - [Fact] - public void IsSpecialImplementation() - { - Assert.IsType(PixelOperations.Instance); - } - - [Fact] - public void ToVector4SimdAligned() - { - if (!Vector.IsHardwareAccelerated) - { - return; - } - - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) - ); - } - - - // [Fact] // Profiling benchmark - enable manually! -#pragma warning disable xUnit1013 // Public method should be marked as test - public void Benchmark_ToVector4() -#pragma warning restore xUnit1013 // Public method should be marked as test - { - int times = 200000; - int count = 1024; - - using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) - using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) - { - this.Measure( - times, - () => - { - PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); - }); - } - } - } - - public class Argb32 : PixelOperationsTests - { - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public Argb32(ITestOutputHelper output) - : base(output) - { - } - - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - } - - [Theory] - [WithBlankImages(1, 1, PixelTypes.All)] - public void GetGlobalInstance(TestImageProvider dummy) - where TPixel : struct, IPixel - { - Assert.NotNull(PixelOperations.Instance); +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Buffers; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public partial class PixelOperationsTests + { + public class Rgba32 : PixelOperationsTests + { + public Rgba32(ITestOutputHelper output) + : base(output) + { + } + + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() + { + Assert.IsType(PixelOperations.Instance); + } + + [Fact] + public void ToVector4SimdAligned() + { + if (!Vector.IsHardwareAccelerated) + { + return; + } + + ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) + ); + } + + [Fact] + public void BulkConvertByteToNormalizedFloat() + { + if (!Vector.IsHardwareAccelerated) + { + return; + } + + ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => + { + ReadOnlySpan sBytes = MemoryMarshal.Cast(s); + Span dFloats = MemoryMarshal.Cast(d.Memory.Span); + + SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + } + ); + } + + + // [Fact] // Profiling benchmark - enable manually! +#pragma warning disable xUnit1013 // Public method should be marked as test + public void Benchmark_ToVector4() +#pragma warning restore xUnit1013 // Public method should be marked as test + { + int times = 200000; + int count = 1024; + + using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) + using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) + { + this.Measure( + times, + () => + { + PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); + }); + } + } + } + + public class Argb32 : PixelOperationsTests + { + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public Argb32(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + } + + [Theory] + [WithBlankImages(1, 1, PixelTypes.All)] + public void GetGlobalInstance(TestImageProvider dummy) + where TPixel : struct, IPixel + { + Assert.NotNull(PixelOperations.Instance); } [Fact] @@ -99,594 +123,594 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Transparent)); Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal,PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - } - } - - public abstract class PixelOperationsTests : MeasureFixture - where TPixel : struct, IPixel - { - protected PixelOperationsTests(ITestOutputHelper output) - : base(output) - { - } - - public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - - private static PixelOperations Operations => PixelOperations.Instance; - - internal static TPixel[] CreateExpectedPixelData(Vector4[] source) - { - var expected = new TPixel[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i].PackFromVector4(source[i]); - } - return expected; - } - - internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source) - { - var expected = new TPixel[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i].PackFromScaledVector4(source[i]); - } - return expected; - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromVector4(int count) - { - Vector4[] source = CreateVector4TestData(count); - TPixel[] expected = CreateExpectedPixelData(source); - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromScaledVector4(int count) - { - Vector4[] source = CreateVector4TestData(count); - TPixel[] expected = CreateScaledExpectedPixelData(source); - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromScaledVector4(s, d.GetSpan(), count) - ); - } - - internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToVector4(); - } - return expected; - } - - internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToScaledVector4(); - } - return expected; - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToVector4(int count) - { - TPixel[] source = CreatePixelTestData(count); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => Operations.ToVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToScaledVector4(int count) - { - TPixel[] source = CreateScaledPixelTestData(count); - Vector4[] expected = CreateExpectedScaledVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => Operations.ToScaledVector4(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgb24Bytes(int count) - { - byte[] source = CreateByteTestData(count * 3); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - - expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgb24Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var rgb = default(Rgb24); - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - source[i].ToRgb24(ref rgb); - expected[i3] = rgb.R; - expected[i3 + 1] = rgb.G; - expected[i3 + 2] = rgb.B; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgba32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgba32Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var rgba = default(Rgba32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToRgba32(ref rgba); - expected[i4] = rgba.R; - expected[i4 + 1] = rgba.G; - expected[i4 + 2] = rgba.B; - expected[i4 + 3] = rgba.A; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgb48Bytes(int count) - { - byte[] source = CreateByteTestData(count * 6); - Span sourceSpan = source.AsSpan(); - var expected = new TPixel[count]; - - var rgba64 = new Rgba64(0, 0, 0, 65535); - for (int i = 0; i < count; i++) - { - int i6 = i * 6; - rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; - expected[i].PackFromRgba64(rgba64); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgb48Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 6]; - Rgb48 rgb = default; - - for (int i = 0; i < count; i++) - { - int i6 = i * 6; - source[i].ToRgb48(ref rgb); - Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); - expected[i6] = rgb48Bytes[0]; - expected[i6 + 1] = rgb48Bytes[1]; - expected[i6 + 2] = rgb48Bytes[2]; - expected[i6 + 3] = rgb48Bytes[3]; - expected[i6 + 4] = rgb48Bytes[4]; - expected[i6 + 5] = rgb48Bytes[5]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromRgba64Bytes(int count) - { - byte[] source = CreateByteTestData(count * 8); - Span sourceSpan = source.AsSpan(); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i8 = i * 8; - expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToRgba64Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 8]; - Rgba64 rgba = default; - - for (int i = 0; i < count; i++) - { - int i8 = i * 8; - source[i].ToRgba64(ref rgba); - Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); - expected[i8] = rgba64Bytes[0]; - expected[i8 + 1] = rgba64Bytes[1]; - expected[i8 + 2] = rgba64Bytes[2]; - expected[i8 + 3] = rgba64Bytes[3]; - expected[i8 + 4] = rgba64Bytes[4]; - expected[i8 + 5] = rgba64Bytes[5]; - expected[i8 + 6] = rgba64Bytes[6]; - expected[i8 + 7] = rgba64Bytes[7]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromBgr24Bytes(int count) - { - byte[] source = CreateByteTestData(count * 3); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - - expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToBgr24Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var bgr = default(Bgr24); - - for (int i = 0; i < count; i++) - { - int i3 = i * 3; - source[i].ToBgr24(ref bgr); - expected[i3] = bgr.B; - expected[i3 + 1] = bgr.G; - expected[i3 + 2] = bgr.R; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromBgra32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToZyxwBytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var bgra = default(Bgra32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToBgra32(ref bgra); - expected[i4] = bgra.B; - expected[i4 + 1] = bgra.G; - expected[i4 + 2] = bgra.R; - expected[i4 + 3] = bgra.A; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void PackFromArgb32Bytes(int count) - { - byte[] source = CreateByteTestData(count * 4); - var expected = new TPixel[count]; - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToArgb32Bytes(int count) - { - TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var argb = default(Argb32); - - for (int i = 0; i < count; i++) - { - int i4 = i * 4; - source[i].ToArgb32(ref argb); - expected[i4] = argb.A; - expected[i4 + 1] = argb.R; - expected[i4 + 2] = argb.G; - expected[i4 + 3] = argb.B; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) - ); - } - - private class TestBuffers : IDisposable - where TSource : struct - where TDest : struct - { - public TSource[] SourceBuffer { get; } - public IMemoryOwner ActualDestBuffer { get; } - public TDest[] ExpectedDestBuffer { get; } - - public TestBuffers(TSource[] source, TDest[] expectedDest) - { - this.SourceBuffer = source; - this.ExpectedDestBuffer = expectedDest; - this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); - } - - public void Dispose() - { - this.ActualDestBuffer.Dispose(); - } - - private const float Tolerance = 0.0001f; - - public void Verify() - { - int count = this.ExpectedDestBuffer.Length; - - if (typeof(TDest) == typeof(Vector4)) - { - - Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); - Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); - - for (int i = 0; i < count; i++) - { - // ReSharper disable PossibleNullReferenceException - Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); - // ReSharper restore PossibleNullReferenceException - } - } - else - { - Span expected = this.ExpectedDestBuffer.AsSpan(); - Span actual = this.ActualDestBuffer.GetSpan(); - for (int i = 0; i < count; i++) - { - Assert.Equal(expected[i], actual[i]); - } - } - } - } - - internal static void TestOperation( - TSource[] source, - TDest[] expected, - Action> action) - where TSource : struct - where TDest : struct - { - using (var buffers = new TestBuffers(source, expected)) - { - action(buffers.SourceBuffer, buffers.ActualDestBuffer); - buffers.Verify(); - } - } - - internal static Vector4[] CreateVector4TestData(int length) - { - var result = new Vector4[length]; - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - result[i] = GetVector(rnd); - } - return result; - } - - internal static TPixel[] CreatePixelTestData(int length) - { - var result = new TPixel[length]; - - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - Vector4 v = GetVector(rnd); - result[i].PackFromVector4(v); - } - - return result; - } - - internal static TPixel[] CreateScaledPixelTestData(int length) - { - var result = new TPixel[length]; - - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - Vector4 v = GetVector(rnd); - result[i].PackFromScaledVector4(v); - } - - return result; - } - - internal static byte[] CreateByteTestData(int length) - { - byte[] result = new byte[length]; - var rnd = new Random(42); // Deterministic random values - - for (int i = 0; i < result.Length; i++) - { - result[i] = (byte)rnd.Next(255); - } - return result; - } - - internal static Vector4 GetVector(Random rnd) - { - return new Vector4( - (float)rnd.NextDouble(), - (float)rnd.NextDouble(), - (float)rnd.NextDouble(), - (float)rnd.NextDouble() - ); - } - - [StructLayout(LayoutKind.Sequential)] - private unsafe struct Rgba64Bytes - { - public fixed byte Data[8]; - - public byte this[int idx] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ref byte self = ref Unsafe.As(ref this); - return Unsafe.Add(ref self, idx); - } - } - } - } + } + } + + public abstract class PixelOperationsTests : MeasureFixture + where TPixel : struct, IPixel + { + protected PixelOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + private static PixelOperations Operations => PixelOperations.Instance; + + internal static TPixel[] CreateExpectedPixelData(Vector4[] source) + { + var expected = new TPixel[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i].PackFromVector4(source[i]); + } + return expected; + } + + internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source) + { + var expected = new TPixel[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i].PackFromScaledVector4(source[i]); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromVector4(int count) + { + Vector4[] source = CreateVector4TestData(count); + TPixel[] expected = CreateExpectedPixelData(source); + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromScaledVector4(int count) + { + Vector4[] source = CreateVector4TestData(count); + TPixel[] expected = CreateScaledExpectedPixelData(source); + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromScaledVector4(s, d.GetSpan(), count) + ); + } + + internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToVector4(); + } + return expected; + } + + internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToScaledVector4(); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToVector4(int count) + { + TPixel[] source = CreatePixelTestData(count); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToScaledVector4(int count) + { + TPixel[] source = CreateScaledPixelTestData(count); + Vector4[] expected = CreateExpectedScaledVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => Operations.ToScaledVector4(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgb24Bytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgb24Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + var rgb = default(Rgb24); + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + source[i].ToRgb24(ref rgb); + expected[i3] = rgb.R; + expected[i3 + 1] = rgb.G; + expected[i3 + 2] = rgb.B; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgba32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgba32Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var rgba = default(Rgba32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToRgba32(ref rgba); + expected[i4] = rgba.R; + expected[i4 + 1] = rgba.G; + expected[i4 + 2] = rgba.B; + expected[i4 + 3] = rgba.A; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgb48Bytes(int count) + { + byte[] source = CreateByteTestData(count * 6); + Span sourceSpan = source.AsSpan(); + var expected = new TPixel[count]; + + var rgba64 = new Rgba64(0, 0, 0, 65535); + for (int i = 0; i < count; i++) + { + int i6 = i * 6; + rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; + expected[i].PackFromRgba64(rgba64); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgb48Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 6]; + Rgb48 rgb = default; + + for (int i = 0; i < count; i++) + { + int i6 = i * 6; + source[i].ToRgb48(ref rgb); + Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); + expected[i6] = rgb48Bytes[0]; + expected[i6 + 1] = rgb48Bytes[1]; + expected[i6 + 2] = rgb48Bytes[2]; + expected[i6 + 3] = rgb48Bytes[3]; + expected[i6 + 4] = rgb48Bytes[4]; + expected[i6 + 5] = rgb48Bytes[5]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromRgba64Bytes(int count) + { + byte[] source = CreateByteTestData(count * 8); + Span sourceSpan = source.AsSpan(); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i8 = i * 8; + expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToRgba64Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 8]; + Rgba64 rgba = default; + + for (int i = 0; i < count; i++) + { + int i8 = i * 8; + source[i].ToRgba64(ref rgba); + Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); + expected[i8] = rgba64Bytes[0]; + expected[i8 + 1] = rgba64Bytes[1]; + expected[i8 + 2] = rgba64Bytes[2]; + expected[i8 + 3] = rgba64Bytes[3]; + expected[i8 + 4] = rgba64Bytes[4]; + expected[i8 + 5] = rgba64Bytes[5]; + expected[i8 + 6] = rgba64Bytes[6]; + expected[i8 + 7] = rgba64Bytes[7]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromBgr24Bytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToBgr24Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + var bgr = default(Bgr24); + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + source[i].ToBgr24(ref bgr); + expected[i3] = bgr.B; + expected[i3 + 1] = bgr.G; + expected[i3 + 2] = bgr.R; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromBgra32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToZyxwBytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var bgra = default(Bgra32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToBgra32(ref bgra); + expected[i4] = bgra.B; + expected[i4 + 1] = bgra.G; + expected[i4 + 2] = bgra.R; + expected[i4 + 3] = bgra.A; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromArgb32Bytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToArgb32Bytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var argb = default(Argb32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToArgb32(ref argb); + expected[i4] = argb.A; + expected[i4 + 1] = argb.R; + expected[i4 + 2] = argb.G; + expected[i4 + 3] = argb.B; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) + ); + } + + private class TestBuffers : IDisposable + where TSource : struct + where TDest : struct + { + public TSource[] SourceBuffer { get; } + public IMemoryOwner ActualDestBuffer { get; } + public TDest[] ExpectedDestBuffer { get; } + + public TestBuffers(TSource[] source, TDest[] expectedDest) + { + this.SourceBuffer = source; + this.ExpectedDestBuffer = expectedDest; + this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); + } + + public void Dispose() + { + this.ActualDestBuffer.Dispose(); + } + + private const float Tolerance = 0.0001f; + + public void Verify() + { + int count = this.ExpectedDestBuffer.Length; + + if (typeof(TDest) == typeof(Vector4)) + { + + Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); + Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); + + for (int i = 0; i < count; i++) + { + // ReSharper disable PossibleNullReferenceException + Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); + // ReSharper restore PossibleNullReferenceException + } + } + else + { + Span expected = this.ExpectedDestBuffer.AsSpan(); + Span actual = this.ActualDestBuffer.GetSpan(); + for (int i = 0; i < count; i++) + { + Assert.Equal(expected[i], actual[i]); + } + } + } + } + + internal static void TestOperation( + TSource[] source, + TDest[] expected, + Action> action) + where TSource : struct + where TDest : struct + { + using (var buffers = new TestBuffers(source, expected)) + { + action(buffers.SourceBuffer, buffers.ActualDestBuffer); + buffers.Verify(); + } + } + + internal static Vector4[] CreateVector4TestData(int length) + { + var result = new Vector4[length]; + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = GetVector(rnd); + } + return result; + } + + internal static TPixel[] CreatePixelTestData(int length) + { + var result = new TPixel[length]; + + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + Vector4 v = GetVector(rnd); + result[i].PackFromVector4(v); + } + + return result; + } + + internal static TPixel[] CreateScaledPixelTestData(int length) + { + var result = new TPixel[length]; + + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + Vector4 v = GetVector(rnd); + result[i].PackFromScaledVector4(v); + } + + return result; + } + + internal static byte[] CreateByteTestData(int length) + { + byte[] result = new byte[length]; + var rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = (byte)rnd.Next(255); + } + return result; + } + + internal static Vector4 GetVector(Random rnd) + { + return new Vector4( + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble() + ); + } + + [StructLayout(LayoutKind.Sequential)] + private unsafe struct Rgba64Bytes + { + public fixed byte Data[8]; + + public byte this[int idx] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ref byte self = ref Unsafe.As(ref this); + return Unsafe.Add(ref self, idx); + } + } + } + } } \ No newline at end of file From c087ffe468236520a2a09417098dd2311754c766 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 15 Oct 2018 01:11:59 +0200 Subject: [PATCH 014/238] SIMD byte -> float conversion: BulkConvertByteToNormalizedFloatFast --- src/ImageSharp/Common/Extensions/SimdUtils.cs | 45 +++++++++++++++++-- .../Color/Bulk/ToVector4.cs | 16 +++++-- .../ImageSharp.Benchmarks.csproj | 2 +- .../PixelFormats/PixelOperationsTests.cs | 24 ++++++++++ .../Tests/TestEnvironmentTests.cs | 2 + 5 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Extensions/SimdUtils.cs index db1e80dda..56118a764 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.cs @@ -105,13 +105,50 @@ namespace SixLabors.ImageSharp } } - internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + /// + /// Fast -> conversion for RyuJIT runtimes having dotnet/coreclr#10662 merged. + /// + /// https://github.com/dotnet/coreclr/pull/10662 + /// + /// + internal static void BulkConvertByteToNormalizedFloatFast(ReadOnlySpan source, Span dest) { - if (!Vector.IsHardwareAccelerated) + Guard.IsTrue( + source.Length % Vector.Count == 0, + nameof(source), + "dest.Length should be divisable by Vector.Count!"); + + int n = source.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) { - throw new InvalidOperationException( - "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + Vector f0 = Vector.ConvertToSingle(w0) * scale; + Vector f1 = Vector.ConvertToSingle(w1) * scale; + Vector f2 = Vector.ConvertToSingle(w2) * scale; + Vector f3 = Vector.ConvertToSingle(w3) * scale; + + ref Vector d = ref Unsafe.Add(ref destBase, i * 4); + d = f0; + Unsafe.Add(ref d, 1) = f1; + Unsafe.Add(ref d, 2) = f2; + Unsafe.Add(ref d, 3) = f3; } + } + + internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + { + GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); DebugGuard.IsTrue((dest.Length % Vector.Count) == 0, nameof(source), "dest.Length should be divisable by Vector.Count!"); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 7b6f902d8..0e5e9d94f 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, - 1024)] + 2048)] public int Count { get; set; } [GlobalSetup] @@ -72,14 +72,14 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [CoreJob] - //[ClrJob] + [ClrJob] public class ToVector4_Rgba32 : ToVector4 { class Config : ManualConfig { } - [Benchmark] + //[Benchmark] public void BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -87,5 +87,15 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } + + [Benchmark] + public void BulkConvertByteToNormalizedFloatFast() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.BulkConvertByteToNormalizedFloatFast(sBytes, dFloats); + } + } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 36b7d4db4..e470e7821 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -1,6 +1,6 @@  - netcoreapp2.0;net461 + netcoreapp2.1;net461 Exe True SixLabors.ImageSharp.Benchmarks diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index a96da03e7..2e84886c0 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -73,6 +73,30 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ); } + [Fact] + public void BulkConvertByteToNormalizedFloatFast() + { + if (!Vector.IsHardwareAccelerated) + { + return; + } + + ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(128); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => + { + ReadOnlySpan sBytes = MemoryMarshal.Cast(s); + Span dFloats = MemoryMarshal.Cast(d.Memory.Span); + + SimdUtils.BulkConvertByteToNormalizedFloatFast(sBytes, dFloats); + } + ); + } + // [Fact] // Profiling benchmark - enable manually! #pragma warning disable xUnit1013 // Public method should be marked as test diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs index 8a3e69059..30bb16c2a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs @@ -3,6 +3,8 @@ using System; using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Formats; From ad659fb73166dede231a1d3d44e27f6755ad4e09 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 15 Oct 2018 01:30:35 +0200 Subject: [PATCH 015/238] move tests --- src/ImageSharp/Common/Extensions/SimdUtils.cs | 2 +- .../Color/Bulk/ToVector4.cs | 2 +- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 40 ++++++++++++++++ .../PixelFormats/PixelOperationsTests.cs | 48 ------------------- .../TestUtilities/TestDataGenerator.cs | 7 +++ 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Extensions/SimdUtils.cs index 56118a764..481e0726d 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.cs @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp /// https://github.com/dotnet/coreclr/pull/10662 /// /// - internal static void BulkConvertByteToNormalizedFloatFast(ReadOnlySpan source, Span dest) + internal static void BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(ReadOnlySpan source, Span dest) { Guard.IsTrue( source.Length % Vector.Count == 0, diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 0e5e9d94f..3ea256e85 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.BulkConvertByteToNormalizedFloatFast(sBytes, dFloats); + SimdUtils.BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(sBytes, dFloats); } } diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index c6c3b68f3..4e39af70f 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -186,6 +186,46 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, dest); } + [Theory] + [InlineData(1, 0)] + [InlineData(2, 32)] + [InlineData(3, 128)] + public void BulkConvertByteToNormalizedFloat(int seed, int count) + { + if (this.SkipOnNonAvx2()) + { + return; + } + + byte[] source = new Random(seed).GenerateRandomByteArray(count); + float[] result = new float[count]; + float[] expected = source.Select(b => (float)b / 255f).ToArray(); + + SimdUtils.BulkConvertByteToNormalizedFloat(source, result); + + Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); + } + + [Theory] + [InlineData(1, 0)] + [InlineData(2, 32)] + [InlineData(3, 128)] + public void BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(int seed, int count) + { + if (!Vector.IsHardwareAccelerated) + { + return; + } + + byte[] source = new Random(seed).GenerateRandomByteArray(count); + float[] result = new float[count]; + float[] expected = source.Select(b => (float)b / 255f).ToArray(); + + SimdUtils.BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(source, result); + + Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); + } + [Theory] [InlineData(0)] [InlineData(7)] diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 2e84886c0..4d7ec71e7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -49,54 +49,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ); } - [Fact] - public void BulkConvertByteToNormalizedFloat() - { - if (!Vector.IsHardwareAccelerated) - { - return; - } - - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => - { - ReadOnlySpan sBytes = MemoryMarshal.Cast(s); - Span dFloats = MemoryMarshal.Cast(d.Memory.Span); - - SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); - } - ); - } - - [Fact] - public void BulkConvertByteToNormalizedFloatFast() - { - if (!Vector.IsHardwareAccelerated) - { - return; - } - - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(128); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => - { - ReadOnlySpan sBytes = MemoryMarshal.Cast(s); - Span dFloats = MemoryMarshal.Cast(d.Memory.Span); - - SimdUtils.BulkConvertByteToNormalizedFloatFast(sBytes, dFloats); - } - ); - } - // [Fact] // Profiling benchmark - enable manually! #pragma warning disable xUnit1013 // Public method should be marked as test diff --git a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs index 0b1b89cc0..6f3b18e1f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs @@ -46,6 +46,13 @@ namespace SixLabors.ImageSharp.Tests return values; } + public static byte[] GenerateRandomByteArray(this Random rnd, int length) + { + byte[] values = new byte[length]; + rnd.NextBytes(values); + return values; + } + private static float GetRandomFloat(Random rnd, float minVal, float maxVal) { return (float)rnd.NextDouble() * (maxVal - minVal) + minVal; From 9a9262e58fa5473d43c3e059657891d019ce1f8e Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 15 Oct 2018 18:16:13 +0100 Subject: [PATCH 016/238] Generate bulk pixel operations for all standard packing operations and fix conversion --- src/ImageSharp/ImageFrame{TPixel}.cs | 14 +- src/ImageSharp/ImageSharp.csproj | 72 ++ src/ImageSharp/PixelFormats/Alpha8.cs | 8 + src/ImageSharp/PixelFormats/Argb32.cs | 31 +- src/ImageSharp/PixelFormats/Bgr24.cs | 17 +- src/ImageSharp/PixelFormats/Bgr565.cs | 8 + src/ImageSharp/PixelFormats/Bgra32.cs | 33 +- src/ImageSharp/PixelFormats/Bgra4444.cs | 8 + src/ImageSharp/PixelFormats/Bgra5551.cs | 11 +- src/ImageSharp/PixelFormats/Byte4.cs | 12 +- .../Argb32.PixelOperations.Generated.cs | 177 +++++ .../Argb32.PixelOperations.Generated.tt | 85 +++ .../Bgr24.PixelOperations.Generated.cs | 177 +++++ .../Bgr24.PixelOperations.Generated.tt | 85 +++ .../Bgra32.PixelOperations.Generated.cs | 177 +++++ .../Bgra32.PixelOperations.Generated.tt | 85 +++ .../Gray16.PixelOperations.Generated.cs | 177 +++++ .../Gray16.PixelOperations.Generated.tt | 85 +++ .../Gray8.PixelOperations.Generated.cs | 177 +++++ .../Gray8.PixelOperations.Generated.tt | 85 +++ .../PixelOperations{TPixel}.Generated.cs | 468 ++++++------ .../PixelOperations{TPixel}.Generated.tt | 70 +- .../Rgb24.PixelOperations.Generated.cs | 177 +++++ .../Rgb24.PixelOperations.Generated.tt | 85 +++ .../Rgb48.PixelOperations.Generated.cs | 177 +++++ .../Rgb48.PixelOperations.Generated.tt | 85 +++ .../Rgba32.PixelOperations.Generated.cs | 120 +-- .../Rgba32.PixelOperations.Generated.tt | 70 +- .../Rgba64.PixelOperations.Generated.cs | 177 +++++ .../Rgba64.PixelOperations.Generated.tt | 85 +++ src/ImageSharp/PixelFormats/Gray16.cs | 44 +- src/ImageSharp/PixelFormats/Gray8.cs | 34 +- src/ImageSharp/PixelFormats/HalfSingle.cs | 27 +- src/ImageSharp/PixelFormats/HalfVector2.cs | 8 + src/ImageSharp/PixelFormats/HalfVector4.cs | 8 + src/ImageSharp/PixelFormats/IPixel.cs | 12 + .../PixelFormats/NormalizedByte2.cs | 8 + .../PixelFormats/NormalizedByte4.cs | 8 + .../PixelFormats/NormalizedShort2.cs | 8 + .../PixelFormats/NormalizedShort4.cs | 8 + .../PixelFormats/PixelOperations{TPixel}.cs | 54 ++ src/ImageSharp/PixelFormats/Rg32.cs | 8 + src/ImageSharp/PixelFormats/Rgb24.cs | 19 +- src/ImageSharp/PixelFormats/Rgb48.cs | 22 +- src/ImageSharp/PixelFormats/Rgba1010102.cs | 14 +- .../PixelFormats/Rgba32.PixelOperations.cs | 66 +- src/ImageSharp/PixelFormats/Rgba32.cs | 16 + src/ImageSharp/PixelFormats/Rgba64.cs | 24 +- .../PixelFormats/RgbaVector.Definitions.cs | 721 ------------------ .../RgbaVector.PixelOperations.cs | 18 +- src/ImageSharp/PixelFormats/RgbaVector.cs | 10 +- src/ImageSharp/PixelFormats/Short2.cs | 12 +- src/ImageSharp/PixelFormats/Short4.cs | 12 +- .../PixelFormats/PixelOperationsTests.cs | 644 +++++++++++----- 54 files changed, 3441 insertions(+), 1402 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs create mode 100644 src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt delete mode 100644 src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index be1792ced..ecf9e13ce 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Buffers; -using System.Numerics; using System.Runtime.CompilerServices; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; @@ -289,22 +287,16 @@ namespace SixLabors.ImageSharp var target = new ImageFrame(configuration, this.Width, this.Height, this.MetaData.DeepClone()); - ParallelHelper.IterateRowsWithTempBuffer( + ParallelHelper.IterateRows( this.Bounds(), configuration, - (rows, tempRowBuffer) => + (rows) => { for (int y = rows.Min; y < rows.Max; y++) { Span sourceRow = this.GetPixelRowSpan(y); Span targetRow = target.GetPixelRowSpan(y); - Span tempRowSpan = tempRowBuffer.Span; - - PixelOperations.Instance.ToScaledVector4(sourceRow, tempRowSpan, sourceRow.Length); - PixelOperations.Instance.PackFromScaledVector4( - tempRowSpan, - targetRow, - targetRow.Length); + PixelOperations.Instance.To(sourceRow, targetRow, sourceRow.Length); } }); diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index a7ca0a014..7eec03cb6 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -76,10 +76,42 @@ TextTemplatingFileGenerator PixelOperations{TPixel}.Generated.cs + + TextTemplatingFileGenerator + Argb32.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Bgr24.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Bgra32.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Gray8.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Gray16.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Rgb24.PixelOperations.Generated.cs + TextTemplatingFileGenerator Rgba32.PixelOperations.Generated.cs + + TextTemplatingFileGenerator + Rgb48.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Rgba64.PixelOperations.Generated.cs + PorterDuffFunctions.Generated.cs TextTemplatingFileGenerator @@ -110,11 +142,51 @@ True PixelOperations{TPixel}.Generated.tt + + True + True + Argb32.PixelOperations.Generated.tt + + + True + True + Bgr24.PixelOperations.Generated.tt + + + True + True + Bgra32.PixelOperations.Generated.tt + + + True + True + Gray8.PixelOperations.Generated.tt + + + True + True + Gray16.PixelOperations.Generated.tt + + + True + True + Rgb24.PixelOperations.Generated.tt + True True Rgba32.PixelOperations.Generated.tt + + True + True + Rgb48.PixelOperations.Generated.tt + + + True + True + Rgba64.PixelOperations.Generated.tt + True True diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 063200c69..1e724768d 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -79,6 +79,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = source.A; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackedValue = byte.MaxValue; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.A; @@ -91,6 +95,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackedValue = byte.MaxValue; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 0da8516a3..1e3bd9326 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// as it avoids the need to create new values for modification operations. /// [StructLayout(LayoutKind.Sequential)] - public struct Argb32 : IPixel, IPackedVector + public partial struct Argb32 : IPixel, IPackedVector { /// /// Gets or sets the alpha component. @@ -165,7 +165,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Argb32 left, Argb32 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -187,6 +187,16 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = source.PackedValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -218,6 +228,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = byte.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) @@ -269,13 +289,6 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.Argb.GetHashCode(); - /// - /// Gets the representation without normalizing to [0, 1] - /// - /// A of values in [0, 255] - [MethodImpl(InliningOptions.ShortMethod)] - internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); - /// /// Packs the four floats into a color. /// diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 063fed522..ed65bebf7 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Explicit)] - public struct Bgr24 : IPixel + public partial struct Bgr24 : IPixel { /// /// The blue component. @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Bgr24 left, Bgr24 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -104,6 +104,10 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.B; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this = source; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -132,6 +136,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = rgb; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this = source.Bgr; diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 5b19fb25c..454f458b1 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -87,6 +87,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToVector4()); @@ -99,6 +103,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromVector4(source.ToVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 6fd086779..9b0ed4f96 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Bgra32 : IPixel, IPackedVector + public partial struct Bgra32 : IPixel, IPackedVector { /// /// Gets or sets the blue component. @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Bgra32 left, Bgra32 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -151,7 +151,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.PackedValue; + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -184,6 +194,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); @@ -220,13 +240,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public override string ToString() => $"Bgra32({this.B}, {this.G}, {this.R}, {this.A})"; - /// - /// Gets the representation without normalizing to [0, 1] - /// - /// A of values in [0, 255] - [MethodImpl(InliningOptions.ShortMethod)] - internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); - /// /// Packs a into a color. /// diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index 8a5e3f76b..08484eba8 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -90,6 +90,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -102,6 +106,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 25f289b84..df0a46730 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -91,6 +91,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -103,6 +107,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -147,8 +155,5 @@ namespace SixLabors.ImageSharp.PixelFormats | (((int)Math.Round(vector.Z * 31F) & 0x1F) << 0) | (((int)Math.Round(vector.W) & 0x1) << 15)); } - - [MethodImpl(InliningOptions.ShortMethod)] - private Vector4 ToByteScaledVector4() => this.ToVector4() * 255F; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index fbdf4862d..34546e027 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -89,11 +89,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToByteScaledVector4()); + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToByteScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -103,6 +107,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs new file mode 100644 index 000000000..0b40df8da --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Argb32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt new file mode 100644 index 000000000..f35adee02 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Argb32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs new file mode 100644 index 000000000..e89525457 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgr24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt new file mode 100644 index 000000000..76163549b --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgr24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs new file mode 100644 index 000000000..2311e0bde --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgra32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt new file mode 100644 index 000000000..4c2925d18 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgra32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs new file mode 100644 index 000000000..a2d9aa755 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray16 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt new file mode 100644 index 000000000..b900e343a --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray16 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs new file mode 100644 index 000000000..de2c11d4d --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray8 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt new file mode 100644 index 000000000..4590420e5 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray8 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 852ff73e0..66966543f 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -11,633 +11,633 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations { /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Argb32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba64(temp); + ref Argb32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromArgb32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba64 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba64Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToArgb32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba64(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToArgb32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Bgr24 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgb48(temp); + ref Bgr24 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromBgr24(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb48 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb48Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToBgr24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb48(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToBgr24(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Bgra32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Bgra32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromBgra32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToBgra32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToBgra32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Gray8 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromBgra32(temp); + ref Gray8 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromGray8(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgra32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToGray8Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgra32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToGray8(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Gray16 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp.Rgb = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Gray16 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromGray16(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToGray16Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb24(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToGray16(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgb24 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp.Bgr = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Rgb24 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgb24(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgr24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgb24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgr24(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgb24(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgba32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromArgb32(temp); + ref Rgba32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgba32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToArgb32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgba32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToArgb32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgba32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Gray8 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgb48 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromGray8(temp); + ref Rgb48 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgb48(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgb48 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray8Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgb48Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray8(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgb48(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Gray16 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgba64 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromGray16(temp); + ref Rgba64 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgba64(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgba64 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray16Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgba64Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray16(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgba64(sourcePixels, MemoryMarshal.Cast(destBytes), count); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index 9fbe57ed9..913dabb08 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -11,7 +11,7 @@ <#@ output extension=".cs" #> <# - void GeneratePackFromMethods(string pixelType, string tempPixelType, string assignToTempCode) + void GeneratePackFromMethods(string pixelType) { #> @@ -25,17 +25,15 @@ { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors<<#=tempPixelType#>>.Black; + ref <#=pixelType#> sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - <#=assignToTempCode#> - dp.PackFrom<#=tempPixelType#>(temp); + ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFrom<#=pixelType#>(sp); } } @@ -51,6 +49,7 @@ { this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); } + <# } @@ -61,19 +60,20 @@ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> dest, int count) + internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(dest); + ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -82,13 +82,13 @@ /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void To<#=pixelType#>Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void To<#=pixelType#>Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.To<#=pixelType#>(sourceColors, MemoryMarshal.Cast>(destBytes), count); + this.To<#=pixelType#>(sourcePixels, MemoryMarshal.Cast>(destBytes), count); } <# } @@ -107,32 +107,32 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations {<# - GeneratePackFromMethods("Rgba64", "Rgba64", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgba64"); - - GeneratePackFromMethods("Rgb48", "Rgb48", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgb48"); - - GeneratePackFromMethods("Rgba32", "Rgba32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgba32"); - - GeneratePackFromMethods("Bgra32", "Bgra32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Bgra32"); - - GeneratePackFromMethods("Rgb24", "Rgba32", "temp.Rgb = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgb24"); + GeneratePackFromMethods("Argb32"); + GenerateToDestFormatMethods("Argb32"); - GeneratePackFromMethods("Bgr24", "Rgba32", "temp.Bgr = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Bgr24"); GenerateToDestFormatMethods("Bgr24"); - GeneratePackFromMethods("Argb32", "Argb32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Argb32"); + GeneratePackFromMethods("Bgra32"); + GenerateToDestFormatMethods("Bgra32"); - GeneratePackFromMethods("Gray8", "Gray8", "temp = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Gray8"); GenerateToDestFormatMethods("Gray8"); - GeneratePackFromMethods("Gray16", "Gray16", "temp = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Gray16"); GenerateToDestFormatMethods("Gray16"); + GeneratePackFromMethods("Rgb24"); + GenerateToDestFormatMethods("Rgb24"); + + GeneratePackFromMethods("Rgba32"); + GenerateToDestFormatMethods("Rgba32"); + + GeneratePackFromMethods("Rgb48"); + GenerateToDestFormatMethods("Rgb48"); + + GeneratePackFromMethods("Rgba64"); + GenerateToDestFormatMethods("Rgba64"); + #> } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs new file mode 100644 index 000000000..ad4ee2764 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt new file mode 100644 index 000000000..6a10b401f --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs new file mode 100644 index 000000000..0a1ef0387 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb48 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt new file mode 100644 index 000000000..e38c85bf6 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb48 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index 962150595..bd3e014b4 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -13,133 +13,161 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rgba32 { + + /// + /// Provides optimized overrides for bulk operations. + /// internal partial class PixelOperations { + /// + internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + /// - internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb24 destRef = ref MemoryMarshal.GetReference(dest); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp = Unsafe.As(ref sp); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.Bgr = sp; dp.A = byte.MaxValue; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destRef = ref MemoryMarshal.GetReference(dest); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.Bgr; + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destRef = ref MemoryMarshal.GetReference(dest); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromRgba32(sp); } } /// - internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destRef = ref MemoryMarshal.GetReference(dest); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromRgba32(sp); } } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt index 9d9145f0b..23d0be740 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt @@ -9,45 +9,24 @@ <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> <# - void GeneratePackFromMethod(string pixelType, string converterCode) + void GenerateConvertToMethod(string pixelType) { #> /// - internal override void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < count; i++) - { - ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - <#=converterCode#> - } - } - <# - } - - void GenerateConvertToMethod(string pixelType, string converterCode) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> dest, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(dest); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - <#=converterCode#> + + dp.PackFromRgba32(sp); } } <# @@ -68,20 +47,37 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rgba32 { + + /// + /// Provides optimized overrides for bulk operations. + /// internal partial class PixelOperations { - <# - GeneratePackFromMethod("Rgb24", "Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue;"); - GenerateConvertToMethod("Rgb24", "dp = Unsafe.As(ref sp);"); + /// + internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - GeneratePackFromMethod("Bgr24", "dp.Bgr = sp; dp.A = byte.MaxValue;"); - GenerateConvertToMethod("Bgr24", "dp = sp.Bgr;"); - - GeneratePackFromMethod("Bgra32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); - GenerateConvertToMethod("Bgra32", "dp.PackFromRgba32(sp);"); + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - GeneratePackFromMethod("Argb32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); - GenerateConvertToMethod("Argb32", "dp.PackFromRgba32(sp);"); + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); #> } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs new file mode 100644 index 000000000..e6f9b37a7 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgba64 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt new file mode 100644 index 000000000..e99834157 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgba64 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index f9aada937..34f221d79 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -13,9 +13,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// /// - public struct Gray16 : IPixel, IPackedVector + public partial struct Gray16 : IPixel, IPackedVector { private const float Max = ushort.MaxValue; + private const float Average = 1 / 3F; /// /// Initializes a new instance of the struct. @@ -49,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Gray16 left, Gray16 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -63,11 +64,8 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; - this.PackedValue = ImageMaths.Get16BitBT709Luminance( - (ushort)MathF.Round(vector.X), - (ushort)MathF.Round(vector.Y), - (ushort)MathF.Round(vector.Z)); + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max * Average; + this.PackedValue = (ushort)MathF.Round(vector.X + vector.Y + vector.Z); } /// @@ -88,6 +86,16 @@ namespace SixLabors.ImageSharp.PixelFormats ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -106,6 +114,16 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = source.PackedValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) @@ -130,7 +148,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); + public void PackFromRgba64(Rgba64 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); /// public override bool Equals(object obj) => obj is Gray16 other && this.Equals(other); @@ -145,5 +163,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); + + [MethodImpl(InliningOptions.ShortMethod)] + internal void ConvertFromRgbaScaledVector4(Vector4 vector) + { + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + (ushort)MathF.Round(vector.X), + (ushort)MathF.Round(vector.Y), + (ushort)MathF.Round(vector.Z)); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index b1fa2b1e1..581240587 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -12,17 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// /// - public struct Gray8 : IPixel, IPackedVector + public partial struct Gray8 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// private static readonly Vector4 MaxBytes = new Vector4(255F); - - /// - /// The half vector value. - /// private static readonly Vector4 Half = new Vector4(0.5F); + private const float Average = 1 / 3F; /// /// Initializes a new instance of the struct. @@ -56,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Gray8 left, Gray8 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -72,9 +66,8 @@ namespace SixLabors.ImageSharp.PixelFormats { vector *= MaxBytes; vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - - this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z); + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes) * Average; + this.PackedValue = (byte)(vector.X + vector.Y + vector.Z); } /// @@ -89,6 +82,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); @@ -101,6 +98,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); @@ -138,5 +139,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); + + [MethodImpl(InliningOptions.ShortMethod)] + internal void ConvertFromRgbaScaledVector4(Vector4 vector) + { + vector *= MaxBytes; + vector += Half; + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); + this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 8048a3825..78edc9a08 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -14,16 +14,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct HalfSingle : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half vector value. - /// - private static readonly Vector4 Half = new Vector4(0.5F); - /// /// Initializes a new instance of the struct. /// @@ -89,6 +79,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -101,6 +95,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -137,14 +135,5 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - - [MethodImpl(InliningOptions.ShortMethod)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= MaxBytes; - vector += Half; - return Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index f398f508b..e3777bc2f 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -90,6 +90,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -102,6 +106,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 45d93efc0..079c3ee38 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -98,6 +98,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -110,6 +114,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index a3017501c..87125fa0a 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -61,6 +61,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromArgb32(Argb32 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromBgr24(Bgr24 source); + /// /// Packs the pixel from an value. /// @@ -79,6 +85,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromGray16(Gray16 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromRgb24(Rgb24 source); + /// /// Packs the pixel from an value. /// diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 86b528090..3eaa69c03 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -97,6 +97,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -113,6 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index b538e4a44..e0e3e6502 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -102,6 +102,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -114,6 +118,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 6135826f4..0aa573637 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -97,6 +97,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -109,6 +113,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 9717829a2..577e90154 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -104,6 +104,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -116,6 +120,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index b12a2bfa5..f1b40e81f 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -105,6 +105,60 @@ namespace SixLabors.ImageSharp.PixelFormats } } + /// + /// Performs a bulk conversion of a collection of one pixel format into another. + /// + /// The pixel format. + /// The to the source colors. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void To(ReadOnlySpan sourceColors, Span destinationColors, int count) + where TPixel2 : struct, IPixel + { + GuardSpans(sourceColors, nameof(sourceColors), destinationColors, nameof(destinationColors), count); + + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + + // Gray8 and Gray16 are special implementations of IPixel in that they do not conform to the + // standard RGBA colorspace format and must be converted from RGBA using the special ITU BT709 alogrithm. + // One of the requirements of PackFromScaledVector4/ToScaledVector4 is that it unaware of this and + // packs/unpacks the pixel without and conversion so we employ custom methods do do this. + if (typeof(TPixel2).Equals(typeof(Gray16))) + { + ref Gray16 gray16Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref gray16Ref, i); + dp.ConvertFromRgbaScaledVector4(sp.ToScaledVector4()); + } + + return; + } + + if (typeof(TPixel2).Equals(typeof(Gray8))) + { + ref Gray8 gray8Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref gray8Ref, i); + dp.ConvertFromRgbaScaledVector4(sp.ToScaledVector4()); + } + + return; + } + + // Normal converson + ref TPixel2 destRef = ref MemoryMarshal.GetReference(destinationColors); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel2 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); + } + } + /// /// Verifies that the given 'source' and 'destination' spans are at least of 'minLength' size. /// Throwing an if the condition is not met. diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 3375a9753..02c294b4f 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -85,6 +85,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -97,6 +101,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index ae037b376..a2b896605 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Explicit)] - public struct Rgb24 : IPixel + public partial struct Rgb24 : IPixel { /// /// The red component. @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgb24 left, Rgb24 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -118,6 +118,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.B; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -148,7 +157,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this = Unsafe.As(ref source); + public void PackFromRgb24(Rgb24 source) => this = source; + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this = source.Rgb; /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/Rgb48.cs index 2ee1be6fe..7406fda42 100644 --- a/src/ImageSharp/PixelFormats/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/Rgb48.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Rgb48 : IPixel + public partial struct Rgb48 : IPixel { private const float Max = ushort.MaxValue; @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgb48 left, Rgb48 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -104,6 +104,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -136,6 +145,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.PackedValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 8bcf34f30..86b639e22 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -91,6 +91,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -105,16 +109,20 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// + /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 40d8e0190..3111a6ee1 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -86,33 +86,10 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) - { - Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); - Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - - if (count < 256 || !Vector.IsHardwareAccelerated) - { - // Doesn't worth to bother with SIMD: - base.ToVector4(sourceColors, destinationVectors, count); - return; - } - - int remainder = count % Vector.Count; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ToVector4SimdAligned(sourceColors, destinationVectors, alignedCount); - } + internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) => this.PackFromVector4(sourceVectors, destinationColors, count); - if (remainder > 0) - { - sourceColors = sourceColors.Slice(alignedCount); - destinationVectors = destinationVectors.Slice(alignedCount); - base.ToVector4(sourceColors, destinationVectors, remainder); - } - } + /// + internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) => this.ToVector4(sourceColors, destinationVectors, count); /// internal override void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) @@ -145,25 +122,32 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) => this.ToVector4(sourceColors, destinationVectors, count); - - /// - internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) => this.PackFromVector4(sourceVectors, destinationColors, count); - - /// - internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - source.Slice(0, count).CopyTo(destPixels); - } + if (count < 256 || !Vector.IsHardwareAccelerated) + { + // Doesn't worth to bother with SIMD: + base.ToVector4(sourceColors, destinationVectors, count); + return; + } - /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span dest, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + int remainder = count % Vector.Count; + int alignedCount = count - remainder; - sourcePixels.Slice(0, count).CopyTo(dest); + if (alignedCount > 0) + { + ToVector4SimdAligned(sourceColors, destinationVectors, alignedCount); + } + + if (remainder > 0) + { + sourceColors = sourceColors.Slice(alignedCount); + destinationVectors = destinationVectors.Slice(alignedCount); + base.ToVector4(sourceColors, destinationVectors, remainder); + } } /// diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index 83620c823..e7814d23a 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -246,6 +246,14 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.Bgr = source; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -277,6 +285,14 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = byte.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.Rgb = source; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this = source; diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 623f7051a..738c5e3dd 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Rgba64 : IPixel, IPackedVector + public partial struct Rgba64 : IPixel, IPackedVector { private const float Max = ushort.MaxValue; @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgba64 left, Rgba64 right) => left.PackedValue != right.PackedValue; /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -134,6 +134,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ushort.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -165,6 +175,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = ushort.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ushort.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) diff --git a/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs b/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs deleted file mode 100644 index 2ef37c43a..000000000 --- a/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.PixelFormats -{ - /// - /// Provides operators and composition algorithms. - /// - public partial struct RgbaVector - { - /// - /// Represents a matching the W3C definition that has an hex value of #F0F8FF. - /// - public static readonly RgbaVector AliceBlue = NamedColors.AliceBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAEBD7. - /// - public static readonly RgbaVector AntiqueWhite = NamedColors.AntiqueWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. - /// - public static readonly RgbaVector Aqua = NamedColors.Aqua; - - /// - /// Represents a matching the W3C definition that has an hex value of #7FFFD4. - /// - public static readonly RgbaVector Aquamarine = NamedColors.Aquamarine; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0FFFF. - /// - public static readonly RgbaVector Azure = NamedColors.Azure; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5F5DC. - /// - public static readonly RgbaVector Beige = NamedColors.Beige; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4C4. - /// - public static readonly RgbaVector Bisque = NamedColors.Bisque; - - /// - /// Represents a matching the W3C definition that has an hex value of #000000. - /// - public static readonly RgbaVector Black = NamedColors.Black; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFEBCD. - /// - public static readonly RgbaVector BlanchedAlmond = NamedColors.BlanchedAlmond; - - /// - /// Represents a matching the W3C definition that has an hex value of #0000FF. - /// - public static readonly RgbaVector Blue = NamedColors.Blue; - - /// - /// Represents a matching the W3C definition that has an hex value of #8A2BE2. - /// - public static readonly RgbaVector BlueViolet = NamedColors.BlueViolet; - - /// - /// Represents a matching the W3C definition that has an hex value of #A52A2A. - /// - public static readonly RgbaVector Brown = NamedColors.Brown; - - /// - /// Represents a matching the W3C definition that has an hex value of #DEB887. - /// - public static readonly RgbaVector BurlyWood = NamedColors.BurlyWood; - - /// - /// Represents a matching the W3C definition that has an hex value of #5F9EA0. - /// - public static readonly RgbaVector CadetBlue = NamedColors.CadetBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #7FFF00. - /// - public static readonly RgbaVector Chartreuse = NamedColors.Chartreuse; - - /// - /// Represents a matching the W3C definition that has an hex value of #D2691E. - /// - public static readonly RgbaVector Chocolate = NamedColors.Chocolate; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF7F50. - /// - public static readonly RgbaVector Coral = NamedColors.Coral; - - /// - /// Represents a matching the W3C definition that has an hex value of #6495ED. - /// - public static readonly RgbaVector CornflowerBlue = NamedColors.CornflowerBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF8DC. - /// - public static readonly RgbaVector Cornsilk = NamedColors.Cornsilk; - - /// - /// Represents a matching the W3C definition that has an hex value of #DC143C. - /// - public static readonly RgbaVector Crimson = NamedColors.Crimson; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. - /// - public static readonly RgbaVector Cyan = NamedColors.Cyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #00008B. - /// - public static readonly RgbaVector DarkBlue = NamedColors.DarkBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #008B8B. - /// - public static readonly RgbaVector DarkCyan = NamedColors.DarkCyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #B8860B. - /// - public static readonly RgbaVector DarkGoldenrod = NamedColors.DarkGoldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #A9A9A9. - /// - public static readonly RgbaVector DarkGray = NamedColors.DarkGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #006400. - /// - public static readonly RgbaVector DarkGreen = NamedColors.DarkGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #BDB76B. - /// - public static readonly RgbaVector DarkKhaki = NamedColors.DarkKhaki; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B008B. - /// - public static readonly RgbaVector DarkMagenta = NamedColors.DarkMagenta; - - /// - /// Represents a matching the W3C definition that has an hex value of #556B2F. - /// - public static readonly RgbaVector DarkOliveGreen = NamedColors.DarkOliveGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF8C00. - /// - public static readonly RgbaVector DarkOrange = NamedColors.DarkOrange; - - /// - /// Represents a matching the W3C definition that has an hex value of #9932CC. - /// - public static readonly RgbaVector DarkOrchid = NamedColors.DarkOrchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B0000. - /// - public static readonly RgbaVector DarkRed = NamedColors.DarkRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #E9967A. - /// - public static readonly RgbaVector DarkSalmon = NamedColors.DarkSalmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #8FBC8B. - /// - public static readonly RgbaVector DarkSeaGreen = NamedColors.DarkSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #483D8B. - /// - public static readonly RgbaVector DarkSlateBlue = NamedColors.DarkSlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #2F4F4F. - /// - public static readonly RgbaVector DarkSlateGray = NamedColors.DarkSlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #00CED1. - /// - public static readonly RgbaVector DarkTurquoise = NamedColors.DarkTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #9400D3. - /// - public static readonly RgbaVector DarkViolet = NamedColors.DarkViolet; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF1493. - /// - public static readonly RgbaVector DeepPink = NamedColors.DeepPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #00BFFF. - /// - public static readonly RgbaVector DeepSkyBlue = NamedColors.DeepSkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #696969. - /// - public static readonly RgbaVector DimGray = NamedColors.DimGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #1E90FF. - /// - public static readonly RgbaVector DodgerBlue = NamedColors.DodgerBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #B22222. - /// - public static readonly RgbaVector Firebrick = NamedColors.Firebrick; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFAF0. - /// - public static readonly RgbaVector FloralWhite = NamedColors.FloralWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #228B22. - /// - public static readonly RgbaVector ForestGreen = NamedColors.ForestGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. - /// - public static readonly RgbaVector Fuchsia = NamedColors.Fuchsia; - - /// - /// Represents a matching the W3C definition that has an hex value of #DCDCDC. - /// - public static readonly RgbaVector Gainsboro = NamedColors.Gainsboro; - - /// - /// Represents a matching the W3C definition that has an hex value of #F8F8FF. - /// - public static readonly RgbaVector GhostWhite = NamedColors.GhostWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFD700. - /// - public static readonly RgbaVector Gold = NamedColors.Gold; - - /// - /// Represents a matching the W3C definition that has an hex value of #DAA520. - /// - public static readonly RgbaVector Goldenrod = NamedColors.Goldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #808080. - /// - public static readonly RgbaVector Gray = NamedColors.Gray; - - /// - /// Represents a matching the W3C definition that has an hex value of #008000. - /// - public static readonly RgbaVector Green = NamedColors.Green; - - /// - /// Represents a matching the W3C definition that has an hex value of #ADFF2F. - /// - public static readonly RgbaVector GreenYellow = NamedColors.GreenYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0FFF0. - /// - public static readonly RgbaVector Honeydew = NamedColors.Honeydew; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF69B4. - /// - public static readonly RgbaVector HotPink = NamedColors.HotPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #CD5C5C. - /// - public static readonly RgbaVector IndianRed = NamedColors.IndianRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #4B0082. - /// - public static readonly RgbaVector Indigo = NamedColors.Indigo; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFF0. - /// - public static readonly RgbaVector Ivory = NamedColors.Ivory; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0E68C. - /// - public static readonly RgbaVector Khaki = NamedColors.Khaki; - - /// - /// Represents a matching the W3C definition that has an hex value of #E6E6FA. - /// - public static readonly RgbaVector Lavender = NamedColors.Lavender; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF0F5. - /// - public static readonly RgbaVector LavenderBlush = NamedColors.LavenderBlush; - - /// - /// Represents a matching the W3C definition that has an hex value of #7CFC00. - /// - public static readonly RgbaVector LawnGreen = NamedColors.LawnGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFACD. - /// - public static readonly RgbaVector LemonChiffon = NamedColors.LemonChiffon; - - /// - /// Represents a matching the W3C definition that has an hex value of #ADD8E6. - /// - public static readonly RgbaVector LightBlue = NamedColors.LightBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #F08080. - /// - public static readonly RgbaVector LightCoral = NamedColors.LightCoral; - - /// - /// Represents a matching the W3C definition that has an hex value of #E0FFFF. - /// - public static readonly RgbaVector LightCyan = NamedColors.LightCyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAFAD2. - /// - public static readonly RgbaVector LightGoldenrodYellow = NamedColors.LightGoldenrodYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #D3D3D3. - /// - public static readonly RgbaVector LightGray = NamedColors.LightGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #90EE90. - /// - public static readonly RgbaVector LightGreen = NamedColors.LightGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFB6C1. - /// - public static readonly RgbaVector LightPink = NamedColors.LightPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFA07A. - /// - public static readonly RgbaVector LightSalmon = NamedColors.LightSalmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #20B2AA. - /// - public static readonly RgbaVector LightSeaGreen = NamedColors.LightSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #87CEFA. - /// - public static readonly RgbaVector LightSkyBlue = NamedColors.LightSkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #778899. - /// - public static readonly RgbaVector LightSlateGray = NamedColors.LightSlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #B0C4DE. - /// - public static readonly RgbaVector LightSteelBlue = NamedColors.LightSteelBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFE0. - /// - public static readonly RgbaVector LightYellow = NamedColors.LightYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FF00. - /// - public static readonly RgbaVector Lime = NamedColors.Lime; - - /// - /// Represents a matching the W3C definition that has an hex value of #32CD32. - /// - public static readonly RgbaVector LimeGreen = NamedColors.LimeGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAF0E6. - /// - public static readonly RgbaVector Linen = NamedColors.Linen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. - /// - public static readonly RgbaVector Magenta = NamedColors.Magenta; - - /// - /// Represents a matching the W3C definition that has an hex value of #800000. - /// - public static readonly RgbaVector Maroon = NamedColors.Maroon; - - /// - /// Represents a matching the W3C definition that has an hex value of #66CDAA. - /// - public static readonly RgbaVector MediumAquamarine = NamedColors.MediumAquamarine; - - /// - /// Represents a matching the W3C definition that has an hex value of #0000CD. - /// - public static readonly RgbaVector MediumBlue = NamedColors.MediumBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #BA55D3. - /// - public static readonly RgbaVector MediumOrchid = NamedColors.MediumOrchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #9370DB. - /// - public static readonly RgbaVector MediumPurple = NamedColors.MediumPurple; - - /// - /// Represents a matching the W3C definition that has an hex value of #3CB371. - /// - public static readonly RgbaVector MediumSeaGreen = NamedColors.MediumSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #7B68EE. - /// - public static readonly RgbaVector MediumSlateBlue = NamedColors.MediumSlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FA9A. - /// - public static readonly RgbaVector MediumSpringGreen = NamedColors.MediumSpringGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #48D1CC. - /// - public static readonly RgbaVector MediumTurquoise = NamedColors.MediumTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #C71585. - /// - public static readonly RgbaVector MediumVioletRed = NamedColors.MediumVioletRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #191970. - /// - public static readonly RgbaVector MidnightBlue = NamedColors.MidnightBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5FFFA. - /// - public static readonly RgbaVector MintCream = NamedColors.MintCream; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4E1. - /// - public static readonly RgbaVector MistyRose = NamedColors.MistyRose; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4B5. - /// - public static readonly RgbaVector Moccasin = NamedColors.Moccasin; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFDEAD. - /// - public static readonly RgbaVector NavajoWhite = NamedColors.NavajoWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #000080. - /// - public static readonly RgbaVector Navy = NamedColors.Navy; - - /// - /// Represents a matching the W3C definition that has an hex value of #FDF5E6. - /// - public static readonly RgbaVector OldLace = NamedColors.OldLace; - - /// - /// Represents a matching the W3C definition that has an hex value of #808000. - /// - public static readonly RgbaVector Olive = NamedColors.Olive; - - /// - /// Represents a matching the W3C definition that has an hex value of #6B8E23. - /// - public static readonly RgbaVector OliveDrab = NamedColors.OliveDrab; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFA500. - /// - public static readonly RgbaVector Orange = NamedColors.Orange; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF4500. - /// - public static readonly RgbaVector OrangeRed = NamedColors.OrangeRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #DA70D6. - /// - public static readonly RgbaVector Orchid = NamedColors.Orchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #EEE8AA. - /// - public static readonly RgbaVector PaleGoldenrod = NamedColors.PaleGoldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #98FB98. - /// - public static readonly RgbaVector PaleGreen = NamedColors.PaleGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #AFEEEE. - /// - public static readonly RgbaVector PaleTurquoise = NamedColors.PaleTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #DB7093. - /// - public static readonly RgbaVector PaleVioletRed = NamedColors.PaleVioletRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFEFD5. - /// - public static readonly RgbaVector PapayaWhip = NamedColors.PapayaWhip; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFDAB9. - /// - public static readonly RgbaVector PeachPuff = NamedColors.PeachPuff; - - /// - /// Represents a matching the W3C definition that has an hex value of #CD853F. - /// - public static readonly RgbaVector Peru = NamedColors.Peru; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFC0CB. - /// - public static readonly RgbaVector Pink = NamedColors.Pink; - - /// - /// Represents a matching the W3C definition that has an hex value of #DDA0DD. - /// - public static readonly RgbaVector Plum = NamedColors.Plum; - - /// - /// Represents a matching the W3C definition that has an hex value of #B0E0E6. - /// - public static readonly RgbaVector PowderBlue = NamedColors.PowderBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #800080. - /// - public static readonly RgbaVector Purple = NamedColors.Purple; - - /// - /// Represents a matching the W3C definition that has an hex value of #663399. - /// - public static readonly RgbaVector RebeccaPurple = NamedColors.RebeccaPurple; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF0000. - /// - public static readonly RgbaVector Red = NamedColors.Red; - - /// - /// Represents a matching the W3C definition that has an hex value of #BC8F8F. - /// - public static readonly RgbaVector RosyBrown = NamedColors.RosyBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #4169E1. - /// - public static readonly RgbaVector RoyalBlue = NamedColors.RoyalBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B4513. - /// - public static readonly RgbaVector SaddleBrown = NamedColors.SaddleBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #FA8072. - /// - public static readonly RgbaVector Salmon = NamedColors.Salmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #F4A460. - /// - public static readonly RgbaVector SandyBrown = NamedColors.SandyBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #2E8B57. - /// - public static readonly RgbaVector SeaGreen = NamedColors.SeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF5EE. - /// - public static readonly RgbaVector SeaShell = NamedColors.SeaShell; - - /// - /// Represents a matching the W3C definition that has an hex value of #A0522D. - /// - public static readonly RgbaVector Sienna = NamedColors.Sienna; - - /// - /// Represents a matching the W3C definition that has an hex value of #C0C0C0. - /// - public static readonly RgbaVector Silver = NamedColors.Silver; - - /// - /// Represents a matching the W3C definition that has an hex value of #87CEEB. - /// - public static readonly RgbaVector SkyBlue = NamedColors.SkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #6A5ACD. - /// - public static readonly RgbaVector SlateBlue = NamedColors.SlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #708090. - /// - public static readonly RgbaVector SlateGray = NamedColors.SlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFAFA. - /// - public static readonly RgbaVector Snow = NamedColors.Snow; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FF7F. - /// - public static readonly RgbaVector SpringGreen = NamedColors.SpringGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #4682B4. - /// - public static readonly RgbaVector SteelBlue = NamedColors.SteelBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #D2B48C. - /// - public static readonly RgbaVector Tan = NamedColors.Tan; - - /// - /// Represents a matching the W3C definition that has an hex value of #008080. - /// - public static readonly RgbaVector Teal = NamedColors.Teal; - - /// - /// Represents a matching the W3C definition that has an hex value of #D8BFD8. - /// - public static readonly RgbaVector Thistle = NamedColors.Thistle; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF6347. - /// - public static readonly RgbaVector Tomato = NamedColors.Tomato; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. - /// - public static readonly RgbaVector Transparent = NamedColors.Transparent; - - /// - /// Represents a matching the W3C definition that has an hex value of #40E0D0. - /// - public static readonly RgbaVector Turquoise = NamedColors.Turquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #EE82EE. - /// - public static readonly RgbaVector Violet = NamedColors.Violet; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5DEB3. - /// - public static readonly RgbaVector Wheat = NamedColors.Wheat; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. - /// - public static readonly RgbaVector White = NamedColors.White; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5F5F5. - /// - public static readonly RgbaVector WhiteSmoke = NamedColors.WhiteSmoke; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFF00. - /// - public static readonly RgbaVector Yellow = NamedColors.Yellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #9ACD32. - /// - public static readonly RgbaVector YellowGreen = NamedColors.YellowGreen; - } -} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs index ce40665cd..aae6ee694 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs @@ -18,11 +18,23 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override unsafe void ToVector4(ReadOnlySpan sourceColors, Span destVectors, int count) + internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - GuardSpans(sourceColors, nameof(sourceColors), destVectors, nameof(destVectors), count); + GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - MemoryMarshal.Cast(sourceColors).Slice(0, count).CopyTo(destVectors); + MemoryMarshal.Cast(sourceVectors).Slice(0, count).CopyTo(destinationColors); + } + + /// + internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + => this.ToVector4(sourceColors, destinationVectors, count); + + /// + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + { + GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + + MemoryMarshal.Cast(sourceColors).Slice(0, count).CopyTo(destinationVectors); } } } diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index 5ca0ce406..b5ccf8aed 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static RgbaVector FromHex(string hex) => ColorBuilder.FromHex(hex); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -125,6 +125,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -137,6 +141,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 24430a5d9..db29b401e 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -105,11 +105,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -119,10 +119,18 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 492513747..6d6e5f084 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -110,11 +110,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -124,10 +124,18 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 92b04f587..e9cc98884 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -13,20 +13,257 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.PixelFormats { - public partial class PixelOperationsTests + public class PixelOperationsTests { - public class Rgba32 : PixelOperationsTests + public class Argb32OperationsTests : PixelOperationsTests { - public Rgba32(ITestOutputHelper output) + public Argb32OperationsTests(ITestOutputHelper output) : base(output) { } - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + // For 4.6 test runner MemberData does not work without redeclaring the public field in the + // derived test class: + // TODO: Can this not be delared in the parent class? public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Bgr24OperationsTests : PixelOperationsTests + { + public Bgr24OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Bgra32OperationsTests : PixelOperationsTests + { + public Bgra32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Gray8OperationsTests : PixelOperationsTests + { + public Gray8OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + expected[i].PackFromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + ); + } + } + + public class Gray16OperationsTests : PixelOperationsTests + { + public Gray16OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + expected[i].PackFromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + ); + } + } + + public class Rgba32OperationsTests : PixelOperationsTests + { + public Rgba32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); [Fact] public void ToVector4SimdAligned() @@ -36,63 +273,86 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats return; } - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); + Rgba32[] source = CreatePixelTestData(64); Vector4[] expected = CreateExpectedVector4Data(source); TestOperation( source, expected, - (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) + (s, d) => Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) ); } - // [Fact] // Profiling benchmark - enable manually! #pragma warning disable xUnit1013 // Public method should be marked as test public void Benchmark_ToVector4() #pragma warning restore xUnit1013 // Public method should be marked as test { - int times = 200000; - int count = 1024; + const int times = 200000; + const int count = 1024; - using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) + using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) { this.Measure( times, - () => - { - PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); - }); + () => PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count)); } } } - public class Argb32 : PixelOperationsTests + public class Rgb48OperationsTests : PixelOperationsTests { - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public Argb32(ITestOutputHelper output) + public Rgb48OperationsTests(ITestOutputHelper output) : base(output) { } public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Rgba64OperationsTests : PixelOperationsTests + { + public Rgba64OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class RgbaVectorOperationsTests : PixelOperationsTests + { + public RgbaVectorOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } [Theory] [WithBlankImages(1, 1, PixelTypes.All)] - public void GetGlobalInstance(TestImageProvider dummy) + public void GetGlobalInstance(TestImageProvider _) where TPixel : struct, IPixel => Assert.NotNull(PixelOperations.Instance); [Fact] public void IsOpaqueColor() { - Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - - Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Transparent)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); + Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Transparent)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); } } @@ -106,7 +366,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - private static PixelOperations Operations => PixelOperations.Instance; + internal static PixelOperations Operations => PixelOperations.Instance; internal static TPixel[] CreateExpectedPixelData(Vector4[] source) { @@ -210,383 +470,333 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb24Bytes(int count) + public void PackFromArgb32Bytes(int count) { - byte[] source = CreateByteTestData(count * 3); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i3 = i * 3; + int i4 = i * 4; - expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); + expected[i].PackFromArgb32(new Argb32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgb24Bytes(int count) + public void ToArgb32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var rgb = default(Rgb24); + byte[] expected = new byte[count * 4]; + var argb = default(Argb32); for (int i = 0; i < count; i++) { - int i3 = i * 3; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i3] = rgb.R; - expected[i3 + 1] = rgb.G; - expected[i3 + 2] = rgb.B; + int i4 = i * 4; + argb.PackFromScaledVector4(source[i].ToScaledVector4()); + + expected[i4] = argb.A; + expected[i4 + 1] = argb.R; + expected[i4 + 2] = argb.G; + expected[i4 + 3] = argb.B; } TestOperation( source, expected, - (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba32Bytes(int count) + public void PackFromBgr24Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; + int i3 = i * 3; - expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); + expected[i].PackFromBgr24(new Bgr24(source[i3 + 2], source[i3 + 1], source[i3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgba32Bytes(int count) + public void ToBgr24Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var rgba = default(Rgba32); + byte[] expected = new byte[count * 3]; + var bgr = default(Bgr24); for (int i = 0; i < count; i++) { - int i4 = i * 4; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i4] = rgba.R; - expected[i4 + 1] = rgba.G; - expected[i4 + 2] = rgba.B; - expected[i4 + 3] = rgba.A; + int i3 = i * 3; + bgr.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = bgr.B; + expected[i3 + 1] = bgr.G; + expected[i3 + 2] = bgr.R; } TestOperation( source, expected, - (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb48Bytes(int count) + public void PackFromBgra32Bytes(int count) { - byte[] source = CreateByteTestData(count * 6); - Span sourceSpan = source.AsSpan(); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; - var rgba64 = new Rgba64(0, 0, 0, 65535); for (int i = 0; i < count; i++) { - int i6 = i * 6; - rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; - expected[i].PackFromRgba64(rgba64); + int i4 = i * 4; + + expected[i].PackFromBgra32(new Bgra32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgb48Bytes(int count) + public void ToBgra32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 6]; - Rgb48 rgb = default; + byte[] expected = new byte[count * 4]; + var bgra = default(Bgra32); for (int i = 0; i < count; i++) { - int i6 = i * 6; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); - Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); - expected[i6] = rgb48Bytes[0]; - expected[i6 + 1] = rgb48Bytes[1]; - expected[i6 + 2] = rgb48Bytes[2]; - expected[i6 + 3] = rgb48Bytes[3]; - expected[i6 + 4] = rgb48Bytes[4]; - expected[i6 + 5] = rgb48Bytes[5]; + int i4 = i * 4; + bgra.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = bgra.B; + expected[i4 + 1] = bgra.G; + expected[i4 + 2] = bgra.R; + expected[i4 + 3] = bgra.A; } TestOperation( source, expected, - (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba64Bytes(int count) + public void PackFromRgb24Bytes(int count) { - byte[] source = CreateByteTestData(count * 8); - Span sourceSpan = source.AsSpan(); + byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i8 = i * 8; - expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); + int i3 = i * 3; + + expected[i].PackFromRgb24(new Rgb24(source[i3 + 0], source[i3 + 1], source[i3 + 2])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgba64Bytes(int count) + public void ToRgb24Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 8]; - Rgba64 rgba = default; + byte[] expected = new byte[count * 3]; + var rgb = default(Rgb24); for (int i = 0; i < count; i++) { - int i8 = i * 8; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); - Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); - expected[i8] = rgba64Bytes[0]; - expected[i8 + 1] = rgba64Bytes[1]; - expected[i8 + 2] = rgba64Bytes[2]; - expected[i8 + 3] = rgba64Bytes[3]; - expected[i8 + 4] = rgba64Bytes[4]; - expected[i8 + 5] = rgba64Bytes[5]; - expected[i8 + 6] = rgba64Bytes[6]; - expected[i8 + 7] = rgba64Bytes[7]; + int i3 = i * 3; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = rgb.R; + expected[i3 + 1] = rgb.G; + expected[i3 + 2] = rgb.B; } TestOperation( source, expected, - (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgr24Bytes(int count) + public void PackFromRgba32Bytes(int count) { - byte[] source = CreateByteTestData(count * 3); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i3 = i * 3; + int i4 = i * 4; - expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); + expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToBgr24Bytes(int count) + public void ToRgba32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var bgr = default(Bgr24); + byte[] expected = new byte[count * 4]; + var rgba = default(Rgba32); for (int i = 0; i < count; i++) { - int i3 = i * 3; - bgr.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i3] = bgr.B; - expected[i3 + 1] = bgr.G; - expected[i3 + 2] = bgr.R; + int i4 = i * 4; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = rgba.R; + expected[i4 + 1] = rgba.G; + expected[i4 + 2] = rgba.B; + expected[i4 + 3] = rgba.A; } TestOperation( source, expected, - (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgra32Bytes(int count) + public void PackFromRgb48Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 6); + Span sourceSpan = source.AsSpan(); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); + int i6 = i * 6; + expected[i].PackFromRgb48(MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]); } TestOperation( source, expected, - (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToBgra32Bytes(int count) + public void ToRgb48Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var bgra = default(Bgra32); + byte[] expected = new byte[count * 6]; + Rgb48 rgb = default; for (int i = 0; i < count; i++) { - int i4 = i * 4; - bgra.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i4] = bgra.B; - expected[i4 + 1] = bgra.G; - expected[i4 + 2] = bgra.R; - expected[i4 + 3] = bgra.A; + int i6 = i * 6; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes rgb48Bytes = Unsafe.As(ref rgb); + expected[i6] = rgb48Bytes[0]; + expected[i6 + 1] = rgb48Bytes[1]; + expected[i6 + 2] = rgb48Bytes[2]; + expected[i6 + 3] = rgb48Bytes[3]; + expected[i6 + 4] = rgb48Bytes[4]; + expected[i6 + 5] = rgb48Bytes[5]; } TestOperation( source, expected, - (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromArgb32Bytes(int count) + public void PackFromRgba64Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 8); + Span sourceSpan = source.AsSpan(); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + int i8 = i * 8; + expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); } TestOperation( source, expected, - (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToArgb32Bytes(int count) + public void ToRgba64Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var argb = default(Argb32); + byte[] expected = new byte[count * 8]; + Rgba64 rgba = default; for (int i = 0; i < count; i++) { - int i4 = i * 4; - argb.PackFromScaledVector4(source[i].ToScaledVector4()); - - expected[i4] = argb.A; - expected[i4 + 1] = argb.R; - expected[i4 + 2] = argb.G; - expected[i4 + 3] = argb.B; + int i8 = i * 8; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes rgba64Bytes = Unsafe.As(ref rgba); + expected[i8] = rgba64Bytes[0]; + expected[i8 + 1] = rgba64Bytes[1]; + expected[i8 + 2] = rgba64Bytes[2]; + expected[i8 + 3] = rgba64Bytes[3]; + expected[i8 + 4] = rgba64Bytes[4]; + expected[i8 + 5] = rgba64Bytes[5]; + expected[i8 + 6] = rgba64Bytes[6]; + expected[i8 + 7] = rgba64Bytes[7]; } TestOperation( source, expected, - (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) ); } - private class TestBuffers : IDisposable - where TSource : struct - where TDest : struct - { - public TSource[] SourceBuffer { get; } - public IMemoryOwner ActualDestBuffer { get; } - public TDest[] ExpectedDestBuffer { get; } - - public TestBuffers(TSource[] source, TDest[] expectedDest) - { - this.SourceBuffer = source; - this.ExpectedDestBuffer = expectedDest; - this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); - } - - public void Dispose() => this.ActualDestBuffer.Dispose(); - - private const float Tolerance = 0.0001f; - - public void Verify() - { - int count = this.ExpectedDestBuffer.Length; - - if (typeof(TDest) == typeof(Vector4)) - { - - Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); - Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); - - for (int i = 0; i < count; i++) - { - // ReSharper disable PossibleNullReferenceException - Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); - // ReSharper restore PossibleNullReferenceException - } - } - else - { - Span expected = this.ExpectedDestBuffer.AsSpan(); - Span actual = this.ActualDestBuffer.GetSpan(); - for (int i = 0; i < count; i++) - { - Assert.Equal(expected[i], actual[i]); - } - } - } - } - internal static void TestOperation( TSource[] source, TDest[] expected, @@ -666,7 +876,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [StructLayout(LayoutKind.Sequential)] - private unsafe struct Rgba64Bytes + internal unsafe struct OctetBytes { public fixed byte Data[8]; @@ -675,10 +885,56 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - ref byte self = ref Unsafe.As(ref this); + ref byte self = ref Unsafe.As(ref this); return Unsafe.Add(ref self, idx); } } } + + private class TestBuffers : IDisposable + where TSource : struct + where TDest : struct + { + public TSource[] SourceBuffer { get; } + public IMemoryOwner ActualDestBuffer { get; } + public TDest[] ExpectedDestBuffer { get; } + + public TestBuffers(TSource[] source, TDest[] expectedDest) + { + this.SourceBuffer = source; + this.ExpectedDestBuffer = expectedDest; + this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); + } + + public void Dispose() => this.ActualDestBuffer.Dispose(); + + public void Verify() + { + int count = this.ExpectedDestBuffer.Length; + + if (typeof(TDest) == typeof(Vector4)) + { + Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); + Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); + + var comparer = new ApproximateFloatComparer(0.001f); + for (int i = 0; i < count; i++) + { + // ReSharper disable PossibleNullReferenceException + Assert.Equal(expected[i], actual[i], comparer); + // ReSharper restore PossibleNullReferenceException + } + } + else + { + Span expected = this.ExpectedDestBuffer.AsSpan(); + Span actual = this.ActualDestBuffer.GetSpan(); + for (int i = 0; i < count; i++) + { + Assert.Equal(expected[i], actual[i]); + } + } + } + } } } \ No newline at end of file From df32de1d2a31c2d3021a54c440d843a772a39eda Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 15 Oct 2018 19:53:28 +0100 Subject: [PATCH 017/238] Fix sandbox tests --- tests/ImageSharp.Sandbox46/Program.cs | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index fa1d63878..4d89929a0 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -6,14 +6,9 @@ namespace SixLabors.ImageSharp.Sandbox46 { using System; - using System.Runtime.DesignerServices; - - using SixLabors.ImageSharp.Tests; - using SixLabors.ImageSharp.Tests.Colors; using SixLabors.ImageSharp.Tests.Formats.Jpg; using SixLabors.ImageSharp.Tests.PixelFormats; using SixLabors.ImageSharp.Tests.Processing.Processors.Transforms; - using SixLabors.ImageSharp.Tests.Processing.Transforms; using Xunit.Abstractions; @@ -21,15 +16,9 @@ namespace SixLabors.ImageSharp.Sandbox46 { private class ConsoleOutput : ITestOutputHelper { - public void WriteLine(string message) - { - Console.WriteLine(message); - } + public void WriteLine(string message) => Console.WriteLine(message); - public void WriteLine(string format, params object[] args) - { - Console.WriteLine(format, args); - } + public void WriteLine(string format, params object[] args) => Console.WriteLine(format, args); } /// @@ -58,20 +47,20 @@ namespace SixLabors.ImageSharp.Sandbox46 private static void RunResizeProfilingTest() { - ResizeProfilingBenchmarks test = new ResizeProfilingBenchmarks(new ConsoleOutput()); + var test = new ResizeProfilingBenchmarks(new ConsoleOutput()); test.ResizeBicubic(2000, 2000); } private static void RunToVector4ProfilingTest() { - PixelOperationsTests.Rgba32 tests = new PixelOperationsTests.Rgba32(new ConsoleOutput()); + var tests = new PixelOperationsTests.Rgba32OperationsTests(new ConsoleOutput()); tests.Benchmark_ToVector4(); } private static void RunDecodeJpegProfilingTests() { Console.WriteLine("RunDecodeJpegProfilingTests..."); - JpegProfilingBenchmarks benchmarks = new JpegProfilingBenchmarks(new ConsoleOutput()); + var benchmarks = new JpegProfilingBenchmarks(new ConsoleOutput()); foreach (object[] data in JpegProfilingBenchmarks.DecodeJpegData) { string fileName = (string)data[0]; From b03202ca1936f85ab014be237327b50353e4e398 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 15 Oct 2018 22:29:39 +0100 Subject: [PATCH 018/238] Fix JIT issue on 32bit framework --- src/ImageSharp/PixelFormats/Rgba32.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index e7814d23a..415c39c0e 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -133,7 +133,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// public Rgb24 Rgb { - [MethodImpl(InliningOptions.ShortMethod)] + // If this is changed to ShortMethod then several jpeg encoding tests fail + // on 32 bit Net 4.6.2 and NET 4.7.1 + [MethodImpl(InliningOptions.ColdPath)] get => Unsafe.As(ref this); [MethodImpl(InliningOptions.ShortMethod)] From f72fcbdc0f9ff2f787bd2e076f8193dc59225d0d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 16 Oct 2018 00:35:45 +0200 Subject: [PATCH 019/238] uniformize conversion code --- .../SimdUtils.ExtendedIntrinsics.cs | 64 ++++++++++ src/ImageSharp/Common/Extensions/SimdUtils.cs | 50 ++------ .../PixelFormats/Rgba32.PixelOperations.cs | 117 +++--------------- .../Color/Bulk/PackFromVector4.cs | 4 +- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 6 +- .../PixelFormats/PixelOperationsTests.cs | 38 ++---- 6 files changed, 103 insertions(+), 176 deletions(-) create mode 100644 src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs new file mode 100644 index 000000000..ec52b90ef --- /dev/null +++ b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs @@ -0,0 +1,64 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp +{ + internal static partial class SimdUtils + { + /// + /// Methods accelerated only in RyuJIT having dotnet/coreclr#10662 merged (.NET Core 2.1+ .NET 4.7.2+) + /// PR: + /// https://github.com/dotnet/coreclr/pull/10662 + /// API Proposal: + /// https://github.com/dotnet/corefx/issues/15957 + /// + public static class ExtendedIntrinsics + { + public static bool IsAvailable { get; } = +#if NETCOREAPP2_1 +// TODO: Add a build target for .NET 4.7.2 + true; +#else + false; +#endif + + // ReSharper disable once MemberHidesStaticFromOuterClass + internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + { + Guard.IsTrue( + source.Length % Vector.Count == 0, + nameof(source), + "dest.Length should be divisable by Vector.Count!"); + + int n = source.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + Vector f0 = Vector.ConvertToSingle(w0) * scale; + Vector f1 = Vector.ConvertToSingle(w1) * scale; + Vector f2 = Vector.ConvertToSingle(w2) * scale; + Vector f3 = Vector.ConvertToSingle(w3) * scale; + + ref Vector d = ref Unsafe.Add(ref destBase, i * 4); + d = f0; + Unsafe.Add(ref d, 1) = f1; + Unsafe.Add(ref d, 2) = f2; + Unsafe.Add(ref d, 3) = f3; + } + } + } + } +} diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Extensions/SimdUtils.cs index 481e0726d..3630ede32 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.cs @@ -14,12 +14,12 @@ namespace SixLabors.ImageSharp /// /// Various extension and utility methods for and utilizing SIMD capabilities /// - internal static class SimdUtils + internal static partial class SimdUtils { /// /// Gets a value indicating whether the code is being executed on AVX2 CPU where both float and integer registers are of size 256 byte. /// - public static bool IsAvx2CompatibleArchitecture => Vector.Count == 8 && Vector.Count == 8; + public static bool IsAvx2CompatibleArchitecture { get; } = Vector.IsHardwareAccelerated && Vector.Count == 8 && Vector.Count == 8; internal static void GuardAvx2(string operation) { @@ -61,7 +61,8 @@ namespace SixLabors.ImageSharp /// /// Convert 'source.Length' values normalized into [0..1] from 'source' into 'dest' buffer of values. - /// The values gonna be scaled up into [0-255] and rounded. + /// The values are scaled up into [0-255] and rounded. + /// The implementation is SIMD optimized and works only with `source.Length` divisible by . /// Based on: /// /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions @@ -106,46 +107,13 @@ namespace SixLabors.ImageSharp } /// - /// Fast -> conversion for RyuJIT runtimes having dotnet/coreclr#10662 merged. + /// Converts `dest.Length` bytes to -s to -s normalized into [0..1] + /// The implementation is SIMD optimized and works only with `dest.Length` divisible by . + /// Implementation adapted from: /// - /// https://github.com/dotnet/coreclr/pull/10662 + /// http://stackoverflow.com/a/5362789 /// /// - internal static void BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(ReadOnlySpan source, Span dest) - { - Guard.IsTrue( - source.Length % Vector.Count == 0, - nameof(source), - "dest.Length should be divisable by Vector.Count!"); - - int n = source.Length / Vector.Count; - - ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - - var scale = new Vector(1f / 255f); - - for (int i = 0; i < n; i++) - { - Vector b = Unsafe.Add(ref sourceBase, i); - - Vector.Widen(b, out Vector s0, out Vector s1); - Vector.Widen(s0, out Vector w0, out Vector w1); - Vector.Widen(s1, out Vector w2, out Vector w3); - - Vector f0 = Vector.ConvertToSingle(w0) * scale; - Vector f1 = Vector.ConvertToSingle(w1) * scale; - Vector f2 = Vector.ConvertToSingle(w2) * scale; - Vector f3 = Vector.ConvertToSingle(w3) * scale; - - ref Vector d = ref Unsafe.Add(ref destBase, i * 4); - d = f0; - Unsafe.Add(ref d, 1) = f1; - Unsafe.Add(ref d, 2) = f2; - Unsafe.Add(ref d, 3) = f3; - } - } - internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); @@ -188,7 +156,7 @@ namespace SixLabors.ImageSharp /// internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); + GuardAvx2(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 76e119ba4..6745079da 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.Memory; @@ -19,99 +18,37 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal partial class PixelOperations : PixelOperations { - /// - /// SIMD optimized bulk implementation of - /// that works only with `count` divisible by . - /// - /// The to the source colors. - /// The to the dstination vectors. - /// The number of pixels to convert. - /// - /// Implementation adapted from: - /// - /// http://stackoverflow.com/a/5362789 - /// - /// TODO: We can replace this implementation in the future using new Vector API-s: - /// - /// https://github.com/dotnet/corefx/issues/15957 - /// - /// - internal static void ToVector4SimdAligned(ReadOnlySpan sourceColors, Span destVectors, int count) - { - if (!Vector.IsHardwareAccelerated) - { - throw new InvalidOperationException( - "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); - } - - DebugGuard.IsTrue( - count % Vector.Count == 0, - nameof(count), - "Argument 'count' should divisible by Vector.Count!"); - - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f - var mask = new Vector(255); - - int unpackedRawCount = count * 4; - - ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(sourceColors)); - ref WideRgba destBaseAsWide = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); - ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsWide); - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWide); - - for (int i = 0; i < count; i++) - { - uint sVal = Unsafe.Add(ref sourceBase, i); - ref WideRgba dst = ref Unsafe.Add(ref destBaseAsWide, i); - - // This call is the bottleneck now: - dst.Load(sVal); - } - - int numOfVectors = unpackedRawCount / Vector.Count; - - for (int i = 0; i < numOfVectors; i++) - { - Vector vi = Unsafe.Add(ref destBaseAsUInt, i); - - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - Unsafe.Add(ref destBaseAsFloat, i) = vf; - } - } - /// internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - if (count < 256 || !Vector.IsHardwareAccelerated) + if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) { // Doesn't worth to bother with SIMD: base.ToVector4(sourceColors, destinationVectors, count); return; } - int remainder = count % Vector.Count; + int remainder = count % 2; int alignedCount = count - remainder; if (alignedCount > 0) { - ToVector4SimdAligned(sourceColors, destinationVectors, alignedCount); + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); + Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); + + SimdUtils.BulkConvertByteToNormalizedFloat( + rawSrc, + rawDest); } if (remainder > 0) { - sourceColors = sourceColors.Slice(alignedCount); - destinationVectors = destinationVectors.Slice(alignedCount); - base.ToVector4(sourceColors, destinationVectors, remainder); + // actually: remainder == 1 + int lastIdx = count - 1; + destinationVectors[lastIdx] = sourceColors[lastIdx].ToVector4(); } } @@ -120,7 +57,7 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - if (!SimdUtils.IsAvx2CompatibleArchitecture) + if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) { base.PackFromVector4(sourceVectors, destinationColors, count); return; @@ -131,10 +68,10 @@ namespace SixLabors.ImageSharp.PixelFormats if (alignedCount > 0) { - ReadOnlySpan flatSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); - Span flatDest = MemoryMarshal.Cast(destinationColors); + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); + Span rawDest = MemoryMarshal.Cast(destinationColors); - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(flatSrc, flatDest); + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); } if (remainder > 0) @@ -172,30 +109,6 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(dest); } - - /// - /// Value type to store -s widened into multiple -s. - /// - [StructLayout(LayoutKind.Sequential)] - private struct WideRgba - { - private uint r; - - private uint g; - - private uint b; - - private uint a; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Load(uint p) - { - this.r = p; - this.g = p >> GreenShift; - this.b = p >> BlueShift; - this.a = p >> AlphaShift; - } - } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index a5fa59ba0..bdae7d065 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -23,7 +23,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk private IMemoryOwner destination; - [Params(16, 128, 512)] + [Params( + //64, + 2048)] public int Count { get; set; } [GlobalSetup] diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 4e39af70f..0488dd5e1 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -205,12 +205,12 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } - + [Theory] [InlineData(1, 0)] [InlineData(2, 32)] [InlineData(3, 128)] - public void BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(int seed, int count) + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int seed, int count) { if (!Vector.IsHardwareAccelerated) { @@ -221,7 +221,7 @@ namespace SixLabors.ImageSharp.Tests.Common float[] result = new float[count]; float[] expected = source.Select(b => (float)b / 255f).ToArray(); - SimdUtils.BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(source, result); + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(source, result); Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 4d7ec71e7..535952e05 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -17,43 +17,26 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { public class Rgba32 : PixelOperationsTests { + public const string SkipProfilingBenchmarks = +#if true + "Profiling benchmark - enable manually!"; +#else + null; +#endif + public Rgba32(ITestOutputHelper output) : base(output) { } - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() { Assert.IsType(PixelOperations.Instance); } - [Fact] - public void ToVector4SimdAligned() - { - if (!Vector.IsHardwareAccelerated) - { - return; - } - - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); - Vector4[] expected = CreateExpectedVector4Data(source); - - TestOperation( - source, - expected, - (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) - ); - } - - - // [Fact] // Profiling benchmark - enable manually! -#pragma warning disable xUnit1013 // Public method should be marked as test + [Fact(Skip = SkipProfilingBenchmarks)] public void Benchmark_ToVector4() -#pragma warning restore xUnit1013 // Public method should be marked as test { int times = 200000; int count = 1024; @@ -73,13 +56,10 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public class Argb32 : PixelOperationsTests { - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: public Argb32(ITestOutputHelper output) : base(output) { } - - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; } [Theory] @@ -110,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + public static TheoryData ArraySizesData => new TheoryData { 0, 1, 2, 7, 16, 1111 }; private static PixelOperations Operations => PixelOperations.Instance; From 664672d7e4c5c13c6041b90688a398bf1e574859 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 16 Oct 2018 01:02:39 +0200 Subject: [PATCH 020/238] BulkConvertNormalizedFloatToByteClampOverflows --- .../SimdUtils.ExtendedIntrinsics.cs | 66 +++++++++++++++++-- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 18 +++++ 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs index ec52b90ef..97f364a10 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs @@ -24,6 +24,9 @@ namespace SixLabors.ImageSharp false; #endif + /// + /// A variant of , which is faster on new .NET runtime. + /// // ReSharper disable once MemberHidesStaticFromOuterClass internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { @@ -37,7 +40,7 @@ namespace SixLabors.ImageSharp ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - var scale = new Vector(1f / 255f); + const float Scale = 1f / 255f; for (int i = 0; i < n; i++) { @@ -47,10 +50,10 @@ namespace SixLabors.ImageSharp Vector.Widen(s0, out Vector w0, out Vector w1); Vector.Widen(s1, out Vector w2, out Vector w3); - Vector f0 = Vector.ConvertToSingle(w0) * scale; - Vector f1 = Vector.ConvertToSingle(w1) * scale; - Vector f2 = Vector.ConvertToSingle(w2) * scale; - Vector f3 = Vector.ConvertToSingle(w3) * scale; + Vector f0 = Vector.ConvertToSingle(w0) * Scale; + Vector f1 = Vector.ConvertToSingle(w1) * Scale; + Vector f2 = Vector.ConvertToSingle(w2) * Scale; + Vector f3 = Vector.ConvertToSingle(w3) * Scale; ref Vector d = ref Unsafe.Add(ref destBase, i * 4); d = f0; @@ -59,6 +62,59 @@ namespace SixLabors.ImageSharp Unsafe.Add(ref d, 3) = f3; } } + + /// + /// A variant of , which is faster on new .NET runtime. + /// + // ReSharper disable once MemberHidesStaticFromOuterClass + internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) + { + Guard.IsTrue( + dest.Length % Vector.Count == 0, + nameof(source), + "dest.Length should be divisable by Vector.Count!"); + + int n = dest.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); + + for (int i = 0; i < n; i++) + { + ref Vector s = ref Unsafe.Add(ref sourceBase, i * 4); + + Vector f0 = s; + f0 = Clamp(f0); + + Vector f1 = Unsafe.Add(ref s, 1); + f1 = Clamp(f1); + + Vector f2 = Unsafe.Add(ref s, 2); + f2 = Clamp(f2); + + Vector f3 = Unsafe.Add(ref s, 3); + f3 = Clamp(f3); + + Vector w0 = Vector.ConvertToUInt32(f0 * 255f); + Vector w1 = Vector.ConvertToUInt32(f1 * 255f); + Vector w2 = Vector.ConvertToUInt32(f2 * 255f); + Vector w3 = Vector.ConvertToUInt32(f3 * 255f); + + Vector u0 = Vector.Narrow(w0, w1); + Vector u1 = Vector.Narrow(w2, w3); + + Vector b = Vector.Narrow(u0, u1); + + Unsafe.Add(ref destBase, i) = b; + } + + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector Clamp(Vector x) + { + return Vector.Min(Vector.Max(x, Vector.Zero), Vector.One); + } } } } diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 0488dd5e1..4b23ca30f 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -226,6 +226,24 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } + [Theory] + [InlineData(1, 0)] + [InlineData(2, 32)] + [InlineData(3, 128)] + public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int seed, int count) + { + float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, -50, 444); + float[] normalized = orig.Select(f => f / 255f).ToArray(); + + byte[] dest = new byte[count]; + + SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(normalized, dest); + + byte[] expected = orig.Select(f => (byte)Clamp255(f)).ToArray(); + + Assert.Equal(expected, dest); + } + [Theory] [InlineData(0)] [InlineData(7)] From 4ab0731425e821cefae6dee776afe269a6d753d5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 16 Oct 2018 01:13:43 +0200 Subject: [PATCH 021/238] disappointing benchmark results --- .../SimdUtils.ExtendedIntrinsics.cs | 5 +- .../Color/Bulk/PackFromVector4.cs | 48 +++++++++++++++++-- .../Color/Bulk/ToVector4.cs | 6 +-- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs index 97f364a10..90048ca9b 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs @@ -66,6 +66,10 @@ namespace SixLabors.ImageSharp /// /// A variant of , which is faster on new .NET runtime. /// + /// + /// It does NOT worth yet to utilize this method (2018 Oct). + /// See benchmark results for the "PackFromVector4_Rgba32" benchmark! + /// // ReSharper disable once MemberHidesStaticFromOuterClass internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { @@ -107,7 +111,6 @@ namespace SixLabors.ImageSharp Unsafe.Add(ref destBase, i) = b; } - } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index bdae7d065..4bf98e5ce 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -3,6 +3,7 @@ // ReSharper disable InconsistentNaming +using System; using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; @@ -19,9 +20,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public abstract class PackFromVector4 where TPixel : struct, IPixel { - private IMemoryOwner source; + protected IMemoryOwner source; - private IMemoryOwner destination; + protected IMemoryOwner destination; [Params( //64, @@ -42,7 +43,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.source.Dispose(); } - [Benchmark(Baseline = true)] + [Benchmark] public void PerElement() { ref Vector4 s = ref MemoryMarshal.GetReference(this.source.GetSpan()); @@ -54,7 +55,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + [Benchmark(Baseline = true)] public void CommonBulk() { new PixelOperations().PackFromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); @@ -69,6 +70,45 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public class PackFromVector4_Rgba32 : PackFromVector4 { + //[Benchmark] + public void BulkConvertNormalizedFloatToByteClampOverflows() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); + } + + [Benchmark] + public void ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); + } + // RESULTS: + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742187 Hz, Resolution=364.6724 ns, Timer=TSC + // .NET Core SDK=2.1.400-preview-009063 + // [Host] : .NET Core 2.1.1 (CoreCLR 4.6.26606.02, CoreFX 4.6.26606.05), 64bit RyuJIT + // Job-XIFINS : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-RTQZPN : .NET Core 2.1.1 (CoreCLR 4.6.26606.02, CoreFX 4.6.26606.05), 64bit RyuJIT + // + // LaunchCount=1 TargetCount=3 WarmupCount=3 + // + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | + // ----------------------------------------------------------------- |-------- |------ |----------:|-----------:|----------:|-------:|---------:|----------:| + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3.755 us | 0.8959 us | 0.0506 us | 0.22 | 0.00 | 0 B | + // PerElement | Clr | 2048 | 17.387 us | 15.1569 us | 0.8564 us | 1.02 | 0.04 | 0 B | + // CommonBulk | Clr | 2048 | 17.121 us | 0.7634 us | 0.0431 us | 1.00 | 0.00 | 24 B | + // OptimizedBulk | Clr | 2048 | 4.018 us | 0.3858 us | 0.0218 us | 0.23 | 0.00 | 0 B | + // | | | | | | | | | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 22.232 us | 1.6154 us | 0.0913 us | 1.31 | 0.04 | 0 B | + // PerElement | Core | 2048 | 16.741 us | 2.9254 us | 0.1653 us | 0.98 | 0.03 | 0 B | + // CommonBulk | Core | 2048 | 17.022 us | 11.4894 us | 0.6492 us | 1.00 | 0.00 | 24 B | + // OptimizedBulk | Core | 2048 | 3.707 us | 0.1500 us | 0.0085 us | 0.22 | 0.01 | 0 B | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 3ea256e85..39c1fbd47 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { } - //[Benchmark] + [Benchmark] public void BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -89,12 +89,12 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark] - public void BulkConvertByteToNormalizedFloatFast() + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.BulkConvertByteToNormalizedFloatWithExtendedIntrinsics(sBytes, dFloats); + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } } From 3cd3d0e25f4fdc76f2d715d5a74d13c0ac02eb9d Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 16 Oct 2018 13:41:58 +0100 Subject: [PATCH 022/238] Use FormattableString --- src/ImageSharp/PixelFormats/Bgr565.cs | 2 +- src/ImageSharp/PixelFormats/Bgra4444.cs | 2 +- src/ImageSharp/PixelFormats/Bgra5551.cs | 2 +- src/ImageSharp/PixelFormats/Byte4.cs | 2 +- src/ImageSharp/PixelFormats/HalfSingle.cs | 3 ++- src/ImageSharp/PixelFormats/HalfVector2.cs | 3 ++- src/ImageSharp/PixelFormats/HalfVector4.cs | 3 ++- src/ImageSharp/PixelFormats/NormalizedByte2.cs | 2 +- src/ImageSharp/PixelFormats/NormalizedByte4.cs | 2 +- src/ImageSharp/PixelFormats/NormalizedShort2.cs | 2 +- src/ImageSharp/PixelFormats/NormalizedShort4.cs | 2 +- src/ImageSharp/PixelFormats/Rg32.cs | 2 +- src/ImageSharp/PixelFormats/Rgba1010102.cs | 6 +++++- src/ImageSharp/PixelFormats/RgbaVector.cs | 3 ++- src/ImageSharp/PixelFormats/Short2.cs | 2 +- src/ImageSharp/PixelFormats/Short4.cs | 2 +- 16 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 454f458b1..04af6ef0f 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -148,7 +148,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector3(); - return $"Bgr565({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##})"; + return FormattableString.Invariant($"Bgr565({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index 08484eba8..db1c8f865 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"Bgra4444({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"Bgra4444({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index df0a46730..5d9003cdd 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"Bgra5551({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"Bgra5551({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index 34546e027..230c31c5c 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"Bgra5551({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"Bgra5551({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 78edc9a08..bef4a5dd9 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -130,7 +131,7 @@ namespace SixLabors.ImageSharp.PixelFormats public bool Equals(HalfSingle other) => this.PackedValue.Equals(other.PackedValue); /// - public override string ToString() => $"HalfSingle({this.ToSingle():#0.##})"; + public override string ToString() => FormattableString.Invariant($"HalfSingle({this.ToSingle():#0.##})"); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index e3777bc2f..5bd9924c5 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -150,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector2(); - return $"HalfVector2({vector.X:#0.##}, {vector.Y:#0.##})"; + return FormattableString.Invariant($"HalfVector2({vector.X:#0.##}, {vector.Y:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 079c3ee38..2e487ef98 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -145,7 +146,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"HalfVector4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"HalfVector4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 3eaa69c03..219ec8763 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -161,7 +161,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector2(); - return $"NormalizedByte2({vector.X:#0.##}, {vector.Y:#0.##})"; + return FormattableString.Invariant($"NormalizedByte2({vector.X:#0.##}, {vector.Y:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index e0e3e6502..d5795cb4b 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"NormalizedByte4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"NormalizedByte4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 0aa573637..34e752496 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector2(); - return $"NormalizedShort2({vector.X:#0.##}, {vector.Y:#0.##})"; + return FormattableString.Invariant($"NormalizedShort2({vector.X:#0.##}, {vector.Y:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 577e90154..6fda84bc2 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -155,7 +155,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"NormalizedShort4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"NormalizedShort4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 02c294b4f..0831f6524 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector2(); - return $"Rg32({vector.X:#0.##}, {vector.Y:#0.##})"; + return FormattableString.Invariant($"Rg32({vector.X:#0.##}, {vector.Y:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 86b639e22..14265b54e 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -135,7 +135,11 @@ namespace SixLabors.ImageSharp.PixelFormats public bool Equals(Rgba1010102 other) => this.PackedValue == other.PackedValue; /// - public override string ToString() => this.ToVector4().ToString(); + public override string ToString() + { + var vector = this.ToVector4(); + return FormattableString.Invariant($"Rgba1010102({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index b5ccf8aed..b2a3dc578 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -189,7 +190,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"RgbaVector({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"; + return FormattableString.Invariant($"RgbaVector({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"); } /// diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index db29b401e..81df3ef7b 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector2(); - return $"Short2({vector.X:#0.##}, {vector.Y:#0.##})"; + return FormattableString.Invariant($"Short2({vector.X:#0.##}, {vector.Y:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 6d6e5f084..48bd01d6e 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override string ToString() { var vector = this.ToVector4(); - return $"Short4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"; + return FormattableString.Invariant($"Short4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})"); } [MethodImpl(InliningOptions.ShortMethod)] From b66375044b9283dacd71c5ccf8a2f6d099831bc3 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 16 Oct 2018 14:26:40 +0100 Subject: [PATCH 023/238] Use new IPixel API --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 24 +++------ src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 34 +++++++++---- .../Formats/Png/PngScanlineProcessor.cs | 51 +++++-------------- 3 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 71852acdd..dabab651d 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -219,8 +219,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp where TPixel : struct, IPixel { TPixel color = default; - var rgba = new Rgba32(0, 0, 0, 255); - using (Buffer2D buffer = this.memoryAllocator.Allocate2D(width, height, AllocationOptions.Clean)) { this.UncompressRle8(width, buffer.GetSpan()); @@ -233,8 +231,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp for (int x = 0; x < width; x++) { - rgba.Bgr = Unsafe.As(ref colors[bufferRow[x] * 4]); - color.PackFromRgba32(rgba); + color.PackFromBgr24(Unsafe.As(ref colors[bufferRow[x] * 4])); pixelRow[x] = color; } } @@ -352,8 +349,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp using (IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(arrayWidth + padding, AllocationOptions.Clean)) { TPixel color = default; - var rgba = new Rgba32(0, 0, 0, 255); - Span rowSpan = row.GetSpan(); for (int y = 0; y < height; y++) @@ -363,7 +358,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp int offset = 0; Span pixelRow = pixels.GetRowSpan(newY); - // TODO: Could use PixelOperations here! for (int x = 0; x < arrayWidth; x++) { int colOffset = x * ppb; @@ -371,9 +365,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp { int colorIndex = ((rowSpan[offset] >> (8 - bits - (shift * bits))) & mask) * 4; - // Stored in b-> g-> r order. - rgba.Bgr = Unsafe.As(ref colors[colorIndex]); - color.PackFromRgba32(rgba); + color.PackFromBgr24(Unsafe.As(ref colors[colorIndex])); pixelRow[newX] = color; } @@ -397,7 +389,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp int padding = CalculatePadding(width, 2); int stride = (width * 2) + padding; TPixel color = default; - var rgba = new Rgba32(0, 0, 0, 255); using (IManagedByteBuffer buffer = this.memoryAllocator.AllocateManagedByteBuffer(stride)) { @@ -412,11 +403,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp { short temp = BitConverter.ToInt16(buffer.Array, offset); - rgba.R = GetBytesFrom5BitValue((temp & Rgb16RMask) >> 10); - rgba.G = GetBytesFrom5BitValue((temp & Rgb16GMask) >> 5); - rgba.B = GetBytesFrom5BitValue(temp & Rgb16BMask); + var rgb = new Rgb24( + GetBytesFrom5BitValue((temp & Rgb16RMask) >> 10), + GetBytesFrom5BitValue((temp & Rgb16GMask) >> 5), + GetBytesFrom5BitValue(temp & Rgb16BMask)); - color.PackFromRgba32(rgba); + color.PackFromRgb24(rgb); pixelRow[x] = color; offset += 2; } @@ -537,7 +529,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.metaData = meta; short bitsPerPixel = this.infoHeader.BitsPerPixel; - var bmpMetaData = this.metaData.GetFormatMetaData(BmpFormat.Instance); + BmpMetaData bmpMetaData = this.metaData.GetFormatMetaData(BmpFormat.Instance); // We can only encode at these bit rates so far. if (bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel24) diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index 207f126f9..155e6484f 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -481,22 +481,36 @@ namespace SixLabors.ImageSharp.Formats.Gif } ref TPixel rowRef = ref MemoryMarshal.GetReference(imageFrame.GetPixelRowSpan(writeY)); - var rgba = new Rgba32(0, 0, 0, 255); + bool transFlag = this.graphicsControlExtension.TransparencyFlag; - // #403 The left + width value can be larger than the image width - for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width && x < imageWidth; x++) + if (!transFlag) { - int index = Unsafe.Add(ref indicesRef, i); - - if (!this.graphicsControlExtension.TransparencyFlag - || this.graphicsControlExtension.TransparencyIndex != index) + // #403 The left + width value can be larger than the image width + for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width && x < imageWidth; x++) { + int index = Unsafe.Add(ref indicesRef, i); ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); - rgba.Rgb = colorTable[index]; - pixel.PackFromRgba32(rgba); + Rgb24 rgb = colorTable[index]; + pixel.PackFromRgb24(rgb); + + i++; } + } + else + { + byte transIndex = this.graphicsControlExtension.TransparencyIndex; + for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width && x < imageWidth; x++) + { + int index = Unsafe.Add(ref indicesRef, i); + if (transIndex != index) + { + ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); + Rgb24 rgb = colorTable[index]; + pixel.PackFromRgb24(rgb); + } - i++; + i++; + } } } diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 6c81ba76c..92c76a3fa 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -32,30 +32,19 @@ namespace SixLabors.ImageSharp.Formats.Png { if (header.BitDepth == 16) { - Rgb48 rgb48 = default; for (int x = 0, o = 0; x < header.Width; x++, o += 2) { ushort luminance = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2)); - rgb48.R = luminance; - rgb48.G = luminance; - rgb48.B = luminance; - - pixel.PackFromRgb48(rgb48); + pixel.PackFromGray16(new Gray16(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } else { - // TODO: We should really be using Rgb24 here but IPixel does not have a PackFromRgb24 method. - var rgba32 = new Rgba32(0, 0, 0, byte.MaxValue); for (int x = 0; x < header.Width; x++) { byte luminance = (byte)(Unsafe.Add(ref scanlineSpanRef, x) * scaleFactor); - rgba32.R = luminance; - rgba32.G = luminance; - rgba32.B = luminance; - - pixel.PackFromRgba32(rgba32); + pixel.PackFromGray8(new Gray8(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -115,30 +104,19 @@ namespace SixLabors.ImageSharp.Formats.Png { if (header.BitDepth == 16) { - Rgb48 rgb48 = default; for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o += 2) { ushort luminance = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2)); - rgb48.R = luminance; - rgb48.G = luminance; - rgb48.B = luminance; - - pixel.PackFromRgb48(rgb48); + pixel.PackFromGray16(new Gray16(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } else { - // TODO: We should really be using Rgb24 here but IPixel does not have a PackFromRgb24 method. - var rgba32 = new Rgba32(0, 0, 0, byte.MaxValue); for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o++) { byte luminance = (byte)(Unsafe.Add(ref scanlineSpanRef, o) * scaleFactor); - rgba32.R = luminance; - rgba32.G = luminance; - rgba32.B = luminance; - - pixel.PackFromRgba32(rgba32); + pixel.PackFromGray8(new Gray8(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -309,14 +287,12 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - // TODO: We should have PackFromRgb24. - var rgba = new Rgba32(0, 0, 0, byte.MaxValue); for (int x = 0; x < header.Width; x++) { int index = Unsafe.Add(ref scanlineSpanRef, x); - rgba.Rgb = Unsafe.Add(ref palettePixelsRef, index); + Rgb24 rgb = Unsafe.Add(ref palettePixelsRef, index); - pixel.PackFromRgba32(rgba); + pixel.PackFromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -356,13 +332,12 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - var rgba = new Rgba32(0, 0, 0, byte.MaxValue); for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o++) { int index = Unsafe.Add(ref scanlineSpanRef, o); - rgba.Rgb = Unsafe.Add(ref palettePixelsRef, index); + Rgb24 rgb = Unsafe.Add(ref palettePixelsRef, index); - pixel.PackFromRgba32(rgba); + pixel.PackFromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -509,14 +484,14 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - var rgba = new Rgba32(0, 0, 0, byte.MaxValue); + Rgb24 rgb = default; for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o += bytesPerPixel) { - rgba.R = Unsafe.Add(ref scanlineSpanRef, o); - rgba.G = Unsafe.Add(ref scanlineSpanRef, o + bytesPerSample); - rgba.B = Unsafe.Add(ref scanlineSpanRef, o + (2 * bytesPerSample)); + rgb.R = Unsafe.Add(ref scanlineSpanRef, o); + rgb.G = Unsafe.Add(ref scanlineSpanRef, o + bytesPerSample); + rgb.B = Unsafe.Add(ref scanlineSpanRef, o + (2 * bytesPerSample)); - pixel.PackFromRgba32(rgba); + pixel.PackFromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } From 010265ec7f7d1d74886d0f12a0d53739500a13f6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 17 Oct 2018 23:39:29 +0200 Subject: [PATCH 024/238] todo notes --- .../Common/Extensions/SimdUtils.ExtendedIntrinsics.cs | 1 + tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs index 90048ca9b..fba54b033 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs @@ -69,6 +69,7 @@ namespace SixLabors.ImageSharp /// /// It does NOT worth yet to utilize this method (2018 Oct). /// See benchmark results for the "PackFromVector4_Rgba32" benchmark! + /// TODO: Check again later! /// // ReSharper disable once MemberHidesStaticFromOuterClass internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index 4bf98e5ce..fb505ddcb 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -88,7 +88,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); } + // TODO: Check again later! // RESULTS: + // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores // Frequency=2742187 Hz, Resolution=364.6724 ns, Timer=TSC From 01ee560c08973e16b9aec65e09ce5769255c0cd5 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 18 Oct 2018 17:04:41 +0100 Subject: [PATCH 025/238] Use scaled luminance trns comparison. --- src/ImageSharp/Formats/Png/PngScanlineProcessor.cs | 6 ++++-- tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs | 3 ++- tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Png/gray-1-trns.png | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 tests/Images/Input/Png/gray-1-trns.png diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 6c81ba76c..5ea25e72d 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -80,6 +80,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { + byte scaledLuminanceTrans = (byte)(luminanceTrans * scaleFactor); Rgba32 rgba32 = default; for (int x = 0; x < header.Width; x++) { @@ -87,7 +88,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.R = luminance; rgba32.G = luminance; rgba32.B = luminance; - rgba32.A = luminance.Equals(luminanceTrans) ? byte.MinValue : byte.MaxValue; + rgba32.A = luminance.Equals(scaledLuminanceTrans) ? byte.MinValue : byte.MaxValue; pixel.PackFromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; @@ -163,6 +164,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { + byte scaledLuminanceTrans = (byte)(luminanceTrans * scaleFactor); Rgba32 rgba32 = default; for (int x = pixelOffset; x < header.Width; x += increment) { @@ -170,7 +172,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.R = luminance; rgba32.G = luminance; rgba32.B = luminance; - rgba32.A = luminance.Equals(luminanceTrans) ? byte.MinValue : byte.MaxValue; + rgba32.A = luminance.Equals(scaledLuminanceTrans) ? byte.MinValue : byte.MaxValue; pixel.PackFromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 54f3e397c..f51f9b6c5 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -40,7 +40,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png TestImages.Png.VimImage2, TestImages.Png.Rgb24BppTrans, - TestImages.Png.GrayAlpha8Bit + TestImages.Png.GrayAlpha8Bit, + TestImages.Png.Gray1BitTrans }; public static readonly string[] TestImages48Bpp = diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index fdf586c43..758f25634 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -45,6 +45,7 @@ namespace SixLabors.ImageSharp.Tests public const string Kaboom = "Png/kaboom.png"; public const string PDSrc = "Png/pd-source.png"; public const string PDDest = "Png/pd-dest.png"; + public const string Gray1BitTrans = "Png/gray-1-trns.png"; // Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html public const string Filter0 = "Png/filter0.png"; diff --git a/tests/Images/Input/Png/gray-1-trns.png b/tests/Images/Input/Png/gray-1-trns.png new file mode 100644 index 000000000..65e72ad62 --- /dev/null +++ b/tests/Images/Input/Png/gray-1-trns.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca88b334de7037abfacd9d87c2cb8eec7391f355c1d6b4a694fc4240f358ee1 +size 366 From f87436634ab93f5ba4f7b1fff28aede1a4fec248 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 18 Oct 2018 22:45:39 +0200 Subject: [PATCH 026/238] common fixtures for PixelConversion* benchmarks --- .../General/PixelConversion/ITestPixel.cs | 24 ++++++ .../PixelConversion_ConvertFromRgba32.cs | 81 ++----------------- .../PixelConversion_ConvertFromVector4.cs | 53 ++++-------- .../PixelConversion_ConvertToRgba32.cs | 59 ++------------ .../General/PixelConversion/TestArgb.cs | 74 +++++++++++++++++ .../General/PixelConversion/TestRgba.cs | 57 +++++++++++++ 6 files changed, 181 insertions(+), 167 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs rename tests/ImageSharp.Benchmarks/General/{ => PixelConversion}/PixelConversion_ConvertFromRgba32.cs (66%) rename tests/ImageSharp.Benchmarks/General/{ => PixelConversion}/PixelConversion_ConvertFromVector4.cs (75%) rename tests/ImageSharp.Benchmarks/General/{ => PixelConversion}/PixelConversion_ConvertToRgba32.cs (68%) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs new file mode 100644 index 000000000..ede617032 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs @@ -0,0 +1,24 @@ +using System.Numerics; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + interface ITestPixel + where T : struct, ITestPixel + { + void FromRgba32(Rgba32 source); + + void FromRgba32(ref Rgba32 source); + + void FromBytes(byte r, byte g, byte b, byte a); + + void FromVector4(Vector4 source); + + void FromVector4(ref Vector4 source); + + Rgba32 ToRgba32(); + + void CopyToRgba32(ref Rgba32 dest); + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs similarity index 66% rename from tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromRgba32.cs rename to tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index f5bd135e1..046c7dd90 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -1,86 +1,15 @@ // ReSharper disable InconsistentNaming -using SixLabors.ImageSharp.PixelFormats; +using System.Runtime.CompilerServices; -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; +using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ public class PixelConversion_ConvertFromRgba32 { - interface ITestPixel - where T : struct, ITestPixel - { - void FromRgba32(Rgba32 source); - - void FromRgba32(ref Rgba32 source); - - void FromBytes(byte r, byte g, byte b, byte a); - } - - [StructLayout(LayoutKind.Sequential)] - struct TestArgb : ITestPixel - { - private byte a, r, g, b; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromRgba32(Rgba32 p) - { - this.r = p.R; - this.g = p.G; - this.b = p.B; - this.a = p.A; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromRgba32(ref Rgba32 p) - { - this.r = p.R; - this.g = p.G; - this.b = p.B; - this.a = p.A; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromBytes(byte r, byte g, byte b, byte a) - { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - } - - [StructLayout(LayoutKind.Sequential)] - struct TestRgba : ITestPixel - { - private byte r, g, b, a; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromRgba32(Rgba32 source) - { - this = Unsafe.As(ref source); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromRgba32(ref Rgba32 source) - { - this = Unsafe.As(ref source); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromBytes(byte r, byte g, byte b, byte a) - { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - } - struct ConversionRunner where T : struct, ITestPixel { diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs similarity index 75% rename from tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromVector4.cs rename to tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs index 5b059e2e6..30af857b1 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs @@ -1,46 +1,17 @@ // ReSharper disable InconsistentNaming -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using System.Numerics; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - - using BenchmarkDotNet.Attributes; - - public class PixelConversion_ConvertFromVector4 - { - interface ITestPixel - where T : struct, ITestPixel - { - void FromVector4(Vector4 source); - - void FromVector4(ref Vector4 source); - } - [StructLayout(LayoutKind.Sequential)] - struct TestArgb : ITestPixel - { - private byte a, r, g, b; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromVector4(Vector4 p) - { - this.r = (byte)p.X; - this.g = (byte)p.Y; - this.b = (byte)p.Z; - this.a = (byte)p.W; - } +using BenchmarkDotNet.Attributes; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void FromVector4(ref Vector4 p) - { - this.r = (byte)p.X; - this.g = (byte)p.Y; - this.b = (byte)p.Z; - this.a = (byte)p.W; - } - } +using SixLabors.ImageSharp.PixelFormats; +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertFromVector4 + { [StructLayout(LayoutKind.Sequential)] struct TestRgbaVector : ITestPixel { @@ -57,6 +28,12 @@ namespace SixLabors.ImageSharp.Benchmarks.General { this.v = p; } + + public void FromRgba32(Rgba32 source) => throw new System.NotImplementedException(); + public void FromRgba32(ref Rgba32 source) => throw new System.NotImplementedException(); + public void FromBytes(byte r, byte g, byte b, byte a) => throw new System.NotImplementedException(); + public Rgba32 ToRgba32() => throw new System.NotImplementedException(); + public void CopyToRgba32(ref Rgba32 dest) => throw new System.NotImplementedException(); } struct ConversionRunner diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertToRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs similarity index 68% rename from tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertToRgba32.cs rename to tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs index 5656904fe..89b4031a8 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion_ConvertToRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs @@ -1,14 +1,14 @@ // ReSharper disable InconsistentNaming -using SixLabors.ImageSharp.PixelFormats; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; +using BenchmarkDotNet.Attributes; - using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ /// /// When implementing TPixel --> Rgba32 style conversions on IPixel, should which API should we prefer? /// 1. Rgba32 ToRgba32(); @@ -18,53 +18,6 @@ namespace SixLabors.ImageSharp.Benchmarks.General /// public class PixelConversion_ConvertToRgba32 { - interface ITestPixel - where T : struct, ITestPixel - { - Rgba32 ToRgba32(); - - void CopyToRgba32(ref Rgba32 dest); - } - - [StructLayout(LayoutKind.Sequential)] - struct TestArgb : ITestPixel - { - private byte a, r, g, b; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Rgba32 ToRgba32() - { - return new Rgba32(this.r, this.g, this.b, this.a); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void CopyToRgba32(ref Rgba32 dest) - { - dest.R = this.r; - dest.G = this.g; - dest.B = this.b; - dest.A = this.a; - } - } - - [StructLayout(LayoutKind.Sequential)] - struct TestRgba : ITestPixel - { - private byte r, g, b, a; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Rgba32 ToRgba32() - { - return Unsafe.As(ref this); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void CopyToRgba32(ref Rgba32 dest) - { - dest = Unsafe.As(ref this); - } - } - struct ConversionRunner where T : struct, ITestPixel { diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs new file mode 100644 index 000000000..ddac1d105 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs @@ -0,0 +1,74 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + [StructLayout(LayoutKind.Sequential)] + struct TestArgb : ITestPixel + { + private byte a, r, g, b; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromRgba32(Rgba32 p) + { + this.r = p.R; + this.g = p.G; + this.b = p.B; + this.a = p.A; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromRgba32(ref Rgba32 p) + { + this.r = p.R; + this.g = p.G; + this.b = p.B; + this.a = p.A; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromBytes(byte r, byte g, byte b, byte a) + { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromVector4(Vector4 p) + { + this.r = (byte)p.X; + this.g = (byte)p.Y; + this.b = (byte)p.Z; + this.a = (byte)p.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromVector4(ref Vector4 p) + { + this.r = (byte)p.X; + this.g = (byte)p.Y; + this.b = (byte)p.Z; + this.a = (byte)p.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Rgba32 ToRgba32() + { + return new Rgba32(this.r, this.g, this.b, this.a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToRgba32(ref Rgba32 dest) + { + dest.R = this.r; + dest.G = this.g; + dest.B = this.b; + dest.A = this.a; + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs new file mode 100644 index 000000000..b06e84063 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -0,0 +1,57 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + [StructLayout(LayoutKind.Sequential)] + struct TestRgba : ITestPixel + { + private byte r, g, b, a; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromRgba32(Rgba32 source) + { + this = Unsafe.As(ref source); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromRgba32(ref Rgba32 source) + { + this = Unsafe.As(ref source); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FromBytes(byte r, byte g, byte b, byte a) + { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public void FromVector4(Vector4 source) + { + throw new System.NotImplementedException(); + } + + public void FromVector4(ref Vector4 source) + { + throw new System.NotImplementedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Rgba32 ToRgba32() + { + return Unsafe.As(ref this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToRgba32(ref Rgba32 dest) + { + dest = Unsafe.As(ref this); + } + } +} \ No newline at end of file From d90d6527fffa77e2b90eebf3055b5cc785d4aec7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 18 Oct 2018 22:56:02 +0200 Subject: [PATCH 027/238] PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation --- ...vertToRgba32_AsPartOfCompositeOperation.cs | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs new file mode 100644 index 000000000..a27f7c3a5 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs @@ -0,0 +1,113 @@ +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation + { + struct ConversionRunner + where T : struct, ITestPixel + { + private T[] source; + + private Rgba32[] dest; + + public ConversionRunner(int count) + { + this.source = new T[count]; + this.dest = new Rgba32[count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunRetvalConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Rgba32 destBaseRef = ref this.dest[0]; + + Rgba32 temp; + + for (int i = 0; i < count; i++) + { + temp = Unsafe.Add(ref sourceBaseRef, i).ToRgba32(); + + // manipulate pixel before saving to dest buffer: + temp.A = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunCopyToConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Rgba32 destBaseRef = ref this.dest[0]; + + Rgba32 temp = default; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref sourceBaseRef, i).CopyToRgba32(ref temp); + + // manipulate pixel before saving to dest buffer: + temp.A = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + } + + private ConversionRunner compatibleMemoryLayoutRunner; + + private ConversionRunner permutedRunner; + + [Params(128)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.compatibleMemoryLayoutRunner = new ConversionRunner(this.Count); + this.permutedRunner = new ConversionRunner(this.Count); + } + + [Benchmark(Baseline = true)] + public void CompatibleRetval() + { + this.compatibleMemoryLayoutRunner.RunRetvalConversion(); + } + + [Benchmark] + public void CompatibleCopyTo() + { + this.compatibleMemoryLayoutRunner.RunCopyToConversion(); + } + + [Benchmark] + public void PermutedRetval() + { + this.permutedRunner.RunRetvalConversion(); + } + + [Benchmark] + public void PermutedCopyTo() + { + this.permutedRunner.RunCopyToConversion(); + } + } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ----------------- |------ |-----------:|----------:|----------:|-------:|---------:| + // CompatibleRetval | 128 | 210.1 ns | 0.8443 ns | 0.7484 ns | 1.00 | 0.00 | + // CompatibleCopyTo | 128 | 140.1 ns | 0.4297 ns | 0.4019 ns | 0.67 | 0.00 | + // PermutedRetval | 128 | 1,044.6 ns | 3.7901 ns | 3.3599 ns | 4.97 | 0.02 | + // PermutedCopyTo | 128 | 140.3 ns | 0.6495 ns | 0.5757 ns | 0.67 | 0.00 | +} \ No newline at end of file From 4b846ed14e4e09611714c40a6d8c6a5871dca65b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 18 Oct 2018 23:13:44 +0200 Subject: [PATCH 028/238] benchmarks for TPixel -> Vector4 conversion --- .../General/PixelConversion/ITestPixel.cs | 4 + .../PixelConversion_ConvertFromVector4.cs | 9 ++ .../PixelConversion_ConvertToRgba32.cs | 2 +- ...vertToRgba32_AsPartOfCompositeOperation.cs | 14 +-- .../PixelConversion_ConvertToVector4.cs | 83 ++++++++++++++++ ...ertToVector4_AsPartOfCompositeOperation.cs | 95 +++++++++++++++++++ .../General/PixelConversion/TestArgb.cs | 15 +++ .../General/PixelConversion/TestRgba.cs | 15 +++ 8 files changed, 229 insertions(+), 8 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs index ede617032..b5f339fb3 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs @@ -20,5 +20,9 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion Rgba32 ToRgba32(); void CopyToRgba32(ref Rgba32 dest); + + Vector4 ToVector4(); + + void CopyToVector4(ref Vector4 dest); } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs index 30af857b1..d0c8a3045 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs @@ -29,6 +29,15 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion this.v = p; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() => this.v; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest = this.v; + } + public void FromRgba32(Rgba32 source) => throw new System.NotImplementedException(); public void FromRgba32(ref Rgba32 source) => throw new System.NotImplementedException(); public void FromBytes(byte r, byte g, byte b, byte a) => throw new System.NotImplementedException(); diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs index 89b4031a8..d205e1e63 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion private ConversionRunner permutedRunner; - [Params(128)] + [Params(32)] public int Count { get; set; } [GlobalSetup] diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs index a27f7c3a5..fff9ae9bc 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion private ConversionRunner permutedRunner; - [Params(128)] + [Params(32)] public int Count { get; set; } [GlobalSetup] @@ -104,10 +104,10 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | - // ----------------- |------ |-----------:|----------:|----------:|-------:|---------:| - // CompatibleRetval | 128 | 210.1 ns | 0.8443 ns | 0.7484 ns | 1.00 | 0.00 | - // CompatibleCopyTo | 128 | 140.1 ns | 0.4297 ns | 0.4019 ns | 0.67 | 0.00 | - // PermutedRetval | 128 | 1,044.6 ns | 3.7901 ns | 3.3599 ns | 4.97 | 0.02 | - // PermutedCopyTo | 128 | 140.3 ns | 0.6495 ns | 0.5757 ns | 0.67 | 0.00 | + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ----------------- |------ |----------:|----------:|----------:|-------:|---------:| + // CompatibleRetval | 32 | 53.05 ns | 0.1865 ns | 0.1557 ns | 1.00 | 0.00 | + // CompatibleCopyTo | 32 | 36.12 ns | 0.3596 ns | 0.3003 ns | 0.68 | 0.01 | + // PermutedRetval | 32 | 303.61 ns | 5.1697 ns | 4.8358 ns | 5.72 | 0.09 | + // PermutedCopyTo | 32 | 38.05 ns | 0.8053 ns | 1.2297 ns | 0.72 | 0.02 | } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs new file mode 100644 index 000000000..29a113991 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs @@ -0,0 +1,83 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertToVector4 + { + struct ConversionRunner + where T : struct, ITestPixel + { + private T[] source; + + private Vector4[] dest; + + public ConversionRunner(int count) + { + this.source = new T[count]; + this.dest = new Vector4[count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunRetvalConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref destBaseRef, i) = Unsafe.Add(ref sourceBaseRef, i).ToVector4(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunCopyToConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref sourceBaseRef, i).CopyToVector4(ref Unsafe.Add(ref destBaseRef, i)); + } + } + } + + private ConversionRunner runner; + + [Params(32)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.runner = new ConversionRunner(this.Count); + } + + [Benchmark(Baseline = true)] + public void UseRetval() + { + this.runner.RunRetvalConversion(); + } + + [Benchmark] + public void UseCopyTo() + { + this.runner.RunCopyToConversion(); + } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // ---------- |------ |---------:|----------:|----------:|-------:| + // UseRetval | 32 | 94.99 ns | 1.1199 ns | 0.9352 ns | 1.00 | + // UseCopyTo | 32 | 59.47 ns | 0.6104 ns | 0.5710 ns | 0.63 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs new file mode 100644 index 000000000..e5eb5c6ca --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs @@ -0,0 +1,95 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_ConvertToVector4_AsPartOfCompositeOperation + { + struct ConversionRunner + where T : struct, ITestPixel + { + private T[] source; + + private Vector4[] dest; + + public ConversionRunner(int count) + { + this.source = new T[count]; + this.dest = new Vector4[count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunRetvalConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + Vector4 temp; + + for (int i = 0; i < count; i++) + { + temp = Unsafe.Add(ref sourceBaseRef, i).ToVector4(); + + // manipulate pixel before saving to dest buffer: + temp.W = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RunCopyToConversion() + { + int count = this.source.Length; + + ref T sourceBaseRef = ref this.source[0]; + ref Vector4 destBaseRef = ref this.dest[0]; + + Vector4 temp = default; + + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref sourceBaseRef, i).CopyToVector4(ref temp); + + // manipulate pixel before saving to dest buffer: + temp.W = 0; + + Unsafe.Add(ref destBaseRef, i) = temp; + } + } + } + + private ConversionRunner runner; + + [Params(32)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.runner = new ConversionRunner(this.Count); + } + + [Benchmark(Baseline = true)] + public void UseRetval() + { + this.runner.RunRetvalConversion(); + } + + [Benchmark] + public void UseCopyTo() + { + this.runner.RunCopyToConversion(); + } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // ---------- |------ |----------:|----------:|----------:|-------:| + // UseRetval | 32 | 100.35 ns | 0.4844 ns | 0.4532 ns | 1.00 | + // UseCopyTo | 32 | 53.95 ns | 0.1269 ns | 0.1125 ns | 0.54 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs index ddac1d105..61a7df81d 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs @@ -70,5 +70,20 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion dest.B = this.b; dest.A = this.a; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.r, this.g, this.b, this.a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest.X = this.r; + dest.Y = this.g; + dest.Z = this.b; + dest.W = this.a; + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs index b06e84063..3da7fcc4c 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -53,5 +53,20 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion { dest = Unsafe.As(ref this); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.r, this.g, this.b, this.a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void CopyToVector4(ref Vector4 dest) + { + dest.X = this.r; + dest.Y = this.g; + dest.Z = this.b; + dest.W = this.a; + } } } \ No newline at end of file From 8f4e8a663a9c37347d91917a98ab4e95f709f016 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 19 Oct 2018 13:14:33 +0200 Subject: [PATCH 029/238] cleanup --- .../SimdUtils.ExtendedIntrinsics.cs | 32 +++-- .../{Extensions => Helpers}/SimdUtils.cs | 18 +-- .../PixelFormats/PixelOperations{TPixel}.cs | 56 +++++---- .../PixelFormats/Rgba32.PixelOperations.cs | 69 ++++++++--- .../Color/Bulk/ToVector4.cs | 112 ++++++++++++++++-- .../PixelFormats/PixelOperationsTests.cs | 2 +- 6 files changed, 220 insertions(+), 69 deletions(-) rename src/ImageSharp/Common/{Extensions => Helpers}/SimdUtils.ExtendedIntrinsics.cs (81%) rename src/ImageSharp/Common/{Extensions => Helpers}/SimdUtils.cs (96%) diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs similarity index 81% rename from src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs rename to src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index fba54b033..6def8938a 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp { public static bool IsAvailable { get; } = #if NETCOREAPP2_1 -// TODO: Add a build target for .NET 4.7.2 +// TODO: Also available in .NET 4.7.2, we need to add a build target! true; #else false; @@ -31,14 +31,15 @@ namespace SixLabors.ImageSharp internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { Guard.IsTrue( - source.Length % Vector.Count == 0, + dest.Length % Vector.Count == 0, nameof(source), "dest.Length should be divisable by Vector.Count!"); - int n = source.Length / Vector.Count; + int n = dest.Length / Vector.Count; ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); + ref Vector destBaseU = ref Unsafe.As, Vector>(ref destBase); const float Scale = 1f / 255f; @@ -50,16 +51,23 @@ namespace SixLabors.ImageSharp Vector.Widen(s0, out Vector w0, out Vector w1); Vector.Widen(s1, out Vector w2, out Vector w3); - Vector f0 = Vector.ConvertToSingle(w0) * Scale; - Vector f1 = Vector.ConvertToSingle(w1) * Scale; - Vector f2 = Vector.ConvertToSingle(w2) * Scale; - Vector f3 = Vector.ConvertToSingle(w3) * Scale; + ref Vector d = ref Unsafe.Add(ref destBaseU, i * 4); + d = w0; + Unsafe.Add(ref d, 1) = w1; + Unsafe.Add(ref d, 2) = w2; + Unsafe.Add(ref d, 3) = w3; + } + + n = dest.Length / Vector.Count; + + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref destBase, i); + ref Vector du = ref Unsafe.As, Vector>(ref df); - ref Vector d = ref Unsafe.Add(ref destBase, i * 4); - d = f0; - Unsafe.Add(ref d, 1) = f1; - Unsafe.Add(ref d, 2) = f2; - Unsafe.Add(ref d, 3) = f3; + Vector v = Vector.ConvertToSingle(du); + v *= Scale; + df = v; } } diff --git a/src/ImageSharp/Common/Extensions/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs similarity index 96% rename from src/ImageSharp/Common/Extensions/SimdUtils.cs rename to src/ImageSharp/Common/Helpers/SimdUtils.cs index 3630ede32..91aed8c79 100644 --- a/src/ImageSharp/Common/Extensions/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -2,13 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; - namespace SixLabors.ImageSharp { /// @@ -131,23 +128,26 @@ namespace SixLabors.ImageSharp ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); int n = dest.Length / 8; - Octet.OfUInt32 temp = default; for (int i = 0; i < n; i++) { - Octet.OfByte sVal = Unsafe.Add(ref sourceBase, i); + ref Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); + ref Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i); + d.LoadFrom(ref s); + } - // This call is the bottleneck now: - temp.LoadFrom(ref sVal); + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); - Vector vi = Unsafe.As>(ref temp); + var vi = Vector.AsVectorUInt32(df); vi &= mask; vi |= magicInt; var vf = Vector.AsVectorSingle(vi); vf = (vf - magicFloat) * bVec; - Unsafe.Add(ref destBaseAsFloat, i) = vf; + df = vf; } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index b12a2bfa5..39c442fe0 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -29,17 +29,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); - - for (int i = 0; i < count; i++) - { - ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromVector4(sp); - } + PackFromVector4Common(sourceVectors, destinationColors, count); } /// @@ -50,17 +40,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { - GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); - - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); - - for (int i = 0; i < count; i++) - { - ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref Vector4 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToVector4(); - } + ToVector4Common(sourceColors, destinationVectors, count); } /// @@ -126,5 +106,37 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.MustBeSizedAtLeast(source, minLength, sourceParamName); Guard.MustBeSizedAtLeast(destination, minLength, destinationParamName); } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void PackFromVector4Common(ReadOnlySpan sourceVectors, Span destinationColors, int count) + { + GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); + + for (int i = 0; i < count; i++) + { + ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromVector4(sp); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void ToVector4Common(ReadOnlySpan sourceColors, Span destinationVectors, int count) + { + GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Vector4 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToVector4(); + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 6745079da..0b96a599b 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -27,28 +27,17 @@ namespace SixLabors.ImageSharp.PixelFormats if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) { // Doesn't worth to bother with SIMD: - base.ToVector4(sourceColors, destinationVectors, count); + ToVector4Common(sourceColors, destinationVectors, count); return; } - int remainder = count % 2; - int alignedCount = count - remainder; - - if (alignedCount > 0) + if (SimdUtils.ExtendedIntrinsics.IsAvailable) { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); - Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); - - SimdUtils.BulkConvertByteToNormalizedFloat( - rawSrc, - rawDest); + ConvertToVector4UsingExtendedIntrinsics(sourceColors, destinationVectors, count); } - - if (remainder > 0) + else { - // actually: remainder == 1 - int lastIdx = count - 1; - destinationVectors[lastIdx] = sourceColors[lastIdx].ToVector4(); + ConvertToVector4UsingStandardIntrinsics(sourceColors, destinationVectors, count); } } @@ -59,7 +48,7 @@ namespace SixLabors.ImageSharp.PixelFormats if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) { - base.PackFromVector4(sourceVectors, destinationColors, count); + PackFromVector4Common(sourceVectors, destinationColors, count); return; } @@ -109,6 +98,52 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(dest); } + + private static void ConvertToVector4UsingExtendedIntrinsics( + ReadOnlySpan sourceColors, + Span destinationVectors, + int count) + { + int remainder = count % 8; + int alignedCount = count - remainder; + + if (alignedCount > 0) + { + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); + Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); + + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); + } + + if (remainder > 0) + { + ToVector4Common(sourceColors.Slice(alignedCount), destinationVectors.Slice(alignedCount), remainder); + } + } + + private static void ConvertToVector4UsingStandardIntrinsics( + ReadOnlySpan sourceColors, + Span destinationVectors, + int count) + { + int remainder = count % 2; + int alignedCount = count - remainder; + + if (alignedCount > 0) + { + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); + Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); + + SimdUtils.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); + } + + if (remainder > 0) + { + // actually: remainder == 1 + int lastIdx = count - 1; + destinationVectors[lastIdx] = sourceColors[lastIdx].ToVector4(); + } + } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 39c1fbd47..6afd3cf6b 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -6,6 +6,7 @@ using System.Buffers; using System; using System.Numerics; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; @@ -28,7 +29,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, - 2048)] + //512 + 256 + )] public int Count { get; set; } [GlobalSetup] @@ -45,7 +48,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.destination.Dispose(); } - [Benchmark] + //[Benchmark] public void PerElement() { Span s = this.source.GetSpan(); @@ -53,32 +56,48 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk for (int i = 0; i < this.Count; i++) { - TPixel c = s[i]; - d[i] = c.ToVector4(); + d[i] = s[i].ToVector4(); } } - [Benchmark(Baseline = true)] + //[Benchmark] public void CommonBulk() { new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } - [Benchmark] + //[Benchmark] public void OptimizedBulk() { PixelOperations.Instance.ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } } - [CoreJob] - [ClrJob] + [RyuJitX64Job] + [DisassemblyDiagnoser(printAsm: true, printSource: true)] public class ToVector4_Rgba32 : ToVector4 { class Config : ManualConfig { } + [Benchmark(Baseline = true)] + public void FastScalarBulk() + { + ref Rgba32 sBase = ref this.source.GetSpan()[0]; + ref Vector4 dBase = ref this.destination.GetSpan()[0]; + + for (int i = 0; i < this.Count; i++) + { + ref Rgba32 s = ref Unsafe.Add(ref sBase, i); + ref Vector4 d = ref Unsafe.Add(ref dBase, i); + d.X = s.R; + d.Y = s.G; + d.Z = s.B; + d.W = s.A; + } + } + [Benchmark] public void BulkConvertByteToNormalizedFloat() { @@ -97,5 +116,82 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } + //[Benchmark] + public void Original() + { + ToVector4SimdAligned(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void ToVector4SimdAligned(ReadOnlySpan sourceColors, Span destVectors, int count) + { + if (!Vector.IsHardwareAccelerated) + { + throw new InvalidOperationException( + "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); + } + + DebugGuard.IsTrue( + count % Vector.Count == 0, + nameof(count), + "Argument 'count' should divisible by Vector.Count!"); + + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); + + int unpackedRawCount = count * 4; + + ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(sourceColors)); + ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); + ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsUnpacked); + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsUnpacked); + + for (int i = 0; i < count; i++) + { + uint sVal = Unsafe.Add(ref sourceBase, i); + ref UnpackedRGBA dst = ref Unsafe.Add(ref destBaseAsUnpacked, i); + + // This call is the bottleneck now: + dst.Load(sVal); + } + + int numOfVectors = unpackedRawCount / Vector.Count; + + for (int i = 0; i < numOfVectors; i++) + { + Vector vi = Unsafe.Add(ref destBaseAsUInt, i); + + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + + Unsafe.Add(ref destBaseAsFloat, i) = vf; + } + } + + [StructLayout(LayoutKind.Sequential)] + private struct UnpackedRGBA + { + private uint r; + + private uint g; + + private uint b; + + private uint a; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Load(uint p) + { + this.r = p; + this.g = p >> 8; + this.b = p >> 16; + this.a = p >> 24; + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 535952e05..abf764881 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static TheoryData ArraySizesData => new TheoryData { 0, 1, 2, 7, 16, 1111 }; + public static TheoryData ArraySizesData => new TheoryData { 0, 1, 2, 7, 16, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 1111 }; private static PixelOperations Operations => PixelOperations.Instance; From 63233c251688fbeeec5786d034fe003c5ea2584c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 19 Oct 2018 13:38:03 +0200 Subject: [PATCH 030/238] benchmark conversion steps separately --- .../General/Vectorization/UInt32ToSingle.cs | 66 +++++++++++++++++++ .../Vectorization/WidenBytesToUInt32.cs | 61 +++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs create mode 100644 tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs new file mode 100644 index 000000000..4a4b939b6 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs @@ -0,0 +1,66 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization +{ + public class UInt32ToSingle + { + private float[] data; + + private const int Count = 64; + + [GlobalSetup] + public void Setup() + { + this.data = new float[Count]; + } + + [Benchmark(Baseline = true)] + public void MagicMethod() + { + ref Vector b = ref Unsafe.As>(ref this.data[0]); + + int n = Count / Vector.Count; + + Vector magick = new Vector(32768.0f); + Vector scale = new Vector(255f) / new Vector(256f); + + for (int i = 0; i < n; i++) + { + // union { float f; uint32_t i; } u; + // u.f = 32768.0f + x * (255.0f / 256.0f); + // return (uint8_t)u.i; + + ref Vector d = ref Unsafe.Add(ref b, i); + Vector x = d; + //x = Vector.Max(x, Vector.Zero); + //x = Vector.Min(x, Vector.One); + + x = (x * scale) + magick; + d = x; + } + } + + [Benchmark] + public void StandardSimd() + { + int n = Count / Vector.Count; + + ref Vector b = ref Unsafe.As>(ref this.data[0]); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref b, i); + Vector du = Unsafe.As, Vector>(ref df); + + Vector v = Vector.ConvertToSingle(du); + v *= scale; + df = v; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs new file mode 100644 index 000000000..f71f6ec1b --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs @@ -0,0 +1,61 @@ +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization +{ + public class WidenBytesToUInt32 + { + private byte[] source; + + private uint[] dest; + + private const int Count = 64; + + [GlobalSetup] + public void Setup() + { + this.source = new byte[Count]; + this.dest = new uint[Count]; + } + + [Benchmark(Baseline = true)] + public void Standard() + { + const int N = Count / 8; + + ref SimdUtils.Octet.OfByte sBase = ref Unsafe.As(ref this.source[0]); + ref SimdUtils.Octet.OfUInt32 dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < N; i++) + { + Unsafe.Add(ref dBase, i).LoadFrom(ref Unsafe.Add(ref sBase, i)); + } + } + + [Benchmark] + public void Simd() + { + int n = Count / Vector.Count; + + ref Vector sBase = ref Unsafe.As>(ref this.source[0]); + ref Vector dBase = ref Unsafe.As>(ref this.dest[0]); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + ref Vector d = ref Unsafe.Add(ref dBase, i * 4); + d = w0; + Unsafe.Add(ref d, 1) = w1; + Unsafe.Add(ref d, 2) = w2; + Unsafe.Add(ref d, 3) = w3; + } + } + } +} \ No newline at end of file From 635ce2bede01aaaa02244ed14cf86d2ed58d646e Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 19 Oct 2018 21:56:27 +0100 Subject: [PATCH 031/238] Add generic palette quantizer, refactor + werner palette --- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 5 +- src/ImageSharp/PixelFormats/ColorConstants.cs | 409 +++++++++++------- .../PixelFormats/NamedColors{TPixel}.cs | 26 +- src/ImageSharp/Processing/KnownQuantizers.cs | 13 +- .../Quantization/OctreeQuantizer.cs | 13 +- .../PaletteFrameQuantizer{TPixel}.cs | 5 +- .../Quantization/PaletteQuantizer.cs | 50 +-- .../Quantization/PaletteQuantizer{TPixel}.cs | 92 ++++ .../Quantization/QuantizerConstants.cs | 21 + .../Quantization/WebSafePaletteQuantizer.cs | 47 ++ .../Quantization/WernerPaletteQuantizer.cs | 48 ++ .../Processors/Quantization/WuQuantizer.cs | 13 +- .../ImageSharp.Benchmarks/Codecs/EncodeGif.cs | 2 +- .../Codecs/EncodeGifMultiple.cs | 2 +- .../Codecs/EncodeIndexedPng.cs | 4 +- .../Formats/GeneralFormatTests.cs | 3 +- .../Formats/Gif/GifEncoderTests.cs | 2 +- .../Quantization/QuantizedImageTests.cs | 11 +- 18 files changed, 545 insertions(+), 221 deletions(-) create mode 100644 src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs create mode 100644 src/ImageSharp/Processing/Processors/Quantization/QuantizerConstants.cs create mode 100644 src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs create mode 100644 src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index ae0366e6e..a8cd169e5 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Formats.Gif private void EncodeGlobal(Image image, QuantizedFrame quantized, int transparencyIndex, Stream stream) where TPixel : struct, IPixel { - var palleteQuantizer = new PaletteQuantizer(this.quantizer.Diffuser); + var palleteQuantizer = new PaletteQuantizer(quantized.Palette, this.quantizer.Diffuser); for (int i = 0; i < image.Frames.Count; i++) { @@ -149,8 +149,7 @@ namespace SixLabors.ImageSharp.Formats.Gif } else { - using (QuantizedFrame paletteQuantized - = palleteQuantizer.CreateFrameQuantizer(() => quantized.Palette).QuantizeFrame(frame)) + using (QuantizedFrame paletteQuantized = palleteQuantizer.CreateFrameQuantizer().QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } diff --git a/src/ImageSharp/PixelFormats/ColorConstants.cs b/src/ImageSharp/PixelFormats/ColorConstants.cs index bac05c53d..14df38569 100644 --- a/src/ImageSharp/PixelFormats/ColorConstants.cs +++ b/src/ImageSharp/PixelFormats/ColorConstants.cs @@ -11,157 +11,268 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Gets a collection of named, web safe, colors as defined in the CSS Color Module Level 4. /// - public static readonly Rgba32[] WebSafeColors = GetWebSafeColors(); + public static readonly Rgba32[] WebSafeColors = + { + Rgba32.AliceBlue, + Rgba32.AntiqueWhite, + Rgba32.Aqua, + Rgba32.Aquamarine, + Rgba32.Azure, + Rgba32.Beige, + Rgba32.Bisque, + Rgba32.Black, + Rgba32.BlanchedAlmond, + Rgba32.Blue, + Rgba32.BlueViolet, + Rgba32.Brown, + Rgba32.BurlyWood, + Rgba32.CadetBlue, + Rgba32.Chartreuse, + Rgba32.Chocolate, + Rgba32.Coral, + Rgba32.CornflowerBlue, + Rgba32.Cornsilk, + Rgba32.Crimson, + Rgba32.Cyan, + Rgba32.DarkBlue, + Rgba32.DarkCyan, + Rgba32.DarkGoldenrod, + Rgba32.DarkGray, + Rgba32.DarkGreen, + Rgba32.DarkKhaki, + Rgba32.DarkMagenta, + Rgba32.DarkOliveGreen, + Rgba32.DarkOrange, + Rgba32.DarkOrchid, + Rgba32.DarkRed, + Rgba32.DarkSalmon, + Rgba32.DarkSeaGreen, + Rgba32.DarkSlateBlue, + Rgba32.DarkSlateGray, + Rgba32.DarkTurquoise, + Rgba32.DarkViolet, + Rgba32.DeepPink, + Rgba32.DeepSkyBlue, + Rgba32.DimGray, + Rgba32.DodgerBlue, + Rgba32.Firebrick, + Rgba32.FloralWhite, + Rgba32.ForestGreen, + Rgba32.Fuchsia, + Rgba32.Gainsboro, + Rgba32.GhostWhite, + Rgba32.Gold, + Rgba32.Goldenrod, + Rgba32.Gray, + Rgba32.Green, + Rgba32.GreenYellow, + Rgba32.Honeydew, + Rgba32.HotPink, + Rgba32.IndianRed, + Rgba32.Indigo, + Rgba32.Ivory, + Rgba32.Khaki, + Rgba32.Lavender, + Rgba32.LavenderBlush, + Rgba32.LawnGreen, + Rgba32.LemonChiffon, + Rgba32.LightBlue, + Rgba32.LightCoral, + Rgba32.LightCyan, + Rgba32.LightGoldenrodYellow, + Rgba32.LightGray, + Rgba32.LightGreen, + Rgba32.LightPink, + Rgba32.LightSalmon, + Rgba32.LightSeaGreen, + Rgba32.LightSkyBlue, + Rgba32.LightSlateGray, + Rgba32.LightSteelBlue, + Rgba32.LightYellow, + Rgba32.Lime, + Rgba32.LimeGreen, + Rgba32.Linen, + Rgba32.Magenta, + Rgba32.Maroon, + Rgba32.MediumAquamarine, + Rgba32.MediumBlue, + Rgba32.MediumOrchid, + Rgba32.MediumPurple, + Rgba32.MediumSeaGreen, + Rgba32.MediumSlateBlue, + Rgba32.MediumSpringGreen, + Rgba32.MediumTurquoise, + Rgba32.MediumVioletRed, + Rgba32.MidnightBlue, + Rgba32.MintCream, + Rgba32.MistyRose, + Rgba32.Moccasin, + Rgba32.NavajoWhite, + Rgba32.Navy, + Rgba32.OldLace, + Rgba32.Olive, + Rgba32.OliveDrab, + Rgba32.Orange, + Rgba32.OrangeRed, + Rgba32.Orchid, + Rgba32.PaleGoldenrod, + Rgba32.PaleGreen, + Rgba32.PaleTurquoise, + Rgba32.PaleVioletRed, + Rgba32.PapayaWhip, + Rgba32.PeachPuff, + Rgba32.Peru, + Rgba32.Pink, + Rgba32.Plum, + Rgba32.PowderBlue, + Rgba32.Purple, + Rgba32.RebeccaPurple, + Rgba32.Red, + Rgba32.RosyBrown, + Rgba32.RoyalBlue, + Rgba32.SaddleBrown, + Rgba32.Salmon, + Rgba32.SandyBrown, + Rgba32.SeaGreen, + Rgba32.SeaShell, + Rgba32.Sienna, + Rgba32.Silver, + Rgba32.SkyBlue, + Rgba32.SlateBlue, + Rgba32.SlateGray, + Rgba32.Snow, + Rgba32.SpringGreen, + Rgba32.SteelBlue, + Rgba32.Tan, + Rgba32.Teal, + Rgba32.Thistle, + Rgba32.Tomato, + Rgba32.Transparent, + Rgba32.Turquoise, + Rgba32.Violet, + Rgba32.Wheat, + Rgba32.White, + Rgba32.WhiteSmoke, + Rgba32.Yellow, + Rgba32.YellowGreen + }; /// - /// Returns an array of web safe colors. + /// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. + /// The hex codes were collected and defined by Nicholas Rougeux /// - /// The - private static Rgba32[] GetWebSafeColors() - => new Rgba32[] - { - Rgba32.AliceBlue, - Rgba32.AntiqueWhite, - Rgba32.Aqua, - Rgba32.Aquamarine, - Rgba32.Azure, - Rgba32.Beige, - Rgba32.Bisque, - Rgba32.Black, - Rgba32.BlanchedAlmond, - Rgba32.Blue, - Rgba32.BlueViolet, - Rgba32.Brown, - Rgba32.BurlyWood, - Rgba32.CadetBlue, - Rgba32.Chartreuse, - Rgba32.Chocolate, - Rgba32.Coral, - Rgba32.CornflowerBlue, - Rgba32.Cornsilk, - Rgba32.Crimson, - Rgba32.Cyan, - Rgba32.DarkBlue, - Rgba32.DarkCyan, - Rgba32.DarkGoldenrod, - Rgba32.DarkGray, - Rgba32.DarkGreen, - Rgba32.DarkKhaki, - Rgba32.DarkMagenta, - Rgba32.DarkOliveGreen, - Rgba32.DarkOrange, - Rgba32.DarkOrchid, - Rgba32.DarkRed, - Rgba32.DarkSalmon, - Rgba32.DarkSeaGreen, - Rgba32.DarkSlateBlue, - Rgba32.DarkSlateGray, - Rgba32.DarkTurquoise, - Rgba32.DarkViolet, - Rgba32.DeepPink, - Rgba32.DeepSkyBlue, - Rgba32.DimGray, - Rgba32.DodgerBlue, - Rgba32.Firebrick, - Rgba32.FloralWhite, - Rgba32.ForestGreen, - Rgba32.Fuchsia, - Rgba32.Gainsboro, - Rgba32.GhostWhite, - Rgba32.Gold, - Rgba32.Goldenrod, - Rgba32.Gray, - Rgba32.Green, - Rgba32.GreenYellow, - Rgba32.Honeydew, - Rgba32.HotPink, - Rgba32.IndianRed, - Rgba32.Indigo, - Rgba32.Ivory, - Rgba32.Khaki, - Rgba32.Lavender, - Rgba32.LavenderBlush, - Rgba32.LawnGreen, - Rgba32.LemonChiffon, - Rgba32.LightBlue, - Rgba32.LightCoral, - Rgba32.LightCyan, - Rgba32.LightGoldenrodYellow, - Rgba32.LightGray, - Rgba32.LightGreen, - Rgba32.LightPink, - Rgba32.LightSalmon, - Rgba32.LightSeaGreen, - Rgba32.LightSkyBlue, - Rgba32.LightSlateGray, - Rgba32.LightSteelBlue, - Rgba32.LightYellow, - Rgba32.Lime, - Rgba32.LimeGreen, - Rgba32.Linen, - Rgba32.Magenta, - Rgba32.Maroon, - Rgba32.MediumAquamarine, - Rgba32.MediumBlue, - Rgba32.MediumOrchid, - Rgba32.MediumPurple, - Rgba32.MediumSeaGreen, - Rgba32.MediumSlateBlue, - Rgba32.MediumSpringGreen, - Rgba32.MediumTurquoise, - Rgba32.MediumVioletRed, - Rgba32.MidnightBlue, - Rgba32.MintCream, - Rgba32.MistyRose, - Rgba32.Moccasin, - Rgba32.NavajoWhite, - Rgba32.Navy, - Rgba32.OldLace, - Rgba32.Olive, - Rgba32.OliveDrab, - Rgba32.Orange, - Rgba32.OrangeRed, - Rgba32.Orchid, - Rgba32.PaleGoldenrod, - Rgba32.PaleGreen, - Rgba32.PaleTurquoise, - Rgba32.PaleVioletRed, - Rgba32.PapayaWhip, - Rgba32.PeachPuff, - Rgba32.Peru, - Rgba32.Pink, - Rgba32.Plum, - Rgba32.PowderBlue, - Rgba32.Purple, - Rgba32.RebeccaPurple, - Rgba32.Red, - Rgba32.RosyBrown, - Rgba32.RoyalBlue, - Rgba32.SaddleBrown, - Rgba32.Salmon, - Rgba32.SandyBrown, - Rgba32.SeaGreen, - Rgba32.SeaShell, - Rgba32.Sienna, - Rgba32.Silver, - Rgba32.SkyBlue, - Rgba32.SlateBlue, - Rgba32.SlateGray, - Rgba32.Snow, - Rgba32.SpringGreen, - Rgba32.SteelBlue, - Rgba32.Tan, - Rgba32.Teal, - Rgba32.Thistle, - Rgba32.Tomato, - Rgba32.Transparent, - Rgba32.Turquoise, - Rgba32.Violet, - Rgba32.Wheat, - Rgba32.White, - Rgba32.WhiteSmoke, - Rgba32.Yellow, - Rgba32.YellowGreen - }; + public static readonly Rgba32[] WernerColors = + { + Rgba32.FromHex("#f1e9cd"), + Rgba32.FromHex("#f2e7cf"), + Rgba32.FromHex("#ece6d0"), + Rgba32.FromHex("#f2eacc"), + Rgba32.FromHex("#f3e9ca"), + Rgba32.FromHex("#f2ebcd"), + Rgba32.FromHex("#e6e1c9"), + Rgba32.FromHex("#e2ddc6"), + Rgba32.FromHex("#cbc8b7"), + Rgba32.FromHex("#bfbbb0"), + Rgba32.FromHex("#bebeb3"), + Rgba32.FromHex("#b7b5ac"), + Rgba32.FromHex("#bab191"), + Rgba32.FromHex("#9c9d9a"), + Rgba32.FromHex("#8a8d84"), + Rgba32.FromHex("#5b5c61"), + Rgba32.FromHex("#555152"), + Rgba32.FromHex("#413f44"), + Rgba32.FromHex("#454445"), + Rgba32.FromHex("#423937"), + Rgba32.FromHex("#433635"), + Rgba32.FromHex("#252024"), + Rgba32.FromHex("#241f20"), + Rgba32.FromHex("#281f3f"), + Rgba32.FromHex("#1c1949"), + Rgba32.FromHex("#4f638d"), + Rgba32.FromHex("#383867"), + Rgba32.FromHex("#5c6b8f"), + Rgba32.FromHex("#657abb"), + Rgba32.FromHex("#6f88af"), + Rgba32.FromHex("#7994b5"), + Rgba32.FromHex("#6fb5a8"), + Rgba32.FromHex("#719ba2"), + Rgba32.FromHex("#8aa1a6"), + Rgba32.FromHex("#d0d5d3"), + Rgba32.FromHex("#8590ae"), + Rgba32.FromHex("#3a2f52"), + Rgba32.FromHex("#39334a"), + Rgba32.FromHex("#6c6d94"), + Rgba32.FromHex("#584c77"), + Rgba32.FromHex("#533552"), + Rgba32.FromHex("#463759"), + Rgba32.FromHex("#bfbac0"), + Rgba32.FromHex("#77747f"), + Rgba32.FromHex("#4a475c"), + Rgba32.FromHex("#b8bfaf"), + Rgba32.FromHex("#b2b599"), + Rgba32.FromHex("#979c84"), + Rgba32.FromHex("#5d6161"), + Rgba32.FromHex("#61ac86"), + Rgba32.FromHex("#a4b6a7"), + Rgba32.FromHex("#adba98"), + Rgba32.FromHex("#93b778"), + Rgba32.FromHex("#7d8c55"), + Rgba32.FromHex("#33431e"), + Rgba32.FromHex("#7c8635"), + Rgba32.FromHex("#8e9849"), + Rgba32.FromHex("#c2c190"), + Rgba32.FromHex("#67765b"), + Rgba32.FromHex("#ab924b"), + Rgba32.FromHex("#c8c76f"), + Rgba32.FromHex("#ccc050"), + Rgba32.FromHex("#ebdd99"), + Rgba32.FromHex("#ab9649"), + Rgba32.FromHex("#dbc364"), + Rgba32.FromHex("#e6d058"), + Rgba32.FromHex("#ead665"), + Rgba32.FromHex("#d09b2c"), + Rgba32.FromHex("#a36629"), + Rgba32.FromHex("#a77d35"), + Rgba32.FromHex("#f0d696"), + Rgba32.FromHex("#d7c485"), + Rgba32.FromHex("#f1d28c"), + Rgba32.FromHex("#efcc83"), + Rgba32.FromHex("#f3daa7"), + Rgba32.FromHex("#dfa837"), + Rgba32.FromHex("#ebbc71"), + Rgba32.FromHex("#d17c3f"), + Rgba32.FromHex("#92462f"), + Rgba32.FromHex("#be7249"), + Rgba32.FromHex("#bb603c"), + Rgba32.FromHex("#c76b4a"), + Rgba32.FromHex("#a75536"), + Rgba32.FromHex("#b63e36"), + Rgba32.FromHex("#b5493a"), + Rgba32.FromHex("#cd6d57"), + Rgba32.FromHex("#711518"), + Rgba32.FromHex("#e9c49d"), + Rgba32.FromHex("#eedac3"), + Rgba32.FromHex("#eecfbf"), + Rgba32.FromHex("#ce536b"), + Rgba32.FromHex("#b74a70"), + Rgba32.FromHex("#b7757c"), + Rgba32.FromHex("#612741"), + Rgba32.FromHex("#7a4848"), + Rgba32.FromHex("#3f3033"), + Rgba32.FromHex("#8d746f"), + Rgba32.FromHex("#4d3635"), + Rgba32.FromHex("#6e3b31"), + Rgba32.FromHex("#864735"), + Rgba32.FromHex("#553d3a"), + Rgba32.FromHex("#613936"), + Rgba32.FromHex("#7a4b3a"), + Rgba32.FromHex("#946943"), + Rgba32.FromHex("#c39e6d"), + Rgba32.FromHex("#513e32"), + Rgba32.FromHex("#8b7859"), + Rgba32.FromHex("#9b856b"), + Rgba32.FromHex("#766051"), + Rgba32.FromHex("#453b32") + }; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs index 0f42e182c..a0916b163 100644 --- a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs @@ -14,9 +14,10 @@ namespace SixLabors.ImageSharp.PixelFormats where TPixel : struct, IPixel { /// - /// Thread-safe backing field for . + /// Thread-safe backing field for the constant palettes. /// private static readonly Lazy WebSafePaletteLazy = new Lazy(GetWebSafePalette, true); + private static readonly Lazy WernerPaletteLazy = new Lazy(GetWernerPalette, true); /// /// Represents a matching the W3C definition that has an hex value of #F0F8FF. @@ -729,18 +730,27 @@ namespace SixLabors.ImageSharp.PixelFormats public static readonly TPixel YellowGreen = ColorBuilder.FromRGBA(154, 205, 50, 255); /// - /// Gets a matching the W3C definition of web safe colors. + /// Gets a collection of web safe, colors as defined in the CSS Color Module Level 4. /// public static TPixel[] WebSafePalette => WebSafePaletteLazy.Value; - private static TPixel[] GetWebSafePalette() + /// + /// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. + /// The hex codes were collected and defined by Nicholas Rougeux + /// + public static TPixel[] WernerPalette => WernerPaletteLazy.Value; + + private static TPixel[] GetWebSafePalette() => GetPalette(ColorConstants.WebSafeColors); + + private static TPixel[] GetWernerPalette() => GetPalette(ColorConstants.WernerColors); + + private static TPixel[] GetPalette(Rgba32[] palette) { - Rgba32[] constants = ColorConstants.WebSafeColors; - var safe = new TPixel[constants.Length + 1]; + var converted = new TPixel[palette.Length + 1]; - Span constantsBytes = MemoryMarshal.Cast(constants.AsSpan()); - PixelOperations.Instance.PackFromRgba32Bytes(constantsBytes, safe, constants.Length); - return safe; + Span constantsBytes = MemoryMarshal.Cast(palette.AsSpan()); + PixelOperations.Instance.PackFromRgba32Bytes(constantsBytes, converted, palette.Length); + return converted; } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/KnownQuantizers.cs b/src/ImageSharp/Processing/KnownQuantizers.cs index fe9806310..e93a9921a 100644 --- a/src/ImageSharp/Processing/KnownQuantizers.cs +++ b/src/ImageSharp/Processing/KnownQuantizers.cs @@ -23,9 +23,16 @@ namespace SixLabors.ImageSharp.Processing public static IQuantizer Wu { get; } = new WuQuantizer(); /// - /// Gets the palette based, Using the collection of web-safe colors. - /// The quantizer supports multiple alpha values. + /// Gets the palette based quantizer consisting of web safe colors as defined in the CSS Color Module Level 4. + /// The quantizer supports a single alpha value. + /// + public static IQuantizer WebSafe { get; } = new WebSafePaletteQuantizer(); + + /// + /// Gets the palette based quantizer consisting of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. + /// The hex codes were collected and defined by Nicholas Rougeux + /// The quantizer supports a single alpha value. /// - public static IQuantizer Palette { get; } = new PaletteQuantizer(); + public static IQuantizer Werner { get; } = new WernerPaletteQuantizer(); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs index 22bb5223f..d0dd18393 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs @@ -15,11 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class OctreeQuantizer : IQuantizer { - /// - /// The default maximum number of colors to use when quantizing the image. - /// - public const int DefaultMaxColors = 256; - /// /// Initializes a new instance of the class. /// @@ -42,7 +37,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// Whether to apply dithering to the output image public OctreeQuantizer(bool dither) - : this(GetDiffuser(dither), DefaultMaxColors) + : this(GetDiffuser(dither), QuantizerConstants.MaxColors) { } @@ -51,7 +46,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The error diffusion algorithm, if any, to apply to the output image public OctreeQuantizer(IErrorDiffuser diffuser) - : this(diffuser, DefaultMaxColors) + : this(diffuser, QuantizerConstants.MaxColors) { } @@ -63,7 +58,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public OctreeQuantizer(IErrorDiffuser diffuser, int maxColors) { this.Diffuser = diffuser; - this.MaxColors = maxColors.Clamp(1, DefaultMaxColors); + this.MaxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); } /// @@ -83,7 +78,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public IFrameQuantizer CreateFrameQuantizer(int maxColors) where TPixel : struct, IPixel { - maxColors = maxColors.Clamp(1, DefaultMaxColors); + maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); return new OctreeFrameQuantizer(this, maxColors); } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs index cdf3514e2..10f46e68a 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs @@ -33,12 +33,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The palette quantizer. /// An array of all colors in the palette. - public PaletteFrameQuantizer(PaletteQuantizer quantizer, TPixel[] colors) + public PaletteFrameQuantizer(IQuantizer quantizer, TPixel[] colors) : base(quantizer, true) { - // TODO: Why is this value constrained? Gif has limitations but theoretically - // we might want to reduce the palette of an image to greater than that limitation. - Guard.MustBeBetweenOrEqualTo(colors.Length, 1, 256, nameof(colors)); this.palette = colors; this.paletteVector = new Vector4[this.palette.Length]; PixelOperations.Instance.ToScaledVector4(this.palette, this.paletteVector, this.palette.Length); diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index 27ef05dfe..5dace6b17 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -8,18 +8,18 @@ using SixLabors.ImageSharp.Processing.Processors.Dithering; namespace SixLabors.ImageSharp.Processing.Processors.Quantization { /// - /// Allows the quantization of images pixels using web safe colors defined in the CSS Color Module Level 4. - /// Override this class to provide your own palette. + /// Allows the quantization of images pixels using color palettes. + /// Override this class to provide your own palette. /// - /// By default the quantizer uses dithering and the + /// By default the quantizer uses dithering. /// /// - public class PaletteQuantizer : IQuantizer + public abstract class PaletteQuantizer : IQuantizer { /// /// Initializes a new instance of the class. /// - public PaletteQuantizer() + protected PaletteQuantizer() : this(true) { } @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Initializes a new instance of the class. /// /// Whether to apply dithering to the output image - public PaletteQuantizer(bool dither) + protected PaletteQuantizer(bool dither) : this(GetDiffuser(dither)) { } @@ -37,41 +37,39 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Initializes a new instance of the class. /// /// The error diffusion algorithm, if any, to apply to the output image - public PaletteQuantizer(IErrorDiffuser diffuser) => this.Diffuser = diffuser; + protected PaletteQuantizer(IErrorDiffuser diffuser) => this.Diffuser = diffuser; /// public IErrorDiffuser Diffuser { get; } /// - public virtual IFrameQuantizer CreateFrameQuantizer() - where TPixel : struct, IPixel - => this.CreateFrameQuantizer(() => NamedColors.WebSafePalette); + public abstract IFrameQuantizer CreateFrameQuantizer() + where TPixel : struct, IPixel; /// - public IFrameQuantizer CreateFrameQuantizer(int maxColors) + public abstract IFrameQuantizer CreateFrameQuantizer(int maxColors) + where TPixel : struct, IPixel; + + /// + /// Creates the generic frame quantizer. + /// + /// The pixel format. + /// The color palette. + /// The maximum number of colors to hold in the color palette. + /// The + protected IFrameQuantizer CreateFrameQuantizer(TPixel[] palette, int maxColors) where TPixel : struct, IPixel { - TPixel[] websafe = NamedColors.WebSafePalette; - int max = Math.Min(maxColors, websafe.Length); + int max = Math.Min(QuantizerConstants.MaxColors, Math.Min(maxColors, palette.Length)); - if (max != websafe.Length) + if (max != palette.Length) { - return this.CreateFrameQuantizer(() => NamedColors.WebSafePalette.AsSpan(0, max).ToArray()); + return new PaletteFrameQuantizer(this, palette.AsSpan(0, max).ToArray()); } - return this.CreateFrameQuantizer(() => websafe); + return new PaletteFrameQuantizer(this, palette); } - /// - /// Gets the palette to use to quantize the image. - /// - /// The pixel format. - /// The method to return the palette. - /// The - public IFrameQuantizer CreateFrameQuantizer(Func paletteFunction) - where TPixel : struct, IPixel - => new PaletteFrameQuantizer(this, paletteFunction.Invoke()); - private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs new file mode 100644 index 000000000..02ffc76ef --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs @@ -0,0 +1,92 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Dithering; + +namespace SixLabors.ImageSharp.Processing.Processors.Quantization +{ + /// + /// A generic palette quantizer. + /// + /// The pixel format. + public class PaletteQuantizer : IQuantizer + where TPixel : struct, IPixel + { + private readonly TPixel[] palette; + + /// + /// Initializes a new instance of the class. + /// + /// The color palette to use. + public PaletteQuantizer(TPixel[] palette) + : this(palette, true) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The color palette to use. + /// Whether to apply dithering to the output image + public PaletteQuantizer(TPixel[] palette, bool dither) + : this(palette, GetDiffuser(dither)) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The color palette to use. + /// The error diffusion algorithm, if any, to apply to the output image + public PaletteQuantizer(TPixel[] palette, IErrorDiffuser diffuser) + { + Guard.MustBeBetweenOrEqualTo(palette.Length, QuantizerConstants.MinColors, QuantizerConstants.MaxColors, nameof(palette)); + this.palette = palette; + this.Diffuser = diffuser; + } + + /// + public IErrorDiffuser Diffuser { get; } + + /// + public IFrameQuantizer CreateFrameQuantizer() + where TPixel1 : struct, IPixel + { + if (!typeof(TPixel).Equals(typeof(TPixel1))) + { + throw new InvalidOperationException("Generic method type must be the same as class type."); + } + + TPixel[] paletteRef = this.palette; + return new PaletteFrameQuantizer(this, Unsafe.As(ref paletteRef)); + } + + /// + public IFrameQuantizer CreateFrameQuantizer(int maxColors) + where TPixel1 : struct, IPixel + { + if (!typeof(TPixel).Equals(typeof(TPixel1))) + { + throw new InvalidOperationException("Generic method type must be the same as class type."); + } + + TPixel[] paletteRef = this.palette; + TPixel1[] castPalette = Unsafe.As(ref paletteRef); + + maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); + int max = Math.Min(maxColors, castPalette.Length); + + if (max != castPalette.Length) + { + return new PaletteFrameQuantizer(this, castPalette.AsSpan(0, max).ToArray()); + } + + return new PaletteFrameQuantizer(this, castPalette); + } + + private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/QuantizerConstants.cs b/src/ImageSharp/Processing/Processors/Quantization/QuantizerConstants.cs new file mode 100644 index 000000000..d79a91c30 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Quantization/QuantizerConstants.cs @@ -0,0 +1,21 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Processing.Processors.Quantization +{ + /// + /// Contains color quantization specific constants. + /// + internal static class QuantizerConstants + { + /// + /// The minimum number of colors to use when quantizing an image. + /// + public const int MinColors = 1; + + /// + /// The maximum number of colors to use when quantizing an image. + /// + public const int MaxColors = 256; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs new file mode 100644 index 000000000..bfa368a2e --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs @@ -0,0 +1,47 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Dithering; + +namespace SixLabors.ImageSharp.Processing.Processors.Quantization +{ + /// + /// A palette quantizer consisting of web safe colors as defined in the CSS Color Module Level 4. + /// + public class WebSafePaletteQuantizer : PaletteQuantizer + { + /// + /// Initializes a new instance of the class. + /// + public WebSafePaletteQuantizer() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Whether to apply dithering to the output image + public WebSafePaletteQuantizer(bool dither) + : base(dither) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The error diffusion algorithm, if any, to apply to the output image + public WebSafePaletteQuantizer(IErrorDiffuser diffuser) + : base(diffuser) + { + } + + /// + public override IFrameQuantizer CreateFrameQuantizer() + => this.CreateFrameQuantizer(NamedColors.WebSafePalette.Length); + + /// + public override IFrameQuantizer CreateFrameQuantizer(int maxColors) + => this.CreateFrameQuantizer(NamedColors.WebSafePalette, maxColors); + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs new file mode 100644 index 000000000..9a91a63d3 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs @@ -0,0 +1,48 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Dithering; + +namespace SixLabors.ImageSharp.Processing.Processors.Quantization +{ + /// + /// A palette quantizer consisting of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. + /// The hex codes were collected and defined by Nicholas Rougeux + /// + public class WernerPaletteQuantizer : PaletteQuantizer + { + /// + /// Initializes a new instance of the class. + /// + public WernerPaletteQuantizer() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Whether to apply dithering to the output image + public WernerPaletteQuantizer(bool dither) + : base(dither) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The error diffusion algorithm, if any, to apply to the output image + public WernerPaletteQuantizer(IErrorDiffuser diffuser) + : base(diffuser) + { + } + + /// + public override IFrameQuantizer CreateFrameQuantizer() + => this.CreateFrameQuantizer(NamedColors.WernerPalette.Length); + + /// + public override IFrameQuantizer CreateFrameQuantizer(int maxColors) + => this.CreateFrameQuantizer(NamedColors.WernerPalette, maxColors); + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs index 5123e737d..629f7a238 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs @@ -14,11 +14,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WuQuantizer : IQuantizer { - /// - /// The default maximum number of colors to use when quantizing the image. - /// - public const int DefaultMaxColors = 256; - /// /// Initializes a new instance of the class. /// @@ -41,7 +36,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// Whether to apply dithering to the output image public WuQuantizer(bool dither) - : this(GetDiffuser(dither), DefaultMaxColors) + : this(GetDiffuser(dither), QuantizerConstants.MaxColors) { } @@ -50,7 +45,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The error diffusion algorithm, if any, to apply to the output image public WuQuantizer(IErrorDiffuser diffuser) - : this(diffuser, DefaultMaxColors) + : this(diffuser, QuantizerConstants.MaxColors) { } @@ -62,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public WuQuantizer(IErrorDiffuser diffuser, int maxColors) { this.Diffuser = diffuser; - this.MaxColors = maxColors.Clamp(1, DefaultMaxColors); + this.MaxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); } /// @@ -82,7 +77,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public IFrameQuantizer CreateFrameQuantizer(int maxColors) where TPixel : struct, IPixel { - maxColors = maxColors.Clamp(1, DefaultMaxColors); + maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); return new WuFrameQuantizer(this, maxColors); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeGif.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeGif.cs index 12e74ccdb..89eb63d62 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeGif.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeGif.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public void GifCore() { // Try to get as close to System.Drawing's output as possible - var options = new GifEncoder { Quantizer = new PaletteQuantizer(false) }; + var options = new GifEncoder { Quantizer = new WebSafePaletteQuantizer(false) }; using (var memoryStream = new MemoryStream()) { this.bmpCore.SaveAsGif(memoryStream, options); diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeGifMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeGifMultiple.cs index 9b94347f3..bf9627f4c 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeGifMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeGifMultiple.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs this.ForEachImageSharpImage((img, ms) => { // Try to get as close to System.Drawing's output as possible - var options = new GifEncoder { Quantizer = new PaletteQuantizer(false) }; + var options = new GifEncoder { Quantizer = new WebSafePaletteQuantizer(false) }; img.Save(ms, options); return null; }); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs index 962b34eb7..639d1594e 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs { using (var memoryStream = new MemoryStream()) { - var options = new PngEncoder { Quantizer = KnownQuantizers.Palette }; + var options = new PngEncoder { Quantizer = KnownQuantizers.WebSafe }; this.bmpCore.SaveAsPng(memoryStream, options); } } @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs { using (var memoryStream = new MemoryStream()) { - var options = new PngEncoder { Quantizer = new PaletteQuantizer(false) }; + var options = new PngEncoder { Quantizer = new WebSafePaletteQuantizer(false) }; this.bmpCore.SaveAsPng(memoryStream, options); } } diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index 1d21c65fd..158a085d5 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -67,7 +67,8 @@ namespace SixLabors.ImageSharp.Tests new TheoryData { nameof(KnownQuantizers.Octree), - nameof(KnownQuantizers.Palette), + nameof(KnownQuantizers.WebSafe), + nameof(KnownQuantizers.Werner), nameof(KnownQuantizers.Wu) }; diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index c5c971962..a98ae164a 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif { // Use the palette quantizer without dithering to ensure results // are consistant - Quantizer = new PaletteQuantizer(false) + Quantizer = new WebSafePaletteQuantizer(false) }; // Always save as we need to compare the encoded output. diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index c2b1c26c5..fb32522c9 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -13,15 +13,18 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void QuantizersDitherByDefault() { - var palette = new PaletteQuantizer(); + var werner = new WernerPaletteQuantizer(); + var websafe = new WebSafePaletteQuantizer(); var octree = new OctreeQuantizer(); var wu = new WuQuantizer(); - Assert.NotNull(palette.Diffuser); + Assert.NotNull(werner.Diffuser); + Assert.NotNull(websafe.Diffuser); Assert.NotNull(octree.Diffuser); Assert.NotNull(wu.Diffuser); - Assert.True(palette.CreateFrameQuantizer().Dither); + Assert.True(werner.CreateFrameQuantizer().Dither); + Assert.True(websafe.CreateFrameQuantizer().Dither); Assert.True(octree.CreateFrameQuantizer().Dither); Assert.True(wu.CreateFrameQuantizer().Dither); } @@ -36,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests { Assert.True(image[0, 0].Equals(default(TPixel))); - var quantizer = new PaletteQuantizer(dither); + var quantizer = new WebSafePaletteQuantizer(dither); foreach (ImageFrame frame in image.Frames) { From 3e92875a9a9b0bc6ecd8e81b98b2c5d29a8cbf8c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 20 Oct 2018 14:42:23 +0200 Subject: [PATCH 032/238] fixed benchmarks and optimized implementation --- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 61 +++--- .../Color/Bulk/PackFromVector4.cs | 67 +++--- .../Color/Bulk/ToVector4.cs | 197 +++++++++++++++--- .../General/Vectorization/UInt32ToSingle.cs | 52 +++-- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 6 +- 5 files changed, 279 insertions(+), 104 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 6def8938a..3131f1873 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -39,9 +39,8 @@ namespace SixLabors.ImageSharp ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - ref Vector destBaseU = ref Unsafe.As, Vector>(ref destBase); - const float Scale = 1f / 255f; + var scale = new Vector(1f / 255f); for (int i = 0; i < n; i++) { @@ -51,26 +50,28 @@ namespace SixLabors.ImageSharp Vector.Widen(s0, out Vector w0, out Vector w1); Vector.Widen(s1, out Vector w2, out Vector w3); - ref Vector d = ref Unsafe.Add(ref destBaseU, i * 4); - d = w0; - Unsafe.Add(ref d, 1) = w1; - Unsafe.Add(ref d, 2) = w2; - Unsafe.Add(ref d, 3) = w3; - } - - n = dest.Length / Vector.Count; + Vector f0 = ConvertToSingle(w0, scale); + Vector f1 = ConvertToSingle(w1, scale); + Vector f2 = ConvertToSingle(w2, scale); + Vector f3 = ConvertToSingle(w3, scale); - for (int i = 0; i < n; i++) - { - ref Vector df = ref Unsafe.Add(ref destBase, i); - ref Vector du = ref Unsafe.As, Vector>(ref df); - - Vector v = Vector.ConvertToSingle(du); - v *= Scale; - df = v; + ref Vector d = ref Unsafe.Add(ref destBase, i * 4); + d = f0; + Unsafe.Add(ref d, 1) = f1; + Unsafe.Add(ref d, 2) = f2; + Unsafe.Add(ref d, 3) = f3; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector ConvertToSingle(Vector u, Vector scale) + { + Vector vi = Vector.AsVectorInt32(u); + Vector v = Vector.ConvertToSingle(vi); + v *= scale; + return v; + } + /// /// A variant of , which is faster on new .NET runtime. /// @@ -92,26 +93,21 @@ namespace SixLabors.ImageSharp ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); + Vector scale = new Vector(255); + for (int i = 0; i < n; i++) { ref Vector s = ref Unsafe.Add(ref sourceBase, i * 4); Vector f0 = s; - f0 = Clamp(f0); - Vector f1 = Unsafe.Add(ref s, 1); - f1 = Clamp(f1); - Vector f2 = Unsafe.Add(ref s, 2); - f2 = Clamp(f2); - Vector f3 = Unsafe.Add(ref s, 3); - f3 = Clamp(f3); - Vector w0 = Vector.ConvertToUInt32(f0 * 255f); - Vector w1 = Vector.ConvertToUInt32(f1 * 255f); - Vector w2 = Vector.ConvertToUInt32(f2 * 255f); - Vector w3 = Vector.ConvertToUInt32(f3 * 255f); + Vector w0 = ConvertToUInt32(f0, scale); + Vector w1 = ConvertToUInt32(f1, scale); + Vector w2 = ConvertToUInt32(f2, scale); + Vector w3 = ConvertToUInt32(f3, scale); Vector u0 = Vector.Narrow(w0, w1); Vector u1 = Vector.Narrow(w2, w3); @@ -123,9 +119,12 @@ namespace SixLabors.ImageSharp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector Clamp(Vector x) + private static Vector ConvertToUInt32(Vector vf, Vector scale) { - return Vector.Min(Vector.Max(x, Vector.Zero), Vector.One); + vf = Vector.Min(Vector.Max(vf, Vector.Zero), Vector.One); + vf *= scale; + Vector vi = Vector.ConvertToInt32(vf); + return Vector.AsVectorUInt32(vi); } } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index fb505ddcb..1153d8f40 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -26,7 +26,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, - 2048)] + 2048 + )] public int Count { get; set; } [GlobalSetup] @@ -43,7 +44,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.source.Dispose(); } - [Benchmark] + //[Benchmark] public void PerElement() { ref Vector4 s = ref MemoryMarshal.GetReference(this.source.GetSpan()); @@ -55,14 +56,14 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark(Baseline = true)] - public void CommonBulk() + [Benchmark] + public void PixelOperations_Base() { new PixelOperations().PackFromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } [Benchmark] - public void OptimizedBulk() + public void PixelOperations_Specialized() { PixelOperations.Instance.PackFromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } @@ -70,7 +71,30 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public class PackFromVector4_Rgba32 : PackFromVector4 { - //[Benchmark] + [Benchmark] + public void FastDefault() + { + ref Vector4 sBase = ref this.source.GetSpan()[0]; + ref Rgba32 dBase = ref this.destination.GetSpan()[0]; + + Vector4 maxBytes = new Vector4(255); + Vector4 half = new Vector4(0.5f); + + for (int i = 0; i < this.Count; i++) + { + Vector4 v = Unsafe.Add(ref sBase, i); + v *= maxBytes; + v += half; + v = Vector4.Clamp(v, Vector4.Zero, maxBytes); + ref Rgba32 d = ref Unsafe.Add(ref dBase, i); + d.R = (byte)v.X; + d.G = (byte)v.Y; + d.B = (byte)v.Z; + d.A = (byte)v.W; + } + } + + [Benchmark(Baseline = true)] public void BulkConvertNormalizedFloatToByteClampOverflows() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -88,29 +112,16 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); } - // TODO: Check again later! // RESULTS: - // - // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 - // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores - // Frequency=2742187 Hz, Resolution=364.6724 ns, Timer=TSC - // .NET Core SDK=2.1.400-preview-009063 - // [Host] : .NET Core 2.1.1 (CoreCLR 4.6.26606.02, CoreFX 4.6.26606.05), 64bit RyuJIT - // Job-XIFINS : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-RTQZPN : .NET Core 2.1.1 (CoreCLR 4.6.26606.02, CoreFX 4.6.26606.05), 64bit RyuJIT - // - // LaunchCount=1 TargetCount=3 WarmupCount=3 + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | + // ----------------------------------------------------------------- |-------- |------ |----------:|----------:|----------:|-------:|---------:|----------:| + // FastDefault | Clr | 2048 | 15.989 us | 6.1384 us | 0.3468 us | 4.07 | 0.08 | 0 B | + // BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3.931 us | 0.6264 us | 0.0354 us | 1.00 | 0.00 | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 2.100 us | 0.4717 us | 0.0267 us | 0.53 | 0.01 | 0 B | // - // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | - // ----------------------------------------------------------------- |-------- |------ |----------:|-----------:|----------:|-------:|---------:|----------:| - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3.755 us | 0.8959 us | 0.0506 us | 0.22 | 0.00 | 0 B | - // PerElement | Clr | 2048 | 17.387 us | 15.1569 us | 0.8564 us | 1.02 | 0.04 | 0 B | - // CommonBulk | Clr | 2048 | 17.121 us | 0.7634 us | 0.0431 us | 1.00 | 0.00 | 24 B | - // OptimizedBulk | Clr | 2048 | 4.018 us | 0.3858 us | 0.0218 us | 0.23 | 0.00 | 0 B | - // | | | | | | | | | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 22.232 us | 1.6154 us | 0.0913 us | 1.31 | 0.04 | 0 B | - // PerElement | Core | 2048 | 16.741 us | 2.9254 us | 0.1653 us | 0.98 | 0.03 | 0 B | - // CommonBulk | Core | 2048 | 17.022 us | 11.4894 us | 0.6492 us | 1.00 | 0.00 | 24 B | - // OptimizedBulk | Core | 2048 | 3.707 us | 0.1500 us | 0.0085 us | 0.22 | 0.01 | 0 B | + // | | | | | | | | | + // FastDefault | Core | 2048 | 14.693 us | 0.5131 us | 0.0290 us | 3.76 | 0.03 | 0 B | + // BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 3.913 us | 0.5661 us | 0.0320 us | 1.00 | 0.00 | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 1.966 us | 0.4056 us | 0.0229 us | 0.50 | 0.01 | 0 B | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 6afd3cf6b..d699d168b 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -29,8 +29,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, - //512 - 256 + //256, + //512, + 2048 )] public int Count { get; set; } @@ -60,70 +61,214 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - //[Benchmark] - public void CommonBulk() + [Benchmark] + public void PixelOperations_Base() { new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } - //[Benchmark] - public void OptimizedBulk() + [Benchmark] + public void PixelOperations_Specialized() { PixelOperations.Instance.ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } } - [RyuJitX64Job] - [DisassemblyDiagnoser(printAsm: true, printSource: true)] + [Config(typeof(Config.ShortClr))] public class ToVector4_Rgba32 : ToVector4 { - class Config : ManualConfig - { - } - - [Benchmark(Baseline = true)] - public void FastScalarBulk() + [Benchmark] + public void BasicBulk() { ref Rgba32 sBase = ref this.source.GetSpan()[0]; ref Vector4 dBase = ref this.destination.GetSpan()[0]; + Vector4 scale = new Vector4(1f / 255f); + + Vector4 v = default; + for (int i = 0; i < this.Count; i++) { ref Rgba32 s = ref Unsafe.Add(ref sBase, i); - ref Vector4 d = ref Unsafe.Add(ref dBase, i); - d.X = s.R; - d.Y = s.G; - d.Z = s.B; - d.W = s.A; + v.X = s.R; + v.Y = s.G; + v.Z = s.B; + v.W = s.A; + v *= scale; + Unsafe.Add(ref dBase, i) = v; + } + } + + [Benchmark(Baseline = true)] + public void BulkConvertByteToNormalizedFloat_2Loops() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); + + ref SimdUtils.Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref SimdUtils.Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dFloats)); + + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); + + int n = dFloats.Length / 8; + + for (int i = 0; i < n; i++) + { + ref SimdUtils.Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); + ref SimdUtils.Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i); + d.LoadFrom(ref s); + } + + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); + + var vi = Vector.AsVectorUInt32(df); + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + + df = vf; + } + } + + //[Benchmark] + public void BulkConvertByteToNormalizedFloat_ConvertInSameLoop() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); + + ref SimdUtils.Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref SimdUtils.Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dFloats)); + + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); + + int n = dFloats.Length / 8; + + var temp = default(SimdUtils.Octet.OfUInt32); + ref Vector tempRef = ref Unsafe.As>(ref temp); + + for (int i = 0; i < n; i++) + { + ref SimdUtils.Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); + temp.LoadFrom(ref s); + + Vector vi = tempRef; + + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + + Unsafe.Add(ref destBaseAsFloat, i) = vf; } } [Benchmark] - public void BulkConvertByteToNormalizedFloat() + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + int n = dFloats.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); + ref Vector destBaseU = ref Unsafe.As, Vector>(ref destBase); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + ref Vector d = ref Unsafe.Add(ref destBaseU, i * 4); + d = w0; + Unsafe.Add(ref d, 1) = w1; + Unsafe.Add(ref d, 2) = w2; + Unsafe.Add(ref d, 3) = w3; + } + + n = dFloats.Length / Vector.Count; + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + ref Vector dRef = ref Unsafe.Add(ref destBase, i); + + Vector du = Vector.AsVectorInt32(dRef); + Vector v = Vector.ConvertToSingle(du); + v *= scale; + + dRef = v; + } } [Benchmark] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat() + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + int n = dFloats.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + Vector f0 = ConvertToNormalizedSingle(w0, scale); + Vector f1 = ConvertToNormalizedSingle(w1, scale); + Vector f2 = ConvertToNormalizedSingle(w2, scale); + Vector f3 = ConvertToNormalizedSingle(w3, scale); + + ref Vector d = ref Unsafe.Add(ref destBase, i * 4); + d = f0; + Unsafe.Add(ref d, 1) = f1; + Unsafe.Add(ref d, 2) = f2; + Unsafe.Add(ref d, 3) = f3; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector ConvertToNormalizedSingle(Vector u, Vector scale) + { + Vector vi = Vector.AsVectorInt32(u); + Vector v = Vector.ConvertToSingle(vi); + v *= scale; + return v; } //[Benchmark] - public void Original() + public void OldImplementation() { - ToVector4SimdAligned(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + ToVector4OldImplementation(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ToVector4SimdAligned(ReadOnlySpan sourceColors, Span destVectors, int count) + private static void ToVector4OldImplementation(ReadOnlySpan sourceColors, Span destVectors, int count) { if (!Vector.IsHardwareAccelerated) { diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs index 4a4b939b6..be19e719a 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization { private float[] data; - private const int Count = 64; + private const int Count = 32; [GlobalSetup] public void Setup() @@ -24,8 +24,10 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization int n = Count / Vector.Count; - Vector magick = new Vector(32768.0f); - Vector scale = new Vector(255f) / new Vector(256f); + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); for (int i = 0; i < n; i++) { @@ -33,13 +35,16 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization // u.f = 32768.0f + x * (255.0f / 256.0f); // return (uint8_t)u.i; - ref Vector d = ref Unsafe.Add(ref b, i); - Vector x = d; - //x = Vector.Max(x, Vector.Zero); - //x = Vector.Min(x, Vector.One); + ref Vector df = ref Unsafe.Add(ref b, i); + + var vi = Vector.AsVectorUInt32(df); + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; - x = (x * scale) + magick; - d = x; + df = vf; } } @@ -48,18 +53,37 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization { int n = Count / Vector.Count; - ref Vector b = ref Unsafe.As>(ref this.data[0]); + ref Vector bf = ref Unsafe.As>(ref this.data[0]); + ref Vector bu = ref Unsafe.As, Vector>(ref bf); var scale = new Vector(1f / 255f); for (int i = 0; i < n; i++) { - ref Vector df = ref Unsafe.Add(ref b, i); - Vector du = Unsafe.As, Vector>(ref df); + Vector u = Unsafe.Add(ref bu, i); + Vector v = Vector.ConvertToSingle(u); + v *= scale; + Unsafe.Add(ref bf, i) = v; + } + } - Vector v = Vector.ConvertToSingle(du); + // This code is not correct at all, it's just here as reference + [Benchmark] + public void StandardSimdFromInt() + { + int n = Count / Vector.Count; + + ref Vector bf = ref Unsafe.As>(ref this.data[0]); + ref Vector bu = ref Unsafe.As, Vector>(ref bf); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + Vector u = Unsafe.Add(ref bu, i); + Vector v = Vector.ConvertToSingle(u); v *= scale; - df = v; + Unsafe.Add(ref bf, i) = v; } } } diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 4b23ca30f..7ed18ef86 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -212,15 +212,11 @@ namespace SixLabors.ImageSharp.Tests.Common [InlineData(3, 128)] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int seed, int count) { - if (!Vector.IsHardwareAccelerated) - { - return; - } - byte[] source = new Random(seed).GenerateRandomByteArray(count); float[] result = new float[count]; float[] expected = source.Select(b => (float)b / 255f).ToArray(); + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(source, result); Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); From f31c95e25dba23c8b5a53cf8e8a7194c82e822bf Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 20 Oct 2018 19:47:08 +0200 Subject: [PATCH 033/238] fix accuracy issues --- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 20 +++--- .../PixelFormats/Rgba32.PixelOperations.cs | 57 +++++++++++---- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 70 +++++++++---------- .../TestUtilities/TestDataGenerator.cs | 9 +-- 4 files changed, 91 insertions(+), 65 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 3131f1873..ec91e5098 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp { Guard.IsTrue( dest.Length % Vector.Count == 0, - nameof(source), + nameof(dest), "dest.Length should be divisable by Vector.Count!"); int n = dest.Length / Vector.Count; @@ -93,8 +93,6 @@ namespace SixLabors.ImageSharp ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - Vector scale = new Vector(255); - for (int i = 0; i < n; i++) { ref Vector s = ref Unsafe.Add(ref sourceBase, i * 4); @@ -104,10 +102,10 @@ namespace SixLabors.ImageSharp Vector f2 = Unsafe.Add(ref s, 2); Vector f3 = Unsafe.Add(ref s, 3); - Vector w0 = ConvertToUInt32(f0, scale); - Vector w1 = ConvertToUInt32(f1, scale); - Vector w2 = ConvertToUInt32(f2, scale); - Vector w3 = ConvertToUInt32(f3, scale); + Vector w0 = ConvertToUInt32(f0); + Vector w1 = ConvertToUInt32(f1); + Vector w2 = ConvertToUInt32(f2); + Vector w3 = ConvertToUInt32(f3); Vector u0 = Vector.Narrow(w0, w1); Vector u1 = Vector.Narrow(w2, w3); @@ -119,10 +117,12 @@ namespace SixLabors.ImageSharp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector ConvertToUInt32(Vector vf, Vector scale) + private static Vector ConvertToUInt32(Vector vf) { - vf = Vector.Min(Vector.Max(vf, Vector.Zero), Vector.One); - vf *= scale; + Vector maxBytes = new Vector(255f); + vf *= maxBytes; + vf += new Vector(0.5f); + vf = Vector.Min(Vector.Max(vf, Vector.Zero), maxBytes); Vector vi = Vector.ConvertToInt32(vf); return Vector.AsVectorUInt32(vi); } diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 0b96a599b..bfef60c60 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -52,22 +52,13 @@ namespace SixLabors.ImageSharp.PixelFormats return; } - int remainder = count % 2; - int alignedCount = count - remainder; - - if (alignedCount > 0) + if (SimdUtils.ExtendedIntrinsics.IsAvailable) { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); - Span rawDest = MemoryMarshal.Cast(destinationColors); - - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); + ConvertFromVector4ExtendedIntrinsics(sourceVectors, destinationColors, count); } - - if (remainder > 0) + else { - // actually: remainder == 1 - int lastIdx = count - 1; - destinationColors[lastIdx].PackFromVector4(sourceVectors[lastIdx]); + ConvertFromVector4StandardIntrinsics(sourceVectors, destinationColors, count); } } @@ -144,6 +135,46 @@ namespace SixLabors.ImageSharp.PixelFormats destinationVectors[lastIdx] = sourceColors[lastIdx].ToVector4(); } } + + private static void ConvertFromVector4ExtendedIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) + { + int remainder = count % 8; + int alignedCount = count - remainder; + + if (alignedCount > 0) + { + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors); + Span rawDest = MemoryMarshal.Cast(destinationColors.Slice(0, alignedCount)); + + SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); + } + + if (remainder > 0) + { + PackFromVector4Common(sourceVectors.Slice(alignedCount), destinationColors.Slice(alignedCount), remainder); + } + } + + private static void ConvertFromVector4StandardIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) + { + int remainder = count % 2; + int alignedCount = count - remainder; + + if (alignedCount > 0) + { + ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); + Span rawDest = MemoryMarshal.Cast(destinationColors); + + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); + } + + if (remainder > 0) + { + // actually: remainder == 1 + int lastIdx = count - 1; + destinationColors[lastIdx].PackFromVector4(sourceVectors[lastIdx]); + } + } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 7ed18ef86..4e1717bda 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -160,31 +160,6 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, dest); } - private static float Clamp255(float x) => Math.Min(255f, Math.Max(0f, x)); - - [Theory] - [InlineData(1, 0)] - [InlineData(1, 8)] - [InlineData(2, 16)] - [InlineData(3, 128)] - public void BulkConvertNormalizedFloatToByteClampOverflows(int seed, int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, -50, 444); - float[] normalized = orig.Select(f => f / 255f).ToArray(); - - byte[] dest = new byte[count]; - - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(normalized, dest); - - byte[] expected = orig.Select(f => (byte)Clamp255(f)).ToArray(); - - Assert.Equal(expected, dest); - } [Theory] [InlineData(1, 0)] @@ -222,23 +197,44 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } + + public static readonly TheoryData BulkConvertNormalizedFloatToByteClampOverflows_Data = + new TheoryData + { + 0, 64, 1024 + }; + [Theory] - [InlineData(1, 0)] - [InlineData(2, 32)] - [InlineData(3, 128)] - public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int seed, int count) + [MemberData(nameof(BulkConvertNormalizedFloatToByteClampOverflows_Data))] + public void BulkConvertNormalizedFloatToByteClampOverflows(int count) { - float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, -50, 444); - float[] normalized = orig.Select(f => f / 255f).ToArray(); + if (this.SkipOnNonAvx2()) + { + return; + } - byte[] dest = new byte[count]; + float[] source = new Random(count).GenerateRandomFloatArray(count, -0.1f, 1.2f); + byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); + byte[] actual = new byte[count]; - SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(normalized, dest); + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(source, actual); - byte[] expected = orig.Select(f => (byte)Clamp255(f)).ToArray(); + Assert.Equal(expected, actual); + } - Assert.Equal(expected, dest); + [Theory] + [MemberData(nameof(BulkConvertNormalizedFloatToByteClampOverflows_Data))] + public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) + { + float[] source = new Random(count).GenerateRandomFloatArray(count, -0.1f, 1.2f); + byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); + byte[] actual = new byte[count]; + + SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(source, actual); + + Assert.Equal(expected, actual); } + private static byte NormalizedFloatToByte(float f) => (byte)Math.Min(255f, Math.Max(0f, f * 255f + 0.5f)); [Theory] [InlineData(0)] @@ -265,7 +261,7 @@ namespace SixLabors.ImageSharp.Tests.Common float[] source = { 0, 7, 42, 255, 0.5f, 1.1f, 2.6f, 16f }; - var expected = source.Select(f => (byte)Math.Round(f)).ToArray(); + byte[] expected = source.Select(f => (byte)Math.Round(f)).ToArray(); source = source.Select(f => f / 255f).ToArray(); @@ -299,8 +295,6 @@ namespace SixLabors.ImageSharp.Tests.Common iiRef = x; - //Tuple8.OfUInt32 ii = Unsafe.As, Tuple8.OfUInt32>(ref x); - ref Tuple8.OfByte d = ref MemoryMarshal.Cast(dest)[0]; d.LoadFrom(ref ii); diff --git a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs index 6f3b18e1f..912b86e34 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs @@ -33,19 +33,20 @@ namespace SixLabors.ImageSharp.Tests return values; } - public static float[] GenerateRandomRoundedFloatArray(this Random rnd, int length, int minVal, int maxValExclusive) + public static float[] GenerateRandomRoundedFloatArray(this Random rnd, int length, float minVal, float maxVal) { float[] values = new float[length]; for (int i = 0; i < length; i++) { - int val = rnd.Next(minVal, maxValExclusive); - values[i] = (float)val; + values[i] = (float) Math.Round(rnd.GetRandomFloat(minVal, maxVal)); } return values; } + + public static byte[] GenerateRandomByteArray(this Random rnd, int length) { byte[] values = new byte[length]; @@ -53,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests return values; } - private static float GetRandomFloat(Random rnd, float minVal, float maxVal) + private static float GetRandomFloat(this Random rnd, float minVal, float maxVal) { return (float)rnd.NextDouble() * (maxVal - minVal) + minVal; } From d4d95ed564e7e94a56cb2dd8a58cbd04ddddf40d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 20 Oct 2018 20:05:20 +0200 Subject: [PATCH 034/238] cleanup benchmarks --- .../Color/Bulk/ToVector4.cs | 96 ++----------------- 1 file changed, 10 insertions(+), 86 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index d699d168b..726e214a9 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -100,84 +100,24 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark(Baseline = true)] - public void BulkConvertByteToNormalizedFloat_2Loops() + public void BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f - var mask = new Vector(255); - - ref SimdUtils.Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); - ref SimdUtils.Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dFloats)); - - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); - - int n = dFloats.Length / 8; - - for (int i = 0; i < n; i++) - { - ref SimdUtils.Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); - ref SimdUtils.Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i); - d.LoadFrom(ref s); - } - - for (int i = 0; i < n; i++) - { - ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); - - var vi = Vector.AsVectorUInt32(df); - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - df = vf; - } + SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } - //[Benchmark] - public void BulkConvertByteToNormalizedFloat_ConvertInSameLoop() + [Benchmark] + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f - var mask = new Vector(255); - - ref SimdUtils.Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); - ref SimdUtils.Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dFloats)); - - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); - - int n = dFloats.Length / 8; - - var temp = default(SimdUtils.Octet.OfUInt32); - ref Vector tempRef = ref Unsafe.As>(ref temp); - - for (int i = 0; i < n; i++) - { - ref SimdUtils.Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); - temp.LoadFrom(ref s); - - Vector vi = tempRef; - - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - Unsafe.Add(ref destBaseAsFloat, i) = vf; - } + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } - [Benchmark] + //[Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -219,7 +159,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + //[Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -264,23 +204,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk //[Benchmark] public void OldImplementation() { - ToVector4OldImplementation(this.source.GetSpan(), this.destination.GetSpan(), this.Count); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void ToVector4OldImplementation(ReadOnlySpan sourceColors, Span destVectors, int count) - { - if (!Vector.IsHardwareAccelerated) - { - throw new InvalidOperationException( - "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); - } - - DebugGuard.IsTrue( - count % Vector.Count == 0, - nameof(count), - "Argument 'count' should divisible by Vector.Count!"); - + int count = this.Count; var bVec = new Vector(256.0f / 255.0f); var magicFloat = new Vector(32768.0f); var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f @@ -288,8 +212,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk int unpackedRawCount = count * 4; - ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(sourceColors)); - ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(destVectors)); + ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)this.source.GetSpan())); + ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(this.destination.GetSpan())); ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsUnpacked); ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsUnpacked); From 81c57a812df67e346d562b794e0e499e8f4aa993 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 20 Oct 2018 22:49:31 +0200 Subject: [PATCH 035/238] Bulk conversion of arbitrary-sized Span-s of scalars --- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 212 +++++++++++++++ .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 90 +++++-- src/ImageSharp/Common/Helpers/SimdUtils.cs | 255 +++--------------- src/ImageSharp/Common/Tuples/Octet.cs | 100 +++++++ src/ImageSharp/Common/Tuples/Vector4Pair.cs | 2 +- .../JpegColorConverter.FromYCbCrSimd.cs | 2 +- .../JpegColorConverter.FromYCbCrSimdAvx2.cs | 2 +- .../ColorConverters/JpegColorConverter.cs | 2 +- .../PixelFormats/Rgba32.PixelOperations.cs | 12 +- .../Color/Bulk/ToVector4.cs | 8 +- .../General/Vectorization/UInt32ToSingle.cs | 27 +- .../Vectorization/WidenBytesToUInt32.cs | 7 +- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 108 +++++--- 13 files changed, 537 insertions(+), 290 deletions(-) create mode 100644 src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs create mode 100644 src/ImageSharp/Common/Tuples/Octet.cs diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs new file mode 100644 index 000000000..e4dc1a1d8 --- /dev/null +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -0,0 +1,212 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Tuples; + +// ReSharper disable MemberHidesStaticFromOuterClass +namespace SixLabors.ImageSharp +{ + internal static partial class SimdUtils + { + /// + /// 256bit / AVX2 intrinsics NOT depending on newer API-s (Vector.Widen, Vector.Narrow, Vector.ConvertTo*) + /// + public static class BasicIntrinsics256 + { + public static bool IsAvailable { get; } = IsAvx2CompatibleArchitecture; + + /// + /// as much elements as possible, slicing them down (keeping the remainder). + /// + internal static void BulkConvertByteToNormalizedFloatReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (IsAvailable) + { + int remainder = source.Length % 8; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertByteToNormalizedFloat( + source.Slice(0, alignedCount), + dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } + } + + /// + /// Convert 'source.Length' values normalized into [0..1] from 'source' + /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. + /// The implementation is SIMD optimized and works only with `source.Length` divisible by 8/>. + /// Based on: + /// + /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions + /// + /// + internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) + { + GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); + + DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); + + if (source.Length == 0) + { + return; + } + + ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + int n = source.Length / 8; + + Vector magick = new Vector(32768.0f); + Vector scale = new Vector(255f) / new Vector(256f); + + // need to copy to a temporary struct, because + // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) + // does not work. TODO: This might be a CoreClr bug, need to ask/report + var temp = default(Octet.OfUInt32); + ref Vector tempRef = ref Unsafe.As>(ref temp); + + for (int i = 0; i < n; i++) + { + // union { float f; uint32_t i; } u; + // u.f = 32768.0f + x * (255.0f / 256.0f); + // return (uint8_t)u.i; + Vector x = Unsafe.Add(ref srcBase, i); + x = (x * scale) + magick; + tempRef = x; + + ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); + d.LoadFrom(ref temp); + } + } + + /// + /// SIMD optimized implementation for . + /// Works only with `dest.Length` divisible by 8. + /// Implementation adapted from: + /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions + /// http://stackoverflow.com/a/536278 + /// + internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + { + GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); + + DebugGuard.IsTrue((dest.Length % 8) == 0, nameof(source), "dest.Length should be divisable by 8!"); + + var bVec = new Vector(256.0f / 255.0f); + var magicFloat = new Vector(32768.0f); + var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var mask = new Vector(255); + + ref Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + + ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); + + int n = dest.Length / 8; + + for (int i = 0; i < n; i++) + { + ref Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); + ref Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i); + d.LoadFrom(ref s); + } + + for (int i = 0; i < n; i++) + { + ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); + + var vi = Vector.AsVectorUInt32(df); + vi &= mask; + vi |= magicInt; + + var vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + + df = vf; + } + } + + /// + /// as much elements as possible, slicing them down (keeping the remainder). + /// + internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (IsAvailable) + { + int remainder = source.Length % Vector.Count; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertNormalizedFloatToByteClampOverflows(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } + } + + /// + /// Same as but clamps overflown values before conversion. + /// + internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) + { + GuardAvx2(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); + + DebugGuard.IsTrue((source.Length % 8) == 0, nameof(source), "source.Length should be divisible by 8!"); + + if (source.Length == 0) + { + return; + } + + ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + int n = source.Length / 8; + + Vector magick = new Vector(32768.0f); + Vector scale = new Vector(255f) / new Vector(256f); + + // need to copy to a temporary struct, because + // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) + // does not work. TODO: This might be a CoreClr bug, need to ask/report + var temp = default(Octet.OfUInt32); + ref Vector tempRef = ref Unsafe.As>(ref temp); + + for (int i = 0; i < n; i++) + { + // union { float f; uint32_t i; } u; + // u.f = 32768.0f + x * (255.0f / 256.0f); + // return (uint8_t)u.i; + Vector x = Unsafe.Add(ref srcBase, i); + x = Vector.Max(x, Vector.Zero); + x = Vector.Min(x, Vector.One); + + x = (x * scale) + magick; + tempRef = x; + + ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); + d.LoadFrom(ref temp); + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index ec91e5098..5c0b8ee93 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -1,8 +1,10 @@ using System; +using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +// ReSharper disable MemberHidesStaticFromOuterClass namespace SixLabors.ImageSharp { internal static partial class SimdUtils @@ -18,22 +20,47 @@ namespace SixLabors.ImageSharp { public static bool IsAvailable { get; } = #if NETCOREAPP2_1 -// TODO: Also available in .NET 4.7.2, we need to add a build target! - true; + // TODO: Also available in .NET 4.7.2, we need to add a build target! + Vector.IsHardwareAccelerated; #else false; #endif /// - /// A variant of , which is faster on new .NET runtime. + /// as much elements as possible, slicing them down (keeping the remainder). + /// + [Conditional("NETCOREAPP2_1")] + internal static void BulkConvertByteToNormalizedFloatReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (IsAvailable) + { + int remainder = source.Length % Vector.Count; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertByteToNormalizedFloat(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } + } + + /// + /// A variant of , which is faster on new RyuJIT runtime. /// // ReSharper disable once MemberHidesStaticFromOuterClass internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - Guard.IsTrue( + DebugGuard.IsTrue( dest.Length % Vector.Count == 0, nameof(source), - "dest.Length should be divisable by Vector.Count!"); + "dest.Length should be divisible by Vector.Count!"); int n = dest.Length / Vector.Count; @@ -63,34 +90,52 @@ namespace SixLabors.ImageSharp } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector ConvertToSingle(Vector u, Vector scale) + /// + /// as much elements as possible, slicing them down (keeping the remainder). + /// + [Conditional("NETCOREAPP2_1")] + internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( + ref ReadOnlySpan source, + ref Span dest) { - Vector vi = Vector.AsVectorInt32(u); - Vector v = Vector.ConvertToSingle(vi); - v *= scale; - return v; + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (IsAvailable) + { + int remainder = source.Length % Vector.Count; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertNormalizedFloatToByteClampOverflows(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } } /// - /// A variant of , which is faster on new .NET runtime. + /// A variant of , which is faster on new .NET runtime. /// /// /// It does NOT worth yet to utilize this method (2018 Oct). /// See benchmark results for the "PackFromVector4_Rgba32" benchmark! /// TODO: Check again later! /// - // ReSharper disable once MemberHidesStaticFromOuterClass - internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) + internal static void BulkConvertNormalizedFloatToByteClampOverflows( + ReadOnlySpan source, + Span dest) { - Guard.IsTrue( + DebugGuard.IsTrue( dest.Length % Vector.Count == 0, nameof(dest), - "dest.Length should be divisable by Vector.Count!"); + "dest.Length should be divisible by Vector.Count!"); int n = dest.Length / Vector.Count; - ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Vector sourceBase = + ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); for (int i = 0; i < n; i++) @@ -126,6 +171,15 @@ namespace SixLabors.ImageSharp Vector vi = Vector.ConvertToInt32(vf); return Vector.AsVectorUInt32(vi); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector ConvertToSingle(Vector u, Vector scale) + { + Vector vi = Vector.AsVectorInt32(u); + Vector v = Vector.ConvertToSingle(vi); + v *= scale; + return v; + } } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 91aed8c79..73e9bacfa 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -6,6 +6,9 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tuples; + namespace SixLabors.ImageSharp { /// @@ -16,7 +19,8 @@ namespace SixLabors.ImageSharp /// /// Gets a value indicating whether the code is being executed on AVX2 CPU where both float and integer registers are of size 256 byte. /// - public static bool IsAvx2CompatibleArchitecture { get; } = Vector.IsHardwareAccelerated && Vector.Count == 8 && Vector.Count == 8; + public static bool IsAvx2CompatibleArchitecture { get; } = + Vector.IsHardwareAccelerated && Vector.Count == 8 && Vector.Count == 8; internal static void GuardAvx2(string operation) { @@ -57,236 +61,61 @@ namespace SixLabors.ImageSharp } /// - /// Convert 'source.Length' values normalized into [0..1] from 'source' into 'dest' buffer of values. - /// The values are scaled up into [0-255] and rounded. - /// The implementation is SIMD optimized and works only with `source.Length` divisible by . - /// Based on: - /// - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// - /// - internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) - { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); - - DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - Vector magick = new Vector(32768.0f); - Vector scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet.OfUInt32); - ref Vector tempRef = ref Unsafe.As>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = (x * scale) + magick; - tempRef = x; - - ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - - /// - /// Converts `dest.Length` bytes to -s to -s normalized into [0..1] - /// The implementation is SIMD optimized and works only with `dest.Length` divisible by . - /// Implementation adapted from: - /// - /// http://stackoverflow.com/a/5362789 - /// + /// Converts `dest.Length` -s to -s normalized into [0..1]. + /// should be the of the same size as , + /// but there are no restrictions on the span's length. /// internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); - - DebugGuard.IsTrue((dest.Length % Vector.Count) == 0, nameof(source), "dest.Length should be divisable by Vector.Count!"); - - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f - var mask = new Vector(255); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - ref Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); - ref Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsWideOctet); - - int n = dest.Length / 8; - - for (int i = 0; i < n; i++) - { - ref Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i); - ref Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i); - d.LoadFrom(ref s); - } + ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); + BasicIntrinsics256.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); - for (int i = 0; i < n; i++) + // Deal with the remainder: + int count = source.Length; + if (count > 0) { - ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); - - var vi = Vector.AsVectorUInt32(df); - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - df = vf; + // TODO: Do we need to optimize anything on this? (There are at most 7 remainders) + ref byte sBase = ref MemoryMarshal.GetReference(source); + ref float dBase = ref MemoryMarshal.GetReference(dest); + for (int i = 0; i < count; i++) + { + Unsafe.Add(ref dBase, i) = Unsafe.Add(ref sBase, i) / 255f; + } } } /// - /// Same as but clamps overflown values before conversion. + /// Convert 'source.Length' values normalized into [0..1] from 'source' into 'dest' buffer of . + /// The values are scaled up into [0-255] and rounded, overflows are clamped. + /// should be the of the same size as , + /// but there are no restrictions on the span's length. /// internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); - - DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - Vector magick = new Vector(32768.0f); - Vector scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet.OfUInt32); - ref Vector tempRef = ref Unsafe.As>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = Vector.Max(x, Vector.Zero); - x = Vector.Min(x, Vector.One); - - x = (x * scale) + magick; - tempRef = x; - - ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - - // TODO: Replace these with T4-d library level tuples! - internal static class Octet - { - [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(uint))] - public struct OfUInt32 - { - [FieldOffset(0 * sizeof(uint))] - public uint V0; - - [FieldOffset(1 * sizeof(uint))] - public uint V1; - - [FieldOffset(2 * sizeof(uint))] - public uint V2; - - [FieldOffset(3 * sizeof(uint))] - public uint V3; - - [FieldOffset(4 * sizeof(uint))] - public uint V4; - - [FieldOffset(5 * sizeof(uint))] - public uint V5; + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - [FieldOffset(6 * sizeof(uint))] - public uint V6; + ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); + BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); - [FieldOffset(7 * sizeof(uint))] - public uint V7; - - public override string ToString() - { - return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; - } - - [MethodImpl(InliningOptions.ShortMethod)] - public void LoadFrom(ref OfByte src) - { - this.V0 = src.V0; - this.V1 = src.V1; - this.V2 = src.V2; - this.V3 = src.V3; - this.V4 = src.V4; - this.V5 = src.V5; - this.V6 = src.V6; - this.V7 = src.V7; - } - } - - [StructLayout(LayoutKind.Explicit, Size = 8)] - public struct OfByte + // Deal with the remainder: + int count = source.Length; + if (count > 0) { - [FieldOffset(0)] - public byte V0; - - [FieldOffset(1)] - public byte V1; - - [FieldOffset(2)] - public byte V2; - - [FieldOffset(3)] - public byte V3; - - [FieldOffset(4)] - public byte V4; - - [FieldOffset(5)] - public byte V5; - - [FieldOffset(6)] - public byte V6; - - [FieldOffset(7)] - public byte V7; - - public override string ToString() - { - return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; - } + ref float sBase = ref MemoryMarshal.GetReference(source); + ref byte dBase = ref MemoryMarshal.GetReference(dest); - [MethodImpl(InliningOptions.ShortMethod)] - public void LoadFrom(ref OfUInt32 src) + for (int i = 0; i < count; i++) { - this.V0 = (byte)src.V0; - this.V1 = (byte)src.V1; - this.V2 = (byte)src.V2; - this.V3 = (byte)src.V3; - this.V4 = (byte)src.V4; - this.V5 = (byte)src.V5; - this.V6 = (byte)src.V6; - this.V7 = (byte)src.V7; + // TODO: Do we need to optimize anything on this? (There are at most 7 remainders) + float f = Unsafe.Add(ref sBase, i); + f *= 255f; + f += 0.5f; + f = MathF.Max(0, f); + f = MathF.Min(255f, f); + + Unsafe.Add(ref dBase, i) = (byte)f; } } } diff --git a/src/ImageSharp/Common/Tuples/Octet.cs b/src/ImageSharp/Common/Tuples/Octet.cs new file mode 100644 index 000000000..ae01a3121 --- /dev/null +++ b/src/ImageSharp/Common/Tuples/Octet.cs @@ -0,0 +1,100 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp.Tuples +{ + internal static class Octet + { + [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(uint))] + public struct OfUInt32 + { + [FieldOffset(0 * sizeof(uint))] + public uint V0; + + [FieldOffset(1 * sizeof(uint))] + public uint V1; + + [FieldOffset(2 * sizeof(uint))] + public uint V2; + + [FieldOffset(3 * sizeof(uint))] + public uint V3; + + [FieldOffset(4 * sizeof(uint))] + public uint V4; + + [FieldOffset(5 * sizeof(uint))] + public uint V5; + + [FieldOffset(6 * sizeof(uint))] + public uint V6; + + [FieldOffset(7 * sizeof(uint))] + public uint V7; + + public override string ToString() + { + return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; + } + + [MethodImpl(InliningOptions.ShortMethod)] + public void LoadFrom(ref OfByte src) + { + this.V0 = src.V0; + this.V1 = src.V1; + this.V2 = src.V2; + this.V3 = src.V3; + this.V4 = src.V4; + this.V5 = src.V5; + this.V6 = src.V6; + this.V7 = src.V7; + } + } + + [StructLayout(LayoutKind.Explicit, Size = 8)] + public struct OfByte + { + [FieldOffset(0)] + public byte V0; + + [FieldOffset(1)] + public byte V1; + + [FieldOffset(2)] + public byte V2; + + [FieldOffset(3)] + public byte V3; + + [FieldOffset(4)] + public byte V4; + + [FieldOffset(5)] + public byte V5; + + [FieldOffset(6)] + public byte V6; + + [FieldOffset(7)] + public byte V7; + + public override string ToString() + { + return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; + } + + [MethodImpl(InliningOptions.ShortMethod)] + public void LoadFrom(ref OfUInt32 src) + { + this.V0 = (byte)src.V0; + this.V1 = (byte)src.V1; + this.V2 = (byte)src.V2; + this.V3 = (byte)src.V3; + this.V4 = (byte)src.V4; + this.V5 = (byte)src.V5; + this.V6 = (byte)src.V6; + this.V7 = (byte)src.V7; + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Tuples/Vector4Pair.cs b/src/ImageSharp/Common/Tuples/Vector4Pair.cs index 309d5e2e5..5988b2200 100644 --- a/src/ImageSharp/Common/Tuples/Vector4Pair.cs +++ b/src/ImageSharp/Common/Tuples/Vector4Pair.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace SixLabors.ImageSharp.Common.Tuples +namespace SixLabors.ImageSharp.Tuples { /// /// Its faster to process multiple Vector4-s together, so let's pair them! diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs index 4b2626c58..5c63a478d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs @@ -6,7 +6,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Common.Tuples; +using SixLabors.ImageSharp.Tuples; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs index ab4947e65..3f26cdc90 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs @@ -6,7 +6,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Common.Tuples; +using SixLabors.ImageSharp.Tuples; // ReSharper disable ImpureMethodCallOnReadonlyValueField namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs index 60abb7fb2..293f3bc1f 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs @@ -6,8 +6,8 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; -using SixLabors.ImageSharp.Common.Tuples; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.Tuples; using SixLabors.Memory; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index bfef60c60..564b93ef5 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats } else { - ConvertToVector4UsingStandardIntrinsics(sourceColors, destinationVectors, count); + ConvertToVector4UsingBasicIntrinsics(sourceColors, destinationVectors, count); } } @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.PixelFormats } else { - ConvertFromVector4StandardIntrinsics(sourceVectors, destinationColors, count); + ConvertFromVector4BasicIntrinsics(sourceVectors, destinationColors, count); } } @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.PixelFormats } } - private static void ConvertToVector4UsingStandardIntrinsics( + private static void ConvertToVector4UsingBasicIntrinsics( ReadOnlySpan sourceColors, Span destinationVectors, int count) @@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.PixelFormats ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); - SimdUtils.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); + SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); } if (remainder > 0) @@ -155,7 +155,7 @@ namespace SixLabors.ImageSharp.PixelFormats } } - private static void ConvertFromVector4StandardIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) + private static void ConvertFromVector4BasicIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) { int remainder = count % 2; int alignedCount = count - remainder; @@ -165,7 +165,7 @@ namespace SixLabors.ImageSharp.PixelFormats ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); Span rawDest = MemoryMarshal.Cast(destinationColors); - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); + SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); } if (remainder > 0) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 726e214a9..855e9e4b9 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -30,8 +30,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, //256, - //512, - 2048 + 512 + //1024 )] public int Count { get; set; } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } - //[Benchmark] + [Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - //[Benchmark] + [Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs index be19e719a..ca85a350c 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs @@ -5,6 +5,7 @@ using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization { + [Config(typeof(Config.ShortClr))] public class UInt32ToSingle { private float[] data; @@ -66,8 +67,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization Unsafe.Add(ref bf, i) = v; } } - - // This code is not correct at all, it's just here as reference + [Benchmark] public void StandardSimdFromInt() { @@ -86,5 +86,28 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization Unsafe.Add(ref bf, i) = v; } } + + + [Benchmark] + public void StandardSimdFromInt_RefCast() + { + int n = Count / Vector.Count; + + ref Vector bf = ref Unsafe.As>(ref this.data[0]); + ref Vector bu = ref Unsafe.As, Vector>(ref bf); + + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + ref Vector fRef = ref Unsafe.Add(ref bf, i); + + Vector du = Vector.AsVectorInt32(fRef); + Vector v = Vector.ConvertToSingle(du); + v *= scale; + + fRef = v; + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs index f71f6ec1b..2bc3af4c9 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs @@ -3,8 +3,11 @@ using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Tuples; + namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization { + [Config(typeof(Config.ShortClr))] public class WidenBytesToUInt32 { private byte[] source; @@ -25,8 +28,8 @@ namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization { const int N = Count / 8; - ref SimdUtils.Octet.OfByte sBase = ref Unsafe.As(ref this.source[0]); - ref SimdUtils.Octet.OfUInt32 dBase = ref Unsafe.As(ref this.dest[0]); + ref Octet.OfByte sBase = ref Unsafe.As(ref this.source[0]); + ref Octet.OfUInt32 dBase = ref Unsafe.As(ref this.dest[0]); for (int i = 0; i < N; i++) { diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 4e1717bda..2dcba2b74 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Common { float[] data = new float[Vector.Count]; - var rnd = new Random(); + var rnd = new Random(seed); for (int i = 0; i < Vector.Count; i++) { @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Tests.Common [InlineData(1, 8)] [InlineData(2, 16)] [InlineData(3, 128)] - public void BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) + public void BasicIntrinsics_BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) { if (this.SkipOnNonAvx2()) { @@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.Tests.Common byte[] dest = new byte[count]; - SimdUtils.BulkConvertNormalizedFloatToByte(normalized, dest); + SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(normalized, dest); byte[] expected = orig.Select(f => (byte)(f)).ToArray(); @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Common [InlineData(1, 8)] [InlineData(2, 16)] [InlineData(3, 128)] - public void BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) + public void BasicIntrinsics_BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) { if (this.SkipOnNonAvx2()) { @@ -153,87 +153,113 @@ namespace SixLabors.ImageSharp.Tests.Common byte[] dest = new byte[count]; - SimdUtils.BulkConvertNormalizedFloatToByte(source, dest); + SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(source, dest); byte[] expected = source.Select(f => (byte)Math.Round(f * 255f)).ToArray(); Assert.Equal(expected, dest); } + public static readonly TheoryData ArraySizesDivisibleBy8 = new TheoryData { 0, 8, 16, 1024 }; + + public static readonly TheoryData ArraySizesDivisibleBy32 = new TheoryData { 0, 32, 512 }; + + public static readonly TheoryData ArbitraryArraySizes = + new TheoryData + { + 0, 1, 2, 3, 4, 7, 8, 9, 15, 16, 17, 63, 64, 255, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 520, + }; [Theory] - [InlineData(1, 0)] - [InlineData(2, 32)] - [InlineData(3, 128)] - public void BulkConvertByteToNormalizedFloat(int seed, int count) + [MemberData(nameof(ArraySizesDivisibleBy8))] + public void BasicIntrinsics_BulkConvertByteToNormalizedFloat(int count) { if (this.SkipOnNonAvx2()) { return; } - byte[] source = new Random(seed).GenerateRandomByteArray(count); - float[] result = new float[count]; - float[] expected = source.Select(b => (float)b / 255f).ToArray(); - - SimdUtils.BulkConvertByteToNormalizedFloat(source, result); - - Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); + TestImpl_BulkConvertByteToNormalizedFloat( + count, + (s, d) => SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(s.Span, d.Span)); } [Theory] - [InlineData(1, 0)] - [InlineData(2, 32)] - [InlineData(3, 128)] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int seed, int count) + [MemberData(nameof(ArraySizesDivisibleBy32))] + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int count) + { + TestImpl_BulkConvertByteToNormalizedFloat( + count, + (s, d) => SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(s.Span, d.Span)); + } + + [Theory] + [MemberData(nameof(ArbitraryArraySizes))] + public void BulkConvertByteToNormalizedFloat(int count) + { + TestImpl_BulkConvertByteToNormalizedFloat( + count, + (s, d) => SimdUtils.BulkConvertByteToNormalizedFloat(s.Span, d.Span)); + } + + private static void TestImpl_BulkConvertByteToNormalizedFloat( + int count, + Action, Memory> convert) { - byte[] source = new Random(seed).GenerateRandomByteArray(count); + byte[] source = new Random(count).GenerateRandomByteArray(count); float[] result = new float[count]; float[] expected = source.Select(b => (float)b / 255f).ToArray(); - - SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(source, result); + convert(source, result); Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } - - public static readonly TheoryData BulkConvertNormalizedFloatToByteClampOverflows_Data = - new TheoryData - { - 0, 64, 1024 - }; - [Theory] - [MemberData(nameof(BulkConvertNormalizedFloatToByteClampOverflows_Data))] - public void BulkConvertNormalizedFloatToByteClampOverflows(int count) + [MemberData(nameof(ArraySizesDivisibleBy8))] + public void BasicIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) { if (this.SkipOnNonAvx2()) { return; } - float[] source = new Random(count).GenerateRandomFloatArray(count, -0.1f, 1.2f); - byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); - byte[] actual = new byte[count]; - - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(source, actual); - - Assert.Equal(expected, actual); + TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, + (s, d) => SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span) + ); } [Theory] - [MemberData(nameof(BulkConvertNormalizedFloatToByteClampOverflows_Data))] + [MemberData(nameof(ArraySizesDivisibleBy32))] public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) + { + TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, + (s, d) => SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span) + ); + } + + [Theory] + [MemberData(nameof(ArbitraryArraySizes))] + public void BulkConvertNormalizedFloatToByteClampOverflows(int count) + { + TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, + (s, d) => SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span) + ); + } + + private static void TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( + int count, + Action, Memory> convert) { float[] source = new Random(count).GenerateRandomFloatArray(count, -0.1f, 1.2f); byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); byte[] actual = new byte[count]; - SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(source, actual); + convert(source, actual); Assert.Equal(expected, actual); } + private static byte NormalizedFloatToByte(float f) => (byte)Math.Min(255f, Math.Max(0f, f * 255f + 0.5f)); [Theory] From f143411ea80b6b6999356868af7a03b761025859 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 20 Oct 2018 23:31:21 +0200 Subject: [PATCH 036/238] fix benchmarks --- .../Color/Bulk/PackFromVector4.cs | 4 +- .../Color/Bulk/ToVector4.cs | 73 ++----------------- 2 files changed, 8 insertions(+), 69 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index 1153d8f40..eb7154955 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -95,12 +95,12 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark(Baseline = true)] - public void BulkConvertNormalizedFloatToByteClampOverflows() + public void BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); + SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); } [Benchmark] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 855e9e4b9..c50c7ce5a 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -30,8 +30,9 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( //64, //256, - 512 - //1024 + //512, + //1024, + 2048 )] public int Count { get; set; } @@ -100,12 +101,12 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark(Baseline = true)] - public void BulkConvertByteToNormalizedFloat() + public void BasicIntrinsics256_BulkConvertByteToNormalizedFloat() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - SimdUtils.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } [Benchmark] @@ -117,7 +118,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } - [Benchmark] + //[Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -200,67 +201,5 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk v *= scale; return v; } - - //[Benchmark] - public void OldImplementation() - { - int count = this.Count; - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f - var mask = new Vector(255); - - int unpackedRawCount = count * 4; - - ref uint sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference((ReadOnlySpan)this.source.GetSpan())); - ref UnpackedRGBA destBaseAsUnpacked = ref Unsafe.As(ref MemoryMarshal.GetReference(this.destination.GetSpan())); - ref Vector destBaseAsUInt = ref Unsafe.As>(ref destBaseAsUnpacked); - ref Vector destBaseAsFloat = ref Unsafe.As>(ref destBaseAsUnpacked); - - for (int i = 0; i < count; i++) - { - uint sVal = Unsafe.Add(ref sourceBase, i); - ref UnpackedRGBA dst = ref Unsafe.Add(ref destBaseAsUnpacked, i); - - // This call is the bottleneck now: - dst.Load(sVal); - } - - int numOfVectors = unpackedRawCount / Vector.Count; - - for (int i = 0; i < numOfVectors; i++) - { - Vector vi = Unsafe.Add(ref destBaseAsUInt, i); - - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - Unsafe.Add(ref destBaseAsFloat, i) = vf; - } - } - - [StructLayout(LayoutKind.Sequential)] - private struct UnpackedRGBA - { - private uint r; - - private uint g; - - private uint b; - - private uint a; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Load(uint p) - { - this.r = p; - this.g = p >> 8; - this.b = p >> 16; - this.a = p >> 24; - } - } } } \ No newline at end of file From 4c9bf4ac27ab9bab36c42a89bbc735dc9b759e72 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 01:21:36 +0200 Subject: [PATCH 037/238] simplify Rgba32.PixelOperations, include benchmark results --- .../PixelFormats/PixelOperations{TPixel}.cs | 60 ++++----- .../PixelFormats/Rgba32.PixelOperations.cs | 123 ++---------------- .../Color/Bulk/PackFromVector4.cs | 41 ++++-- .../Color/Bulk/ToVector4.cs | 32 ++++- 4 files changed, 94 insertions(+), 162 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 39c442fe0..cbf164a71 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -29,7 +29,19 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - PackFromVector4Common(sourceVectors, destinationColors, count); + ReadOnlySpan sourceVectors1 = sourceVectors; + Span destinationColors1 = destinationColors; + GuardSpans(sourceVectors1, nameof(sourceVectors1), destinationColors1, nameof(destinationColors1), count); + + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors1); + ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors1); + + for (int i = 0; i < count; i++) + { + ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromVector4(sp); + } } /// @@ -40,7 +52,19 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { - ToVector4Common(sourceColors, destinationVectors, count); + ReadOnlySpan sourceColors1 = sourceColors; + Span destinationVectors1 = destinationVectors; + GuardSpans(sourceColors1, nameof(sourceColors1), destinationVectors1, nameof(destinationVectors1), count); + + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors1); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors1); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Vector4 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToVector4(); + } } /// @@ -106,37 +130,5 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.MustBeSizedAtLeast(source, minLength, sourceParamName); Guard.MustBeSizedAtLeast(destination, minLength, destinationParamName); } - - [MethodImpl(InliningOptions.ShortMethod)] - internal static void PackFromVector4Common(ReadOnlySpan sourceVectors, Span destinationColors, int count) - { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); - - for (int i = 0; i < count; i++) - { - ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromVector4(sp); - } - } - - [MethodImpl(InliningOptions.ShortMethod)] - internal static void ToVector4Common(ReadOnlySpan sourceColors, Span destinationVectors, int count) - { - GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); - - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); - - for (int i = 0; i < count; i++) - { - ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref Vector4 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToVector4(); - } - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 564b93ef5..bb42ec7e3 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -24,21 +24,12 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) - { - // Doesn't worth to bother with SIMD: - ToVector4Common(sourceColors, destinationVectors, count); - return; - } + sourceColors = sourceColors.Slice(0, count); + destinationVectors = destinationVectors.Slice(0, count); - if (SimdUtils.ExtendedIntrinsics.IsAvailable) - { - ConvertToVector4UsingExtendedIntrinsics(sourceColors, destinationVectors, count); - } - else - { - ConvertToVector4UsingBasicIntrinsics(sourceColors, destinationVectors, count); - } + SimdUtils.BulkConvertByteToNormalizedFloat( + MemoryMarshal.Cast(sourceColors), + MemoryMarshal.Cast(destinationVectors)); } /// @@ -46,20 +37,12 @@ namespace SixLabors.ImageSharp.PixelFormats { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - if (count < 128 || !SimdUtils.IsAvx2CompatibleArchitecture) - { - PackFromVector4Common(sourceVectors, destinationColors, count); - return; - } + sourceVectors = sourceVectors.Slice(0, count); + destinationColors = destinationColors.Slice(0, count); - if (SimdUtils.ExtendedIntrinsics.IsAvailable) - { - ConvertFromVector4ExtendedIntrinsics(sourceVectors, destinationColors, count); - } - else - { - ConvertFromVector4BasicIntrinsics(sourceVectors, destinationColors, count); - } + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( + MemoryMarshal.Cast(sourceVectors), + MemoryMarshal.Cast(destinationColors)); } /// @@ -89,92 +72,6 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(dest); } - - private static void ConvertToVector4UsingExtendedIntrinsics( - ReadOnlySpan sourceColors, - Span destinationVectors, - int count) - { - int remainder = count % 8; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); - Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); - - SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); - } - - if (remainder > 0) - { - ToVector4Common(sourceColors.Slice(alignedCount), destinationVectors.Slice(alignedCount), remainder); - } - } - - private static void ConvertToVector4UsingBasicIntrinsics( - ReadOnlySpan sourceColors, - Span destinationVectors, - int count) - { - int remainder = count % 2; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceColors); - Span rawDest = MemoryMarshal.Cast(destinationVectors.Slice(0, alignedCount)); - - SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(rawSrc, rawDest); - } - - if (remainder > 0) - { - // actually: remainder == 1 - int lastIdx = count - 1; - destinationVectors[lastIdx] = sourceColors[lastIdx].ToVector4(); - } - } - - private static void ConvertFromVector4ExtendedIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) - { - int remainder = count % 8; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors); - Span rawDest = MemoryMarshal.Cast(destinationColors.Slice(0, alignedCount)); - - SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); - } - - if (remainder > 0) - { - PackFromVector4Common(sourceVectors.Slice(alignedCount), destinationColors.Slice(alignedCount), remainder); - } - } - - private static void ConvertFromVector4BasicIntrinsics(ReadOnlySpan sourceVectors, Span destinationColors, int count) - { - int remainder = count % 2; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ReadOnlySpan rawSrc = MemoryMarshal.Cast(sourceVectors.Slice(0, alignedCount)); - Span rawDest = MemoryMarshal.Cast(destinationColors); - - SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflows(rawSrc, rawDest); - } - - if (remainder > 0) - { - // actually: remainder == 1 - int lastIdx = count - 1; - destinationColors[lastIdx].PackFromVector4(sourceVectors[lastIdx]); - } - } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index eb7154955..7a212b052 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk protected IMemoryOwner destination; [Params( - //64, + 64, 2048 )] public int Count { get; set; } @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public class PackFromVector4_Rgba32 : PackFromVector4 { [Benchmark] - public void FastDefault() + public void BasicBulk() { ref Vector4 sBase = ref this.source.GetSpan()[0]; ref Rgba32 dBase = ref this.destination.GetSpan()[0]; @@ -112,16 +112,31 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); } - // RESULTS: - // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | - // ----------------------------------------------------------------- |-------- |------ |----------:|----------:|----------:|-------:|---------:|----------:| - // FastDefault | Clr | 2048 | 15.989 us | 6.1384 us | 0.3468 us | 4.07 | 0.08 | 0 B | - // BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3.931 us | 0.6264 us | 0.0354 us | 1.00 | 0.00 | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 2.100 us | 0.4717 us | 0.0267 us | 0.53 | 0.01 | 0 B | - // - // | | | | | | | | | - // FastDefault | Core | 2048 | 14.693 us | 0.5131 us | 0.0290 us | 3.76 | 0.03 | 0 B | - // BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 3.913 us | 0.5661 us | 0.0320 us | 1.00 | 0.00 | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 1.966 us | 0.4056 us | 0.0229 us | 0.50 | 0.01 | 0 B | + // RESULTS (2018 October): + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ------------------------------------------------------------------ |-------- |------ |-------------:|-------------:|-----------:|-------:|---------:|-------:|----------:| + // BasicBulk | Clr | 64 | 581.62 ns | 33.625 ns | 1.8999 ns | 2.27 | 0.02 | - | 0 B | + // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 64 | 256.66 ns | 45.153 ns | 2.5512 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 64 | 201.92 ns | 30.161 ns | 1.7042 ns | 0.79 | 0.01 | - | 0 B | + // PixelOperations_Base | Clr | 64 | 665.01 ns | 13.032 ns | 0.7363 ns | 2.59 | 0.02 | 0.0067 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 295.14 ns | 26.335 ns | 1.4880 ns | 1.15 | 0.01 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Core | 64 | 513.22 ns | 91.110 ns | 5.1479 ns | 3.19 | 0.03 | - | 0 B | + // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Core | 64 | 160.76 ns | 2.760 ns | 0.1559 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 64 | 95.98 ns | 10.077 ns | 0.5694 ns | 0.60 | 0.00 | - | 0 B | + // PixelOperations_Base | Core | 64 | 591.74 ns | 49.856 ns | 2.8170 ns | 3.68 | 0.01 | 0.0067 | 24 B | + // PixelOperations_Specialized | Core | 64 | 149.11 ns | 4.485 ns | 0.2534 ns | 0.93 | 0.00 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Clr | 2048 | 15,345.85 ns | 1,213.551 ns | 68.5679 ns | 3.90 | 0.01 | - | 0 B | + // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3,939.49 ns | 71.101 ns | 4.0173 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 2,272.61 ns | 110.671 ns | 6.2531 ns | 0.58 | 0.00 | - | 0 B | + // PixelOperations_Base | Clr | 2048 | 17,422.47 ns | 811.733 ns | 45.8644 ns | 4.42 | 0.01 | - | 24 B | + // PixelOperations_Specialized | Clr | 2048 | 3,984.26 ns | 110.352 ns | 6.2351 ns | 1.01 | 0.00 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Core | 2048 | 14,950.43 ns | 699.309 ns | 39.5123 ns | 3.76 | 0.02 | - | 0 B | + // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 3,978.28 ns | 481.105 ns | 27.1833 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 2,169.54 ns | 75.606 ns | 4.2719 ns | !!0.55!| 0.00 | - | 0 B | + // PixelOperations_Base | Core | 2048 | 18,403.62 ns | 1,494.056 ns | 84.4169 ns | 4.63 | 0.03 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 2,227.60 ns | 486.761 ns | 27.5029 ns | !!0.56!| 0.01 | - | 0 B | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index c50c7ce5a..4a801d64e 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk protected IMemoryOwner destination; [Params( - //64, + 64, //256, //512, //1024, @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + //[Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); @@ -201,5 +201,33 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk v *= scale; return v; } + + // RESULTS (2018 October): + // + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ---------------------------------------------------- |-------- |------ |------------:|-------------:|-----------:|-------:|---------:|-------:|----------:| + // BasicBulk | Clr | 64 | 267.40 ns | 30.711 ns | 1.7352 ns | 1.07 | 0.01 | - | 0 B | + // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Clr | 64 | 249.97 ns | 33.838 ns | 1.9119 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Clr | 64 | 176.97 ns | 5.221 ns | 0.2950 ns | 0.71 | 0.00 | - | 0 B | + // PixelOperations_Base | Clr | 64 | 349.70 ns | 104.331 ns | 5.8949 ns | 1.40 | 0.02 | 0.0072 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 288.31 ns | 26.833 ns | 1.5161 ns | 1.15 | 0.01 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Core | 64 | 185.36 ns | 30.051 ns | 1.6979 ns | 1.26 | 0.01 | - | 0 B | + // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Core | 64 | 146.84 ns | 12.674 ns | 0.7161 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Core | 64 | 67.31 ns | 2.542 ns | 0.1436 ns | 0.46 | 0.00 | - | 0 B | + // PixelOperations_Base | Core | 64 | 272.03 ns | 94.419 ns | 5.3348 ns | 1.85 | 0.03 | 0.0072 | 24 B | + // PixelOperations_Specialized | Core | 64 | 121.91 ns | 31.477 ns | 1.7785 ns | 0.83 | 0.01 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Clr | 2048 | 5,133.04 ns | 284.052 ns | 16.0494 ns | 1.21 | 0.01 | - | 0 B | + // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Clr | 2048 | 4,248.58 ns | 1,095.887 ns | 61.9196 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Clr | 2048 | 1,214.02 ns | 184.349 ns | 10.4160 ns | 0.29 | 0.00 | - | 0 B | + // PixelOperations_Base | Clr | 2048 | 7,096.04 ns | 362.350 ns | 20.4734 ns | 1.67 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Clr | 2048 | 4,314.19 ns | 204.964 ns | 11.5809 ns | 1.02 | 0.01 | - | 0 B | + // | | | | | | | | | | + // BasicBulk | Core | 2048 | 5,038.38 ns | 223.282 ns | 12.6158 ns | 1.20 | 0.01 | - | 0 B | + // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Core | 2048 | 4,199.17 ns | 897.985 ns | 50.7378 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Core | 2048 | 1,113.86 ns | 64.799 ns | 3.6613 ns | !!0.27!| 0.00 | - | 0 B | + // PixelOperations_Base | Core | 2048 | 7,015.00 ns | 920.083 ns | 51.9864 ns | 1.67 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 1,176.59 ns | 256.955 ns | 14.5184 ns | !!0.28!| 0.00 | - | 0 B | } } \ No newline at end of file From 4eb749e387cc26fbda5f489251150152f7367057 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 01:31:55 +0200 Subject: [PATCH 038/238] cleanup code and comments --- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 96 +++++++++---------- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 10 +- src/ImageSharp/Common/Helpers/SimdUtils.cs | 28 +++--- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs index e4dc1a1d8..a8b343498 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -46,53 +46,6 @@ namespace SixLabors.ImageSharp } } - /// - /// Convert 'source.Length' values normalized into [0..1] from 'source' - /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. - /// The implementation is SIMD optimized and works only with `source.Length` divisible by 8/>. - /// Based on: - /// - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// - /// - internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) - { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); - - DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - Vector magick = new Vector(32768.0f); - Vector scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet.OfUInt32); - ref Vector tempRef = ref Unsafe.As>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = (x * scale) + magick; - tempRef = x; - - ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - /// /// SIMD optimized implementation for . /// Works only with `dest.Length` divisible by 8. @@ -165,7 +118,7 @@ namespace SixLabors.ImageSharp } /// - /// Same as but clamps overflown values before conversion. + /// Implementation of which is faster on older runtimes. /// internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { @@ -207,6 +160,53 @@ namespace SixLabors.ImageSharp d.LoadFrom(ref temp); } } + + /// + /// Convert 'source.Length' values normalized into [0..1] from 'source' + /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. + /// The implementation is SIMD optimized and works only with `source.Length` divisible by 8. + /// Based on: + /// + /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions + /// + /// + internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) + { + GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); + + DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); + + if (source.Length == 0) + { + return; + } + + ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); + ref Octet.OfByte destBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + int n = source.Length / 8; + + Vector magick = new Vector(32768.0f); + Vector scale = new Vector(255f) / new Vector(256f); + + // need to copy to a temporary struct, because + // SimdUtils.Octet.OfUInt32 temp = Unsafe.As, SimdUtils.Octet.OfUInt32>(ref x) + // does not work. TODO: This might be a CoreClr bug, need to ask/report + var temp = default(Octet.OfUInt32); + ref Vector tempRef = ref Unsafe.As>(ref temp); + + for (int i = 0; i < n; i++) + { + // union { float f; uint32_t i; } u; + // u.f = 32768.0f + x * (255.0f / 256.0f); + // return (uint8_t)u.i; + Vector x = Unsafe.Add(ref srcBase, i); + x = (x * scale) + magick; + tempRef = x; + + ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i); + d.LoadFrom(ref temp); + } + } } } } \ No newline at end of file diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 5c0b8ee93..fd263b54c 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -52,9 +52,8 @@ namespace SixLabors.ImageSharp } /// - /// A variant of , which is faster on new RyuJIT runtime. + /// Implementation , which is faster on new RyuJIT runtime. /// - // ReSharper disable once MemberHidesStaticFromOuterClass internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue( @@ -116,13 +115,8 @@ namespace SixLabors.ImageSharp } /// - /// A variant of , which is faster on new .NET runtime. + /// Implementation of , which is faster on new .NET runtime. /// - /// - /// It does NOT worth yet to utilize this method (2018 Oct). - /// See benchmark results for the "PackFromVector4_Rgba32" benchmark! - /// TODO: Check again later! - /// internal static void BulkConvertNormalizedFloatToByteClampOverflows( ReadOnlySpan source, Span dest) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 73e9bacfa..111ac2240 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -22,17 +22,10 @@ namespace SixLabors.ImageSharp public static bool IsAvx2CompatibleArchitecture { get; } = Vector.IsHardwareAccelerated && Vector.Count == 8 && Vector.Count == 8; - internal static void GuardAvx2(string operation) - { - if (!IsAvx2CompatibleArchitecture) - { - throw new NotSupportedException($"{operation} is supported only on AVX2 CPU!"); - } - } - /// /// Transform all scalars in 'v' in a way that converting them to would have rounding semantics. /// + /// The vector [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Vector4 PseudoRound(this Vector4 v) { @@ -48,14 +41,15 @@ namespace SixLabors.ImageSharp /// https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L110 /// /// + /// The vector [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static Vector FastRound(this Vector x) + internal static Vector FastRound(this Vector v) { Vector magic0 = new Vector(int.MinValue); // 0x80000000 Vector sgn0 = Vector.AsVectorSingle(magic0); - Vector and0 = Vector.BitwiseAnd(sgn0, x); + Vector and0 = Vector.BitwiseAnd(sgn0, v); Vector or0 = Vector.BitwiseOr(and0, new Vector(8388608.0f)); - Vector add0 = Vector.Add(x, or0); + Vector add0 = Vector.Add(v, or0); Vector sub0 = Vector.Subtract(add0, or0); return sub0; } @@ -65,6 +59,8 @@ namespace SixLabors.ImageSharp /// should be the of the same size as , /// but there are no restrictions on the span's length. /// + /// The source span of bytes + /// The destination span of floats internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); @@ -92,6 +88,8 @@ namespace SixLabors.ImageSharp /// should be the of the same size as , /// but there are no restrictions on the span's length. /// + /// The source span of floats + /// The destination span of bytes internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); @@ -119,5 +117,13 @@ namespace SixLabors.ImageSharp } } } + + private static void GuardAvx2(string operation) + { + if (!IsAvx2CompatibleArchitecture) + { + throw new NotSupportedException($"{operation} is supported only on AVX2 CPU!"); + } + } } } \ No newline at end of file From 8793880447ba5d87c1806c945f0f711988d4982f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 17:29:34 +0200 Subject: [PATCH 039/238] FallbackIntrinsics128 + ImageMaths.Modulo* implementations --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 16 ++ .../Helpers/SimdUtils.BasicIntrinsics256.cs | 2 +- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 5 +- .../SimdUtils.FallbackIntrinsics128.cs | 143 ++++++++++++++++++ src/ImageSharp/Common/Helpers/SimdUtils.cs | 6 +- .../Color/Bulk/PackFromVector4.cs | 26 +--- .../Color/Bulk/ToVector4.cs | 25 +-- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 27 +++- .../Helpers/ImageMathsTests.cs | 54 +++++++ 9 files changed, 256 insertions(+), 48 deletions(-) create mode 100644 src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 35769d96a..e4fd9bce6 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -39,6 +39,22 @@ namespace SixLabors.ImageSharp return (a / GreatestCommonDivisor(a, b)) * b; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Modulo4(int a) => a & 3; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Modulo8(int a) => a & 7; + + /// + /// Fast (mod m) calculator, + /// where should be a power of 2. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ModuloP2(int a, int m) + { + return a & (m - 1); + } + /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs index a8b343498..c7fd21a8f 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp internal static partial class SimdUtils { /// - /// 256bit / AVX2 intrinsics NOT depending on newer API-s (Vector.Widen, Vector.Narrow, Vector.ConvertTo*) + /// Implementation with 256bit / AVX2 intrinsics NOT depending on newer API-s (Vector.Widen etc.) /// public static class BasicIntrinsics256 { diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index fd263b54c..996a08fb4 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -10,8 +10,9 @@ namespace SixLabors.ImageSharp internal static partial class SimdUtils { /// - /// Methods accelerated only in RyuJIT having dotnet/coreclr#10662 merged (.NET Core 2.1+ .NET 4.7.2+) - /// PR: + /// Implementation methods based on newer API-s (Vector.Widen, Vector.Narrow, Vector.ConvertTo*). + /// Only accelerated only on RyuJIT having dotnet/coreclr#10662 merged (.NET Core 2.1+ .NET 4.7.2+) + /// See: /// https://github.com/dotnet/coreclr/pull/10662 /// API Proposal: /// https://github.com/dotnet/corefx/issues/15957 diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs new file mode 100644 index 000000000..bb2147466 --- /dev/null +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -0,0 +1,143 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp +{ + internal static partial class SimdUtils + { + /// + /// Fallback implementation based on (128bit). + /// For , efficient software fallback implementations are present + /// + maybe even mono can emit intrinsics for that type :P + /// + public static class FallbackIntrinsics128 + { + /// + /// as much elements as possible, slicing them down (keeping the remainder). + /// + internal static void BulkConvertByteToNormalizedFloatReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + int remainder = source.Length % 4; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertByteToNormalizedFloat( + source.Slice(0, alignedCount), + dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } + + /// + /// as much elements as possible, slicing them down (keeping the remainder). + /// + internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + int remainder = source.Length % 4; + int alignedCount = source.Length - remainder; + + if (alignedCount > 0) + { + BulkConvertNormalizedFloatToByteClampOverflows( + source.Slice(0, alignedCount), + dest.Slice(0, alignedCount)); + + source = source.Slice(alignedCount); + dest = dest.Slice(alignedCount); + } + } + + /// + /// Implementation of using . + /// + internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) + { + DebugGuard.IsTrue((dest.Length % 4) == 0, nameof(dest), "dest.Length should be divisible by 4!"); + + int count = dest.Length / 4; + if (count == 0) + { + return; + } + + ref ByteVector4 sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref Vector4 dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + + const float Scale = 1f / 255f; + Vector4 d = default; + + for (int i = 0; i < count; i++) + { + ref ByteVector4 s = ref Unsafe.Add(ref sBase, i); + d.X = s.X; + d.Y = s.Y; + d.Z = s.Z; + d.W = s.W; + d *= Scale; + Unsafe.Add(ref dBase, i) = d; + } + } + + /// + /// Implementation of using . + /// + internal static void BulkConvertNormalizedFloatToByteClampOverflows( + ReadOnlySpan source, + Span dest) + { + DebugGuard.IsTrue((source.Length % 4) == 0, nameof(source), "source.Length should be divisible by 4!"); + + int count = source.Length / 4; + if (count == 0) + { + return; + } + + ref Vector4 sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); + ref ByteVector4 dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); + + var half = new Vector4(0.5f); + var maxBytes = new Vector4(255f); + + for (int i = 0; i < count; i++) + { + Vector4 s = Unsafe.Add(ref sBase, i); + s *= maxBytes; + s += half; + + // I'm not sure if Clamp() is properly implemented with intrinsics. + s = Vector4.Max(Vector4.Zero, s); + s = Vector4.Min(maxBytes, s); + + ref ByteVector4 d = ref Unsafe.Add(ref dBase, i); + d.X = (byte)s.X; + d.Y = (byte)s.Y; + d.Z = (byte)s.Z; + d.W = (byte)s.W; + } + } + + [StructLayout(LayoutKind.Sequential)] + private struct ByteVector4 + { + public byte X; + public byte Y; + public byte Z; + public byte W; + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 111ac2240..bc75dc8ca 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp } /// - /// Converts `dest.Length` -s to -s normalized into [0..1]. + /// Converts all input -s to -s normalized into [0..1]. /// should be the of the same size as , /// but there are no restrictions on the span's length. /// @@ -67,6 +67,7 @@ namespace SixLabors.ImageSharp ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); BasicIntrinsics256.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); + FallbackIntrinsics128.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); // Deal with the remainder: int count = source.Length; @@ -83,7 +84,7 @@ namespace SixLabors.ImageSharp } /// - /// Convert 'source.Length' values normalized into [0..1] from 'source' into 'dest' buffer of . + /// Convert all values normalized into [0..1] from 'source' into 'dest' buffer of . /// The values are scaled up into [0-255] and rounded, overflows are clamped. /// should be the of the same size as , /// but there are no restrictions on the span's length. @@ -96,6 +97,7 @@ namespace SixLabors.ImageSharp ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); + FallbackIntrinsics128.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); // Deal with the remainder: int count = source.Length; diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index 7a212b052..a56082fcd 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -72,30 +72,16 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public class PackFromVector4_Rgba32 : PackFromVector4 { [Benchmark] - public void BasicBulk() + public void FallbackIntrinsics128() { - ref Vector4 sBase = ref this.source.GetSpan()[0]; - ref Rgba32 dBase = ref this.destination.GetSpan()[0]; - - Vector4 maxBytes = new Vector4(255); - Vector4 half = new Vector4(0.5f); + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - for (int i = 0; i < this.Count; i++) - { - Vector4 v = Unsafe.Add(ref sBase, i); - v *= maxBytes; - v += half; - v = Vector4.Clamp(v, Vector4.Zero, maxBytes); - ref Rgba32 d = ref Unsafe.Add(ref dBase, i); - d.R = (byte)v.X; - d.G = (byte)v.Y; - d.B = (byte)v.Z; - d.A = (byte)v.W; - } + SimdUtils.FallbackIntrinsics128.BulkConvertNormalizedFloatToByteClampOverflows(sBytes, dFloats); } [Benchmark(Baseline = true)] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows() + public void BasicIntrinsics256() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); @@ -104,7 +90,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark] - public void ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows() + public void ExtendedIntrinsic() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 4a801d64e..519edaa31 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -79,29 +79,16 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk public class ToVector4_Rgba32 : ToVector4 { [Benchmark] - public void BasicBulk() + public void FallbackIntrinsics128() { - ref Rgba32 sBase = ref this.source.GetSpan()[0]; - ref Vector4 dBase = ref this.destination.GetSpan()[0]; - - Vector4 scale = new Vector4(1f / 255f); - - Vector4 v = default; + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - for (int i = 0; i < this.Count; i++) - { - ref Rgba32 s = ref Unsafe.Add(ref sBase, i); - v.X = s.R; - v.Y = s.G; - v.Z = s.B; - v.W = s.A; - v *= scale; - Unsafe.Add(ref dBase, i) = v; - } + SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } [Benchmark(Baseline = true)] - public void BasicIntrinsics256_BulkConvertByteToNormalizedFloat() + public void BasicIntrinsics256() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); @@ -110,7 +97,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat() + public void ExtendedIntrinsics() { Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 2dcba2b74..feefd1758 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Tests.Common [InlineData(1, 8)] [InlineData(2, 16)] [InlineData(3, 128)] - public void BasicIntrinsics_BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) + public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) { if (this.SkipOnNonAvx2()) { @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Common [InlineData(1, 8)] [InlineData(2, 16)] [InlineData(3, 128)] - public void BasicIntrinsics_BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) + public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) { if (this.SkipOnNonAvx2()) { @@ -161,6 +161,7 @@ namespace SixLabors.ImageSharp.Tests.Common } public static readonly TheoryData ArraySizesDivisibleBy8 = new TheoryData { 0, 8, 16, 1024 }; + public static readonly TheoryData ArraySizesDivisibleBy4 = new TheoryData { 0, 4, 8, 28, 1020 }; public static readonly TheoryData ArraySizesDivisibleBy32 = new TheoryData { 0, 32, 512 }; @@ -170,9 +171,18 @@ namespace SixLabors.ImageSharp.Tests.Common 0, 1, 2, 3, 4, 7, 8, 9, 15, 16, 17, 63, 64, 255, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 520, }; + [Theory] + [MemberData(nameof(ArraySizesDivisibleBy4))] + public void FallbackIntrinsics128_BulkConvertByteToNormalizedFloat(int count) + { + TestImpl_BulkConvertByteToNormalizedFloat( + count, + (s, d) => SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(s.Span, d.Span)); + } + [Theory] [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics_BulkConvertByteToNormalizedFloat(int count) + public void BasicIntrinsics256_BulkConvertByteToNormalizedFloat(int count) { if (this.SkipOnNonAvx2()) { @@ -215,9 +225,18 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, result, new ApproximateFloatComparer(1e-5f)); } + [Theory] + [MemberData(nameof(ArraySizesDivisibleBy4))] + public void FallbackIntrinsics128_BulkConvertNormalizedFloatToByteClampOverflows(int count) + { + TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, + (s, d) => SimdUtils.FallbackIntrinsics128.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span) + ); + } + [Theory] [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) + public void BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows(int count) { if (this.SkipOnNonAvx2()) { diff --git a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs index 6c2979fe9..aec4d0b81 100644 --- a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs @@ -9,6 +9,60 @@ namespace SixLabors.ImageSharp.Tests.Helpers public class ImageMathsTests { + [Theory] + [InlineData(0, 0)] + [InlineData(1, 1)] + [InlineData(2, 2)] + [InlineData(3, 3)] + [InlineData(4, 0)] + [InlineData(100, 0)] + [InlineData(123, 3)] + [InlineData(53436353, 1)] + public void Modulo4(int a, int expected) + { + int actual = ImageMaths.Modulo4(a); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0, 0)] + [InlineData(1, 1)] + [InlineData(2, 2)] + [InlineData(6, 6)] + [InlineData(7, 7)] + [InlineData(8, 0)] + [InlineData(100, 4)] + [InlineData(123, 3)] + [InlineData(53436353, 1)] + [InlineData(975, 7)] + public void Modulo8(int a, int expected) + { + int actual = ImageMaths.Modulo8(a); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(0, 2, 0)] + [InlineData(1, 2, 1)] + [InlineData(2, 2, 0)] + [InlineData(0, 4, 0)] + [InlineData(3, 4, 3)] + [InlineData(5, 4, 1)] + [InlineData(5, 8, 5)] + [InlineData(8, 8, 0)] + [InlineData(8, 16, 8)] + [InlineData(15, 16, 15)] + [InlineData(17, 16, 1)] + [InlineData(17, 32, 17)] + [InlineData(31, 32, 31)] + [InlineData(32, 32, 0)] + [InlineData(33, 32, 1)] + public void Modulo2P(int a, int m, int expected) + { + int actual = ImageMaths.ModuloP2(a, m); + Assert.Equal(expected, actual); + } + [Fact] public void FasAbsResultMatchesMath() { From 9b0ee6fb2a60c0897fea87e18db6140194e83853 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 21:00:15 +0200 Subject: [PATCH 040/238] minimize ceremonial overhead in BulkConvertByteToNormalizedFloat() and BulkConvertNormalizedFloatToByteClampOverflows() --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 45 +++++---- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 91 ++++++++++-------- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 96 ++++++++++--------- .../SimdUtils.FallbackIntrinsics128.cs | 56 +++++++---- src/ImageSharp/Common/Helpers/SimdUtils.cs | 84 +++++++++++----- .../Color/Bulk/PackFromVector4.cs | 50 +++++----- .../Color/Bulk/ToVector4.cs | 50 +++++----- .../General/{ => BasicMath}/Abs.cs | 8 +- .../General/{ => BasicMath}/Clamp.cs | 10 +- .../BasicMath/ModuloPowerOfTwoConstant.cs | 23 +++++ .../BasicMath/ModuloPowerOfTwoVariable.cs | 32 +++++++ .../General/{ => BasicMath}/Pow.cs | 3 +- .../ImageSharp.Benchmarks/General/Modulus.cs | 19 ---- .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 17 +++- .../Helpers/ImageMathsTests.cs | 94 ++++++++++-------- 15 files changed, 406 insertions(+), 272 deletions(-) rename tests/ImageSharp.Benchmarks/General/{ => BasicMath}/Abs.cs (88%) rename tests/ImageSharp.Benchmarks/General/{ => BasicMath}/Clamp.cs (94%) create mode 100644 tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs create mode 100644 tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs rename tests/ImageSharp.Benchmarks/General/{ => BasicMath}/Pow.cs (93%) delete mode 100644 tests/ImageSharp.Benchmarks/General/Modulus.cs diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index e4fd9bce6..1395975ec 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -39,22 +39,31 @@ namespace SixLabors.ImageSharp return (a / GreatestCommonDivisor(a, b)) * b; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Modulo4(int a) => a & 3; + /// + /// Calculates % 4 + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static int Modulo4(int x) => x & 3; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Modulo8(int a) => a & 7; + /// + /// Calculates % 8 + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static int Modulo8(int x) => x & 7; /// - /// Fast (mod m) calculator, - /// where should be a power of 2. + /// Fast (x mod m) calculator, with the restriction that + /// should be power of 2. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ModuloP2(int a, int m) + [MethodImpl(InliningOptions.ShortMethod)] + public static int ModuloP2(int x, int m) { - return a & (m - 1); + return x & (m - 1); } + [MethodImpl(InliningOptions.ShortMethod)] + public static float Clamp(float x, float min, float max) => Math.Min(max, Math.Max(min, x)); + /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// @@ -62,7 +71,7 @@ namespace SixLabors.ImageSharp /// A number that is greater than , but less than or equal to /// /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static int FastAbs(int x) { int y = x >> 31; @@ -74,7 +83,7 @@ namespace SixLabors.ImageSharp /// /// A single-precision floating-point number /// The number raised to the power of 2. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static float Pow2(float x) => x * x; /// @@ -82,7 +91,7 @@ namespace SixLabors.ImageSharp /// /// A single-precision floating-point number /// The number raised to the power of 3. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static float Pow3(float x) => x * x * x; /// @@ -93,7 +102,7 @@ namespace SixLabors.ImageSharp /// /// The /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static int GetBitsNeededForColorDepth(int colors) => Math.Max(1, (int)Math.Ceiling(Math.Log(colors, 2))); /// @@ -101,7 +110,7 @@ namespace SixLabors.ImageSharp /// /// The bit depth. /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static int GetColorCountForBitDepth(int bitDepth) => 1 << bitDepth; /// @@ -110,7 +119,7 @@ namespace SixLabors.ImageSharp /// The x provided to G(x). /// The spread of the blur. /// The Gaussian G(x) - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static float Gaussian(float x, float sigma) { const float Numerator = 1.0f; @@ -133,7 +142,7 @@ namespace SixLabors.ImageSharp /// /// The sine cardinal of . /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static float SinC(float f) { if (MathF.Abs(f) > Constants.Epsilon) @@ -156,7 +165,7 @@ namespace SixLabors.ImageSharp /// /// The . /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static float GetBcValue(float x, float b, float c) { if (x < 0F) @@ -192,7 +201,7 @@ namespace SixLabors.ImageSharp /// /// The bounding . /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight) => new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); /// diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs index c7fd21a8f..713d606e7 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -21,28 +21,58 @@ namespace SixLabors.ImageSharp public static bool IsAvailable { get; } = IsAvx2CompatibleArchitecture; /// - /// as much elements as possible, slicing them down (keeping the remainder). + /// as many elements as possible, slicing them down (keeping the remainder). /// + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertByteToNormalizedFloatReduce( ref ReadOnlySpan source, ref Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - if (IsAvailable) + if (!IsAvailable) { - int remainder = source.Length % 8; - int alignedCount = source.Length - remainder; - - if (alignedCount > 0) - { - BulkConvertByteToNormalizedFloat( - source.Slice(0, alignedCount), - dest.Slice(0, alignedCount)); - - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); - } + return; + } + + int remainder = ImageMaths.Modulo8(source.Length); + int adjustedCount = source.Length - remainder; + + if (adjustedCount > 0) + { + BulkConvertByteToNormalizedFloat( + source.Slice(0, adjustedCount), + dest.Slice(0, adjustedCount)); + + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); + } + } + + /// + /// as many elements as possible, slicing them down (keeping the remainder). + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (!IsAvailable) + { + return; + } + + int remainder = ImageMaths.Modulo8(source.Length); + int adjustedCount = source.Length - remainder; + + if (adjustedCount > 0) + { + BulkConvertNormalizedFloatToByteClampOverflows(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); + + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); } } @@ -57,7 +87,7 @@ namespace SixLabors.ImageSharp { GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); - DebugGuard.IsTrue((dest.Length % 8) == 0, nameof(source), "dest.Length should be divisable by 8!"); + DebugGuard.IsTrue(ImageMaths.Modulo8(dest.Length) == 0, nameof(source), "dest.Length should be divisable by 8!"); var bVec = new Vector(256.0f / 255.0f); var magicFloat = new Vector(32768.0f); @@ -93,30 +123,6 @@ namespace SixLabors.ImageSharp } } - /// - /// as much elements as possible, slicing them down (keeping the remainder). - /// - internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - - if (IsAvailable) - { - int remainder = source.Length % Vector.Count; - int alignedCount = source.Length - remainder; - - if (alignedCount > 0) - { - BulkConvertNormalizedFloatToByteClampOverflows(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); - - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); - } - } - } - /// /// Implementation of which is faster on older runtimes. /// @@ -124,7 +130,7 @@ namespace SixLabors.ImageSharp { GuardAvx2(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); - DebugGuard.IsTrue((source.Length % 8) == 0, nameof(source), "source.Length should be divisible by 8!"); + DebugGuard.IsTrue(ImageMaths.Modulo8(source.Length) == 0, nameof(source), "source.Length should be divisible by 8!"); if (source.Length == 0) { @@ -174,7 +180,10 @@ namespace SixLabors.ImageSharp { GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); - DebugGuard.IsTrue((source.Length % Vector.Count) == 0, nameof(source), "source.Length should be divisable by Vector.Count!"); + DebugGuard.IsTrue( + ImageMaths.Modulo8(source.Length) == 0, + nameof(source), + "source.Length should be divisible by 8!"); if (source.Length == 0) { diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 996a08fb4..dfa6f189c 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -28,27 +28,58 @@ namespace SixLabors.ImageSharp #endif /// - /// as much elements as possible, slicing them down (keeping the remainder). + /// as many elements as possible, slicing them down (keeping the remainder). /// - [Conditional("NETCOREAPP2_1")] + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertByteToNormalizedFloatReduce( ref ReadOnlySpan source, ref Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - if (IsAvailable) + if (!IsAvailable) { - int remainder = source.Length % Vector.Count; - int alignedCount = source.Length - remainder; + return; + } + + int remainder = ImageMaths.ModuloP2(source.Length, Vector.Count); + int adjustedCount = source.Length - remainder; - if (alignedCount > 0) - { - BulkConvertByteToNormalizedFloat(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); + if (adjustedCount > 0) + { + BulkConvertByteToNormalizedFloat(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); - } + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); + } + } + + /// + /// as many elements as possible, slicing them down (keeping the remainder). + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( + ref ReadOnlySpan source, + ref Span dest) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + + if (!IsAvailable) + { + return; + } + + int remainder = ImageMaths.ModuloP2(source.Length, Vector.Count); + int adjustedCount = source.Length - remainder; + + if (adjustedCount > 0) + { + BulkConvertNormalizedFloatToByteClampOverflows( + source.Slice(0, adjustedCount), + dest.Slice(0, adjustedCount)); + + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); } } @@ -58,7 +89,7 @@ namespace SixLabors.ImageSharp internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue( - dest.Length % Vector.Count == 0, + ImageMaths.ModuloP2(dest.Length, Vector.Count) == 0, nameof(source), "dest.Length should be divisible by Vector.Count!"); @@ -67,8 +98,6 @@ namespace SixLabors.ImageSharp ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - var scale = new Vector(1f / 255f); - for (int i = 0; i < n; i++) { Vector b = Unsafe.Add(ref sourceBase, i); @@ -77,10 +106,10 @@ namespace SixLabors.ImageSharp Vector.Widen(s0, out Vector w0, out Vector w1); Vector.Widen(s1, out Vector w2, out Vector w3); - Vector f0 = ConvertToSingle(w0, scale); - Vector f1 = ConvertToSingle(w1, scale); - Vector f2 = ConvertToSingle(w2, scale); - Vector f3 = ConvertToSingle(w3, scale); + Vector f0 = ConvertToSingle(w0); + Vector f1 = ConvertToSingle(w1); + Vector f2 = ConvertToSingle(w2); + Vector f3 = ConvertToSingle(w3); ref Vector d = ref Unsafe.Add(ref destBase, i * 4); d = f0; @@ -90,31 +119,6 @@ namespace SixLabors.ImageSharp } } - /// - /// as much elements as possible, slicing them down (keeping the remainder). - /// - [Conditional("NETCOREAPP2_1")] - internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - - if (IsAvailable) - { - int remainder = source.Length % Vector.Count; - int alignedCount = source.Length - remainder; - - if (alignedCount > 0) - { - BulkConvertNormalizedFloatToByteClampOverflows(source.Slice(0, alignedCount), dest.Slice(0, alignedCount)); - - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); - } - } - } - /// /// Implementation of , which is faster on new .NET runtime. /// @@ -123,7 +127,7 @@ namespace SixLabors.ImageSharp Span dest) { DebugGuard.IsTrue( - dest.Length % Vector.Count == 0, + ImageMaths.ModuloP2(dest.Length, Vector.Count) == 0, nameof(dest), "dest.Length should be divisible by Vector.Count!"); @@ -168,11 +172,11 @@ namespace SixLabors.ImageSharp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector ConvertToSingle(Vector u, Vector scale) + private static Vector ConvertToSingle(Vector u) { Vector vi = Vector.AsVectorInt32(u); Vector v = Vector.ConvertToSingle(vi); - v *= scale; + v *= new Vector(1f / 255f); return v; } } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs index bb2147466..2d9f53eaf 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -1,71 +1,81 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +// ReSharper disable MemberHidesStaticFromOuterClass namespace SixLabors.ImageSharp { internal static partial class SimdUtils { /// /// Fallback implementation based on (128bit). - /// For , efficient software fallback implementations are present - /// + maybe even mono can emit intrinsics for that type :P + /// For , efficient software fallback implementations are present, + /// and we hope that even mono's JIT is able to emit SIMD instructions for that type :P /// public static class FallbackIntrinsics128 { /// - /// as much elements as possible, slicing them down (keeping the remainder). + /// as many elements as possible, slicing them down (keeping the remainder). /// + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertByteToNormalizedFloatReduce( ref ReadOnlySpan source, ref Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - int remainder = source.Length % 4; - int alignedCount = source.Length - remainder; + int remainder = ImageMaths.Modulo4(source.Length); + int adjustedCount = source.Length - remainder; - if (alignedCount > 0) + if (adjustedCount > 0) { BulkConvertByteToNormalizedFloat( - source.Slice(0, alignedCount), - dest.Slice(0, alignedCount)); + source.Slice(0, adjustedCount), + dest.Slice(0, adjustedCount)); - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); } } /// - /// as much elements as possible, slicing them down (keeping the remainder). + /// as many elements as possible, slicing them down (keeping the remainder). /// + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertNormalizedFloatToByteClampOverflowsReduce( ref ReadOnlySpan source, ref Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); - int remainder = source.Length % 4; - int alignedCount = source.Length - remainder; + int remainder = ImageMaths.Modulo4(source.Length); + int adjustedCount = source.Length - remainder; - if (alignedCount > 0) + if (adjustedCount > 0) { BulkConvertNormalizedFloatToByteClampOverflows( - source.Slice(0, alignedCount), - dest.Slice(0, alignedCount)); + source.Slice(0, adjustedCount), + dest.Slice(0, adjustedCount)); - source = source.Slice(alignedCount); - dest = dest.Slice(alignedCount); + source = source.Slice(adjustedCount); + dest = dest.Slice(adjustedCount); } } /// /// Implementation of using . /// + [MethodImpl(InliningOptions.ColdPath)] internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue((dest.Length % 4) == 0, nameof(dest), "dest.Length should be divisible by 4!"); + DebugGuard.IsTrue( + ImageMaths.Modulo4(dest.Length) == 0, + nameof(dest), + "dest.Length should be divisible by 4!"); int count = dest.Length / 4; if (count == 0) @@ -94,11 +104,15 @@ namespace SixLabors.ImageSharp /// /// Implementation of using . /// + [MethodImpl(InliningOptions.ColdPath)] internal static void BulkConvertNormalizedFloatToByteClampOverflows( ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue((source.Length % 4) == 0, nameof(source), "source.Length should be divisible by 4!"); + DebugGuard.IsTrue( + ImageMaths.Modulo4(source.Length) == 0, + nameof(source), + "source.Length should be divisible by 4!"); int count = source.Length / 4; if (count == 0) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index bc75dc8ca..95a6030fd 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -61,25 +62,22 @@ namespace SixLabors.ImageSharp /// /// The source span of bytes /// The destination span of floats + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); +#if NETCOREAPP2_1 ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); +#else BasicIntrinsics256.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); +#endif FallbackIntrinsics128.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); // Deal with the remainder: - int count = source.Length; - if (count > 0) + if (source.Length > 0) { - // TODO: Do we need to optimize anything on this? (There are at most 7 remainders) - ref byte sBase = ref MemoryMarshal.GetReference(source); - ref float dBase = ref MemoryMarshal.GetReference(dest); - for (int i = 0; i < count; i++) - { - Unsafe.Add(ref dBase, i) = Unsafe.Add(ref sBase, i) / 255f; - } + ConverByteToNormalizedFloatRemainder(source, dest); } } @@ -91,35 +89,71 @@ namespace SixLabors.ImageSharp /// /// The source span of floats /// The destination span of bytes + [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); +#if NETCOREAPP2_1 ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); +#else BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); +#endif FallbackIntrinsics128.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); // Deal with the remainder: - int count = source.Length; - if (count > 0) + if (source.Length > 0) { - ref float sBase = ref MemoryMarshal.GetReference(source); - ref byte dBase = ref MemoryMarshal.GetReference(dest); - - for (int i = 0; i < count; i++) - { - // TODO: Do we need to optimize anything on this? (There are at most 7 remainders) - float f = Unsafe.Add(ref sBase, i); - f *= 255f; - f += 0.5f; - f = MathF.Max(0, f); - f = MathF.Min(255f, f); - - Unsafe.Add(ref dBase, i) = (byte)f; - } + ConvertNormalizedFloatToByteRemainder(source, dest); } } + [MethodImpl(InliningOptions.ColdPath)] + private static void ConverByteToNormalizedFloatRemainder(ReadOnlySpan source, Span dest) + { + ref byte sBase = ref MemoryMarshal.GetReference(source); + ref float dBase = ref MemoryMarshal.GetReference(dest); + + // There are at most 3 elements at this point, having a for loop is overkill. + // Let's minimize the no. of instructions! + switch (source.Length) + { + case 3: + Unsafe.Add(ref dBase, 2) = Unsafe.Add(ref sBase, 2) / 255f; + goto case 2; + case 2: + Unsafe.Add(ref dBase, 1) = Unsafe.Add(ref sBase, 1) / 255f; + goto case 1; + case 1: + dBase = sBase / 255f; + break; + } + } + + [MethodImpl(InliningOptions.ColdPath)] + private static void ConvertNormalizedFloatToByteRemainder(ReadOnlySpan source, Span dest) + { + ref float sBase = ref MemoryMarshal.GetReference(source); + ref byte dBase = ref MemoryMarshal.GetReference(dest); + + switch (source.Length) + { + case 3: + Unsafe.Add(ref dBase, 2) = ConvertToByte(Unsafe.Add(ref sBase, 2)); + goto case 2; + case 2: + Unsafe.Add(ref dBase, 1) = ConvertToByte(Unsafe.Add(ref sBase, 1)); + goto case 1; + case 1: + dBase = ConvertToByte(sBase); + break; + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + private static byte ConvertToByte(float f) => (byte)ImageMaths.Clamp((f * 255f) + 0.5f, 0, 255f); + + [Conditional("DEBUG")] private static void GuardAvx2(string operation) { if (!IsAvx2CompatibleArchitecture) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index a56082fcd..eaa52a975 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -99,30 +99,30 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } // RESULTS (2018 October): - // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------------------------------------------ |-------- |------ |-------------:|-------------:|-----------:|-------:|---------:|-------:|----------:| - // BasicBulk | Clr | 64 | 581.62 ns | 33.625 ns | 1.8999 ns | 2.27 | 0.02 | - | 0 B | - // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 64 | 256.66 ns | 45.153 ns | 2.5512 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 64 | 201.92 ns | 30.161 ns | 1.7042 ns | 0.79 | 0.01 | - | 0 B | - // PixelOperations_Base | Clr | 64 | 665.01 ns | 13.032 ns | 0.7363 ns | 2.59 | 0.02 | 0.0067 | 24 B | - // PixelOperations_Specialized | Clr | 64 | 295.14 ns | 26.335 ns | 1.4880 ns | 1.15 | 0.01 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Core | 64 | 513.22 ns | 91.110 ns | 5.1479 ns | 3.19 | 0.03 | - | 0 B | - // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Core | 64 | 160.76 ns | 2.760 ns | 0.1559 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 64 | 95.98 ns | 10.077 ns | 0.5694 ns | 0.60 | 0.00 | - | 0 B | - // PixelOperations_Base | Core | 64 | 591.74 ns | 49.856 ns | 2.8170 ns | 3.68 | 0.01 | 0.0067 | 24 B | - // PixelOperations_Specialized | Core | 64 | 149.11 ns | 4.485 ns | 0.2534 ns | 0.93 | 0.00 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Clr | 2048 | 15,345.85 ns | 1,213.551 ns | 68.5679 ns | 3.90 | 0.01 | - | 0 B | - // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 3,939.49 ns | 71.101 ns | 4.0173 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Clr | 2048 | 2,272.61 ns | 110.671 ns | 6.2531 ns | 0.58 | 0.00 | - | 0 B | - // PixelOperations_Base | Clr | 2048 | 17,422.47 ns | 811.733 ns | 45.8644 ns | 4.42 | 0.01 | - | 24 B | - // PixelOperations_Specialized | Clr | 2048 | 3,984.26 ns | 110.352 ns | 6.2351 ns | 1.01 | 0.00 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Core | 2048 | 14,950.43 ns | 699.309 ns | 39.5123 ns | 3.76 | 0.02 | - | 0 B | - // BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 3,978.28 ns | 481.105 ns | 27.1833 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsic_BulkConvertNormalizedFloatToByteClampOverflows | Core | 2048 | 2,169.54 ns | 75.606 ns | 4.2719 ns | !!0.55!| 0.00 | - | 0 B | - // PixelOperations_Base | Core | 2048 | 18,403.62 ns | 1,494.056 ns | 84.4169 ns | 4.63 | 0.03 | - | 24 B | - // PixelOperations_Specialized | Core | 2048 | 2,227.60 ns | 486.761 ns | 27.5029 ns | !!0.56!| 0.01 | - | 0 B | + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ---------------------------- |-------- |------ |-------------:|-------------:|------------:|-------:|---------:|-------:|----------:| + // FallbackIntrinsics128 | Clr | 64 | 340.38 ns | 22.319 ns | 1.2611 ns | 1.41 | 0.01 | - | 0 B | + // BasicIntrinsics256 | Clr | 64 | 240.79 ns | 11.421 ns | 0.6453 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic | Clr | 64 | 199.09 ns | 124.239 ns | 7.0198 ns | 0.83 | 0.02 | - | 0 B | + // PixelOperations_Base | Clr | 64 | 647.99 ns | 24.003 ns | 1.3562 ns | 2.69 | 0.01 | 0.0067 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 259.79 ns | 13.391 ns | 0.7566 ns | 1.08 | 0.00 | - | 0 B | <--- ceremonial overhead has been minimized! + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 64 | 234.64 ns | 12.320 ns | 0.6961 ns | 1.58 | 0.00 | - | 0 B | + // BasicIntrinsics256 | Core | 64 | 148.87 ns | 2.794 ns | 0.1579 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic | Core | 64 | 94.06 ns | 10.015 ns | 0.5659 ns | 0.63 | 0.00 | - | 0 B | + // PixelOperations_Base | Core | 64 | 573.52 ns | 31.865 ns | 1.8004 ns | 3.85 | 0.01 | 0.0067 | 24 B | + // PixelOperations_Specialized | Core | 64 | 117.21 ns | 13.264 ns | 0.7494 ns | 0.79 | 0.00 | - | 0 B | + // | | | | | | | | | | + // FallbackIntrinsics128 | Clr | 2048 | 6,735.93 ns | 2,139.340 ns | 120.8767 ns | 1.71 | 0.03 | - | 0 B | + // BasicIntrinsics256 | Clr | 2048 | 3,929.29 ns | 334.027 ns | 18.8731 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic | Clr | 2048 | 2,226.01 ns | 130.525 ns | 7.3749 ns |!! 0.57 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Clr | 2048 | 16,760.84 ns | 367.800 ns | 20.7814 ns | 4.27 | 0.02 | - | 24 B | <--- Extra copies using "Vector4 TPixel.ToVector4()" + // PixelOperations_Specialized | Clr | 2048 | 3,986.03 ns | 237.238 ns | 13.4044 ns | 1.01 | 0.00 | - | 0 B | <--- can't yet detect whether ExtendedIntrinsics are available :( + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 2048 | 6,644.65 ns | 2,677.090 ns | 151.2605 ns | 1.69 | 0.05 | - | 0 B | + // BasicIntrinsics256 | Core | 2048 | 3,923.70 ns | 1,971.760 ns | 111.4081 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsic | Core | 2048 | 2,092.32 ns | 375.657 ns | 21.2253 ns |!! 0.53 | 0.01 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Core | 2048 | 16,875.73 ns | 1,271.957 ns | 71.8679 ns | 4.30 | 0.10 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 2,129.92 ns | 262.888 ns | 14.8537 ns |!! 0.54 | 0.01 | - | 0 B | <--- ExtendedIntrinsics rock! } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 519edaa31..2cbe549e4 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -191,30 +191,30 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk // RESULTS (2018 October): // - // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ---------------------------------------------------- |-------- |------ |------------:|-------------:|-----------:|-------:|---------:|-------:|----------:| - // BasicBulk | Clr | 64 | 267.40 ns | 30.711 ns | 1.7352 ns | 1.07 | 0.01 | - | 0 B | - // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Clr | 64 | 249.97 ns | 33.838 ns | 1.9119 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Clr | 64 | 176.97 ns | 5.221 ns | 0.2950 ns | 0.71 | 0.00 | - | 0 B | - // PixelOperations_Base | Clr | 64 | 349.70 ns | 104.331 ns | 5.8949 ns | 1.40 | 0.02 | 0.0072 | 24 B | - // PixelOperations_Specialized | Clr | 64 | 288.31 ns | 26.833 ns | 1.5161 ns | 1.15 | 0.01 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Core | 64 | 185.36 ns | 30.051 ns | 1.6979 ns | 1.26 | 0.01 | - | 0 B | - // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Core | 64 | 146.84 ns | 12.674 ns | 0.7161 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Core | 64 | 67.31 ns | 2.542 ns | 0.1436 ns | 0.46 | 0.00 | - | 0 B | - // PixelOperations_Base | Core | 64 | 272.03 ns | 94.419 ns | 5.3348 ns | 1.85 | 0.03 | 0.0072 | 24 B | - // PixelOperations_Specialized | Core | 64 | 121.91 ns | 31.477 ns | 1.7785 ns | 0.83 | 0.01 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Clr | 2048 | 5,133.04 ns | 284.052 ns | 16.0494 ns | 1.21 | 0.01 | - | 0 B | - // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Clr | 2048 | 4,248.58 ns | 1,095.887 ns | 61.9196 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Clr | 2048 | 1,214.02 ns | 184.349 ns | 10.4160 ns | 0.29 | 0.00 | - | 0 B | - // PixelOperations_Base | Clr | 2048 | 7,096.04 ns | 362.350 ns | 20.4734 ns | 1.67 | 0.02 | - | 24 B | - // PixelOperations_Specialized | Clr | 2048 | 4,314.19 ns | 204.964 ns | 11.5809 ns | 1.02 | 0.01 | - | 0 B | - // | | | | | | | | | | - // BasicBulk | Core | 2048 | 5,038.38 ns | 223.282 ns | 12.6158 ns | 1.20 | 0.01 | - | 0 B | - // BasicIntrinsics256_BulkConvertByteToNormalizedFloat | Core | 2048 | 4,199.17 ns | 897.985 ns | 50.7378 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics_BulkConvertByteToNormalizedFloat | Core | 2048 | 1,113.86 ns | 64.799 ns | 3.6613 ns | !!0.27!| 0.00 | - | 0 B | - // PixelOperations_Base | Core | 2048 | 7,015.00 ns | 920.083 ns | 51.9864 ns | 1.67 | 0.02 | - | 24 B | - // PixelOperations_Specialized | Core | 2048 | 1,176.59 ns | 256.955 ns | 14.5184 ns | !!0.28!| 0.00 | - | 0 B | + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ---------------------------- |-------- |------ |------------:|-------------:|------------:|-------:|---------:|-------:|----------:| + // FallbackIntrinsics128 | Clr | 64 | 287.62 ns | 6.026 ns | 0.3405 ns | 1.19 | 0.00 | - | 0 B | + // BasicIntrinsics256 | Clr | 64 | 240.83 ns | 10.585 ns | 0.5981 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Clr | 64 | 168.28 ns | 11.478 ns | 0.6485 ns | 0.70 | 0.00 | - | 0 B | + // PixelOperations_Base | Clr | 64 | 334.08 ns | 38.048 ns | 2.1498 ns | 1.39 | 0.01 | 0.0072 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 255.41 ns | 10.939 ns | 0.6181 ns | 1.06 | 0.00 | - | 0 B | <--- ceremonial overhead has been minimized! + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 64 | 183.29 ns | 8.931 ns | 0.5046 ns | 1.32 | 0.00 | - | 0 B | + // BasicIntrinsics256 | Core | 64 | 139.18 ns | 7.633 ns | 0.4313 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Core | 64 | 66.29 ns | 16.366 ns | 0.9247 ns | 0.48 | 0.01 | - | 0 B | + // PixelOperations_Base | Core | 64 | 257.75 ns | 16.959 ns | 0.9582 ns | 1.85 | 0.01 | 0.0072 | 24 B | + // PixelOperations_Specialized | Core | 64 | 90.14 ns | 9.955 ns | 0.5625 ns | 0.65 | 0.00 | - | 0 B | + // | | | | | | | | | | + // FallbackIntrinsics128 | Clr | 2048 | 5,011.84 ns | 347.991 ns | 19.6621 ns | 1.22 | 0.01 | - | 0 B | + // BasicIntrinsics256 | Clr | 2048 | 4,119.35 ns | 720.153 ns | 40.6900 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Clr | 2048 | 1,195.29 ns | 164.389 ns | 9.2883 ns |!! 0.29 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Clr | 2048 | 6,820.58 ns | 823.433 ns | 46.5255 ns | 1.66 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Clr | 2048 | 4,203.53 ns | 176.714 ns | 9.9847 ns | 1.02 | 0.01 | - | 0 B | <--- can't yet detect whether ExtendedIntrinsics are available :( + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 2048 | 5,017.89 ns | 4,021.533 ns | 227.2241 ns | 1.24 | 0.05 | - | 0 B | + // BasicIntrinsics256 | Core | 2048 | 4,046.51 ns | 1,150.390 ns | 64.9992 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Core | 2048 | 1,130.59 ns | 832.588 ns | 47.0427 ns |!! 0.28 | 0.01 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Core | 2048 | 6,752.68 ns | 272.820 ns | 15.4148 ns | 1.67 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 1,126.13 ns | 79.192 ns | 4.4745 ns |!! 0.28 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Abs.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs similarity index 88% rename from tests/ImageSharp.Benchmarks/General/Abs.cs rename to tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs index a67f3f107..ea53959b6 100644 --- a/tests/ImageSharp.Benchmarks/General/Abs.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs @@ -1,9 +1,9 @@ -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using System; +using System; - using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes; +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath +{ public class Abs { [Params(-1, 1)] diff --git a/tests/ImageSharp.Benchmarks/General/Clamp.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs similarity index 94% rename from tests/ImageSharp.Benchmarks/General/Clamp.cs rename to tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs index ef6bc3c40..d486cb2f3 100644 --- a/tests/ImageSharp.Benchmarks/General/Clamp.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs @@ -3,13 +3,13 @@ // Licensed under the Apache License, Version 2.0. // -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using System; - using System.Runtime.CompilerServices; +using System; +using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes; +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath +{ public class Clamp { [Params(-1, 0, 255, 256)] diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs new file mode 100644 index 000000000..9ddfad722 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs @@ -0,0 +1,23 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Jobs; + +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath +{ + [LongRunJob] + public class ModuloPowerOfTwoConstant + { + private readonly int value = 42; + + [Benchmark(Baseline = true)] + public int Standard() + { + return this.value % 8; + } + + [Benchmark] + public int Bitwise() + { + return ImageMaths.Modulo8(this.value); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs new file mode 100644 index 000000000..5c2fe81fa --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs @@ -0,0 +1,32 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Jobs; + +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath +{ + [LongRunJob] + public class ModuloPowerOfTwoVariable + { + private readonly int value = 42; + + private readonly int m = 32; + + [Benchmark(Baseline = true)] + public int Standard() + { + return this.value % this.m; + } + + [Benchmark] + public int Bitwise() + { + return ImageMaths.ModuloP2(this.value, this.m); + } + + // RESULTS: + // + // Method | Mean | Error | StdDev | Median | Scaled | ScaledSD | + // --------- |----------:|----------:|----------:|----------:|-------:|---------:| + // Standard | 1.2465 ns | 0.0093 ns | 0.0455 ns | 1.2423 ns | 1.00 | 0.00 | + // Bitwise | 0.0265 ns | 0.0103 ns | 0.0515 ns | 0.0000 ns | 0.02 | 0.04 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Pow.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs similarity index 93% rename from tests/ImageSharp.Benchmarks/General/Pow.cs rename to tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs index 325bd9d20..0f256fc78 100644 --- a/tests/ImageSharp.Benchmarks/General/Pow.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs @@ -1,7 +1,8 @@ using System; + using BenchmarkDotNet.Attributes; -namespace SixLabors.ImageSharp.Benchmarks.General +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath { public class Pow { diff --git a/tests/ImageSharp.Benchmarks/General/Modulus.cs b/tests/ImageSharp.Benchmarks/General/Modulus.cs deleted file mode 100644 index e6d5ccce6..000000000 --- a/tests/ImageSharp.Benchmarks/General/Modulus.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace SixLabors.ImageSharp.Benchmarks.General -{ - using BenchmarkDotNet.Attributes; - - public class Modulus - { - [Benchmark(Baseline = true, Description = "Standard Modulus using %")] - public int StandardModulus() - { - return 255 % 256; - } - - [Benchmark(Description = "Bitwise Modulus using &")] - public int BitwiseModulus() - { - return 255 & 255; - } - } -} diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index feefd1758..c63cb3438 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -264,13 +264,26 @@ namespace SixLabors.ImageSharp.Tests.Common TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, (s, d) => SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span) ); + + // for small values, let's stress test the implementation a bit: + if (count > 0 && count < 10) + { + for (int i = 0; i < 20; i++) + { + TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( + count, + (s, d) => SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span), + i + 42); + } + } } private static void TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( int count, - Action, Memory> convert) + Action, Memory> convert, int seed = -1) { - float[] source = new Random(count).GenerateRandomFloatArray(count, -0.1f, 1.2f); + seed = seed > 0 ? seed : count; + float[] source = new Random(seed).GenerateRandomFloatArray(count, -0.2f, 1.2f); byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); byte[] actual = new byte[count]; diff --git a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs index aec4d0b81..d8b1525be 100644 --- a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs @@ -10,56 +10,70 @@ namespace SixLabors.ImageSharp.Tests.Helpers public class ImageMathsTests { [Theory] - [InlineData(0, 0)] - [InlineData(1, 1)] - [InlineData(2, 2)] - [InlineData(3, 3)] - [InlineData(4, 0)] - [InlineData(100, 0)] - [InlineData(123, 3)] - [InlineData(53436353, 1)] - public void Modulo4(int a, int expected) + [InlineData(0)] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + [InlineData(4)] + [InlineData(100)] + [InlineData(123)] + [InlineData(53436353)] + public void Modulo4(int x) { - int actual = ImageMaths.Modulo4(a); - Assert.Equal(expected, actual); + int actual = ImageMaths.Modulo4(x); + Assert.Equal(x % 4, actual); } [Theory] - [InlineData(0, 0)] - [InlineData(1, 1)] + [InlineData(0)] + [InlineData(1)] + [InlineData(2)] + [InlineData(6)] + [InlineData(7)] + [InlineData(8)] + [InlineData(100)] + [InlineData(123)] + [InlineData(53436353)] + [InlineData(975)] + public void Modulo8(int x) + { + int actual = ImageMaths.Modulo8(x); + Assert.Equal(x % 8, actual); + } + + [Theory] + [InlineData(0, 2)] + [InlineData(1, 2)] [InlineData(2, 2)] - [InlineData(6, 6)] - [InlineData(7, 7)] - [InlineData(8, 0)] - [InlineData(100, 4)] - [InlineData(123, 3)] - [InlineData(53436353, 1)] - [InlineData(975, 7)] - public void Modulo8(int a, int expected) + [InlineData(0, 4)] + [InlineData(3, 4)] + [InlineData(5, 4)] + [InlineData(5, 8)] + [InlineData(8, 8)] + [InlineData(8, 16)] + [InlineData(15, 16)] + [InlineData(17, 16)] + [InlineData(17, 32)] + [InlineData(31, 32)] + [InlineData(32, 32)] + [InlineData(33, 32)] + public void Modulo2P(int x, int m) { - int actual = ImageMaths.Modulo8(a); - Assert.Equal(expected, actual); + int actual = ImageMaths.ModuloP2(x, m); + Assert.Equal(x % m, actual); } [Theory] - [InlineData(0, 2, 0)] - [InlineData(1, 2, 1)] - [InlineData(2, 2, 0)] - [InlineData(0, 4, 0)] - [InlineData(3, 4, 3)] - [InlineData(5, 4, 1)] - [InlineData(5, 8, 5)] - [InlineData(8, 8, 0)] - [InlineData(8, 16, 8)] - [InlineData(15, 16, 15)] - [InlineData(17, 16, 1)] - [InlineData(17, 32, 17)] - [InlineData(31, 32, 31)] - [InlineData(32, 32, 0)] - [InlineData(33, 32, 1)] - public void Modulo2P(int a, int m, int expected) + [InlineData(0, 0, 0, 0)] + [InlineData(0.5f, 0, 1, 0.5f)] + [InlineData(-0.5f, -0.1f, 10, -0.1f)] + [InlineData(-0.05f, -0.1f, 10, -0.05f)] + [InlineData(9.9f, -0.1f, 10, 9.9f)] + [InlineData(10f, -0.1f, 10, 10f)] + [InlineData(10.1f, -0.1f, 10, 10f)] + public void Clamp(float x, float min, float max, float expected) { - int actual = ImageMaths.ModuloP2(a, m); + float actual = ImageMaths.Clamp(x, min, max); Assert.Equal(expected, actual); } From 54dcbe4542577f6e89b500264a14b57195eb3640 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 21:09:40 +0200 Subject: [PATCH 041/238] fix comment --- .../Common/Helpers/SimdUtils.FallbackIntrinsics128.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs index 2d9f53eaf..ab18a0067 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp s *= maxBytes; s += half; - // I'm not sure if Clamp() is properly implemented with intrinsics. + // I'm not sure if Vector4.Clamp() is properly implemented with intrinsics. s = Vector4.Max(Vector4.Zero, s); s = Vector4.Min(maxBytes, s); From 8c1dbfac40edaeef96e0a75a1e5bcfdc05c61cea Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 21 Oct 2018 23:38:12 +0200 Subject: [PATCH 042/238] address review findings + some more cleanup --- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 28 ++++++++----------- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 14 +++------- .../SimdUtils.FallbackIntrinsics128.cs | 14 +++------- src/ImageSharp/Common/Helpers/SimdUtils.cs | 22 ++++++++++++++- src/ImageSharp/Common/Tuples/Octet.cs | 13 +++++++-- src/ImageSharp/Common/Tuples/Vector4Pair.cs | 10 +++---- .../JpegColorConverter.FromYCbCrSimd.cs | 2 +- .../JpegColorConverter.FromYCbCrSimdAvx2.cs | 2 +- .../ColorConverters/JpegColorConverter.cs | 4 +-- .../PixelFormats/PixelOperations{TPixel}.cs | 10 +++---- 10 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs index 713d606e7..0f1ce2ab6 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); if (!IsAvailable) { @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); if (!IsAvailable) { @@ -78,16 +78,15 @@ namespace SixLabors.ImageSharp /// /// SIMD optimized implementation for . - /// Works only with `dest.Length` divisible by 8. + /// Works only with span Length divisible by 8. /// Implementation adapted from: /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions /// http://stackoverflow.com/a/536278 /// internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertByteToNormalizedFloat)); - - DebugGuard.IsTrue(ImageMaths.Modulo8(dest.Length) == 0, nameof(source), "dest.Length should be divisable by 8!"); + VerifyIsAvx2Compatible(nameof(BulkConvertByteToNormalizedFloat)); + VerifySpanInput(source, dest, 8); var bVec = new Vector(256.0f / 255.0f); var magicFloat = new Vector(32768.0f); @@ -128,9 +127,8 @@ namespace SixLabors.ImageSharp /// internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); - - DebugGuard.IsTrue(ImageMaths.Modulo8(source.Length) == 0, nameof(source), "source.Length should be divisible by 8!"); + VerifyIsAvx2Compatible(nameof(BulkConvertNormalizedFloatToByteClampOverflows)); + VerifySpanInput(source, dest, 8); if (source.Length == 0) { @@ -168,9 +166,9 @@ namespace SixLabors.ImageSharp } /// - /// Convert 'source.Length' values normalized into [0..1] from 'source' + /// Convert all values normalized into [0..1] from 'source' /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. - /// The implementation is SIMD optimized and works only with `source.Length` divisible by 8. + /// This implementation is SIMD optimized and works only when span Length is divisible by 8. /// Based on: /// /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions @@ -178,12 +176,8 @@ namespace SixLabors.ImageSharp /// internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) { - GuardAvx2(nameof(BulkConvertNormalizedFloatToByte)); - - DebugGuard.IsTrue( - ImageMaths.Modulo8(source.Length) == 0, - nameof(source), - "source.Length should be divisible by 8!"); + VerifyIsAvx2Compatible(nameof(BulkConvertNormalizedFloatToByte)); + VerifySpanInput(source, dest, 8); if (source.Length == 0) { diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index dfa6f189c..e0d6187dc 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); if (!IsAvailable) { @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); if (!IsAvailable) { @@ -88,10 +88,7 @@ namespace SixLabors.ImageSharp /// internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue( - ImageMaths.ModuloP2(dest.Length, Vector.Count) == 0, - nameof(source), - "dest.Length should be divisible by Vector.Count!"); + VerifySpanInput(source, dest, Vector.Count); int n = dest.Length / Vector.Count; @@ -126,10 +123,7 @@ namespace SixLabors.ImageSharp ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue( - ImageMaths.ModuloP2(dest.Length, Vector.Count) == 0, - nameof(dest), - "dest.Length should be divisible by Vector.Count!"); + VerifySpanInput(source, dest, Vector.Count); int n = dest.Length / Vector.Count; diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs index ab18a0067..565ea08f5 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); int remainder = ImageMaths.Modulo4(source.Length); int adjustedCount = source.Length - remainder; @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp ref ReadOnlySpan source, ref Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); int remainder = ImageMaths.Modulo4(source.Length); int adjustedCount = source.Length - remainder; @@ -72,10 +72,7 @@ namespace SixLabors.ImageSharp [MethodImpl(InliningOptions.ColdPath)] internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue( - ImageMaths.Modulo4(dest.Length) == 0, - nameof(dest), - "dest.Length should be divisible by 4!"); + VerifySpanInput(source, dest, 4); int count = dest.Length / 4; if (count == 0) @@ -109,10 +106,7 @@ namespace SixLabors.ImageSharp ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue( - ImageMaths.Modulo4(source.Length) == 0, - nameof(source), - "source.Length should be divisible by 4!"); + VerifySpanInput(source, dest, 4); int count = source.Length / 4; if (count == 0) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 95a6030fd..fade8da79 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -154,12 +154,32 @@ namespace SixLabors.ImageSharp private static byte ConvertToByte(float f) => (byte)ImageMaths.Clamp((f * 255f) + 0.5f, 0, 255f); [Conditional("DEBUG")] - private static void GuardAvx2(string operation) + private static void VerifyIsAvx2Compatible(string operation) { if (!IsAvx2CompatibleArchitecture) { throw new NotSupportedException($"{operation} is supported only on AVX2 CPU!"); } } + + [Conditional("DEBUG")] + private static void VerifySpanInput(ReadOnlySpan source, Span dest, int shouldBeDivisibleBy) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); + DebugGuard.IsTrue( + ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0, + nameof(source), + $"length should be divisable by {shouldBeDivisibleBy}!"); + } + + [Conditional("DEBUG")] + private static void VerifySpanInput(ReadOnlySpan source, Span dest, int shouldBeDivisibleBy) + { + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); + DebugGuard.IsTrue( + ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0, + nameof(source), + $"length should be divisable by {shouldBeDivisibleBy}!"); + } } } \ No newline at end of file diff --git a/src/ImageSharp/Common/Tuples/Octet.cs b/src/ImageSharp/Common/Tuples/Octet.cs index ae01a3121..539b74e32 100644 --- a/src/ImageSharp/Common/Tuples/Octet.cs +++ b/src/ImageSharp/Common/Tuples/Octet.cs @@ -3,8 +3,14 @@ using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Tuples { + /// + /// Contains 8 element value tuples of various types. + /// internal static class Octet { + /// + /// Value tuple of -s + /// [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(uint))] public struct OfUInt32 { @@ -34,7 +40,7 @@ namespace SixLabors.ImageSharp.Tuples public override string ToString() { - return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; + return $"{nameof(Octet)}.{nameof(OfUInt32)}({this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7})"; } [MethodImpl(InliningOptions.ShortMethod)] @@ -51,6 +57,9 @@ namespace SixLabors.ImageSharp.Tuples } } + /// + /// Value tuple of -s + /// [StructLayout(LayoutKind.Explicit, Size = 8)] public struct OfByte { @@ -80,7 +89,7 @@ namespace SixLabors.ImageSharp.Tuples public override string ToString() { - return $"[{this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7}]"; + return $"{nameof(Octet)}.{nameof(OfByte)}({this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7})"; } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Common/Tuples/Vector4Pair.cs b/src/ImageSharp/Common/Tuples/Vector4Pair.cs index 5988b2200..cae283d62 100644 --- a/src/ImageSharp/Common/Tuples/Vector4Pair.cs +++ b/src/ImageSharp/Common/Tuples/Vector4Pair.cs @@ -7,6 +7,7 @@ namespace SixLabors.ImageSharp.Tuples /// /// Its faster to process multiple Vector4-s together, so let's pair them! /// On AVX2 this pair should be convertible to of ! + /// TODO: Investigate defining this as union with an Octet.OfSingle type. /// [StructLayout(LayoutKind.Sequential)] internal struct Vector4Pair @@ -15,8 +16,6 @@ namespace SixLabors.ImageSharp.Tuples public Vector4 B; - private static readonly Vector4 Scale = new Vector4(1 / 255f); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void MultiplyInplace(float value) { @@ -52,8 +51,9 @@ namespace SixLabors.ImageSharp.Tuples b = b.FastRound(); // Downscale by 1/255 - this.A *= Scale; - this.B *= Scale; + var scale = new Vector4(1 / 255f); + this.A *= scale; + this.B *= scale; } /// @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Tuples public override string ToString() { - return $"{this.A}, {this.B}"; + return $"{nameof(Vector4Pair)}({this.A}, {this.B})"; } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs index 5c63a478d..1dc72aaf5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs @@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters // Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order: ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i); - destination.Collect(ref r, ref g, ref b); + destination.Pack(ref r, ref g, ref b); } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs index 3f26cdc90..46644258b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters // Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order: ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i); - destination.Collect(ref rr, ref gg, ref bb); + destination.Pack(ref rr, ref gg, ref bb); } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs index 293f3bc1f..456636dc3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs @@ -157,9 +157,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters public Vector4 V0, V1, V2, V3, V4, V5, V6, V7; /// - /// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order. + /// Pack (r0,r1...r7) (g0,g1...g7) (b0,b1...b7) vector values as (r0,g0,b0,1), (r1,g1,b1,1) ... /// - public void Collect(ref Vector4Pair r, ref Vector4Pair g, ref Vector4Pair b) + public void Pack(ref Vector4Pair r, ref Vector4Pair g, ref Vector4Pair b) { this.V0.X = r.A.X; this.V0.Y = g.A.X; diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index cbf164a71..6c133191a 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -30,11 +30,10 @@ namespace SixLabors.ImageSharp.PixelFormats internal virtual void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { ReadOnlySpan sourceVectors1 = sourceVectors; - Span destinationColors1 = destinationColors; - GuardSpans(sourceVectors1, nameof(sourceVectors1), destinationColors1, nameof(destinationColors1), count); + GuardSpans(sourceVectors1, nameof(sourceVectors1), destinationColors, nameof(destinationColors), count); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors1); - ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors1); + ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); for (int i = 0; i < count; i++) { @@ -53,11 +52,10 @@ namespace SixLabors.ImageSharp.PixelFormats internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { ReadOnlySpan sourceColors1 = sourceColors; - Span destinationVectors1 = destinationVectors; - GuardSpans(sourceColors1, nameof(sourceColors1), destinationVectors1, nameof(destinationVectors1), count); + GuardSpans(sourceColors1, nameof(sourceColors1), destinationVectors, nameof(destinationVectors), count); ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors1); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors1); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); for (int i = 0; i < count; i++) { From 813e743abc9cdad3dfa0f2eb549e6ea2bfeec621 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 00:03:12 +0200 Subject: [PATCH 043/238] drop slow Clamp() implementation --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 3 - src/ImageSharp/Common/Helpers/SimdUtils.cs | 6 +- .../General/BasicMath/ClampFloat.cs | 70 +++++++++++++++++++ .../{Clamp.cs => ClampInt32IntoByte.cs} | 2 +- .../Helpers/ImageMathsTests.cs | 2 +- 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs rename tests/ImageSharp.Benchmarks/General/BasicMath/{Clamp.cs => ClampInt32IntoByte.cs} (98%) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 1395975ec..02a2e9ee5 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -61,9 +61,6 @@ namespace SixLabors.ImageSharp return x & (m - 1); } - [MethodImpl(InliningOptions.ShortMethod)] - public static float Clamp(float x, float min, float max) => Math.Min(max, Math.Max(min, x)); - /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index fade8da79..737e62006 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); #if NETCOREAPP2_1 ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); @@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp [MethodImpl(InliningOptions.ShortMethod)] internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan source, Span dest) { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same size!"); + DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); #if NETCOREAPP2_1 ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp } [MethodImpl(InliningOptions.ShortMethod)] - private static byte ConvertToByte(float f) => (byte)ImageMaths.Clamp((f * 255f) + 0.5f, 0, 255f); + private static byte ConvertToByte(float f) => (byte)ComparableExtensions.Clamp((f * 255f) + 0.5f, 0, 255f); [Conditional("DEBUG")] private static void VerifyIsAvx2Compatible(string operation) diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs new file mode 100644 index 000000000..3b7dea095 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs @@ -0,0 +1,70 @@ +using System; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; + +namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath +{ + public class ClampFloat + { + private readonly float min = -1.5f; + private readonly float max = 2.5f; + private static readonly float[] Values = { -10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10 }; + + [Benchmark(Baseline = true)] + public float UsingMathF() + { + float acc = 0; + + for (int i = 0; i < Values.Length; i++) + { + acc += ClampUsingMathF(Values[i], this.min, this.max); + } + + return acc; + } + + [Benchmark] + public float UsingBranching() + { + float acc = 0; + + for (int i = 0; i < Values.Length; i++) + { + acc += ClampUsingBranching(Values[i], this.min, this.max); + } + + return acc; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float ClampUsingMathF(float x, float min, float max) + { + return Math.Min(max, Math.Max(min, x)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float ClampUsingBranching(float x, float min, float max) + { + if (x >= max) + { + return max; + } + + if (x <= min) + { + return min; + } + + return x; + } + + // RESULTS: + // Method | Mean | Error | StdDev | Scaled | + // --------------- |---------:|----------:|----------:|-------:| + // UsingMathF | 30.37 ns | 0.3764 ns | 0.3337 ns | 1.00 | + // UsingBranching | 18.66 ns | 0.1043 ns | 0.0871 ns | 0.61 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs similarity index 98% rename from tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs rename to tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs index d486cb2f3..6ce82ba11 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/Clamp.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs @@ -10,7 +10,7 @@ using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath { - public class Clamp + public class ClampInt32IntoByte { [Params(-1, 0, 255, 256)] public int Value { get; set; } diff --git a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs index d8b1525be..75ef611a5 100644 --- a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Tests.Helpers [InlineData(10.1f, -0.1f, 10, 10f)] public void Clamp(float x, float min, float max, float expected) { - float actual = ImageMaths.Clamp(x, min, max); + float actual = x.Clamp(min, max); Assert.Equal(expected, actual); } From 1ec9f41eb7888e1d983d8887aa0f19fa1a17764c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 00:05:47 +0200 Subject: [PATCH 044/238] remove useless reassignment in PixelOperations{TPixel} --- src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 6c133191a..b12a2bfa5 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -29,10 +29,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - ReadOnlySpan sourceVectors1 = sourceVectors; - GuardSpans(sourceVectors1, nameof(sourceVectors1), destinationColors, nameof(destinationColors), count); + GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors1); + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); for (int i = 0; i < count; i++) @@ -51,10 +50,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { - ReadOnlySpan sourceColors1 = sourceColors; - GuardSpans(sourceColors1, nameof(sourceColors1), destinationVectors, nameof(destinationVectors), count); + GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors1); + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); for (int i = 0; i < count; i++) From 989f79c826cf738db691006ef43552a14016a43f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 00:47:23 +0200 Subject: [PATCH 045/238] fix PixelOperationsTests --- .../PixelFormats/PixelOperationsTests.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 651e63bdf..8a0aee1a7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -15,15 +15,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { public class PixelOperationsTests { - public class Argb32OperationsTests : PixelOperationsTests - { - public const string SkipProfilingBenchmarks = + public const string SkipProfilingBenchmarks = #if true - "Profiling benchmark - enable manually!"; + "Profiling benchmark - enable manually!"; #else null; #endif + public class Argb32OperationsTests : PixelOperationsTests + { + + public Argb32OperationsTests(ITestOutputHelper output) : base(output) { } @@ -39,8 +41,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } @@ -52,8 +52,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } @@ -65,8 +63,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); @@ -163,8 +159,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); @@ -261,11 +255,10 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + [Fact(Skip = SkipProfilingBenchmarks)] public void Benchmark_ToVector4() { const int times = 200000; @@ -288,8 +281,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } @@ -301,8 +292,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { } - public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - [Fact] public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } From 9dbf074a999c653fada984c4bdbdc85bbe907a7b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 01:28:23 +0200 Subject: [PATCH 046/238] Better benchmarks for ToVector4() proving that the current API is fine --- .../PixelConversion/PixelConversion_ConvertToVector4.cs | 8 ++++---- ...ersion_ConvertToVector4_AsPartOfCompositeOperation.cs | 8 ++++---- .../General/PixelConversion/TestRgba.cs | 9 ++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs index 29a113991..2bc3ee971 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs @@ -75,9 +75,9 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | - // ---------- |------ |---------:|----------:|----------:|-------:| - // UseRetval | 32 | 94.99 ns | 1.1199 ns | 0.9352 ns | 1.00 | - // UseCopyTo | 32 | 59.47 ns | 0.6104 ns | 0.5710 ns | 0.63 | + // Method | Count | Mean | Error | StdDev | Scaled | + // ---------- |------ |---------:|---------:|---------:|-------:| + // UseRetval | 32 | 109.0 ns | 1.202 ns | 1.125 ns | 1.00 | + // UseCopyTo | 32 | 108.6 ns | 1.151 ns | 1.020 ns | 1.00 | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs index e5eb5c6ca..c6daf0f1e 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs @@ -87,9 +87,9 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | - // ---------- |------ |----------:|----------:|----------:|-------:| - // UseRetval | 32 | 100.35 ns | 0.4844 ns | 0.4532 ns | 1.00 | - // UseCopyTo | 32 | 53.95 ns | 0.1269 ns | 0.1125 ns | 0.54 | + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ---------- |------ |---------:|---------:|---------:|-------:|---------:| + // UseRetval | 32 | 120.2 ns | 1.560 ns | 1.383 ns | 1.00 | 0.00 | + // UseCopyTo | 32 | 121.7 ns | 2.439 ns | 2.281 ns | 1.01 | 0.02 | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs index 3da7fcc4c..cc8cf352a 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -57,16 +57,15 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() { - return new Vector4(this.r, this.g, this.b, this.a); + return new Vector4(this.r, this.g, this.b, this.a) * new Vector4(1f / 255f); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyToVector4(ref Vector4 dest) { - dest.X = this.r; - dest.Y = this.g; - dest.Z = this.b; - dest.W = this.a; + var tmp = new Vector4(this.r, this.g, this.b, this.a); + tmp *= new Vector4(1f / 255f); + dest = tmp; } } } \ No newline at end of file From 7caf6642f45cbcdfadb2e185e4b312af3cb09bb3 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 01:45:21 +0200 Subject: [PATCH 047/238] refactored ToRgba32() on most pixel types --- src/ImageSharp/PixelFormats/Alpha8.cs | 6 +- src/ImageSharp/PixelFormats/Argb32.cs | 8 +- src/ImageSharp/PixelFormats/Bgr24.cs | 8 +- src/ImageSharp/PixelFormats/Bgr565.cs | 5 +- src/ImageSharp/PixelFormats/Bgra32.cs | 8 +- src/ImageSharp/PixelFormats/Bgra4444.cs | 5 +- src/ImageSharp/PixelFormats/Bgra5551.cs | 5 +- src/ImageSharp/PixelFormats/Byte4.cs | 5 +- src/ImageSharp/PixelFormats/HalfSingle.cs | 5 +- src/ImageSharp/PixelFormats/HalfVector2.cs | 5 +- src/ImageSharp/PixelFormats/HalfVector4.cs | 5 +- src/ImageSharp/PixelFormats/IPixel.cs | 18 +++- .../PixelFormats/NormalizedByte2.cs | 5 +- .../PixelFormats/NormalizedByte4.cs | 5 +- .../PixelFormats/NormalizedShort2.cs | 5 +- .../PixelFormats/NormalizedShort4.cs | 5 +- .../PixelFormats/PixelBlender{TPixel}.cs | 84 +++++++++---------- src/ImageSharp/PixelFormats/Rg32.cs | 5 +- src/ImageSharp/PixelFormats/Rgba1010102.cs | 5 +- src/ImageSharp/PixelFormats/RgbaVector.cs | 5 +- src/ImageSharp/PixelFormats/Short2.cs | 5 +- src/ImageSharp/PixelFormats/Short4.cs | 5 +- 22 files changed, 148 insertions(+), 64 deletions(-) diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 1e724768d..730734f5f 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -105,7 +105,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(0, 0, 0, this.PackedValue); + public void ToRgba32(ref Rgba32 dest) + { + dest = default; + dest.A = this.PackedValue; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 1e3bd9326..a47d7e8e7 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -250,7 +250,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = this.A; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index ed65bebf7..8eba08bea 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -151,7 +151,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, byte.MaxValue); + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = byte.MaxValue; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 04af6ef0f..295f1ca0a 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -113,7 +113,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 9b0ed4f96..5d70c9e50 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -206,7 +206,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = this.A; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index db1c8f865..29ea63e20 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -116,7 +116,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 5d9003cdd..f6dbb7811 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -117,7 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index 230c31c5c..96eeeec0d 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -117,7 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index bef4a5dd9..a1811e147 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -106,7 +106,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index 5bd9924c5..381650aec 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -117,7 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 2e487ef98..b7d6687ea 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -125,7 +125,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 87125fa0a..c0bcfa459 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -100,8 +100,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Expands the packed representation into an . /// - /// The . - Rgba32 ToRgba32(); + /// The reference to the destination pixel + void ToRgba32(ref Rgba32 dest); /// /// Packs the pixel from an value. @@ -115,4 +115,18 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromRgba64(Rgba64 source); } + + /// + /// Temporary extension methods for compatibility + /// + internal static class PixelExtensions + { + public static Rgba32 ToRgba32(this TPixel pixel) + where TPixel : struct, IPixel + { + Rgba32 result = default; + pixel.ToRgba32(ref result); + return result; + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 219ec8763..9999cfe03 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -107,7 +107,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index d5795cb4b..5f9124bdc 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -128,7 +128,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 34e752496..0cd8d9408 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -123,7 +123,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 6fda84bc2..21aac4d24 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -130,7 +130,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index 63a101656..cca4a1017 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -1,31 +1,31 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Buffers; using System.Numerics; using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; - -namespace SixLabors.ImageSharp.PixelFormats -{ - /// - /// Abstract base class for calling pixel composition functions - /// - /// The type of the pixel - internal abstract class PixelBlender - where TPixel : struct, IPixel - { - /// - /// Blend 2 pixels together. - /// - /// The background color. - /// The source color. - /// - /// A value between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. - /// - /// The final pixel value after composition +using SixLabors.Memory; + +namespace SixLabors.ImageSharp.PixelFormats +{ + /// + /// Abstract base class for calling pixel composition functions + /// + /// The type of the pixel + internal abstract class PixelBlender + where TPixel : struct, IPixel + { + /// + /// Blend 2 pixels together. + /// + /// The background color. + /// The source color. + /// + /// A value between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// The final pixel value after composition public abstract TPixel Blend(TPixel background, TPixel source, float amount); /// @@ -34,9 +34,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// destination span /// the background span /// the source span - /// - /// A value between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// A value between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// protected abstract void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount); @@ -46,9 +46,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// destination span /// the background span /// the source span - /// - /// A span with values between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// A span with values between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// protected abstract void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount); @@ -59,9 +59,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// the destination span /// the background span /// the source span - /// - /// A span with values between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// A span with values between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) { @@ -76,9 +76,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// the destination span /// the background span /// the source span - /// - /// A span with values between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// A span with values between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) where TPixelSrc : struct, IPixel @@ -110,9 +110,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// the destination span /// the background span /// the source span - /// - /// A value between 0 and 1 indicating the weight of the second source vector. - /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// A value between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount) where TPixelSrc : struct, IPixel @@ -135,5 +135,5 @@ namespace SixLabors.ImageSharp.PixelFormats PixelOperations.Instance.PackFromScaledVector4(destinationSpan, destination, destination.Length); } } - } -} + } +} diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 0831f6524..878b2342f 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -111,7 +111,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 14265b54e..7f3e3a870 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -117,7 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index b2a3dc578..25b8155d3 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -152,7 +152,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 81df3ef7b..69a4e35e9 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -129,7 +129,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 48bd01d6e..653bc030f 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -134,7 +134,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void ToRgba32(ref Rgba32 dest) + { + dest.PackFromScaledVector4(this.ToScaledVector4()); + } /// [MethodImpl(InliningOptions.ShortMethod)] From 0b80b7fe0728cf4f189bfca36c5945f770df2349 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 01:58:12 +0200 Subject: [PATCH 048/238] refactor ToRgba32() on the rest --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 2 +- src/ImageSharp/PixelFormats/Gray16.cs | 7 +++++-- src/ImageSharp/PixelFormats/Gray8.cs | 8 +++++++- src/ImageSharp/PixelFormats/Rgb24.cs | 8 +++++++- src/ImageSharp/PixelFormats/Rgb48.cs | 10 +++++----- src/ImageSharp/PixelFormats/Rgba32.cs | 5 ++++- src/ImageSharp/PixelFormats/Rgba64.cs | 11 +++++------ 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 1dc740567..6c52eded5 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp /// /// Scales a value from a 16 bit to it's 8 bit equivalent. /// - /// The 8 bit compoonent value. + /// The 8 bit component value. /// The [MethodImpl(InliningOptions.ShortMethod)] public static byte DownScaleFrom16BitTo8Bit(ushort component) diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index 34f221d79..788278be4 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -136,10 +136,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() + public void ToRgba32(ref Rgba32 dest) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(this.PackedValue); - return new Rgba32(rgb, rgb, rgb, byte.MaxValue); + dest.R = rgb; + dest.G = rgb; + dest.B = rgb; + dest.A = byte.MaxValue; } /// diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index 581240587..8a9ec540d 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -108,7 +108,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.PackedValue, this.PackedValue, this.PackedValue, byte.MaxValue); + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.PackedValue; + dest.G = this.PackedValue; + dest.B = this.PackedValue; + dest.A = byte.MaxValue; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index a2b896605..0113027d6 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -165,7 +165,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, byte.MaxValue); + public void ToRgba32(ref Rgba32 dest) + { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = byte.MaxValue; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/Rgb48.cs index 7406fda42..815bf8c91 100644 --- a/src/ImageSharp/PixelFormats/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/Rgb48.cs @@ -165,12 +165,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() + public void ToRgba32(ref Rgba32 dest) { - byte r = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); - byte g = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); - byte b = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); - return new Rgba32(r, g, b, byte.MaxValue); + dest.R = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); + dest.G = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); + dest.B = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); + dest.A = byte.MaxValue; } /// diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index 415c39c0e..e866d1350 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -301,7 +301,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => this; + public void ToRgba32(ref Rgba32 dest) + { + dest = this; + } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 738c5e3dd..2d1a67670 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -197,13 +197,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() + public void ToRgba32(ref Rgba32 dest) { - byte r = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); - byte g = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); - byte b = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); - byte a = ImageMaths.DownScaleFrom16BitTo8Bit(this.A); - return new Rgba32(r, g, b, a); + dest.R = ImageMaths.DownScaleFrom16BitTo8Bit(this.R); + dest.G = ImageMaths.DownScaleFrom16BitTo8Bit(this.G); + dest.B = ImageMaths.DownScaleFrom16BitTo8Bit(this.B); + dest.A = ImageMaths.DownScaleFrom16BitTo8Bit(this.A); } /// From daf38f9e6d5713c24790d26fb6b41250bb86ae1b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 02:15:15 +0200 Subject: [PATCH 049/238] drop all PixelExtensions usages in product code, keep in test code for now. --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 7 ++++-- src/ImageSharp/PixelFormats/IPixel.cs | 14 ------------ .../PixelFormats/PixelExtensions.cs | 22 +++++++++++++++++++ .../BinaryErrorDiffusionProcessor.cs | 5 +++-- .../BinaryOrderedDitherProcessor.cs | 5 +++-- .../Binarization/BinaryThresholdProcessor.cs | 3 ++- .../ErrorDiffusionPaletteProcessor.cs | 5 +++-- .../OrderedDitherPaletteProcessor.cs | 5 +++-- .../OctreeFrameQuantizer{TPixel}.cs | 12 ++++++---- .../Quantization/WuFrameQuantizer{TPixel}.cs | 3 ++- .../Color/Bulk/ToXyzw.cs | 3 ++- .../Transforms/AffineTransformTests.cs | 3 ++- 12 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/PixelExtensions.cs diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 1e9dbc71a..cf7b7b2c6 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -386,9 +386,10 @@ namespace SixLabors.ImageSharp.Formats.Png { // 8 bit grayscale + alpha // TODO: Should we consider in the future a GrayAlpha16 type. + Rgba32 rgba = default; for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 2) { - var rgba = Unsafe.Add(ref rowSpanRef, x).ToRgba32(); + Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba); Unsafe.Add(ref rawScanlineSpanRef, o) = ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A; } @@ -645,12 +646,14 @@ namespace SixLabors.ImageSharp.Formats.Png ref byte alphaTableRef = ref MemoryMarshal.GetReference(alphaTable.GetSpan()); Span quantizedSpan = quantized.GetPixelSpan(); + Rgba32 rgba = default; + for (int i = 0; i < paletteLength; i++) { if (quantizedSpan.IndexOf((byte)i) > -1) { int offset = i * 3; - var rgba = palette[i].ToRgba32(); + palette[i].ToRgba32(ref rgba); byte alpha = rgba.A; diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index c0bcfa459..3a6fb0a78 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -115,18 +115,4 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromRgba64(Rgba64 source); } - - /// - /// Temporary extension methods for compatibility - /// - internal static class PixelExtensions - { - public static Rgba32 ToRgba32(this TPixel pixel) - where TPixel : struct, IPixel - { - Rgba32 result = default; - pixel.ToRgba32(ref result); - return result; - } - } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelExtensions.cs b/src/ImageSharp/PixelFormats/PixelExtensions.cs new file mode 100644 index 000000000..175696ab6 --- /dev/null +++ b/src/ImageSharp/PixelFormats/PixelExtensions.cs @@ -0,0 +1,22 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.PixelFormats +{ + /// + /// Low-performance extension methods to help conversion syntax, suitable for testing purposes. + /// + internal static class PixelExtensions + { + /// + /// Returns the result of as a new instance. + /// + public static Rgba32 ToRgba32(this TPixel pixel) + where TPixel : struct, IPixel + { + Rgba32 result = default; + pixel.ToRgba32(ref result); + return result; + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs index b338ff446..32cc2f434 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs @@ -88,7 +88,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // Collect the values before looping so we can reduce our calculation count for identical sibling pixels TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; - var rgba = sourcePixel.ToRgba32(); + Rgba32 rgba = default; + sourcePixel.ToRgba32(ref rgba); // Convert to grayscale using ITU-R Recommendation BT.709 if required byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); @@ -105,7 +106,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // rather than calculating it again. This is an inexpensive optimization. if (!previousPixel.Equals(sourcePixel)) { - rgba = sourcePixel.ToRgba32(); + sourcePixel.ToRgba32(ref rgba); luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs index 0b28a1574..cfdaf107c 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs @@ -67,7 +67,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // Collect the values before looping so we can reduce our calculation count for identical sibling pixels TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; - var rgba = sourcePixel.ToRgba32(); + Rgba32 rgba = default; + sourcePixel.ToRgba32(ref rgba); // Convert to grayscale using ITU-R Recommendation BT.709 if required byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); @@ -84,7 +85,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization // rather than calculating it again. This is an inexpensive optimization. if (!previousPixel.Equals(sourcePixel)) { - rgba = sourcePixel.ToRgba32(); + sourcePixel.ToRgba32(ref rgba); luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs index 03b7f73e9..67dcfc7f1 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs @@ -80,6 +80,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization configuration, rows => { + Rgba32 rgba = default; for (int y = rows.Min; y < rows.Max; y++) { Span row = source.GetPixelRowSpan(y); @@ -87,7 +88,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization for (int x = startX; x < endX; x++) { ref TPixel color = ref row[x]; - var rgba = color.ToRgba32(); + color.ToRgba32(ref rgba); // Convert to grayscale using ITU-R Recommendation BT.709 if required byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs index b60322799..911d3e8fd 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffusionPaletteProcessor.cs @@ -76,7 +76,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; PixelPair pair = this.GetClosestPixelPair(ref sourcePixel); - var rgba = sourcePixel.ToRgba32(); + Rgba32 rgba = default; + sourcePixel.ToRgba32(ref rgba); // Convert to grayscale using ITU-R Recommendation BT.709 if required byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); @@ -101,7 +102,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering continue; } - rgba = sourcePixel.ToRgba32(); + sourcePixel.ToRgba32(ref rgba); luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs index 149c7170a..1b4910a14 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDitherPaletteProcessor.cs @@ -53,7 +53,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering TPixel sourcePixel = source[startX, startY]; TPixel previousPixel = sourcePixel; PixelPair pair = this.GetClosestPixelPair(ref sourcePixel); - var rgba = sourcePixel.ToRgba32(); + Rgba32 rgba = default; + sourcePixel.ToRgba32(ref rgba); // Convert to grayscale using ITU-R Recommendation BT.709 if required byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); @@ -78,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering continue; } - rgba = sourcePixel.ToRgba32(); + sourcePixel.ToRgba32(ref rgba); luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); // Setup the previous pointer diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 552aa8af8..29742725a 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -154,7 +154,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization return this.GetClosestPixel(ref pixel); } - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); if (rgba.Equals(default)) { return this.transparentIndex; @@ -434,7 +435,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization { // Go to the next level down in the tree int shift = 7 - level; - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); int index = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) @@ -529,7 +531,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization if (!this.leaf) { int shift = 7 - level; - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) @@ -556,7 +559,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Increment(ref TPixel pixel) { - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); this.pixelCount++; this.red += rgba.R; this.green += rgba.G; diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index f3b5da320..4ef165960 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -879,7 +879,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } // Expected order r->g->b->a - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); int r = rgba.R >> (8 - IndexBits); int g = rgba.G >> (8 - IndexBits); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs index 740287e85..0cf7087d4 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs @@ -46,7 +46,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { TPixel c = s[i]; int i4 = i * 4; - var rgba = c.ToRgba32(); + Rgba32 rgba = default; + c.ToRgba32(ref rgba); d[i4] = rgba.R; d[i4 + 1] = rgba.G; d[i4 + 2] = rgba.B; diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index 17240839d..ae572498a 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -240,7 +240,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms var white = new Rgb24(255, 255, 255); foreach (TPixel pixel in data) { - var rgba = pixel.ToRgba32(); + Rgba32 rgba = default; + pixel.ToRgba32(ref rgba); if (rgba.A == 0) { continue; From 87d5bc96aa0acbc9a414a3d7676f3070864c7dc8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 02:18:28 +0200 Subject: [PATCH 050/238] wakeup message to the git status-checks --- tests/ImageSharp.Tests/Numerics/RationalTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Numerics/RationalTests.cs b/tests/ImageSharp.Tests/Numerics/RationalTests.cs index a9b9106c5..caddd4921 100644 --- a/tests/ImageSharp.Tests/Numerics/RationalTests.cs +++ b/tests/ImageSharp.Tests/Numerics/RationalTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.Primitives; using Xunit; From 618139292f290b287422d90ef994a5548dc945b2 Mon Sep 17 00:00:00 2001 From: Anton Firsov Date: Mon, 22 Oct 2018 02:25:15 +0200 Subject: [PATCH 051/238] Something's wrong with the status checks --- tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs b/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs index f092da708..950434ac3 100644 --- a/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs +++ b/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs @@ -2,7 +2,6 @@ using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; using Xunit; @@ -35,4 +34,4 @@ namespace SixLabors.ImageSharp.Tests.Helpers } } } -} \ No newline at end of file +} From d8bcd0cdaa434c6e66d7b2b1b2b37acc354f39e6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 12:46:16 +0200 Subject: [PATCH 052/238] fix typo --- src/ImageSharp/Common/Helpers/SimdUtils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 737e62006..71eb88b1d 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp // Deal with the remainder: if (source.Length > 0) { - ConverByteToNormalizedFloatRemainder(source, dest); + ConvertByteToNormalizedFloatRemainder(source, dest); } } @@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp } [MethodImpl(InliningOptions.ColdPath)] - private static void ConverByteToNormalizedFloatRemainder(ReadOnlySpan source, Span dest) + private static void ConvertByteToNormalizedFloatRemainder(ReadOnlySpan source, Span dest) { ref byte sBase = ref MemoryMarshal.GetReference(source); ref float dBase = ref MemoryMarshal.GetReference(dest); From ecece916fd22157ac3d2104d8e87681f43c6bc5f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 13:00:08 +0200 Subject: [PATCH 053/238] Move all specific IPixel implementations to a (non-namespace-provider) subfolder --- src/ImageSharp/ImageSharp.csproj | 40 +++++++++---------- src/ImageSharp/ImageSharp.csproj.DotSettings | 7 +++- src/ImageSharp/PixelFormats/ComponentOrder.cs | 31 -------------- .../{ => PixelImplementations}/Alpha8.cs | 0 .../{ => PixelImplementations}/Argb32.cs | 0 .../{ => PixelImplementations}/Bgr24.cs | 0 .../{ => PixelImplementations}/Bgr565.cs | 0 .../{ => PixelImplementations}/Bgra32.cs | 0 .../{ => PixelImplementations}/Bgra4444.cs | 0 .../{ => PixelImplementations}/Bgra5551.cs | 0 .../{ => PixelImplementations}/Byte4.cs | 0 .../Argb32.PixelOperations.Generated.cs | 0 .../Argb32.PixelOperations.Generated.tt | 0 .../Bgr24.PixelOperations.Generated.cs | 0 .../Bgr24.PixelOperations.Generated.tt | 0 .../Bgra32.PixelOperations.Generated.cs | 0 .../Bgra32.PixelOperations.Generated.tt | 0 .../Gray16.PixelOperations.Generated.cs | 0 .../Gray16.PixelOperations.Generated.tt | 0 .../Gray8.PixelOperations.Generated.cs | 0 .../Gray8.PixelOperations.Generated.tt | 0 .../Rgb24.PixelOperations.Generated.cs | 0 .../Rgb24.PixelOperations.Generated.tt | 0 .../Rgb48.PixelOperations.Generated.cs | 0 .../Rgb48.PixelOperations.Generated.tt | 0 .../Rgba32.PixelOperations.Generated.cs | 0 .../Rgba32.PixelOperations.Generated.tt | 0 .../Rgba64.PixelOperations.Generated.cs | 0 .../Rgba64.PixelOperations.Generated.tt | 0 .../{ => PixelImplementations}/Gray16.cs | 0 .../{ => PixelImplementations}/Gray8.cs | 0 .../{ => PixelImplementations}/HalfSingle.cs | 0 .../{ => PixelImplementations}/HalfVector2.cs | 0 .../{ => PixelImplementations}/HalfVector4.cs | 0 .../NormalizedByte2.cs | 0 .../NormalizedByte4.cs | 0 .../NormalizedShort2.cs | 0 .../NormalizedShort4.cs | 0 .../{ => PixelImplementations}/Rg32.cs | 0 .../{ => PixelImplementations}/Rgb24.cs | 0 .../{ => PixelImplementations}/Rgb48.cs | 0 .../{ => PixelImplementations}/Rgba1010102.cs | 0 .../Rgba32.Definitions.cs | 0 .../Rgba32.PixelOperations.cs | 0 .../{ => PixelImplementations}/Rgba32.cs | 0 .../{ => PixelImplementations}/Rgba64.cs | 0 .../RgbaVector.PixelOperations.cs | 0 .../{ => PixelImplementations}/RgbaVector.cs | 0 .../{ => PixelImplementations}/Short2.cs | 0 .../{ => PixelImplementations}/Short4.cs | 0 .../PixelOperations{TPixel}.Generated.cs | 0 .../PixelOperations{TPixel}.Generated.tt | 0 52 files changed, 26 insertions(+), 52 deletions(-) delete mode 100644 src/ImageSharp/PixelFormats/ComponentOrder.cs rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Alpha8.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Argb32.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Bgr24.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Bgr565.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Bgra32.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Bgra4444.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Bgra5551.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Byte4.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Argb32.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Argb32.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Bgr24.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Bgr24.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Bgra32.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Bgra32.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Gray16.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Gray16.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Gray8.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Gray8.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgb24.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgb24.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgb48.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgb48.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgba32.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgba32.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgba64.PixelOperations.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Generated/Rgba64.PixelOperations.Generated.tt (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Gray16.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Gray8.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/HalfSingle.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/HalfVector2.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/HalfVector4.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/NormalizedByte2.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/NormalizedByte4.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/NormalizedShort2.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/NormalizedShort4.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rg32.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgb24.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgb48.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgba1010102.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgba32.Definitions.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgba32.PixelOperations.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgba32.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Rgba64.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/RgbaVector.PixelOperations.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/RgbaVector.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Short2.cs (100%) rename src/ImageSharp/PixelFormats/{ => PixelImplementations}/Short4.cs (100%) rename src/ImageSharp/PixelFormats/{Generated => }/PixelOperations{TPixel}.Generated.cs (100%) rename src/ImageSharp/PixelFormats/{Generated => }/PixelOperations{TPixel}.Generated.tt (100%) diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 17e417dca..8d2ad2abe 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -72,43 +72,43 @@ TextTemplatingFileGenerator Block8x8F.Generated.cs - + TextTemplatingFileGenerator PixelOperations{TPixel}.Generated.cs - + TextTemplatingFileGenerator Argb32.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Bgr24.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Bgra32.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Gray8.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Gray16.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Rgb24.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Rgba32.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Rgb48.PixelOperations.Generated.cs - + TextTemplatingFileGenerator Rgba64.PixelOperations.Generated.cs @@ -137,52 +137,52 @@ True Block8x8F.Generated.tt - + True True PixelOperations{TPixel}.Generated.tt - + True True Argb32.PixelOperations.Generated.tt - + True True Bgr24.PixelOperations.Generated.tt - + True True Bgra32.PixelOperations.Generated.tt - + True True Gray8.PixelOperations.Generated.tt - + True True Gray16.PixelOperations.Generated.tt - + True True Rgb24.PixelOperations.Generated.tt - + True True Rgba32.PixelOperations.Generated.tt - + True True Rgb48.PixelOperations.Generated.tt - + True True Rgba64.PixelOperations.Generated.tt diff --git a/src/ImageSharp/ImageSharp.csproj.DotSettings b/src/ImageSharp/ImageSharp.csproj.DotSettings index 8b2e1bcf0..cd75f91b7 100644 --- a/src/ImageSharp/ImageSharp.csproj.DotSettings +++ b/src/ImageSharp/ImageSharp.csproj.DotSettings @@ -1,3 +1,8 @@  True - True \ No newline at end of file + True + True + True + True + True + True \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/ComponentOrder.cs b/src/ImageSharp/PixelFormats/ComponentOrder.cs deleted file mode 100644 index 868d08259..000000000 --- a/src/ImageSharp/PixelFormats/ComponentOrder.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.PixelFormats -{ - /// - /// Enumerates the various component orders. - /// - internal enum ComponentOrder - { - /// - /// Z-> Y-> X order. Equivalent to B-> G-> R in - /// - Zyx, - - /// - /// Z-> Y-> X-> W order. Equivalent to B-> G-> R-> A in - /// - Zyxw, - - /// - /// X-> Y-> Z order. Equivalent to R-> G-> B in - /// - Xyz, - - /// - /// X-> Y-> Z-> W order. Equivalent to R-> G-> B-> A in - /// - Xyzw, - } -} diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Alpha8.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Argb32.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Bgr24.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Bgr565.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Bgra32.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Bgra4444.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Bgra5551.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Byte4.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Gray16.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Gray8.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs similarity index 100% rename from src/ImageSharp/PixelFormats/HalfSingle.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs similarity index 100% rename from src/ImageSharp/PixelFormats/HalfVector2.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs similarity index 100% rename from src/ImageSharp/PixelFormats/HalfVector4.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs similarity index 100% rename from src/ImageSharp/PixelFormats/NormalizedByte2.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs similarity index 100% rename from src/ImageSharp/PixelFormats/NormalizedByte4.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs similarity index 100% rename from src/ImageSharp/PixelFormats/NormalizedShort2.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs similarity index 100% rename from src/ImageSharp/PixelFormats/NormalizedShort4.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rg32.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgb24.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgb48.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgba1010102.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs diff --git a/src/ImageSharp/PixelFormats/Rgba32.Definitions.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.Definitions.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgba32.Definitions.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.Definitions.cs diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgba32.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Rgba64.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs diff --git a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs similarity index 100% rename from src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs similarity index 100% rename from src/ImageSharp/PixelFormats/RgbaVector.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Short2.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Short4.cs rename to src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs rename to src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt similarity index 100% rename from src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt rename to src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt From c328f6d87deaabab4bb3d4096b180a6c863edfcb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 13:39:10 +0200 Subject: [PATCH 054/238] simplify IPixel method names: PackFrom*** -> From*** --- .../Processing/GradientBrushBase{TPixel}.cs | 2 +- .../Processing/RecolorBrush{TPixel}.cs | 4 +- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 6 +- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 4 +- .../Formats/Png/PngScanlineProcessor.cs | 52 ++--- .../PixelFormats/ColorBuilder{TPixel}.cs | 4 +- src/ImageSharp/PixelFormats/IPixel.cs | 22 +- .../DefaultPixelBlenders.Generated.cs | 216 +++++++++--------- .../PorterDuffFunctions.Generated.cs | 216 +++++++++--------- .../PixelImplementations/Alpha8.cs | 22 +- .../PixelImplementations/Argb32.cs | 22 +- .../PixelImplementations/Bgr24.cs | 26 +-- .../PixelImplementations/Bgr565.cs | 24 +- .../PixelImplementations/Bgra32.cs | 22 +- .../PixelImplementations/Bgra4444.cs | 24 +- .../PixelImplementations/Bgra5551.cs | 24 +- .../PixelImplementations/Byte4.cs | 24 +- .../Argb32.PixelOperations.Generated.cs | 16 +- .../Bgr24.PixelOperations.Generated.cs | 16 +- .../Bgra32.PixelOperations.Generated.cs | 16 +- .../Gray16.PixelOperations.Generated.cs | 16 +- .../Gray8.PixelOperations.Generated.cs | 16 +- .../Rgb24.PixelOperations.Generated.cs | 16 +- .../Rgb48.PixelOperations.Generated.cs | 16 +- .../Rgba32.PixelOperations.Generated.cs | 16 +- .../Rgba64.PixelOperations.Generated.cs | 16 +- .../PixelImplementations/Gray16.cs | 22 +- .../PixelImplementations/Gray8.cs | 22 +- .../PixelImplementations/HalfSingle.cs | 24 +- .../PixelImplementations/HalfVector2.cs | 24 +- .../PixelImplementations/HalfVector4.cs | 26 +-- .../PixelImplementations/NormalizedByte2.cs | 24 +- .../PixelImplementations/NormalizedByte4.cs | 26 +-- .../PixelImplementations/NormalizedShort2.cs | 24 +- .../PixelImplementations/NormalizedShort4.cs | 26 +-- .../PixelFormats/PixelImplementations/Rg32.cs | 24 +- .../PixelImplementations/Rgb24.cs | 24 +- .../PixelImplementations/Rgb48.cs | 22 +- .../PixelImplementations/Rgba1010102.cs | 24 +- .../PixelImplementations/Rgba32.cs | 24 +- .../PixelImplementations/Rgba64.cs | 22 +- .../PixelImplementations/RgbaVector.cs | 24 +- .../PixelImplementations/Short2.cs | 24 +- .../PixelImplementations/Short4.cs | 26 +-- .../PixelOperations{TPixel}.Generated.cs | 36 +-- .../PixelFormats/PixelOperations{TPixel}.cs | 10 +- .../EdgeDetectorCompassProcessor.cs | 2 +- .../Processors/Dithering/ErrorDiffuserBase.cs | 2 +- .../Effects/OilPaintingProcessor.cs | 2 +- .../Processors/Filters/FilterProcessor.cs | 2 +- .../HistogramEqualizationProcessor.cs | 2 +- .../OctreeFrameQuantizer{TPixel}.cs | 2 +- .../Quantization/WuFrameQuantizer{TPixel}.cs | 2 +- .../Transforms/AffineTransformProcessor.cs | 2 +- .../ProjectiveTransformProcessor.cs | 2 +- .../Color/Bulk/PackFromVector4.cs | 2 +- .../Color/Bulk/PackFromXyzw.cs | 2 +- tests/ImageSharp.Benchmarks/Samplers/Glow.cs | 2 +- .../Drawing/FillSolidBrushTests.cs | 2 +- .../Drawing/SolidFillBlendedShapesTests.cs | 2 +- .../Formats/Jpg/GenericBlock8x8Tests.cs | 2 +- .../Jpg/Utils/LibJpegTools.ComponentData.cs | 2 +- .../Jpg/Utils/LibJpegTools.SpectralData.cs | 2 +- tests/ImageSharp.Tests/Issues/Issue594.cs | 8 +- .../PixelFormats/Alpha8Tests.cs | 2 +- .../PixelFormats/Argb32Tests.cs | 2 +- .../PixelFormats/Bgr24Tests.cs | 4 +- .../PixelFormats/Bgr565Tests.cs | 2 +- .../PixelFormats/Bgra32Tests.cs | 4 +- .../PixelFormats/Bgra4444Tests.cs | 2 +- .../PixelFormats/Bgra5551Tests.cs | 4 +- .../PixelFormats/Byte4Tests.cs | 2 +- .../PixelFormats/Gray16Tests.cs | 6 +- .../PixelFormats/Gray8Tests.cs | 6 +- .../PixelFormats/HalfSingleTests.cs | 2 +- .../PixelFormats/HalfVector2Tests.cs | 2 +- .../PixelFormats/HalfVector4Tests.cs | 2 +- .../PixelFormats/NormalizedByte2Tests.cs | 2 +- .../PixelFormats/NormalizedByte4Tests.cs | 2 +- .../PixelFormats/NormalizedShort2Tests.cs | 2 +- .../PixelFormats/NormalizedShort4Tests.cs | 2 +- .../PixelFormats/PixelOperationsTests.cs | 52 ++--- .../PixelFormats/Rg32Tests.cs | 2 +- .../PixelFormats/Rgb24Tests.cs | 4 +- .../PixelFormats/Rgb48Tests.cs | 2 +- .../PixelFormats/Rgba1010102Tests.cs | 2 +- .../PixelFormats/Rgba32Tests.cs | 24 +- .../PixelFormats/Rgba64Tests.cs | 6 +- .../PixelFormats/RgbaVectorTests.cs | 8 +- .../PixelFormats/Short2Tests.cs | 12 +- .../PixelFormats/Short4Tests.cs | 20 +- .../ImageProviders/SolidProvider.cs | 2 +- .../ImageProviders/TestPatternProvider.cs | 8 +- .../TestUtilities/ImagingTestCaseUtility.cs | 4 +- .../TestUtilities/TestImageExtensions.cs | 2 +- .../TestUtilities/TestPixel.cs | 2 +- .../Tests/TestUtilityExtensionsTests.cs | 2 +- 97 files changed, 789 insertions(+), 789 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs b/src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs index 897b3f384..00141a8d8 100644 --- a/src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/GradientBrushBase{TPixel}.cs @@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.Processing onLocalGradient); TPixel resultColor = default; - resultColor.PackFromVector4(result); + resultColor.FromVector4(result); return resultColor; } } diff --git a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs index 87e1dc146..2968b68b5 100644 --- a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs @@ -95,9 +95,9 @@ namespace SixLabors.ImageSharp.Processing // Lets hack a min max extremes for a color space by letting the IPackedPixel clamp our values to something in the correct spaces :) var maxColor = default(TPixel); - maxColor.PackFromVector4(new Vector4(float.MaxValue)); + maxColor.FromVector4(new Vector4(float.MaxValue)); var minColor = default(TPixel); - minColor.PackFromVector4(new Vector4(float.MinValue)); + minColor.FromVector4(new Vector4(float.MinValue)); this.threshold = Vector4.DistanceSquared(maxColor.ToVector4(), minColor.ToVector4()) * threshold; } diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index dabab651d..8ebfb37eb 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -231,7 +231,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp for (int x = 0; x < width; x++) { - color.PackFromBgr24(Unsafe.As(ref colors[bufferRow[x] * 4])); + color.FromBgr24(Unsafe.As(ref colors[bufferRow[x] * 4])); pixelRow[x] = color; } } @@ -365,7 +365,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp { int colorIndex = ((rowSpan[offset] >> (8 - bits - (shift * bits))) & mask) * 4; - color.PackFromBgr24(Unsafe.As(ref colors[colorIndex])); + color.FromBgr24(Unsafe.As(ref colors[colorIndex])); pixelRow[newX] = color; } @@ -408,7 +408,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp GetBytesFrom5BitValue((temp & Rgb16GMask) >> 5), GetBytesFrom5BitValue(temp & Rgb16BMask)); - color.PackFromRgb24(rgb); + color.FromRgb24(rgb); pixelRow[x] = color; offset += 2; } diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index 155e6484f..db512a078 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -491,7 +491,7 @@ namespace SixLabors.ImageSharp.Formats.Gif int index = Unsafe.Add(ref indicesRef, i); ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); Rgb24 rgb = colorTable[index]; - pixel.PackFromRgb24(rgb); + pixel.FromRgb24(rgb); i++; } @@ -506,7 +506,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); Rgb24 rgb = colorTable[index]; - pixel.PackFromRgb24(rgb); + pixel.FromRgb24(rgb); } i++; diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 70f2cb04b..b4e5f201f 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Png for (int x = 0, o = 0; x < header.Width; x++, o += 2) { ushort luminance = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2)); - pixel.PackFromGray16(new Gray16(luminance)); + pixel.FromGray16(new Gray16(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Png for (int x = 0; x < header.Width; x++) { byte luminance = (byte)(Unsafe.Add(ref scanlineSpanRef, x) * scaleFactor); - pixel.PackFromGray8(new Gray8(luminance)); + pixel.FromGray8(new Gray8(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = luminance; rgba64.A = luminance.Equals(luminance16Trans) ? ushort.MinValue : ushort.MaxValue; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.B = luminance; rgba32.A = luminance.Equals(scaledLuminanceTrans) ? byte.MinValue : byte.MaxValue; - pixel.PackFromRgba32(rgba32); + pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Formats.Png for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o += 2) { ushort luminance = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2)); - pixel.PackFromGray16(new Gray16(luminance)); + pixel.FromGray16(new Gray16(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Formats.Png for (int x = pixelOffset, o = 0; x < header.Width; x += increment, o++) { byte luminance = (byte)(Unsafe.Add(ref scanlineSpanRef, o) * scaleFactor); - pixel.PackFromGray8(new Gray8(luminance)); + pixel.FromGray8(new Gray8(luminance)); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = luminance; rgba64.A = luminance.Equals(luminance16Trans) ? ushort.MinValue : ushort.MaxValue; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -152,7 +152,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.B = luminance; rgba32.A = luminance.Equals(scaledLuminanceTrans) ? byte.MinValue : byte.MaxValue; - pixel.PackFromRgba32(rgba32); + pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -182,7 +182,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = luminance; rgba64.A = alpha; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.B = luminance; rgba32.A = alpha; - pixel.PackFromRgba32(rgba32); + pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -233,7 +233,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = luminance; rgba64.A = alpha; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -250,7 +250,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.B = luminance; rgba32.A = alpha; - pixel.PackFromRgba32(rgba32); + pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -283,7 +283,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba.Rgb = Unsafe.Add(ref palettePixelsRef, index); rgba.A = paletteAlpha.Length > index ? Unsafe.Add(ref paletteAlphaRef, index) : byte.MaxValue; - pixel.PackFromRgba32(rgba); + pixel.FromRgba32(rgba); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -294,7 +294,7 @@ namespace SixLabors.ImageSharp.Formats.Png int index = Unsafe.Add(ref scanlineSpanRef, x); Rgb24 rgb = Unsafe.Add(ref palettePixelsRef, index); - pixel.PackFromRgb24(rgb); + pixel.FromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -328,7 +328,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba.A = paletteAlpha.Length > index ? Unsafe.Add(ref paletteAlphaRef, index) : byte.MaxValue; rgba.Rgb = Unsafe.Add(ref palettePixelsRef, index); - pixel.PackFromRgba32(rgba); + pixel.FromRgba32(rgba); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -339,7 +339,7 @@ namespace SixLabors.ImageSharp.Formats.Png int index = Unsafe.Add(ref scanlineSpanRef, o); Rgb24 rgb = Unsafe.Add(ref palettePixelsRef, index); - pixel.PackFromRgb24(rgb); + pixel.FromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -371,7 +371,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgb48.G = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample)); rgb48.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); - pixel.PackFromRgb48(rgb48); + pixel.FromRgb48(rgb48); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -396,7 +396,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.Rgb = rgb48; rgba64.A = rgb48.Equals(rgb48Trans) ? ushort.MinValue : ushort.MaxValue; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -411,7 +411,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba32.Rgb = rgb24; rgba32.A = rgb24.Equals(rgb24Trans) ? byte.MinValue : byte.MaxValue; - pixel.PackFromRgba32(rgba32); + pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -449,7 +449,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.Rgb = rgb48; rgba64.A = rgb48.Equals(rgb48Trans) ? ushort.MinValue : ushort.MaxValue; - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -462,7 +462,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgb48.G = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample)); rgb48.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); - pixel.PackFromRgb48(rgb48); + pixel.FromRgb48(rgb48); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -480,7 +480,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba.B = Unsafe.Add(ref scanlineSpanRef, o + (2 * bytesPerSample)); rgba.A = rgb24Trans.Equals(rgba.Rgb) ? byte.MinValue : byte.MaxValue; - pixel.PackFromRgba32(rgba); + pixel.FromRgba32(rgba); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -493,7 +493,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgb.G = Unsafe.Add(ref scanlineSpanRef, o + bytesPerSample); rgb.B = Unsafe.Add(ref scanlineSpanRef, o + (2 * bytesPerSample)); - pixel.PackFromRgb24(rgb); + pixel.FromRgb24(rgb); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -520,7 +520,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); rgba64.A = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (3 * bytesPerSample), bytesPerSample)); - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -554,7 +554,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); rgba64.A = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (3 * bytesPerSample), bytesPerSample)); - pixel.PackFromRgba64(rgba64); + pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; } } @@ -568,7 +568,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba.B = Unsafe.Add(ref scanlineSpanRef, o + (2 * bytesPerSample)); rgba.A = Unsafe.Add(ref scanlineSpanRef, o + (3 * bytesPerSample)); - pixel.PackFromRgba32(rgba); + pixel.FromRgba32(rgba); Unsafe.Add(ref rowSpanRef, x) = pixel; } } diff --git a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs index cf66f5d5e..2ed316409 100644 --- a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats TPixel result = default; var rgba = new Rgba32(BinaryPrimitives.ReverseEndianness(packedValue)); - result.PackFromRgba32(rgba); + result.FromRgba32(rgba); return result; } @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static TPixel FromRGBA(byte red, byte green, byte blue, byte alpha) { TPixel color = default; - color.PackFromRgba32(new Rgba32(red, green, blue, alpha)); + color.FromRgba32(new Rgba32(red, green, blue, alpha)); return color; } diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 3a6fb0a78..13e35cce0 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Sets the packed representation from a scaled . /// /// The vector to create the packed representation from. - void PackFromScaledVector4(Vector4 vector); + void FromScaledVector4(Vector4 vector); /// /// Expands the packed representation into a scaled @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Sets the packed representation from a . /// /// The vector to create the packed representation from. - void PackFromVector4(Vector4 vector); + void FromVector4(Vector4 vector); /// /// Expands the packed representation into a . @@ -59,43 +59,43 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs the pixel from an value. /// /// The value. - void PackFromArgb32(Argb32 source); + void FromArgb32(Argb32 source); /// /// Packs the pixel from an value. /// /// The value. - void PackFromBgr24(Bgr24 source); + void FromBgr24(Bgr24 source); /// /// Packs the pixel from an value. /// /// The value. - void PackFromBgra32(Bgra32 source); + void FromBgra32(Bgra32 source); /// /// Packs the Pixel from an value. /// /// The value. - void PackFromGray8(Gray8 source); + void FromGray8(Gray8 source); /// /// Packs the Pixel from an value. /// /// The value. - void PackFromGray16(Gray16 source); + void FromGray16(Gray16 source); /// /// Packs the pixel from an value. /// /// The value. - void PackFromRgb24(Rgb24 source); + void FromRgb24(Rgb24 source); /// /// Packs the pixel from an value. /// /// The value. - void PackFromRgba32(Rgba32 source); + void FromRgba32(Rgba32 source); /// /// Expands the packed representation into an . @@ -107,12 +107,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// Packs the pixel from an value. /// /// The value. - void PackFromRgb48(Rgb48 source); + void FromRgb48(Rgb48 source); /// /// Packs the pixel from an value. /// /// The value. - void PackFromRgba64(Rgba64 source); + void FromRgba64(Rgba64 source); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs index 19d1c5dad..c0a38b1a3 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -189,7 +189,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -225,7 +225,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -261,7 +261,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -297,7 +297,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlaySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlaySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -333,7 +333,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -369,7 +369,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -405,7 +405,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -441,7 +441,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -477,7 +477,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -513,7 +513,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -549,7 +549,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -585,7 +585,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -621,7 +621,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlaySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -657,7 +657,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -693,7 +693,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -729,7 +729,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -765,7 +765,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -801,7 +801,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -837,7 +837,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -873,7 +873,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -909,7 +909,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -945,7 +945,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlaySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -981,7 +981,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1017,7 +1017,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1053,7 +1053,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1089,7 +1089,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1125,7 +1125,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1161,7 +1161,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1197,7 +1197,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1233,7 +1233,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1269,7 +1269,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlaySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1305,7 +1305,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1341,7 +1341,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1377,7 +1377,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplySrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1413,7 +1413,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1449,7 +1449,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1485,7 +1485,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1521,7 +1521,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1557,7 +1557,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1593,7 +1593,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlaySrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1629,7 +1629,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1665,7 +1665,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1701,7 +1701,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1737,7 +1737,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1773,7 +1773,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1809,7 +1809,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1845,7 +1845,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1881,7 +1881,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1917,7 +1917,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1953,7 +1953,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightDest(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -1989,7 +1989,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2025,7 +2025,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2061,7 +2061,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2097,7 +2097,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2133,7 +2133,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2169,7 +2169,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2205,7 +2205,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2241,7 +2241,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2277,7 +2277,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightDestAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2313,7 +2313,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2349,7 +2349,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2385,7 +2385,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2421,7 +2421,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2457,7 +2457,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2493,7 +2493,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2529,7 +2529,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2565,7 +2565,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2601,7 +2601,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightDestOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2637,7 +2637,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2673,7 +2673,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2709,7 +2709,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2745,7 +2745,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2781,7 +2781,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2817,7 +2817,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2853,7 +2853,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2889,7 +2889,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2925,7 +2925,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightDestIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2961,7 +2961,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -2997,7 +2997,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3033,7 +3033,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3069,7 +3069,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3105,7 +3105,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3141,7 +3141,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3177,7 +3177,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3213,7 +3213,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3249,7 +3249,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightDestOut(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3285,7 +3285,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3321,7 +3321,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3357,7 +3357,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3393,7 +3393,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3429,7 +3429,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3465,7 +3465,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3501,7 +3501,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3537,7 +3537,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3573,7 +3573,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightClear(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3609,7 +3609,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.NormalXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.NormalXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3645,7 +3645,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.MultiplyXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.MultiplyXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3681,7 +3681,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.AddXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.AddXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3717,7 +3717,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.SubtractXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.SubtractXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3753,7 +3753,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.ScreenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.ScreenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3789,7 +3789,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.DarkenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.DarkenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3825,7 +3825,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.LightenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.LightenXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3861,7 +3861,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.OverlayXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.OverlayXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } @@ -3897,7 +3897,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders public override TPixel Blend(TPixel background, TPixel source, float amount) { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.HardLightXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + dest.FromScaledVector4(PorterDuffFunctions.HardLightXor(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); return dest; } diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs index 0a6ef60ec..64148746e 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -166,7 +166,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -178,7 +178,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -202,7 +202,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -214,7 +214,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -250,7 +250,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(NormalXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(NormalXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -356,7 +356,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplySrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplySrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -368,7 +368,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplySrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplySrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -380,7 +380,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplySrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplySrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -392,7 +392,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplySrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplySrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -404,7 +404,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplySrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplySrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -416,7 +416,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -428,7 +428,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -440,7 +440,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -452,7 +452,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -464,7 +464,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -476,7 +476,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -488,7 +488,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(MultiplyXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(MultiplyXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -594,7 +594,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -606,7 +606,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -618,7 +618,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -630,7 +630,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -642,7 +642,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -654,7 +654,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -666,7 +666,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -678,7 +678,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -690,7 +690,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -702,7 +702,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -714,7 +714,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -726,7 +726,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(AddXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(AddXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -832,7 +832,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -844,7 +844,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -856,7 +856,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -868,7 +868,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -880,7 +880,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -892,7 +892,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -904,7 +904,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -916,7 +916,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -928,7 +928,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -940,7 +940,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -952,7 +952,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -964,7 +964,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(SubtractXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(SubtractXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1070,7 +1070,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1082,7 +1082,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1094,7 +1094,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1106,7 +1106,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1118,7 +1118,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1130,7 +1130,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1142,7 +1142,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1154,7 +1154,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1166,7 +1166,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1178,7 +1178,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1190,7 +1190,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1202,7 +1202,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(ScreenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(ScreenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1308,7 +1308,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1320,7 +1320,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1332,7 +1332,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1344,7 +1344,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1356,7 +1356,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1368,7 +1368,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1380,7 +1380,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1392,7 +1392,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1404,7 +1404,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1416,7 +1416,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1428,7 +1428,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1440,7 +1440,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(DarkenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(DarkenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1546,7 +1546,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1558,7 +1558,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1570,7 +1570,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1582,7 +1582,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1594,7 +1594,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1606,7 +1606,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1618,7 +1618,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1630,7 +1630,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1642,7 +1642,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1654,7 +1654,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1666,7 +1666,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1678,7 +1678,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(LightenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(LightenXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1784,7 +1784,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlaySrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlaySrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1796,7 +1796,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlaySrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlaySrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1808,7 +1808,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlaySrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlaySrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1820,7 +1820,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlaySrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlaySrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1832,7 +1832,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlaySrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlaySrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1844,7 +1844,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1856,7 +1856,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1868,7 +1868,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1880,7 +1880,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1892,7 +1892,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1904,7 +1904,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -1916,7 +1916,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(OverlayXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(OverlayXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2022,7 +2022,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightSrc(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2034,7 +2034,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightSrcAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2046,7 +2046,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightSrcOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2058,7 +2058,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightSrcIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2070,7 +2070,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightSrcOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2082,7 +2082,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightDest(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2094,7 +2094,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightDestAtop(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2106,7 +2106,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightDestOver(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2118,7 +2118,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightDestIn(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2130,7 +2130,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightDestOut(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2142,7 +2142,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightClear(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } @@ -2154,7 +2154,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(HardLightXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(HardLightXor(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs index 730734f5f..75b7ede82 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(vector.W); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(vector.W); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -77,31 +77,31 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackedValue = source.A; + public void FromArgb32(Argb32 source) => this.PackedValue = source.A; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackedValue = byte.MaxValue; + public void FromBgr24(Bgr24 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.A; + public void FromBgra32(Bgra32 source) => this.PackedValue = source.A; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackedValue = byte.MaxValue; + public void FromGray8(Gray8 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; + public void FromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackedValue = byte.MaxValue; + public void FromRgb24(Rgb24 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; + public void FromRgba32(Rgba32 source) => this.PackedValue = source.A; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -113,11 +113,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackedValue = byte.MaxValue; + public void FromRgb48(Rgb48 source) => this.PackedValue = byte.MaxValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Compares an object with the packed vector. diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs index a47d7e8e7..8fc301631 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs @@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); + public void FromVector4(Vector4 vector) => this.Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -185,11 +185,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackedValue = source.PackedValue; + public void FromArgb32(Argb32 source) => this.PackedValue = source.PackedValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.R = source.R; this.G = source.G; @@ -199,7 +199,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = source.R; this.G = source.G; @@ -209,7 +209,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); this.R = rgb; @@ -230,7 +230,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.R = source.R; this.G = source.G; @@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) + public void FromRgba32(Rgba32 source) { this.R = source.R; this.G = source.G; @@ -260,7 +260,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); @@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs index 8eba08bea..9207f046c 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -84,11 +84,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { Rgba32 rgba = default; - rgba.PackFromVector4(vector); - this.PackFromRgba32(rgba); + rgba.FromVector4(vector); + this.FromRgba32(rgba); } /// @@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = source.R; this.G = source.G; @@ -106,11 +106,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this = source; + public void FromBgr24(Bgr24 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = source.R; this.G = source.G; @@ -119,7 +119,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); this.R = rgb; @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.R = source.R; this.G = source.G; @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this = source.Bgr; + public void FromRgba32(Rgba32 source) => this = source.Bgr; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -161,7 +161,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); @@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs index 295f1ca0a..a2e4dc880 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { var vector3 = new Vector3(vector.X, vector.Y, vector.Z); this.PackedValue = Pack(ref vector3); @@ -85,46 +85,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToVector4()); + public void FromArgb32(Argb32 source) => this.FromVector4(source.ToVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToVector4()); + public void FromBgra32(Bgra32 source) => this.FromVector4(source.ToVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromVector4(source.ToVector4()); + public void FromRgba32(Rgba32 source) => this.FromVector4(source.ToVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs index 5d70c9e50..1d156222f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs @@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); + public void FromVector4(Vector4 vector) => this.Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = source.R; this.G = source.G; @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.R = source.R; this.G = source.G; @@ -161,11 +161,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this = source; + public void FromBgra32(Bgra32 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -175,7 +175,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); this.R = rgb; @@ -186,7 +186,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) + public void FromRgba32(Rgba32 source) { this.R = source.R; this.G = source.G; @@ -196,7 +196,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.R = source.R; this.G = source.G; @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); @@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs index 29ea63e20..110b51822 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -88,46 +88,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is Bgra4444 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs index f6dbb7811..dcfb25a64 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -89,46 +89,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is Bgra5551 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs index 96eeeec0d..43a03dc5d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector * 255F); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector * 255F); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -89,46 +89,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is Byte4 byte4 && this.Equals(byte4); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 0b40df8da..2fa7df94e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index e89525457..950c6d5d9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 2311e0bde..f29fa78ec 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index a2d9aa755..1b679c50a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index de2c11d4d..1be3cc468 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index ad4ee2764..c6a7c7069 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index 0a1ef0387..dcc0f3802 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index bd3e014b4..63dbc7405 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index e6f9b37a7..f92fe8ec7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs index 788278be4..2e98a28ad 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max * Average; this.PackedValue = (ushort)MathF.Round(vector.X + vector.Y + vector.Z); @@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.PackedValue = ImageMaths.Get16BitBT709Luminance( ImageMaths.UpscaleFrom8BitTo16Bit(source.R), @@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.PackedValue = ImageMaths.Get16BitBT709Luminance( ImageMaths.UpscaleFrom8BitTo16Bit(source.R), @@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.PackedValue = ImageMaths.Get16BitBT709Luminance( ImageMaths.UpscaleFrom8BitTo16Bit(source.R), @@ -108,15 +108,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); + public void FromGray8(Gray8 source) => this.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackedValue = source.PackedValue; + public void FromGray16(Gray16 source) => this.PackedValue = source.PackedValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.PackedValue = ImageMaths.Get16BitBT709Luminance( ImageMaths.UpscaleFrom8BitTo16Bit(source.R), @@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) + public void FromRgba32(Rgba32 source) { this.PackedValue = ImageMaths.Get16BitBT709Luminance( ImageMaths.UpscaleFrom8BitTo16Bit(source.R), @@ -147,11 +147,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); + public void FromRgb48(Rgb48 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); + public void FromRgba64(Rgba64 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); /// public override bool Equals(object obj) => obj is Gray16 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs index 8a9ec540d..d23fda799 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { vector *= MaxBytes; vector += Half; @@ -80,31 +80,31 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + public void FromArgb32(Argb32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + public void FromBgr24(Bgr24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + public void FromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackedValue = source.PackedValue; + public void FromGray8(Gray8 source) => this.PackedValue = source.PackedValue; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + public void FromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + public void FromRgb24(Rgb24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + public void FromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance( ImageMaths.DownScaleFrom16BitTo8Bit(source.R), ImageMaths.DownScaleFrom16BitTo8Bit(source.G), @@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance( ImageMaths.DownScaleFrom16BitTo8Bit(source.R), ImageMaths.DownScaleFrom16BitTo8Bit(source.G), diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs index a1811e147..8323cf3e8 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { float scaled = vector.X; scaled *= 2F; @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = HalfTypeHelper.Pack(vector.X); + public void FromVector4(Vector4 vector) => this.PackedValue = HalfTypeHelper.Pack(vector.X); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -78,46 +78,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs index 381650aec..cb915459b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; scaled -= Vector2.One; @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(vector.X, vector.Y); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(vector.X, vector.Y); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -89,46 +89,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs index b7d6687ea..9f60ca8c7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs @@ -63,11 +63,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { vector *= 2F; vector -= Vector4.One; - this.PackFromVector4(vector); + this.FromVector4(vector); } /// @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -97,46 +97,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is HalfVector4 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs index 9999cfe03..d39cfd402 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; scaled -= Vector2.One; @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { var vector2 = new Vector2(vector.X, vector.Y); this.PackedValue = Pack(vector2); @@ -95,46 +95,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs index 5f9124bdc..82698d508 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs @@ -66,11 +66,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { vector *= 2F; vector -= Vector4.One; - this.PackFromVector4(vector); + this.FromVector4(vector); } /// @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -100,46 +100,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is NormalizedByte4 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs index 0cd8d9408..b9cab1e7d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F; scaled -= Vector2.One; @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { var vector2 = new Vector2(vector.X, vector.Y); this.PackedValue = Pack(vector2); @@ -95,46 +95,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs index 21aac4d24..3bc74e6c6 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs @@ -66,11 +66,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { vector *= 2F; vector -= Vector4.One; - this.PackFromVector4(vector); + this.FromVector4(vector); } /// @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -102,46 +102,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is NormalizedShort4 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs index 878b2342f..6dc623518 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { var vector2 = new Vector2(vector.X, vector.Y); this.PackedValue = Pack(vector2); @@ -83,46 +83,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs index 0113027d6..293fe0acb 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.PixelFormats var vector = new Vector4(color.ToVector3(), 1F); Rgb24 rgb = default; - rgb.PackFromScaledVector4(vector); + rgb.FromScaledVector4(vector); return rgb; } @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); + public void FromVector4(Vector4 vector) => this.Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = source.R; this.G = source.G; @@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.R = source.R; this.G = source.G; @@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = source.R; this.G = source.G; @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); this.R = rgb; @@ -157,11 +157,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this = source; + public void FromRgb24(Rgb24 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this = source.Rgb; + public void FromRgba32(Rgba32 source) => this = source.Rgb; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -175,7 +175,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); @@ -184,7 +184,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs index 815bf8c91..81497e5f1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; this.R = (ushort)MathF.Round(vector.X); @@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -124,11 +124,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this = source.Rgb; + public void FromRgba64(Rgba64 source) => this = source.Rgb; /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { ushort rgb = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); this.R = rgb; @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) + public void FromRgba32(Rgba32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -175,7 +175,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this = source; + public void FromRgb48(Rgb48 source) => this = source; /// public override bool Equals(object obj) => obj is Rgb48 rgb48 && this.Equals(rgb48); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs index 7f3e3a870..895added1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -89,46 +89,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is Rgba1010102 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs index e866d1350..5a16704ef 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs @@ -181,7 +181,7 @@ namespace SixLabors.ImageSharp.PixelFormats var vector = new Vector4(color.ToVector3(), 1F); Rgba32 rgba = default; - rgba.PackFromScaledVector4(vector); + rgba.FromScaledVector4(vector); return rgba; } @@ -224,7 +224,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -232,7 +232,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.Pack(ref vector); + public void FromVector4(Vector4 vector) => this.Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = source.R; this.G = source.G; @@ -250,7 +250,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.Bgr = source; this.A = byte.MaxValue; @@ -258,7 +258,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = source.R; this.G = source.G; @@ -268,7 +268,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -278,7 +278,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { byte rgb = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); this.R = rgb; @@ -289,7 +289,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.Rgb = source; this.A = byte.MaxValue; @@ -297,7 +297,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this = source; + public void FromRgba32(Rgba32 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -308,7 +308,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); @@ -318,7 +318,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) + public void FromRgba64(Rgba64 source) { this.R = ImageMaths.DownScaleFrom16BitTo8Bit(source.R); this.G = ImageMaths.DownScaleFrom16BitTo8Bit(source.G); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs index 2d1a67670..5ae5492e2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; this.R = (ushort)MathF.Round(vector.X); @@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) + public void FromArgb32(Argb32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) + public void FromBgr24(Bgr24 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -146,7 +146,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) + public void FromBgra32(Bgra32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) + public void FromGray8(Gray8 source) { ushort rgb = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue); this.R = rgb; @@ -167,7 +167,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) + public void FromGray16(Gray16 source) { this.R = source.PackedValue; this.G = source.PackedValue; @@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) + public void FromRgb24(Rgb24 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -187,7 +187,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) + public void FromRgba32(Rgba32 source) { this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); @@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) + public void FromRgb48(Rgb48 source) { this.Rgb = source; this.A = ushort.MaxValue; @@ -215,7 +215,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this = source; + public void FromRgba64(Rgba64 source) => this = source; /// public override bool Equals(object obj) => obj is Rgba64 rgba64 && this.Equals(rgba64); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs index 25b8155d3..ff4c69d70 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) => this.PackFromVector4(vector); + public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One); this.R = vector.X; @@ -124,46 +124,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Converts the value of this instance to a hexadecimal string. diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs index 69a4e35e9..96fe15ed6 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { Vector2 scaled = new Vector2(vector.X, vector.Y) * 65534F; scaled -= new Vector2(32767F); @@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) + public void FromVector4(Vector4 vector) { var vector2 = new Vector2(vector.X, vector.Y); this.PackedValue = Pack(vector2); @@ -101,46 +101,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// /// Expands the packed representation into a . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs index 653bc030f..d224f8eb4 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs @@ -72,11 +72,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromScaledVector4(Vector4 vector) + public void FromScaledVector4(Vector4 vector) { vector *= 65534F; vector -= new Vector4(32767F); - this.PackFromVector4(vector); + this.FromVector4(vector); } /// @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); + public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -106,46 +106,46 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray8(Gray8 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromGray16(Gray16 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public void ToRgba32(ref Rgba32 dest) { - dest.PackFromScaledVector4(this.ToScaledVector4()); + dest.FromScaledVector4(this.ToScaledVector4()); } /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4()); /// public override bool Equals(object obj) => obj is Short4 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs index 66966543f..2708af074 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Argb32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } @@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } @@ -203,7 +203,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray8 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } @@ -273,7 +273,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -308,7 +308,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Gray16 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } @@ -343,7 +343,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -378,7 +378,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb24 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } @@ -413,7 +413,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -448,7 +448,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } @@ -483,7 +483,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -518,7 +518,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgb48 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } @@ -553,7 +553,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -588,7 +588,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Rgba64 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } @@ -623,7 +623,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index f1b40e81f..926b234d7 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static PixelOperations Instance { get; } = default(TPixel).CreatePixelOperations(); /// - /// Bulk version of + /// Bulk version of /// /// The to the source vectors. /// The to the destination colors. @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromVector4(sp); + dp.FromVector4(sp); } } @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Bulk version of + /// Bulk version of /// /// The to the source vectors. /// The to the destination colors. @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromScaledVector4(sp); + dp.FromScaledVector4(sp); } } @@ -155,7 +155,7 @@ namespace SixLabors.ImageSharp.PixelFormats { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); ref TPixel2 dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } diff --git a/src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor.cs index ebf9c8dec..4165cf024 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor.cs @@ -165,7 +165,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution currentPassPixel.ToVector4(), currentTargetPixel.ToVector4()); - currentTargetPixel.PackFromVector4(pixelValue); + currentTargetPixel.FromVector4(pixelValue); } } }); diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffuserBase.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffuserBase.cs index b407841f2..642da2f00 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffuserBase.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDiffuserBase.cs @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering var offsetColor = pixel.ToVector4(); Vector4 result = ((error * coefficient) / this.divisorVector) + offsetColor; - pixel.PackFromVector4(result); + pixel.FromVector4(result); } } } diff --git a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs index 6ad4dcba9..1b17c470e 100644 --- a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs @@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects float blue = MathF.Abs(blueBin[maxIndex] / maxIntensity); ref TPixel pixel = ref targetRow[x]; - pixel.PackFromVector4( + pixel.FromVector4( new Vector4(red, green, blue, sourceRow[x].ToVector4().W)); } } diff --git a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs index e20b42eb7..d3a44c066 100644 --- a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { ref TPixel pixel = ref row[x]; var vector = Vector4.Transform(pixel.ToVector4(), matrix); - pixel.PackFromVector4(vector); + pixel.FromVector4(vector); } } }); diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs index e90b35225..580adc7fe 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin; - pixels[i].PackFromVector4(new Vector4(luminanceEqualized)); + pixels[i].FromVector4(new Vector4(luminanceEqualized)); } } } diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 29742725a..1eeb0be41 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -499,7 +499,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Set the color of the palette entry var vector = Vector3.Clamp(new Vector3(this.red, this.green, this.blue) / this.pixelCount, Vector3.Zero, new Vector3(255)); TPixel pixel = default; - pixel.PackFromRgba32(new Rgba32((byte)vector.X, (byte)vector.Y, (byte)vector.Z, byte.MaxValue)); + pixel.FromRgba32(new Rgba32((byte)vector.X, (byte)vector.Y, (byte)vector.Z, byte.MaxValue)); palette[index] = pixel; // Consume the next palette index diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index 4ef165960..dd947f337 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -199,7 +199,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization float a = Volume(ref this.colorCube[k], vmaSpan); ref TPixel color = ref this.palette[k]; - color.PackFromScaledVector4(new Vector4(r, g, b, a) / weight / 255F); + color.FromScaledVector4(new Vector4(r, g, b, a) / weight / 255F); } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index 790eb8048..e12b91eab 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -218,7 +218,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Reverse the premultiplication Vector4Utils.UnPremultiply(ref sum); - dest.PackFromVector4(sum); + dest.FromVector4(sum); } } }); diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index bad8eab3a..50af26aeb 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -227,7 +227,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Reverse the premultiplication Vector4Utils.UnPremultiply(ref sum); - dest.PackFromVector4(sum); + dest.FromVector4(sum); } } }); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index eaa52a975..e39c464f1 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk for (int i = 0; i < this.Count; i++) { - Unsafe.Add(ref d, i).PackFromVector4(Unsafe.Add(ref s, i)); + Unsafe.Add(ref d, i).FromVector4(Unsafe.Add(ref s, i)); } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs index 7e7dfb365..527235104 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { int i4 = i * 4; var c = default(TPixel); - c.PackFromRgba32(new Rgba32(s[i4], s[i4 + 1], s[i4 + 2], s[i4 + 3])); + c.FromRgba32(new Rgba32(s[i4], s[i4 + 1], s[i4 + 2], s[i4 + 3])); d[i] = c; } } diff --git a/tests/ImageSharp.Benchmarks/Samplers/Glow.cs b/tests/ImageSharp.Benchmarks/Samplers/Glow.cs index ff2e57b97..729971548 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Glow.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Glow.cs @@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Benchmarks float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY)); Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4(); TPixel packed = default(TPixel); - packed.PackFromVector4( + packed.FromVector4( PremultipliedLerp( sourceColor, glowColor.ToVector4(), diff --git a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs index 32f723e72..639b3fe81 100644 --- a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs +++ b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing vec.W = alpha; TPixel fillColor = default; - fillColor.PackFromVector4(vec); + fillColor.FromVector4(vec); using (Image image = provider.GetImage()) { diff --git a/tests/ImageSharp.Tests/Drawing/SolidFillBlendedShapesTests.cs b/tests/ImageSharp.Tests/Drawing/SolidFillBlendedShapesTests.cs index a8fb187ce..94e12f858 100644 --- a/tests/ImageSharp.Tests/Drawing/SolidFillBlendedShapesTests.cs +++ b/tests/ImageSharp.Tests/Drawing/SolidFillBlendedShapesTests.cs @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing var c = NamedColors.Red.ToVector4(); c.W *= 0.5f; var pixel = default(TPixel); - pixel.PackFromVector4(c); + pixel.FromVector4(c); img.Mutate( x => x.Fill( diff --git a/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs index dedb094bc..341d67f0f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { var rgba = new Rgba32((byte)(i + 1), (byte)(j + 1), (byte)200, (byte)255); var color = default(TPixel); - color.PackFromRgba32(rgba); + color.FromRgba32(rgba); pixels[i, j] = color; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs index 57d92fa15..7acce84ce 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils var v = new Vector4(val, val, val, 1); Rgba32 color = default; - color.PackFromVector4(v); + color.FromVector4(v); int yy = by * 8 + y; int xx = bx * 8 + x; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs index bcfabca39..f5618d26d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils var v = new Vector4(val0, val1, val2, 1); Rgba32 color = default; - color.PackFromVector4(v); + color.FromVector4(v); int yy = by * 8 + y; int xx = bx * 8 + x; diff --git a/tests/ImageSharp.Tests/Issues/Issue594.cs b/tests/ImageSharp.Tests/Issues/Issue594.cs index 4a0683fba..48e355ea7 100644 --- a/tests/ImageSharp.Tests/Issues/Issue594.cs +++ b/tests/ImageSharp.Tests/Issues/Issue594.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Issues // Test PackFromScaledVector4. var pixel = default(NormalizedByte4); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); Assert.Equal(0x81818181, pixel.PackedValue); // Test Ordering @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.Issues float w = -0.7f; Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue); var n = default(NormalizedByte4); - n.PackFromRgba32(new Rgba32(141, 90, 192, 39)); + n.FromRgba32(new Rgba32(141, 90, 192, 39)); Assert.Equal(0xA740DA0D, n.PackedValue); Assert.Equal((uint)958796544, new NormalizedByte4(0.0008f, 0.15f, 0.30f, 0.45f).PackedValue); @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Tests.Issues // Test PackFromScaledVector4. var pixel = default(NormalizedShort4); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); Assert.Equal((ulong)0x7FFF7FFF7FFF7FFF, pixel.PackedValue); // Test Ordering @@ -192,7 +192,7 @@ namespace SixLabors.ImageSharp.Tests.Issues // Test PackFromScaledVector4. var pixel = default(Short4); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); Assert.Equal((ulong)0x7FFF7FFF7FFF7FFF, pixel.PackedValue); // Test clamping. diff --git a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs index 37e7d94e4..067c1a977 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); // Act - alpha.PackFromScaledVector4(scaled); + alpha.FromScaledVector4(scaled); byte actual = alpha.PackedValue; // Assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs index 6186793c5..31b9a53a0 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats uint expected = 0xFFFFFFFF; // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); uint actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index 96589a03e..ce284f420 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromRgba32() { var rgb = default(Bgr24); - rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); + rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); Assert.Equal(1, rgb.R); Assert.Equal(2, rgb.G); @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromVector4() { var rgb = default(Bgr24); - rgb.PackFromVector4(Vec(1, 2, 3, 4)); + rgb.FromVector4(Vec(1, 2, 3, 4)); Assert.Equal(1, rgb.R); Assert.Equal(2, rgb.G); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs index 8cbbf558d..5033788b8 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var pixel = default(Bgr565); // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); ushort actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs index 1b890ac49..93993cc39 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromRgba32() { var rgb = default(Rgb24); - rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); + rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); Assert.Equal(1, rgb.R); Assert.Equal(2, rgb.G); @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromVector4() { var c = default(Bgra32); - c.PackFromVector4(Vec(1, 2, 3, 4)); + c.FromVector4(Vec(1, 2, 3, 4)); Assert.Equal(1, c.R); Assert.Equal(2, c.G); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs index a2fc1a052..3f6b7653f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var bgra = default(Bgra4444); // act - bgra.PackFromScaledVector4(scaled); + bgra.FromScaledVector4(scaled); ushort actual = bgra.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs index 084dfbd97..eaf397bb5 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs @@ -53,10 +53,10 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Vector4 scaled = new Bgra5551(Vector4.One).ToScaledVector4(); int expected = 0xFFFF; var pixel = default(Bgra5551); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); ushort actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs index de1c749f6..c172bbdac 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats uint expected = 0xFFFFFFFF; // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); uint actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs index db4fa7019..69a44a9bb 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Vector4 scaled = new Gray16(expected).ToScaledVector4(); // Act - gray.PackFromScaledVector4(scaled); + gray.FromScaledVector4(scaled); ushort actual = gray.PackedValue; // Assert @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var vector = new Gray16(expected).ToVector4(); // Act - gray.PackFromVector4(vector); + gray.FromVector4(vector); ushort actual = gray.PackedValue; // Assert @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ushort expected = ImageMaths.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb); // Act - gray.PackFromRgba32(new Rgba32(rgb, rgb, rgb)); + gray.FromRgba32(new Rgba32(rgb, rgb, rgb)); ushort actual = gray.PackedValue; // Assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index aaca6c877..7886be9e0 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Vector4 scaled = new Gray8(expected).ToScaledVector4(); // Act - gray.PackFromScaledVector4(scaled); + gray.FromScaledVector4(scaled); byte actual = gray.PackedValue; // Assert @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var vector = new Gray8(expected).ToVector4(); // Act - gray.PackFromVector4(vector); + gray.FromVector4(vector); byte actual = gray.PackedValue; // Assert @@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats byte expected = ImageMaths.Get8BitBT709Luminance(rgb, rgb, rgb); // Act - gray.PackFromRgba32(new Rgba32(rgb, rgb, rgb)); + gray.FromRgba32(new Rgba32(rgb, rgb, rgb)); byte actual = gray.PackedValue; // Assert diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs index fed55af6f..a503db01c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var halfSingle = default(HalfSingle); // act - halfSingle.PackFromScaledVector4(scaled); + halfSingle.FromScaledVector4(scaled); ushort actual = halfSingle.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs index c775e3a0d..a892b8413 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var halfVector = default(HalfVector2); // act - halfVector.PackFromScaledVector4(scaled); + halfVector.FromScaledVector4(scaled); uint actual = halfVector.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs index 540a1ed08..02a05a76f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ulong expected = 13547034390470638592uL; // act - halfVector4.PackFromScaledVector4(scaled); + halfVector4.FromScaledVector4(scaled); ulong actual = halfVector4.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs index 98b747a94..faaeae6cc 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats uint expected = 0x8181; // act - byte2.PackFromScaledVector4(scaled); + byte2.FromScaledVector4(scaled); uint actual = byte2.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs index d9cca360b..4465fbaed 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats uint expected = 0x81818181; // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); uint actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs index 83eab82ac..4f66d04e3 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats uint expected = 0x80018001; // act - short2.PackFromScaledVector4(scaled); + short2.FromScaledVector4(scaled); uint actual = short2.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs index 40b2d05e3..b93960dbf 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ulong expected = 0x7FFF7FFF7FFF7FFF; // act - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); ulong actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 8a0aee1a7..ef57458c9 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { - expected[i].PackFromGray8(new Gray8(source[i])); + expected[i].FromGray8(new Gray8(source[i])); } TestOperation( @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { - gray.PackFromScaledVector4(source[i].ToScaledVector4()); + gray.FromScaledVector4(source[i].ToScaledVector4()); expected[i] = gray.PackedValue; } @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i2 = i * 2; - expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); } TestOperation( @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i2 = i * 2; - gray.PackFromScaledVector4(source[i].ToScaledVector4()); + gray.FromScaledVector4(source[i].ToScaledVector4()); OctetBytes bytes = Unsafe.As(ref gray); expected[i2] = bytes[0]; expected[i2 + 1] = bytes[1]; @@ -171,7 +171,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { - expected[i].PackFromGray8(new Gray8(source[i])); + expected[i].FromGray8(new Gray8(source[i])); } TestOperation( @@ -191,7 +191,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { - gray.PackFromScaledVector4(source[i].ToScaledVector4()); + gray.FromScaledVector4(source[i].ToScaledVector4()); expected[i] = gray.PackedValue; } @@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i2 = i * 2; - expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); } TestOperation( @@ -234,7 +234,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i2 = i * 2; - gray.PackFromScaledVector4(source[i].ToScaledVector4()); + gray.FromScaledVector4(source[i].ToScaledVector4()); OctetBytes bytes = Unsafe.As(ref gray); expected[i2] = bytes[0]; expected[i2 + 1] = bytes[1]; @@ -341,7 +341,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < expected.Length; i++) { - expected[i].PackFromVector4(source[i]); + expected[i].FromVector4(source[i]); } return expected; } @@ -352,7 +352,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < expected.Length; i++) { - expected[i].PackFromScaledVector4(source[i]); + expected[i].FromScaledVector4(source[i]); } return expected; } @@ -446,7 +446,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { int i4 = i * 4; - expected[i].PackFromArgb32(new Argb32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + expected[i].FromArgb32(new Argb32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); } TestOperation( @@ -467,7 +467,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i4 = i * 4; - argb.PackFromScaledVector4(source[i].ToScaledVector4()); + argb.FromScaledVector4(source[i].ToScaledVector4()); expected[i4] = argb.A; expected[i4 + 1] = argb.R; @@ -493,7 +493,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { int i3 = i * 3; - expected[i].PackFromBgr24(new Bgr24(source[i3 + 2], source[i3 + 1], source[i3])); + expected[i].FromBgr24(new Bgr24(source[i3 + 2], source[i3 + 1], source[i3])); } TestOperation( @@ -514,7 +514,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i3 = i * 3; - bgr.PackFromScaledVector4(source[i].ToScaledVector4()); + bgr.FromScaledVector4(source[i].ToScaledVector4()); expected[i3] = bgr.B; expected[i3 + 1] = bgr.G; expected[i3 + 2] = bgr.R; @@ -538,7 +538,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { int i4 = i * 4; - expected[i].PackFromBgra32(new Bgra32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); + expected[i].FromBgra32(new Bgra32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); } TestOperation( @@ -559,7 +559,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i4 = i * 4; - bgra.PackFromScaledVector4(source[i].ToScaledVector4()); + bgra.FromScaledVector4(source[i].ToScaledVector4()); expected[i4] = bgra.B; expected[i4 + 1] = bgra.G; expected[i4 + 2] = bgra.R; @@ -584,7 +584,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { int i3 = i * 3; - expected[i].PackFromRgb24(new Rgb24(source[i3 + 0], source[i3 + 1], source[i3 + 2])); + expected[i].FromRgb24(new Rgb24(source[i3 + 0], source[i3 + 1], source[i3 + 2])); } TestOperation( @@ -605,7 +605,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i3 = i * 3; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + rgb.FromScaledVector4(source[i].ToScaledVector4()); expected[i3] = rgb.R; expected[i3 + 1] = rgb.G; expected[i3 + 2] = rgb.B; @@ -629,7 +629,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { int i4 = i * 4; - expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); + expected[i].FromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); } TestOperation( @@ -650,7 +650,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i4 = i * 4; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + rgba.FromScaledVector4(source[i].ToScaledVector4()); expected[i4] = rgba.R; expected[i4 + 1] = rgba.G; expected[i4 + 2] = rgba.B; @@ -675,7 +675,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i6 = i * 6; - expected[i].PackFromRgb48(MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]); + expected[i].FromRgb48(MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]); } TestOperation( @@ -696,7 +696,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i6 = i * 6; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + rgb.FromScaledVector4(source[i].ToScaledVector4()); OctetBytes rgb48Bytes = Unsafe.As(ref rgb); expected[i6] = rgb48Bytes[0]; expected[i6 + 1] = rgb48Bytes[1]; @@ -724,7 +724,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i8 = i * 8; - expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); + expected[i].FromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); } TestOperation( @@ -745,7 +745,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < count; i++) { int i8 = i * 8; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + rgba.FromScaledVector4(source[i].ToScaledVector4()); OctetBytes rgba64Bytes = Unsafe.As(ref rgba); expected[i8] = rgba64Bytes[0]; expected[i8 + 1] = rgba64Bytes[1]; @@ -799,7 +799,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < result.Length; i++) { Vector4 v = GetVector(rnd); - result[i].PackFromVector4(v); + result[i].FromVector4(v); } return result; @@ -814,7 +814,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats for (int i = 0; i < result.Length; i++) { Vector4 v = GetVector(rnd); - result[i].PackFromScaledVector4(v); + result[i].FromScaledVector4(v); } return result; diff --git a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs index 135843e35..d4347cae6 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = rg32.ToScaledVector4(); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); uint actual = pixel.PackedValue; // assert diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index aa6d9024c..918a147d9 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromRgba32() { var rgb = default(Rgb24); - rgb.PackFromRgba32(new Rgba32(1, 2, 3, 4)); + rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); Assert.Equal(1, rgb.R); Assert.Equal(2, rgb.G); @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void PackFromVector4() { var rgb = default(Rgb24); - rgb.PackFromVector4(Vec(1, 2, 3, 4)); + rgb.FromVector4(Vec(1, 2, 3, 4)); Assert.Equal(1, rgb.R); Assert.Equal(2, rgb.G); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs index 16dfd7f57..444a62792 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = short3.ToScaledVector4(); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); // assert Assert.Equal(expected, pixel); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs index 243d4a44c..16aad79a0 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = rgba.ToScaledVector4(); - actual.PackFromScaledVector4(scaled); + actual.FromScaledVector4(scaled); // assert Assert.Equal(expected, actual.PackedValue); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs index 30a5f961b..df83d14fb 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = rgba.ToScaledVector4(); - actual.PackFromScaledVector4(scaled); + actual.FromScaledVector4(scaled); // assert Assert.Equal(expected, actual.PackedValue); @@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(0x1a, 0, 0x80, 0); // act - actual.PackFromRgba32(rgba); + actual.FromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -205,8 +205,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(0x1a, 0, 0x80, 0); // act - rgba.PackFromRgba32(expected); - actual.PackFromRgba32(rgba); + rgba.FromRgba32(expected); + actual.FromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -221,8 +221,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Bgra32(0x1a, 0, 0x80, 0); // act - rgba.PackFromBgra32(expected); - actual.PackFromRgba32(rgba); + rgba.FromBgra32(expected); + actual.FromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -237,8 +237,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Argb32(0x1a, 0, 0x80, 0); // act - rgba.PackFromArgb32(expected); - actual.PackFromRgba32(rgba); + rgba.FromArgb32(expected); + actual.FromRgba32(rgba); // assert Assert.Equal(expected, actual); @@ -253,8 +253,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgb48(65535, 0, 65535); // act - input.PackFromRgb48(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgb48(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); @@ -269,8 +269,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba64(65535, 0, 65535, 0); // act - input.PackFromRgba64(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgba64(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs index e9ac5377d..d6a9db66f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = short4.ToScaledVector4(); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); ulong actual = pixel.PackedValue; // assert @@ -71,8 +71,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { var zero = default(Rgba64); var one = default(Rgba64); - zero.PackFromVector4(Vector4.One * -1234.0f); - one.PackFromVector4(Vector4.One * 1234.0f); + zero.FromVector4(Vector4.One * -1234.0f); + one.FromVector4(Vector4.One * 1234.0f); Assert.Equal(Vector4.Zero, zero.ToVector4()); Assert.Equal(Vector4.One, one.ToVector4()); } diff --git a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs index 9b5fceac7..a6fec9e51 100644 --- a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs @@ -124,8 +124,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgb48(65535, 0, 65535); // act - input.PackFromRgb48(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgb48(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); @@ -140,8 +140,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba64(65535, 0, 65535, 0); // act - input.PackFromRgba64(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgba64(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs index 5f2f45b3b..b15384bf6 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act Vector4 scaled = short2.ToScaledVector4(); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); uint actual = pixel.PackedValue; // assert @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(20, 38, 0, 255); // act - short2.PackFromRgba32(expected); + short2.FromRgba32(expected); actual = short2.ToRgba32(); // assert @@ -119,8 +119,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgb48(65535, 65535, 0); // act - input.PackFromRgb48(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgb48(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); @@ -135,8 +135,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba64(65535, 65535, 0, 65535); // act - input.PackFromRgba64(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgba64(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs index 4245fcf38..6d45606bf 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act var pixel = default(Short4); - pixel.PackFromScaledVector4(scaled); + pixel.FromScaledVector4(scaled); ulong actual = pixel.PackedValue; // assert @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(20, 38, 0, 255); // act - short4.PackFromRgba32(expected); + short4.FromRgba32(expected); actual = short4.ToRgba32(); // assert @@ -123,8 +123,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Bgra32(20, 38, 0, 255); // act - short4.PackFromBgra32(expected); - actual.PackFromRgba32(short4.ToRgba32()); + short4.FromBgra32(expected); + actual.FromRgba32(short4.ToRgba32()); // assert Assert.Equal(expected, actual); @@ -139,8 +139,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Argb32(20, 38, 0, 255); // act - short4.PackFromArgb32(expected); - actual.PackFromRgba32(short4.ToRgba32()); + short4.FromArgb32(expected); + actual.FromRgba32(short4.ToRgba32()); // assert Assert.Equal(expected, actual); @@ -155,8 +155,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgb48(65535, 0, 65535); // act - input.PackFromRgb48(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgb48(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); @@ -171,8 +171,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba64(65535, 0, 65535, 0); // act - input.PackFromRgba64(expected); - actual.PackFromScaledVector4(input.ToScaledVector4()); + input.FromRgba64(expected); + actual.FromScaledVector4(input.ToScaledVector4()); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs index 97ed30b99..d68c37a76 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests { Image image = base.GetImage(); TPixel color = default(TPixel); - color.PackFromRgba32(new Rgba32(this.r, this.g, this.b, this.a)); + color.FromRgba32(new Rgba32(this.r, this.g, this.b, this.a)); image.Mutate(x => x.Fill(color)); return image; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs index 71ae60fab..cc09dc057 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs @@ -163,20 +163,20 @@ namespace SixLabors.ImageSharp.Tests { blue.W = red.W = green.W = (float)x / (float)right; - c.PackFromVector4(red); + c.FromVector4(red); int topBand = top; for (int y = topBand; y < top + height; y++) { pixels[x, y] = c; } topBand = topBand + height; - c.PackFromVector4(green); + c.FromVector4(green); for (int y = topBand; y < topBand + height; y++) { pixels[x, y] = c; } topBand = topBand + height; - c.PackFromVector4(blue); + c.FromVector4(blue); for (int y = topBand; y < bottom; y++) { pixels[x, y] = c; @@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Tests t.PackedValue += stepsPerPixel; Vector4 v = t.ToVector4(); //v.W = (x - left) / (float)left; - c.PackFromVector4(v); + c.FromVector4(v); pixels[x, y] = c; } } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs index 70b630adf..c91ef56a1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs @@ -284,7 +284,7 @@ namespace SixLabors.ImageSharp.Tests { TPixel pixel = img[x, y]; Rgba64 rgbaPixel = default; - rgbaPixel.PackFromScaledVector4(pixel.ToScaledVector4()); + rgbaPixel.FromScaledVector4(pixel.ToScaledVector4()); ushort change = (ushort)Math.Round((perChannelChange / 255F) * 65535F); if (rgbaPixel.R + perChannelChange <= 255) @@ -323,7 +323,7 @@ namespace SixLabors.ImageSharp.Tests rgbaPixel.A -= perChannelChange; } - pixel.PackFromRgba64(rgbaPixel); + pixel.FromRgba64(rgbaPixel); img[x, y] = pixel; } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 2384333bf..9255634b2 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -678,7 +678,7 @@ namespace SixLabors.ImageSharp.Tests { float value = bufferSpan[i] * scale; var v = new Vector4(value, value, value, 1f); - pixels[i].PackFromVector4(v); + pixels[i].FromVector4(v); } return image; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs index 7ce892edb..e998ccd3d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities public TPixel AsPixel() { TPixel pix = default(TPixel); - pix.PackFromVector4(new System.Numerics.Vector4(this.Red, this.Green, this.Blue, this.Alpha)); + pix.FromVector4(new System.Numerics.Vector4(this.Red, this.Green, this.Blue, this.Alpha)); return pix; } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs index 655f5b032..301d0cebe 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Tests v /= 10; var color = default(TPixel); - color.PackFromVector4(v); + color.FromVector4(v); pixels[i, j] = color; } From 11ee7f2aefbdfa82e6248663693044ffc7c60011 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 13:54:25 +0200 Subject: [PATCH 055/238] Rename PackFrom*** -> From***: - in PixelOperations - in T4 templates - in tests --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 4 +- .../Decoder/JpegImagePostProcessor.cs | 2 +- .../Formats/Png/PngScanlineProcessor.cs | 4 +- .../PixelFormats/NamedColors{TPixel}.cs | 2 +- .../DefaultPixelBlenders.Generated.cs | 118 +--------- .../DefaultPixelBlenders.Generated.tt | 214 +++++++++--------- .../PorterDuffFunctions.Generated.tt | 2 +- .../PixelFormats/PixelBlender{TPixel}.cs | 4 +- .../Argb32.PixelOperations.Generated.cs | 2 +- .../Argb32.PixelOperations.Generated.tt | 4 +- .../Bgr24.PixelOperations.Generated.cs | 2 +- .../Bgr24.PixelOperations.Generated.tt | 4 +- .../Bgra32.PixelOperations.Generated.cs | 2 +- .../Bgra32.PixelOperations.Generated.tt | 4 +- .../Gray16.PixelOperations.Generated.cs | 2 +- .../Gray16.PixelOperations.Generated.tt | 4 +- .../Gray8.PixelOperations.Generated.cs | 2 +- .../Gray8.PixelOperations.Generated.tt | 4 +- .../Rgb24.PixelOperations.Generated.cs | 2 +- .../Rgb24.PixelOperations.Generated.tt | 4 +- .../Rgb48.PixelOperations.Generated.cs | 2 +- .../Rgb48.PixelOperations.Generated.tt | 4 +- .../Rgba32.PixelOperations.Generated.cs | 2 +- .../Rgba32.PixelOperations.Generated.tt | 4 +- .../Rgba64.PixelOperations.Generated.cs | 2 +- .../Rgba64.PixelOperations.Generated.tt | 4 +- .../Rgba32.PixelOperations.cs | 6 +- .../RgbaVector.PixelOperations.cs | 2 +- .../PixelOperations{TPixel}.Generated.cs | 82 +++---- .../PixelOperations{TPixel}.Generated.tt | 42 ++-- .../PixelFormats/PixelOperations{TPixel}.cs | 24 +- .../Convolution/Convolution2DProcessor.cs | 2 +- .../Convolution/Convolution2PassProcessor.cs | 2 +- .../Convolution/ConvolutionProcessor.cs | 2 +- .../Processors/Transforms/ResizeProcessor.cs | 2 +- .../Color/Bulk/PackFromVector4.cs | 4 +- .../Color/Bulk/PackFromXyzw.cs | 4 +- .../PixelBlenders/PorterDuffBulkVsPixel.cs | 2 +- tests/ImageSharp.Tests/Issues/Issue594.cs | 24 +- .../PixelFormats/Alpha8Tests.cs | 2 +- .../PixelFormats/Argb32Tests.cs | 2 +- .../PixelFormats/Bgr24Tests.cs | 4 +- .../PixelFormats/Bgr565Tests.cs | 2 +- .../PixelFormats/Bgra32Tests.cs | 4 +- .../PixelFormats/Bgra4444Tests.cs | 2 +- .../PixelFormats/Bgra5551Tests.cs | 2 +- .../PixelFormats/Byte4Tests.cs | 2 +- .../PixelFormats/Gray16Tests.cs | 6 +- .../PixelFormats/Gray8Tests.cs | 6 +- .../PixelFormats/HalfSingleTests.cs | 2 +- .../PixelFormats/HalfVector2Tests.cs | 2 +- .../PixelFormats/HalfVector4Tests.cs | 2 +- .../PixelFormats/NormalizedByte2Tests.cs | 2 +- .../PixelFormats/NormalizedByte4Tests.cs | 2 +- .../PixelFormats/NormalizedShort2Tests.cs | 2 +- .../PixelFormats/NormalizedShort4Tests.cs | 2 +- .../PixelFormats/PixelOperationsTests.cs | 52 ++--- .../PixelFormats/Rg32Tests.cs | 2 +- .../PixelFormats/Rgb24Tests.cs | 4 +- .../PixelFormats/Rgb48Tests.cs | 2 +- .../PixelFormats/Rgba1010102Tests.cs | 2 +- .../PixelFormats/Rgba32Tests.cs | 12 +- .../PixelFormats/Rgba64Tests.cs | 2 +- .../PixelFormats/RgbaVectorTests.cs | 4 +- .../PixelFormats/Short2Tests.cs | 8 +- .../PixelFormats/Short4Tests.cs | 12 +- .../ReferenceCodecs/MagickReferenceDecoder.cs | 4 +- .../ReferenceCodecs/SystemDrawingBridge.cs | 4 +- .../TestUtilities/TestImageExtensions.cs | 2 +- 69 files changed, 321 insertions(+), 437 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 8ebfb37eb..77cd32222 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -436,7 +436,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.stream.Read(row); int newY = Invert(y, height, inverted); Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.PackFromBgr24Bytes(row.GetSpan(), pixelSpan, width); + PixelOperations.Instance.FromBgr24Bytes(row.GetSpan(), pixelSpan, width); } } } @@ -461,7 +461,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.stream.Read(row); int newY = Invert(y, height, inverted); Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.PackFromBgra32Bytes(row.GetSpan(), pixelSpan, width); + PixelOperations.Instance.FromBgra32Bytes(row.GetSpan(), pixelSpan, width); } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs index 94382553c..eb618dff0 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs @@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder Span destRow = destination.GetPixelRowSpan(yy); - PixelOperations.Instance.PackFromVector4(this.rgbaBuffer.GetSpan(), destRow, destination.Width); + PixelOperations.Instance.FromVector4(this.rgbaBuffer.GetSpan(), destRow, destination.Width); } } } diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index b4e5f201f..e4a2562e6 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -377,7 +377,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - PixelOperations.Instance.PackFromRgb24Bytes(scanlineSpan, rowSpan, header.Width); + PixelOperations.Instance.FromRgb24Bytes(scanlineSpan, rowSpan, header.Width); } return; @@ -526,7 +526,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - PixelOperations.Instance.PackFromRgba32Bytes(scanlineSpan, rowSpan, header.Width); + PixelOperations.Instance.FromRgba32Bytes(scanlineSpan, rowSpan, header.Width); } } diff --git a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs index 0f42e182c..1923faa1f 100644 --- a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs @@ -739,7 +739,7 @@ namespace SixLabors.ImageSharp.PixelFormats var safe = new TPixel[constants.Length + 1]; Span constantsBytes = MemoryMarshal.Cast(constants.AsSpan()); - PixelOperations.Instance.PackFromRgba32Bytes(constantsBytes, safe, constants.Length); + PixelOperations.Instance.FromRgba32Bytes(constantsBytes, safe, constants.Length); return safe; } } diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs index c0a38b1a3..1d3cb53af 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs @@ -1,11 +1,4 @@ - - - - - - - -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. // @@ -33,7 +26,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders where TPixel : struct, IPixel { - internal class NormalSrc : PixelBlender { /// @@ -69,7 +61,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplySrc : PixelBlender { /// @@ -105,7 +96,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddSrc : PixelBlender { /// @@ -141,7 +131,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractSrc : PixelBlender { /// @@ -177,7 +166,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenSrc : PixelBlender { /// @@ -213,7 +201,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenSrc : PixelBlender { /// @@ -249,7 +236,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenSrc : PixelBlender { /// @@ -285,7 +271,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlaySrc : PixelBlender { /// @@ -321,7 +306,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightSrc : PixelBlender { /// @@ -357,7 +341,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalSrcAtop : PixelBlender { /// @@ -393,7 +376,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplySrcAtop : PixelBlender { /// @@ -429,7 +411,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddSrcAtop : PixelBlender { /// @@ -465,7 +446,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractSrcAtop : PixelBlender { /// @@ -501,7 +481,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenSrcAtop : PixelBlender { /// @@ -537,7 +516,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenSrcAtop : PixelBlender { /// @@ -573,7 +551,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenSrcAtop : PixelBlender { /// @@ -609,7 +586,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlaySrcAtop : PixelBlender { /// @@ -645,7 +621,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightSrcAtop : PixelBlender { /// @@ -681,7 +656,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalSrcOver : PixelBlender { /// @@ -717,7 +691,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplySrcOver : PixelBlender { /// @@ -753,7 +726,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddSrcOver : PixelBlender { /// @@ -789,7 +761,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractSrcOver : PixelBlender { /// @@ -825,7 +796,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenSrcOver : PixelBlender { /// @@ -861,7 +831,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenSrcOver : PixelBlender { /// @@ -897,7 +866,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenSrcOver : PixelBlender { /// @@ -933,7 +901,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlaySrcOver : PixelBlender { /// @@ -969,7 +936,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightSrcOver : PixelBlender { /// @@ -1005,7 +971,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalSrcIn : PixelBlender { /// @@ -1041,7 +1006,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplySrcIn : PixelBlender { /// @@ -1077,7 +1041,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddSrcIn : PixelBlender { /// @@ -1113,7 +1076,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractSrcIn : PixelBlender { /// @@ -1149,7 +1111,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenSrcIn : PixelBlender { /// @@ -1185,7 +1146,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenSrcIn : PixelBlender { /// @@ -1221,7 +1181,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenSrcIn : PixelBlender { /// @@ -1257,7 +1216,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlaySrcIn : PixelBlender { /// @@ -1293,7 +1251,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightSrcIn : PixelBlender { /// @@ -1329,7 +1286,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalSrcOut : PixelBlender { /// @@ -1365,7 +1321,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplySrcOut : PixelBlender { /// @@ -1401,7 +1356,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddSrcOut : PixelBlender { /// @@ -1437,7 +1391,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractSrcOut : PixelBlender { /// @@ -1473,7 +1426,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenSrcOut : PixelBlender { /// @@ -1509,7 +1461,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenSrcOut : PixelBlender { /// @@ -1545,7 +1496,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenSrcOut : PixelBlender { /// @@ -1581,7 +1531,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlaySrcOut : PixelBlender { /// @@ -1617,7 +1566,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightSrcOut : PixelBlender { /// @@ -1653,7 +1601,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalDest : PixelBlender { /// @@ -1689,7 +1636,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyDest : PixelBlender { /// @@ -1725,7 +1671,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddDest : PixelBlender { /// @@ -1761,7 +1706,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractDest : PixelBlender { /// @@ -1797,7 +1741,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenDest : PixelBlender { /// @@ -1833,7 +1776,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenDest : PixelBlender { /// @@ -1869,7 +1811,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenDest : PixelBlender { /// @@ -1905,7 +1846,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayDest : PixelBlender { /// @@ -1941,7 +1881,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightDest : PixelBlender { /// @@ -1977,7 +1916,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalDestAtop : PixelBlender { /// @@ -2013,7 +1951,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyDestAtop : PixelBlender { /// @@ -2049,7 +1986,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddDestAtop : PixelBlender { /// @@ -2085,7 +2021,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractDestAtop : PixelBlender { /// @@ -2121,7 +2056,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenDestAtop : PixelBlender { /// @@ -2157,7 +2091,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenDestAtop : PixelBlender { /// @@ -2193,7 +2126,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenDestAtop : PixelBlender { /// @@ -2229,7 +2161,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayDestAtop : PixelBlender { /// @@ -2265,7 +2196,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightDestAtop : PixelBlender { /// @@ -2301,7 +2231,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalDestOver : PixelBlender { /// @@ -2337,7 +2266,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyDestOver : PixelBlender { /// @@ -2373,7 +2301,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddDestOver : PixelBlender { /// @@ -2409,7 +2336,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractDestOver : PixelBlender { /// @@ -2445,7 +2371,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenDestOver : PixelBlender { /// @@ -2481,7 +2406,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenDestOver : PixelBlender { /// @@ -2517,7 +2441,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenDestOver : PixelBlender { /// @@ -2553,7 +2476,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayDestOver : PixelBlender { /// @@ -2589,7 +2511,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightDestOver : PixelBlender { /// @@ -2625,7 +2546,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalDestIn : PixelBlender { /// @@ -2661,7 +2581,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyDestIn : PixelBlender { /// @@ -2697,7 +2616,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddDestIn : PixelBlender { /// @@ -2733,7 +2651,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractDestIn : PixelBlender { /// @@ -2769,7 +2686,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenDestIn : PixelBlender { /// @@ -2805,7 +2721,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenDestIn : PixelBlender { /// @@ -2841,7 +2756,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenDestIn : PixelBlender { /// @@ -2877,7 +2791,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayDestIn : PixelBlender { /// @@ -2913,7 +2826,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightDestIn : PixelBlender { /// @@ -2949,7 +2861,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalDestOut : PixelBlender { /// @@ -2985,7 +2896,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyDestOut : PixelBlender { /// @@ -3021,7 +2931,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddDestOut : PixelBlender { /// @@ -3057,7 +2966,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractDestOut : PixelBlender { /// @@ -3093,7 +3001,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenDestOut : PixelBlender { /// @@ -3129,7 +3036,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenDestOut : PixelBlender { /// @@ -3165,7 +3071,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenDestOut : PixelBlender { /// @@ -3201,7 +3106,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayDestOut : PixelBlender { /// @@ -3237,7 +3141,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightDestOut : PixelBlender { /// @@ -3273,7 +3176,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalClear : PixelBlender { /// @@ -3309,7 +3211,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyClear : PixelBlender { /// @@ -3345,7 +3246,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddClear : PixelBlender { /// @@ -3381,7 +3281,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractClear : PixelBlender { /// @@ -3417,7 +3316,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenClear : PixelBlender { /// @@ -3453,7 +3351,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenClear : PixelBlender { /// @@ -3489,7 +3386,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenClear : PixelBlender { /// @@ -3525,7 +3421,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayClear : PixelBlender { /// @@ -3561,7 +3456,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightClear : PixelBlender { /// @@ -3597,7 +3491,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class NormalXor : PixelBlender { /// @@ -3633,7 +3526,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class MultiplyXor : PixelBlender { /// @@ -3669,7 +3561,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class AddXor : PixelBlender { /// @@ -3705,7 +3596,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class SubtractXor : PixelBlender { /// @@ -3741,7 +3631,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class ScreenXor : PixelBlender { /// @@ -3777,7 +3666,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class DarkenXor : PixelBlender { /// @@ -3813,7 +3701,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class LightenXor : PixelBlender { /// @@ -3849,7 +3736,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class OverlayXor : PixelBlender { /// @@ -3885,7 +3771,6 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - internal class HardLightXor : PixelBlender { /// @@ -3921,6 +3806,5 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders } } - } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt index f776da7a0..b7ea7a9d4 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt @@ -1,114 +1,114 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// using System; using System.Numerics; using System.Buffers; using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; - -namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders -{ - /// - /// Collection of Porter Duff alpha blending functions applying different composition models. - /// - /// - /// These functions are designed to be a general solution for all color cases, - /// that is, they take in account the alpha value of both the backdrop - /// and source, and there's no need to alpha-premultiply neither the backdrop - /// nor the source. - /// Note there are faster functions for when the backdrop color is known - /// to be opaque - /// - internal static class DefaultPixelBlenders - where TPixel : struct, IPixel - { - -<# - string[] composers = new []{ - "Src", - "SrcAtop", - "SrcOver", - "SrcIn", - "SrcOut", - "Dest", - "DestAtop", - "DestOver", - "DestIn", - "DestOut", - "Clear", - "Xor", - }; - - string[] blenders = new []{ - "Normal", - "Multiply", - "Add", - "Subtract", - "Screen", - "Darken", - "Lighten", - "Overlay", - "HardLight" - }; - - foreach(var composer in composers) { - foreach(var blender in blenders) { - - string blender_composer= $"{blender}{composer}"; - -#> - internal class <#= blender_composer#> : PixelBlender - { - /// - /// Gets the static instance of this blender. - /// - public static <#=blender_composer#> Instance { get; } = new <#=blender_composer#>(); - - /// - public override TPixel Blend(TPixel background, TPixel source, float amount) - { +using SixLabors.Memory; + +namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders +{ + /// + /// Collection of Porter Duff alpha blending functions applying different composition models. + /// + /// + /// These functions are designed to be a general solution for all color cases, + /// that is, they take in account the alpha value of both the backdrop + /// and source, and there's no need to alpha-premultiply neither the backdrop + /// nor the source. + /// Note there are faster functions for when the backdrop color is known + /// to be opaque + /// + internal static class DefaultPixelBlenders + where TPixel : struct, IPixel + { + +<# + string[] composers = new []{ + "Src", + "SrcAtop", + "SrcOver", + "SrcIn", + "SrcOut", + "Dest", + "DestAtop", + "DestOver", + "DestIn", + "DestOut", + "Clear", + "Xor", + }; + + string[] blenders = new []{ + "Normal", + "Multiply", + "Add", + "Subtract", + "Screen", + "Darken", + "Lighten", + "Overlay", + "HardLight" + }; + + foreach(var composer in composers) { + foreach(var blender in blenders) { + + string blender_composer= $"{blender}{composer}"; + +#> + internal class <#= blender_composer#> : PixelBlender + { + /// + /// Gets the static instance of this blender. + /// + public static <#=blender_composer#> Instance { get; } = new <#=blender_composer#>(); + + /// + public override TPixel Blend(TPixel background, TPixel source, float amount) + { TPixel dest = default; - dest.PackFromScaledVector4(PorterDuffFunctions.<#=blender_composer#>(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); - return dest; - } - - /// - protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount) - { - amount = amount.Clamp(0, 1); - for (int i = 0; i < destination.Length; i++) - { - destination[i] = PorterDuffFunctions.<#=blender_composer#>(background[i], source[i], amount); - } - } - - /// - protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) - { - for (int i = 0; i < destination.Length; i++) - { - destination[i] = PorterDuffFunctions.<#=blender_composer#>(background[i], source[i], amount[i].Clamp(0, 1)); - } - } - } - -<# - } - } - -#> - } + dest.FromScaledVector4(PorterDuffFunctions.<#=blender_composer#>(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1))); + return dest; + } + + /// + protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount) + { + amount = amount.Clamp(0, 1); + for (int i = 0; i < destination.Length; i++) + { + destination[i] = PorterDuffFunctions.<#=blender_composer#>(background[i], source[i], amount); + } + } + + /// + protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) + { + for (int i = 0; i < destination.Length; i++) + { + destination[i] = PorterDuffFunctions.<#=blender_composer#>(background[i], source[i], amount[i].Clamp(0, 1)); + } + } + } + +<# + } + } + +#> + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt index 73c835e60..e21a78031 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt @@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders { opacity = opacity.Clamp(0, 1); TPixel dest = default; - dest.PackFromScaledVector4(<#=blender#><#=composer#>(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); + dest.FromScaledVector4(<#=blender#><#=composer#>(backdrop.ToScaledVector4(), source.ToScaledVector4(), opacity)); return dest; } diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index cca4a1017..48a83335a 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.PixelFormats this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.PackFromScaledVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromScaledVector4(destinationSpan, destination, destination.Length); } } @@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp.PixelFormats this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.PackFromScaledVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromScaledVector4(destinationSpan, destination, destination.Length); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 2fa7df94e..16121d62d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt index f35adee02..f90384671 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromArgb32(sp); + dp.FromArgb32(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 950c6d5d9..cbfbe7099 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt index 76163549b..0f7bd838f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgr24(sp); + dp.FromBgr24(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index f29fa78ec..edd702e0e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt index 4c2925d18..4c4e10fad 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBgra32(sp); + dp.FromBgra32(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index 1b679c50a..ca0e1fe32 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt index b900e343a..1e500dac5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray16(sp); + dp.FromGray16(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index 1be3cc468..6950c337d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt index 4590420e5..7c6e2f767 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromGray8(sp); + dp.FromGray8(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index c6a7c7069..53234cd66 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt index 6a10b401f..b98e1e4c7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb24(sp); + dp.FromRgb24(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index dcc0f3802..61d13978a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt index e38c85bf6..2ff3125b4 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgb48(sp); + dp.FromRgb48(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index 63dbc7405..ae2ffd688 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations { /// - internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt index 23d0be740..fb8d6db34 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba32(sp); + dp.FromRgba32(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations { /// - internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index f92fe8ec7..252068828 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt index e99834157..626f2316d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt @@ -26,7 +26,7 @@ ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromRgba64(sp); + dp.FromRgba64(sp); } } <# @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 13432e58f..4da9f101b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); @@ -52,9 +52,9 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - this.PackFromVector4(sourceVectors, destinationColors, count); + this.FromVector4(sourceVectors, destinationColors, count); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index aae6ee694..ae64ed4de 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs index 2708af074..f1d426389 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs @@ -1,13 +1,13 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. - // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - public partial class PixelOperations { /// @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -33,16 +33,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -103,16 +103,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -173,16 +173,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -243,16 +243,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -296,7 +296,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -313,16 +313,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -366,7 +366,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -383,16 +383,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -436,7 +436,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -453,16 +453,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -506,7 +506,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -523,16 +523,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// @@ -576,7 +576,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -593,16 +593,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); } /// diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt index 913dabb08..723b0358f 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt @@ -11,7 +11,7 @@ <#@ output extension=".cs" #> <# - void GeneratePackFromMethods(string pixelType) + void GenerateFromMethods(string pixelType) { #> @@ -21,7 +21,7 @@ /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) + internal virtual void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -33,21 +33,21 @@ ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFrom<#=pixelType#>(sp); + dp.From<#=pixelType#>(sp); } } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void From<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); + this.From<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); } <# @@ -74,7 +74,7 @@ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i); - dp.PackFromScaledVector4(sp.ToScaledVector4()); + dp.FromScaledVector4(sp.ToScaledVector4()); } } @@ -96,42 +96,42 @@ #> // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. - // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - public partial class PixelOperations {<# - GeneratePackFromMethods("Argb32"); + GenerateFromMethods("Argb32"); GenerateToDestFormatMethods("Argb32"); - GeneratePackFromMethods("Bgr24"); + GenerateFromMethods("Bgr24"); GenerateToDestFormatMethods("Bgr24"); - GeneratePackFromMethods("Bgra32"); + GenerateFromMethods("Bgra32"); GenerateToDestFormatMethods("Bgra32"); - GeneratePackFromMethods("Gray8"); + GenerateFromMethods("Gray8"); GenerateToDestFormatMethods("Gray8"); - GeneratePackFromMethods("Gray16"); + GenerateFromMethods("Gray16"); GenerateToDestFormatMethods("Gray16"); - GeneratePackFromMethods("Rgb24"); + GenerateFromMethods("Rgb24"); GenerateToDestFormatMethods("Rgb24"); - GeneratePackFromMethods("Rgba32"); + GenerateFromMethods("Rgba32"); GenerateToDestFormatMethods("Rgba32"); - GeneratePackFromMethods("Rgb48"); + GenerateFromMethods("Rgb48"); GenerateToDestFormatMethods("Rgb48"); - GeneratePackFromMethods("Rgba64"); + GenerateFromMethods("Rgba64"); GenerateToDestFormatMethods("Rgba64"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 926b234d7..af7690c62 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The to the source vectors. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal virtual void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The to the source vectors. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal virtual void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); @@ -108,12 +108,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Performs a bulk conversion of a collection of one pixel format into another. /// - /// The pixel format. + /// The pixel format. /// The to the source colors. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void To(ReadOnlySpan sourceColors, Span destinationColors, int count) - where TPixel2 : struct, IPixel + internal virtual void To(ReadOnlySpan sourceColors, Span destinationColors, int count) + where TDestinationPixel : struct, IPixel { GuardSpans(sourceColors, nameof(sourceColors), destinationColors, nameof(destinationColors), count); @@ -121,11 +121,11 @@ namespace SixLabors.ImageSharp.PixelFormats // Gray8 and Gray16 are special implementations of IPixel in that they do not conform to the // standard RGBA colorspace format and must be converted from RGBA using the special ITU BT709 alogrithm. - // One of the requirements of PackFromScaledVector4/ToScaledVector4 is that it unaware of this and + // One of the requirements of FromScaledVector4/ToScaledVector4 is that it unaware of this and // packs/unpacks the pixel without and conversion so we employ custom methods do do this. - if (typeof(TPixel2).Equals(typeof(Gray16))) + if (typeof(TDestinationPixel) == typeof(Gray16)) { - ref Gray16 gray16Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + ref Gray16 gray16Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); @@ -136,9 +136,9 @@ namespace SixLabors.ImageSharp.PixelFormats return; } - if (typeof(TPixel2).Equals(typeof(Gray8))) + if (typeof(TDestinationPixel) == typeof(Gray8)) { - ref Gray8 gray8Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + ref Gray8 gray8Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); @@ -150,11 +150,11 @@ namespace SixLabors.ImageSharp.PixelFormats } // Normal converson - ref TPixel2 destRef = ref MemoryMarshal.GetReference(destinationColors); + ref TDestinationPixel destRef = ref MemoryMarshal.GetReference(destinationColors); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel2 dp = ref Unsafe.Add(ref destRef, i); + ref TDestinationPixel dp = ref Unsafe.Add(ref destRef, i); dp.FromScaledVector4(sp.ToScaledVector4()); } } diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs index 0669a1247..df4df64ca 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve2D(in matrixY, in matrixX, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.PackFromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); } }); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs index 1f47649e6..03447531e 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve(in matrix, sourcePixels, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.PackFromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); } }); } diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs index d2f3f8fc5..a42b777fe 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve(in matrix, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.PackFromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); } }); diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index 812c0578b..5bd61aab1 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -309,7 +309,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } Span targetRowSpan = destination.GetPixelRowSpan(y); - PixelOperations.Instance.PackFromVector4(tempRowSpan, targetRowSpan, tempRowSpan.Length); + PixelOperations.Instance.FromVector4(tempRowSpan, targetRowSpan, tempRowSpan.Length); } }); } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index e39c464f1..3839bf58e 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -59,13 +59,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().PackFromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + new PixelOperations().FromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.PackFromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + PixelOperations.Instance.FromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs index 527235104..b1025e80c 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs @@ -55,13 +55,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void CommonBulk() { - new PixelOperations().PackFromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + new PixelOperations().FromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } [Benchmark] public void OptimizedBulk() { - PixelOperations.Instance.PackFromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + PixelOperations.Instance.FromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); } } diff --git a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs index d9cf65d4b..46b58f369 100644 --- a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs +++ b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Benchmarks destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]); } - PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromVector4(destinationSpan, destination, destination.Length); } } diff --git a/tests/ImageSharp.Tests/Issues/Issue594.cs b/tests/ImageSharp.Tests/Issues/Issue594.cs index 48e355ea7..927f0a5ed 100644 --- a/tests/ImageSharp.Tests/Issues/Issue594.cs +++ b/tests/ImageSharp.Tests/Issues/Issue594.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Issues Assert.Equal(0, scaled.Z); Assert.Equal(0, scaled.W); - // Test PackFromScaledVector4. + // Test FromScaledVector4. var pixel = default(NormalizedByte4); pixel.FromScaledVector4(scaled); Assert.Equal(0x81818181, pixel.PackedValue); @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Tests.Issues // http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8 //var r = default(NormalizedByte4); - //r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); + //r.FromRgba32(new Rgba32(9, 115, 202, 127)); //r.ToRgba32(ref rgba); //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); @@ -80,12 +80,12 @@ namespace SixLabors.ImageSharp.Tests.Issues //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); //r = default(NormalizedByte4); - //r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + //r.FromArgb32(new Argb32(9, 115, 202, 127)); //r.ToArgb32(ref argb); //Assert.Equal(argb, new Argb32(9, 115, 202, 127)); //r = default(NormalizedByte4); - //r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + //r.FromBgra32(new Bgra32(9, 115, 202, 127)); //r.ToBgra32(ref bgra); //Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); } @@ -114,7 +114,7 @@ namespace SixLabors.ImageSharp.Tests.Issues Assert.Equal(1, scaled.Z); Assert.Equal(1, scaled.W); - // Test PackFromScaledVector4. + // Test FromScaledVector4. var pixel = default(NormalizedShort4); pixel.FromScaledVector4(scaled); Assert.Equal((ulong)0x7FFF7FFF7FFF7FFF, pixel.PackedValue); @@ -149,17 +149,17 @@ namespace SixLabors.ImageSharp.Tests.Issues //Assert.Equal(argb, new Argb32(141, 90, 192, 39)); //var r = default(NormalizedShort4); - //r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); + //r.FromRgba32(new Rgba32(9, 115, 202, 127)); //r.ToRgba32(ref rgba); //Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); //r = default(NormalizedShort4); - //r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + //r.FromBgra32(new Bgra32(9, 115, 202, 127)); //r.ToBgra32(ref bgra); //Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); //r = default(NormalizedShort4); - //r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + //r.FromArgb32(new Argb32(9, 115, 202, 127)); //r.ToArgb32(ref argb); //Assert.Equal(argb, new Argb32(9, 115, 202, 127)); } @@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.Tests.Issues Assert.Equal(1, scaled.Z); Assert.Equal(1, scaled.W); - // Test PackFromScaledVector4. + // Test FromScaledVector4. var pixel = default(Short4); pixel.FromScaledVector4(scaled); Assert.Equal((ulong)0x7FFF7FFF7FFF7FFF, pixel.PackedValue); @@ -234,17 +234,17 @@ namespace SixLabors.ImageSharp.Tests.Issues //Assert.Equal(argb, new Argb32(172, 177, 243, 128)); //var r = default(Short4); - //r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); + //r.FromRgba32(new Rgba32(20, 38, 0, 255)); //r.ToRgba32(ref rgba); //Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); //r = default(Short4); - //r.PackFromBgra32(new Bgra32(20, 38, 0, 255)); + //r.FromBgra32(new Bgra32(20, 38, 0, 255)); //r.ToBgra32(ref bgra); //Assert.Equal(bgra, new Bgra32(20, 38, 0, 255)); //r = default(Short4); - //r.PackFromArgb32(new Argb32(20, 38, 0, 255)); + //r.FromArgb32(new Argb32(20, 38, 0, 255)); //r.ToArgb32(ref argb); //Assert.Equal(argb, new Argb32(20, 38, 0, 255)); } diff --git a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs index 067c1a977..148b928fa 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Alpha8_PackFromScaledVector4() + public void Alpha8_FromScaledVector4() { // Arrange Alpha8 alpha = default; diff --git a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs index 31b9a53a0..b9f741490 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Argb32Tests.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Argb32_PackFromScaledVector4() + public void Argb32_FromScaledVector4() { // arrange Vector4 scaled = new Argb32(Vector4.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index ce284f420..2295fbe56 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] - public void PackFromRgba32() + public void FromRgba32() { var rgb = default(Bgr24); rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); @@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats a / 255f); [Fact] - public void PackFromVector4() + public void FromVector4() { var rgb = default(Bgr24); rgb.FromVector4(Vec(1, 2, 3, 4)); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs index 5033788b8..967e358e1 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr565Tests.cs @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Bgr565_PackFromScaledVector4() + public void Bgr565_FromScaledVector4() { // arrange Vector4 scaled = new Bgr565(Vector3.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs index 93993cc39..a5c53ed8b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Fact] - public void PackFromRgba32() + public void FromRgba32() { var rgb = default(Rgb24); rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); @@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats a / 255f); [Fact] - public void PackFromVector4() + public void FromVector4() { var c = default(Bgra32); c.FromVector4(Vec(1, 2, 3, 4)); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs index 3f6b7653f..8b56ec19f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra4444Tests.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Bgra4444_PackFromScaledVector4() + public void Bgra4444_FromScaledVector4() { // arrange Vector4 scaled = new Bgra4444(Vector4.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs index eaf397bb5..76edee8a7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra5551Tests.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Bgra5551_PackFromScaledVector4() + public void Bgra5551_FromScaledVector4() { // arrange Vector4 scaled = new Bgra5551(Vector4.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs index c172bbdac..8391ef25a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Byte4Tests.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Byte4_PackFromScaledVector4() + public void Byte4_FromScaledVector4() { // arrange Vector4 scaled = new Byte4(Vector4.One * 255).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs index 69a44a9bb..220ca2899 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats => Assert.Equal(input, new Gray16(input).PackedValue); [Fact] - public void Gray16_PackFromScaledVector4() + public void Gray16_FromScaledVector4() { // Arrange Gray16 gray = default; @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Gray16_PackFromVector4() + public void Gray16_FromVector4() { // Arrange Gray16 gray = default; @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Gray16_PackFromRgba32() + public void Gray16_FromRgba32() { // Arrange Gray16 gray = default; diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index 7886be9e0..988002c09 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats => Assert.Equal(input, new Gray8(input).PackedValue); [Fact] - public void Gray8_PackFromScaledVector4() + public void Gray8_FromScaledVector4() { // Arrange Gray8 gray = default; @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Gray8_PackFromVector4() + public void Gray8_FromVector4() { // Arrange Gray8 gray = default; @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Gray8_PackFromRgba32() + public void Gray8_FromRgba32() { // Arrange Gray8 gray = default; diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs index a503db01c..85a3b8b32 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfSingleTests.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void HalfSingle_PackFromScaledVector4() + public void HalfSingle_FromScaledVector4() { // arrange Vector4 scaled = new HalfSingle(-1F).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs index a892b8413..ccdd23e8f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector2Tests.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void HalfVector2_PackFromScaledVector4() + public void HalfVector2_FromScaledVector4() { // arrange Vector4 scaled = new HalfVector2(Vector2.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs index 02a05a76f..c61dd97d2 100644 --- a/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/HalfVector4Tests.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void HalfVector4_PackFromScaledVector4() + public void HalfVector4_FromScaledVector4() { // arrange var halfVector4 = default(HalfVector4); diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs index faaeae6cc..506ebe0fe 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte2Tests.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void NormalizedByte2_PackFromScaledVector4() + public void NormalizedByte2_FromScaledVector4() { // arrange Vector4 scaled = new NormalizedByte2(-Vector2.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs index 4465fbaed..19a49e5d8 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedByte4Tests.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void NormalizedByte4_PackFromScaledVector4() + public void NormalizedByte4_FromScaledVector4() { // arrange var pixel = default(NormalizedByte4); diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs index 4f66d04e3..216ed4ad7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort2Tests.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void NormalizedShort2_PackFromScaledVector4() + public void NormalizedShort2_FromScaledVector4() { // arrange Vector4 scaled = new NormalizedShort2(-Vector2.One).ToScaledVector4(); diff --git a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs index b93960dbf..d06d46d06 100644 --- a/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/NormalizedShort4Tests.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void NormalizedShort4_PackFromScaledVector4() + public void NormalizedShort4_FromScaledVector4() { // arrange var pixel = default(NormalizedShort4); diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index ef57458c9..958c4744a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromGray8Bytes(int count) + public void FromGray8Bytes(int count) { byte[] source = CreateByteTestData(count); var expected = new Gray8[count]; @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray8Bytes(s, d.GetSpan(), count) ); } @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromGray16Bytes(int count) + public void FromGray16Bytes(int count) { byte[] source = CreateByteTestData(count * 2); Span sourceSpan = source.AsSpan(); @@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray16Bytes(s, d.GetSpan(), count) ); } @@ -164,7 +164,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromGray8Bytes(int count) + public void FromGray8Bytes(int count) { byte[] source = CreateByteTestData(count); var expected = new Gray16[count]; @@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray8Bytes(s, d.GetSpan(), count) ); } @@ -204,7 +204,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromGray16Bytes(int count) + public void FromGray16Bytes(int count) { byte[] source = CreateByteTestData(count * 2); Span sourceSpan = source.AsSpan(); @@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray16Bytes(s, d.GetSpan(), count) ); } @@ -359,7 +359,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromVector4(int count) + public void FromVector4(int count) { Vector4[] source = CreateVector4TestData(count); TPixel[] expected = CreateExpectedPixelData(source); @@ -367,13 +367,13 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromVector4(s, d.GetSpan(), count) + (s, d) => Operations.FromVector4(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromScaledVector4(int count) + public void FromScaledVector4(int count) { Vector4[] source = CreateVector4TestData(count); TPixel[] expected = CreateScaledExpectedPixelData(source); @@ -381,7 +381,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromScaledVector4(s, d.GetSpan(), count) + (s, d) => Operations.FromScaledVector4(s, d.GetSpan(), count) ); } @@ -437,7 +437,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromArgb32Bytes(int count) + public void FromArgb32Bytes(int count) { byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; @@ -452,7 +452,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromArgb32Bytes(s, d.GetSpan(), count) ); } @@ -484,7 +484,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgr24Bytes(int count) + public void FromBgr24Bytes(int count) { byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; @@ -499,7 +499,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromBgr24Bytes(s, d.GetSpan(), count) ); } @@ -529,7 +529,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgra32Bytes(int count) + public void FromBgra32Bytes(int count) { byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; @@ -544,7 +544,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromBgra32Bytes(s, d.GetSpan(), count) ); } @@ -575,7 +575,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb24Bytes(int count) + public void FromRgb24Bytes(int count) { byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; @@ -590,7 +590,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgb24Bytes(s, d.GetSpan(), count) ); } @@ -620,7 +620,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba32Bytes(int count) + public void FromRgba32Bytes(int count) { byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; @@ -635,7 +635,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgba32Bytes(s, d.GetSpan(), count) ); } @@ -666,7 +666,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb48Bytes(int count) + public void FromRgb48Bytes(int count) { byte[] source = CreateByteTestData(count * 6); Span sourceSpan = source.AsSpan(); @@ -681,7 +681,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgb48Bytes(s, d.GetSpan(), count) ); } @@ -715,7 +715,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba64Bytes(int count) + public void FromRgba64Bytes(int count) { byte[] source = CreateByteTestData(count * 8); Span sourceSpan = source.AsSpan(); @@ -730,7 +730,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgba64Bytes(s, d.GetSpan(), count) ); } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs index d4347cae6..46e5fbc3c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rg32Tests.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rg32_PackFromScaledVector4() + public void Rg32_FromScaledVector4() { // arrange var rg32 = new Rg32(Vector2.One); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index 918a147d9..a60509146 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void PackFromRgba32() + public void FromRgba32() { var rgb = default(Rgb24); rgb.FromRgba32(new Rgba32(1, 2, 3, 4)); @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats a / 255f); [Fact] - public void PackFromVector4() + public void FromVector4() { var rgb = default(Rgb24); rgb.FromVector4(Vec(1, 2, 3, 4)); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs index 444a62792..a7f0e5edf 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats => Assert.Equal(Vector4.One, new Rgb48(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue).ToVector4()); [Fact] - public void Rgb48_PackFromScaledVector4() + public void Rgb48_FromScaledVector4() { // arrange var pixel = default(Rgb48); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs index 16aad79a0..ad7df3076 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba1010102_PackFromScaledVector4() + public void Rgba1010102_FromScaledVector4() { // arrange var rgba = new Rgba1010102(Vector4.One); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs index df83d14fb..8c702f66d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs @@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromScaledVector4() + public void Rgba32_FromScaledVector4() { // arrange var rgba = new Rgba32(Vector4.One); @@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromRgba32_ToRgba32() + public void Rgba32_FromRgba32_ToRgba32() { // arrange var rgba = default(Rgba32); @@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromBgra32_ToRgba32() + public void Rgba32_FromBgra32_ToRgba32() { // arrange var rgba = default(Rgba32); @@ -229,7 +229,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromArgb32_ToArgb32() + public void Rgba32_FromArgb32_ToArgb32() { // arrange var rgba = default(Rgba32); @@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromRgb48() + public void Rgba32_FromRgb48() { // arrange var input = default(Rgba32); @@ -261,7 +261,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba32_PackFromRgba64() + public void Rgba32_FromRgba64() { // arrange var input = default(Rgba32); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs index d6a9db66f..564c26b8b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Rgba64_PackFromScaledVector4() + public void Rgba64_FromScaledVector4() { // arrange var pixel = default(Rgba64); diff --git a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs index a6fec9e51..e880e3851 100644 --- a/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/RgbaVectorTests.cs @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void RgbaVector_PackFromRgb48() + public void RgbaVector_FromRgb48() { // arrange var input = default(RgbaVector); @@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void RgbaVector_PackFromRgba64() + public void RgbaVector_FromRgba64() { // arrange var input = default(RgbaVector); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs index b15384bf6..725e1a0d1 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short2_PackFromScaledVector4() + public void Short2_FromScaledVector4() { // arrange var pixel = default(Short2); @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short2_PackFromRgba32_ToRgba32() + public void Short2_FromRgba32_ToRgba32() { // arrange var short2 = default(Short2); @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short2_PackFromRgb48() + public void Short2_FromRgb48() { // arrange var input = default(Short2); @@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short2_PackFromRgba64() + public void Short2_FromRgba64() { // arrange var input = default(Short2); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs index 6d45606bf..b19917f34 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromScaledVector4() + public void Short4_FromScaledVector4() { // arrange var short4 = new Short4(Vector4.One * 0x7FFF); @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromRgba32_ToRgba32() + public void Short4_FromRgba32_ToRgba32() { // arrange var short4 = default(Short4); @@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromBgra32_ToRgba32() + public void Short4_FromBgra32_ToRgba32() { // arrange var short4 = default(Short4); @@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromArgb32_ToRgba32() + public void Short4_FromArgb32_ToRgba32() { // arrange var short4 = default(Short4); @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromRgb48_ToRgb48() + public void Short4_FromRgb48_ToRgb48() { // arrange var input = default(Short4); @@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Fact] - public void Short4_PackFromRgba64_ToRgba64() + public void Short4_FromRgba64_ToRgba64() { // arrange var input = default(Short4); diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs index 7e942691e..2409ff9ad 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs @@ -31,14 +31,14 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs { byte[] data = pixels.ToByteArray(PixelMapping.RGBA); - PixelOperations.Instance.PackFromRgba32Bytes(data, resultPixels, resultPixels.Length); + PixelOperations.Instance.FromRgba32Bytes(data, resultPixels, resultPixels.Length); } else if (magickImage.Depth == 16) { ushort[] data = pixels.ToShortArray(PixelMapping.RGBA); Span bytes = MemoryMarshal.Cast(data.AsSpan()); - PixelOperations.Instance.PackFromRgba64Bytes(bytes, resultPixels, resultPixels.Length); + PixelOperations.Instance.FromRgba64Bytes(bytes, resultPixels, resultPixels.Length); } else { diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index d06f5630f..1543e2c8f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.PackFromBgra32(workBuffer.GetSpan(), row, row.Length); + PixelOperations.Instance.FromBgra32(workBuffer.GetSpan(), row, row.Length); } } } @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.PackFromBgr24(workBuffer.GetSpan(), row, row.Length); + PixelOperations.Instance.FromBgr24(workBuffer.GetSpan(), row, row.Length); } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 9255634b2..78927dece 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests v.W = 1F; } - PixelOperations.Instance.PackFromScaledVector4(tempSpan, pixelSpan, pixelSpan.Length); + PixelOperations.Instance.FromScaledVector4(tempSpan, pixelSpan, pixelSpan.Length); } } }); From b8a4741da46c7db39b6e5919448e8905cf8e82a0 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 13:56:47 +0200 Subject: [PATCH 056/238] rename stuff in Benchmarks --- .../Color/Bulk/{PackFromXyzw.cs => FromRgba32Bytes.cs} | 4 ++-- .../Color/Bulk/{PackFromVector4.cs => FromVector4.cs} | 4 ++-- .../PixelConversion/PixelConversion_ConvertFromRgba32.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename tests/ImageSharp.Benchmarks/Color/Bulk/{PackFromXyzw.cs => FromRgba32Bytes.cs} (94%) rename tests/ImageSharp.Benchmarks/Color/Bulk/{PackFromVector4.cs => FromVector4.cs} (98%) diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs similarity index 94% rename from tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs rename to tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs index b1025e80c..f3245ebaf 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs @@ -13,7 +13,7 @@ using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { - public abstract class PackFromXyzw + public abstract class FromRgba32Bytes where TPixel : struct, IPixel { private IMemoryOwner destination; @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - public class PackFromXyzw_Rgba32 : PackFromXyzw + public class FromRgba32BytesRgba32 : FromRgba32Bytes { } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs similarity index 98% rename from tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs rename to tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 3839bf58e..72322f0d4 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -17,7 +17,7 @@ using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { [Config(typeof(Config.ShortClr))] - public abstract class PackFromVector4 + public abstract class FromVector4 where TPixel : struct, IPixel { protected IMemoryOwner source; @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - public class PackFromVector4_Rgba32 : PackFromVector4 + public class FromVector4Rgba32 : FromVector4 { [Benchmark] public void FallbackIntrinsics128() diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index 046c7dd90..6a96c8576 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -133,6 +133,6 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion * !!! Conclusion !!! * All memory-incompatible (permuted) variants are equivalent with the the "FromBytes" solution. * In memory compatible cases we should use the optimized Bulk-copying variant anyways, - * so there is no benefit introducing non-bulk API-s other than PackFromBytes() OR PackFromRgba32(). + * so there is no benefit introducing non-bulk API-s other than FromBytes() OR FromRgba32(). */ } \ No newline at end of file From 560957bf0a3271f709e20c3f8cc3b3a57aed064e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 14:18:15 +0200 Subject: [PATCH 057/238] Introduce RgbaCompatible.Common.ttinclude --- .../Argb32.PixelOperations.Generated.cs | 12 ++-- .../Argb32.PixelOperations.Generated.tt | 58 +++---------------- .../Generated/RgbaCompatible.Common.ttinclude | 36 ++++++++++++ 3 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 16121d62d..507c8cd3a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -1,19 +1,19 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. - // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Argb32 { - /// /// Provides optimized overrides for bulk operations. /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt index f90384671..432421166 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt @@ -1,53 +1,13 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="RgbaCompatible.Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromArgb32(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Argb32 { - /// /// Provides optimized overrides for bulk operations. /// @@ -70,14 +30,14 @@ namespace SixLabors.ImageSharp.PixelFormats } <# - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateDefaultConvertToMethod("Argb32", "Bgr24"); + GenerateDefaultConvertToMethod("Argb32", "Bgra32"); + GenerateDefaultConvertToMethod("Argb32", "Gray8"); + GenerateDefaultConvertToMethod("Argb32", "Gray16"); + GenerateDefaultConvertToMethod("Argb32", "Rgb24"); + GenerateDefaultConvertToMethod("Argb32", "Rgba32"); + GenerateDefaultConvertToMethod("Argb32", "Rgb48"); + GenerateDefaultConvertToMethod("Argb32", "Rgba64"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude new file mode 100644 index 000000000..d433bd540 --- /dev/null +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude @@ -0,0 +1,36 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +<#+ + void GenerateDefaultConvertToMethod(string fromPixelType, string toPixelType) + { + #> + + /// + internal override void To<#=toPixelType#>(ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref <#=fromPixelType#> sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=toPixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref <#=fromPixelType#> sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=toPixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.From<#=fromPixelType#>(sp); + } + } + <#+ + } +#> \ No newline at end of file From 663a10c4fb7ac1b60054e614b5ff4f6b19e31ce8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 14:22:55 +0200 Subject: [PATCH 058/238] GenerateDefaultSelfConversionMethods --- .../Argb32.PixelOperations.Generated.cs | 5 ++-- .../Argb32.PixelOperations.Generated.tt | 17 +------------- .../Generated/RgbaCompatible.Common.ttinclude | 23 +++++++++++++++++++ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 507c8cd3a..e5a2ffc2a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -19,7 +19,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt index 432421166..a3e944f98 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt @@ -13,23 +13,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - /// - internal override void FromArgb32(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# + GenerateDefaultSelfConversionMethods("Argb32"); GenerateDefaultConvertToMethod("Argb32", "Bgr24"); GenerateDefaultConvertToMethod("Argb32", "Bgra32"); GenerateDefaultConvertToMethod("Argb32", "Gray8"); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude index d433bd540..150607538 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude @@ -11,6 +11,29 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; <#+ + void GenerateDefaultSelfConversionMethods(string pixelType) + { + #> + + /// + internal override void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void To<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <#+ + } + void GenerateDefaultConvertToMethod(string fromPixelType, string toPixelType) { #> From 3ecde02167b1bd5fce9171ee9a7557062c14622e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 15:04:15 +0200 Subject: [PATCH 059/238] DRY out PixelOperations generators --- .../Argb32.PixelOperations.Generated.cs | 1 + .../Argb32.PixelOperations.Generated.tt | 12 +-- .../Bgr24.PixelOperations.Generated.cs | 32 ++++---- .../Bgr24.PixelOperations.Generated.tt | 67 +---------------- .../Bgra32.PixelOperations.Generated.cs | 16 ++-- .../Bgra32.PixelOperations.Generated.tt | 67 +---------------- .../Gray16.PixelOperations.Generated.cs | 16 ++-- .../Gray16.PixelOperations.Generated.tt | 67 +---------------- .../Gray8.PixelOperations.Generated.cs | 16 ++-- .../Gray8.PixelOperations.Generated.tt | 67 +---------------- .../Rgb24.PixelOperations.Generated.cs | 16 ++-- .../Rgb24.PixelOperations.Generated.tt | 67 +---------------- .../Rgb48.PixelOperations.Generated.cs | 16 ++-- .../Rgb48.PixelOperations.Generated.tt | 67 +---------------- .../Rgba32.PixelOperations.Generated.cs | 22 +++--- .../Rgba32.PixelOperations.Generated.tt | 73 ++----------------- .../Rgba64.PixelOperations.Generated.cs | 16 ++-- .../Rgba64.PixelOperations.Generated.tt | 67 +---------------- ...ble.Common.ttinclude => _Common.ttinclude} | 15 ++++ 19 files changed, 120 insertions(+), 600 deletions(-) rename src/ImageSharp/PixelFormats/PixelImplementations/Generated/{RgbaCompatible.Common.ttinclude => _Common.ttinclude} (81%) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index e5a2ffc2a..655c4c318 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -1,5 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. + // using System; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt index a3e944f98..8c4c6b58a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt @@ -1,4 +1,4 @@ -<#@include file="RgbaCompatible.Common.ttinclude" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> namespace SixLabors.ImageSharp.PixelFormats @@ -14,15 +14,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { <# - GenerateDefaultSelfConversionMethods("Argb32"); - GenerateDefaultConvertToMethod("Argb32", "Bgr24"); - GenerateDefaultConvertToMethod("Argb32", "Bgra32"); - GenerateDefaultConvertToMethod("Argb32", "Gray8"); - GenerateDefaultConvertToMethod("Argb32", "Gray16"); - GenerateDefaultConvertToMethod("Argb32", "Rgb24"); - GenerateDefaultConvertToMethod("Argb32", "Rgba32"); - GenerateDefaultConvertToMethod("Argb32", "Rgb48"); - GenerateDefaultConvertToMethod("Argb32", "Rgba64"); + GenerateAllDefaultConversionMethods("Argb32"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index cbfbe7099..5d2ca335e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Bgr24 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { @@ -43,7 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -60,7 +62,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -77,7 +79,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -94,7 +96,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -111,7 +113,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -128,7 +130,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -145,7 +147,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); @@ -162,7 +164,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - + for (int i = 0; i < count; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt index 0f7bd838f..56e3bf9ba 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < count; i++) - { - ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - dp.FromBgr24(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Bgr24 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromBgr24(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Bgr24"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index edd702e0e..1121f4343 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Bgra32 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt index 4c4e10fad..6563ff907 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromBgra32(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Bgra32 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromBgra32(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Bgra32"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index ca0e1fe32..e27f8bc58 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Gray16 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt index 1e500dac5..3db96d70a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromGray16(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Gray16 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromGray16(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Gray16"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index 6950c337d..26ed91cff 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Gray8 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt index 7c6e2f767..a65d8f263 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromGray8(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Gray8 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromGray8(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Gray8"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 53234cd66..8a6c6bddc 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgb24 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt index b98e1e4c7..796cdeb66 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromRgb24(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgb24 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromRgb24(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Rgb24"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index 61d13978a..1701109ed 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgb48 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt index 2ff3125b4..b8ee99fce 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromRgb48(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgb48 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromRgb48(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Rgb48"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index ae2ffd688..fb817a29a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgba32 { - - /// + /// /// Provides optimized overrides for bulk operations. - /// - internal partial class PixelOperations + /// + internal partial class PixelOperations : PixelOperations { - /// + + /// internal override void FromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt index fb8d6db34..0c4a4c0c0 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromRgba32(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgba32 { - - /// + /// /// Provides optimized overrides for bulk operations. - /// - internal partial class PixelOperations + /// + internal partial class PixelOperations : PixelOperations { - /// - internal override void FromRgba32(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgb48"); - GenerateConvertToMethod("Rgba64"); + GenerateAllDefaultConversionMethods("Rgba32"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index 252068828..d49fb7ae5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -2,24 +2,26 @@ // Licensed under the Apache License, Version 2.0. // + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgba64 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// + + /// internal override void FromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); @@ -35,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats sourcePixels.Slice(0, count).CopyTo(destPixels); } - + /// internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt index 626f2316d..9409e1573 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt @@ -1,83 +1,20 @@ -<# -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. -#> -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> +<#@include file="_Common.ttinclude" #> <#@ output extension=".cs" #> -<# - void GenerateConvertToMethod(string pixelType) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) - { - ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); - ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - - dp.FromRgba64(sp); - } - } - <# - } -#> -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -// namespace SixLabors.ImageSharp.PixelFormats { - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - /// /// Provides optimized overrides for bulk operations. /// public partial struct Rgba64 { - /// /// Provides optimized overrides for bulk operations. /// internal class PixelOperations : PixelOperations { - /// - internal override void FromRgba64(ReadOnlySpan source, Span destPixels, int count) - { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - source.Slice(0, count).CopyTo(destPixels); - } - - /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - - sourcePixels.Slice(0, count).CopyTo(destPixels); - } - <# - GenerateConvertToMethod("Argb32"); - GenerateConvertToMethod("Bgr24"); - GenerateConvertToMethod("Bgra32"); - GenerateConvertToMethod("Gray8"); - GenerateConvertToMethod("Gray16"); - GenerateConvertToMethod("Rgb24"); - GenerateConvertToMethod("Rgba32"); - GenerateConvertToMethod("Rgb48"); + GenerateAllDefaultConversionMethods("Rgba64"); #> } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude similarity index 81% rename from src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude rename to src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index 150607538..af8c42357 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/RgbaCompatible.Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -5,12 +5,15 @@ <#@ import namespace="System.Collections.Generic" #> // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. + // using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; <#+ + static readonly string[] CommonPixelTypeNames = { "Argb32", "Bgr24", "Bgra32", "Gray8", "Gray16", "Rgb24", "Rgba32", "Rgb48", "Rgba64" }; + void GenerateDefaultSelfConversionMethods(string pixelType) { #> @@ -56,4 +59,16 @@ using System.Runtime.InteropServices; } <#+ } + + void GenerateAllDefaultConversionMethods(string pixelType) + { + GenerateDefaultSelfConversionMethods(pixelType); + + var allOtherPixelTypes = CommonPixelTypeNames.Where(p => p != pixelType); + + foreach (string destPixelType in allOtherPixelTypes) + { + GenerateDefaultConvertToMethod(pixelType, destPixelType); + } + } #> \ No newline at end of file From 06c561c89a603c01074fb5943f0035e972cca70f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 15:17:37 +0200 Subject: [PATCH 060/238] CLA assistant, please wake up! --- tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs b/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs index 950434ac3..629b3cdeb 100644 --- a/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs +++ b/tests/ImageSharp.Tests/Helpers/RowIntervalTests.cs @@ -1,8 +1,9 @@ -using System; -using System.Runtime.CompilerServices; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +using System; +using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Memory; - using Xunit; namespace SixLabors.ImageSharp.Tests.Helpers From 4a1091c80a35db1e29c92750c90d8aff0825adbd Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 16:43:31 +0200 Subject: [PATCH 061/238] Adapt Span.CopyTo(...) semantics on color conversion API-s --- .../Conversion/ColorSpaceConverter.CieLab.cs | 78 ++-- .../Conversion/ColorSpaceConverter.CieLch.cs | 79 ++-- .../ColorSpaceConverter.CieLchuv.cs | 79 ++-- .../Conversion/ColorSpaceConverter.CieLuv.cs | 79 ++-- .../Conversion/ColorSpaceConverter.CieXyy.cs | 79 ++-- .../Conversion/ColorSpaceConverter.CieXyz.cs | 82 ++-- .../Conversion/ColorSpaceConverter.Cmyk.cs | 79 ++-- .../Conversion/ColorSpaceConverter.Hsl.cs | 79 ++-- .../Conversion/ColorSpaceConverter.Hsv.cs | 79 ++-- .../ColorSpaceConverter.HunterLab.cs | 368 ++++++++--------- .../ColorSpaceConverter.LinearRgb.cs | 371 ++++++++--------- .../Conversion/ColorSpaceConverter.Lms.cs | 356 ++++++++--------- .../Conversion/ColorSpaceConverter.Rgb.cs | 377 +++++++++--------- .../Conversion/ColorSpaceConverter.YCbCr.cs | 351 ++++++++-------- .../Conversion/IChromaticAdaptation.cs | 7 +- .../Conversion/VonKriesChromaticAdaptation.cs | 9 +- src/ImageSharp/Common/Helpers/Guard.cs | 63 ++- .../CieLabAndCieLchConversionTests.cs | 4 +- .../CieLabAndCieLchuvConversionTests.cs | 4 +- .../CieLabAndCieLuvConversionTests.cs | 4 +- .../CieLabAndCieXyyConversionTests.cs | 4 +- .../CieLabAndCmykConversionTests.cs | 4 +- .../Conversion/CieLabAndHslConversionTests.cs | 4 +- .../Conversion/CieLabAndHsvConversionTests.cs | 4 +- .../CieLabAndHunterLabConversionTests.cs | 4 +- .../CieLabAndLinearRgbConversionTests.cs | 4 +- .../Conversion/CieLabAndLmsConversionTests.cs | 4 +- .../Conversion/CieLabAndRgbConversionTests.cs | 4 +- .../CieLabAndYCbCrConversionTests.cs | 4 +- .../CieLchAndCieLuvConversionTests.cs | 4 +- .../CieLchAndCieXyyConversionTests.cs | 4 +- .../Conversion/CieLchAndHslConversionTests.cs | 4 +- .../Conversion/CieLchAndHsvConversionTests.cs | 4 +- .../CieLchAndHunterLabConversionTests.cs | 4 +- .../CieLchAndLinearRgbConversionTests.cs | 4 +- .../Conversion/CieLchAndLmsConversionTests.cs | 4 +- .../Conversion/CieLchAndRgbConversionTests.cs | 4 +- .../CieLchAndYCbCrConversionTests.cs | 4 +- .../CieLchuvAndCieLchConversionTests.cs | 4 +- .../CieLchuvAndCieLuvConversionTests.cs | 4 +- .../CieLchuvAndCmykConversionTests.cs | 4 +- .../CieLuvAndCieXyyConversionTests.cs | 4 +- .../Conversion/CieLuvAndHslConversionTests.cs | 4 +- .../Conversion/CieLuvAndHsvConversionTests.cs | 4 +- .../CieLuvAndHunterLabConversionTests.cs | 4 +- .../CieLuvAndLinearRgbConversionTests.cs | 4 +- .../Conversion/CieLuvAndLmsConversionTests.cs | 4 +- .../Conversion/CieLuvAndRgbConversionTests.cs | 4 +- .../CieLuvAndYCbCrConversionTests.cs | 4 +- .../Conversion/CieXyyAndHslConversionTests.cs | 4 +- .../Conversion/CieXyyAndHsvConversionTests.cs | 4 +- .../CieXyyAndHunterLabConversionTests.cs | 4 +- .../CieXyyAndLinearRgbConversionTests.cs | 4 +- .../Conversion/CieXyyAndLmsConversionTests.cs | 4 +- .../Conversion/CieXyyAndRgbConversionTests.cs | 4 +- .../CieXyyAndYCbCrConversionTests.cs | 4 +- .../CieXyzAndCieLabConversionTest.cs | 4 +- .../CieXyzAndCieLchConversionTests.cs | 4 +- .../CieXyzAndCieLchuvConversionTests.cs | 4 +- .../CieXyzAndCieLuvConversionTest.cs | 4 +- .../CieXyzAndCieXyyConversionTest.cs | 4 +- .../Conversion/CieXyzAndHslConversionTests.cs | 4 +- .../Conversion/CieXyzAndHsvConversionTests.cs | 4 +- .../CieXyzAndHunterLabConversionTest.cs | 6 +- .../Conversion/CieXyzAndLmsConversionTest.cs | 4 +- .../CieXyzAndYCbCrConversionTests.cs | 4 +- .../CmykAndCieLchConversionTests.cs | 4 +- .../CmykAndCieLuvConversionTests.cs | 4 +- .../CmykAndCieXyyConversionTests.cs | 4 +- .../CmykAndCieXyzConversionTests.cs | 4 +- .../Conversion/CmykAndHslConversionTests.cs | 4 +- .../Conversion/CmykAndHsvConversionTests.cs | 4 +- .../CmykAndHunterLabConversionTests.cs | 4 +- .../Conversion/CmykAndYCbCrConversionTests.cs | 4 +- .../Conversion/RgbAndCieXyzConversionTest.cs | 8 +- .../Conversion/RgbAndCmykConversionTest.cs | 4 +- .../Conversion/RgbAndHslConversionTest.cs | 4 +- .../Conversion/RgbAndHsvConversionTest.cs | 4 +- .../Conversion/RgbAndYCbCrConversionTest.cs | 4 +- .../VonKriesChromaticAdaptationTests.cs | 2 +- tests/ImageSharp.Tests/Helpers/GuardTests.cs | 32 ++ 81 files changed, 1489 insertions(+), 1414 deletions(-) diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs index 3ce14cdea..3c197673d 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs @@ -37,10 +37,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -70,10 +70,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -103,10 +103,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -136,10 +136,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -171,10 +171,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -203,10 +203,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -236,10 +236,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -268,10 +268,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -301,10 +301,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -334,10 +334,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -367,10 +367,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -400,10 +400,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); @@ -433,10 +433,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieLab destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs index 3c9e6658c..0a8607e3b 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -37,10 +38,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -70,10 +71,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -103,10 +104,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -136,10 +137,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -169,10 +170,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -201,10 +202,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -234,10 +235,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -267,10 +268,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -300,10 +301,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -333,10 +334,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -366,10 +367,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -399,10 +400,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); @@ -432,10 +433,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieLch destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs index 01de79488..3a779ee72 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -35,10 +36,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -68,10 +69,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -103,10 +104,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -136,10 +137,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -169,10 +170,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -202,10 +203,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -235,10 +236,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -268,10 +269,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -301,10 +302,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -334,10 +335,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -367,10 +368,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -400,10 +401,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); @@ -432,10 +433,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieLchuv destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs index 0b469e065..90eb8e34d 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -31,10 +32,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -63,10 +64,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -98,10 +99,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -130,10 +131,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -165,10 +166,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -197,10 +198,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -229,10 +230,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -261,10 +262,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -293,10 +294,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -325,10 +326,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -357,10 +358,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -389,10 +390,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); @@ -421,10 +422,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieLuv destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs index b77f48325..d03c10a01 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -32,10 +33,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -65,10 +66,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -98,10 +99,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -131,10 +132,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -159,10 +160,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -192,10 +193,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -225,10 +226,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -258,10 +259,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -291,10 +292,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -324,10 +325,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -357,10 +358,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -390,10 +391,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); @@ -423,10 +424,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyy destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs index 8963ad495..fada6d9c5 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -17,7 +18,8 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion private static readonly CieLuvToCieXyzConverter CieLuvToCieXyzConverter = new CieLuvToCieXyzConverter(); - private static readonly HunterLabToCieXyzConverter HunterLabToCieXyzConverter = new HunterLabToCieXyzConverter(); + private static readonly HunterLabToCieXyzConverter + HunterLabToCieXyzConverter = new HunterLabToCieXyzConverter(); private LinearRgbToCieXyzConverter linearRgbToCieXyzConverter; @@ -40,10 +42,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -75,10 +77,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -110,10 +112,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -145,10 +147,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -177,10 +179,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -211,10 +213,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -245,10 +247,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -279,10 +281,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -314,10 +316,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -350,10 +352,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -382,10 +384,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -415,10 +417,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); @@ -449,10 +451,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref CieXyz destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs index 6f8fe6146..b79851635 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -32,10 +33,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -65,10 +66,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -98,10 +99,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -131,10 +132,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -164,10 +165,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -197,10 +198,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -230,10 +231,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -263,10 +264,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -296,10 +297,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -329,10 +330,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -362,10 +363,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -390,10 +391,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); @@ -423,10 +424,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref Cmyk destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs index 106e8956f..a7080b974 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -32,10 +33,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -65,10 +66,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -98,10 +99,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -131,10 +132,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -164,10 +165,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -197,10 +198,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -230,10 +231,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -263,10 +264,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -296,10 +297,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -329,10 +330,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -362,10 +363,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -390,10 +391,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); @@ -423,10 +424,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref Hsl destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs index 8b4e29215..a2121203c 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -32,10 +33,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -65,10 +66,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -98,10 +99,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -131,10 +132,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -164,10 +165,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -197,10 +198,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -230,10 +231,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -263,10 +264,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -296,10 +297,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -329,10 +330,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -362,10 +363,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -390,10 +391,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); @@ -423,10 +424,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref Hsv destRef = ref MemoryMarshal.GetReference(destination); diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs index b3286a9cc..e5996c238 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs @@ -12,26 +12,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -44,26 +33,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieLch color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -76,26 +54,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieLchuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -108,26 +75,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieLuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -140,26 +96,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieXyy color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -172,29 +117,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in CieXyz color) - { - // Adaptation - CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetHunterLabWhitePoint); - - // Conversion - return this.cieXyzToHunterLabConverter.Convert(adapted); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -207,26 +138,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in Cmyk color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); @@ -240,14 +160,24 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } /// - /// Converts a into a + /// Performs the bulk conversion from into /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in Hsl color) + /// The span to the source colors + /// The span to the destination colors + public void Convert(ReadOnlySpan source, Span destination) { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; + + ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); + ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + + for (int i = 0; i < count; i++) + { + ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); + ref HunterLab dp = ref Unsafe.Add(ref destRef, i); + dp = this.ToHunterLab(sp); + } } /// @@ -255,180 +185,250 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; - ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); + ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); for (int i = 0; i < count; i++) { - ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); + ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref HunterLab dp = ref Unsafe.Add(ref destRef, i); dp = this.ToHunterLab(sp); } } /// - /// Converts a into a + /// Performs the bulk conversion from into /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in Hsv color) + /// The span to the source colors + /// The span to the destination colors + public void Convert(ReadOnlySpan source, Span destination) { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; + + ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); + ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + + for (int i = 0; i < count; i++) + { + ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); + ref HunterLab dp = ref Unsafe.Add(ref destRef, i); + dp = this.ToHunterLab(sp); + } } /// - /// Performs the bulk conversion from into + /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; - ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); + ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); for (int i = 0; i < count; i++) { - ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); + ref Lms sp = ref Unsafe.Add(ref sourceRef, i); ref HunterLab dp = ref Unsafe.Add(ref destRef, i); dp = this.ToHunterLab(sp); } } /// - /// Converts a into a + /// Performs the bulk conversion from into /// - /// The color to convert. - /// The - public HunterLab ToHunterLab(in LinearRgb color) + /// The span to the source colors + /// The span to the destination colors + public void Convert(ReadOnlySpan source, Span destination) { - var xyzColor = this.ToCieXyz(color); - return this.ToHunterLab(xyzColor); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; + + ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); + ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + + for (int i = 0; i < count; i++) + { + ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); + ref HunterLab dp = ref Unsafe.Add(ref destRef, i); + dp = this.ToHunterLab(sp); + } } /// - /// Performs the bulk conversion from into + /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; - ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); + ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); for (int i = 0; i < count; i++) { - ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); + ref YCbCr sp = ref Unsafe.Add(ref sourceRef, i); ref HunterLab dp = ref Unsafe.Add(ref destRef, i); dp = this.ToHunterLab(sp); } } /// - /// Converts a into a + /// Converts a into a /// /// The color to convert. /// The - public HunterLab ToHunterLab(in Lms color) + public HunterLab ToHunterLab(in CieLab color) { var xyzColor = this.ToCieXyz(color); return this.ToHunterLab(xyzColor); } /// - /// Performs the bulk conversion from into + /// Converts a into a /// - /// The span to the source colors - /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + /// The color to convert. + /// The + public HunterLab ToHunterLab(in CieLch color) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } - ref Lms sourceRef = ref MemoryMarshal.GetReference(source); - ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in CieLchuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } - for (int i = 0; i < count; i++) - { - ref Lms sp = ref Unsafe.Add(ref sourceRef, i); - ref HunterLab dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHunterLab(sp); - } + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in CieLuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); } /// - /// Converts a into a + /// Converts a into a /// /// The color to convert. /// The - public HunterLab ToHunterLab(in Rgb color) + public HunterLab ToHunterLab(in CieXyy color) { var xyzColor = this.ToCieXyz(color); return this.ToHunterLab(xyzColor); } /// - /// Performs the bulk conversion from into + /// Converts a into a /// - /// The span to the source colors - /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + /// The color to convert. + /// The + public HunterLab ToHunterLab(in CieXyz color) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + // Adaptation + CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetHunterLabWhitePoint); - ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); - ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + // Conversion + return this.cieXyzToHunterLabConverter.Convert(adapted); + } - for (int i = 0; i < count; i++) - { - ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); - ref HunterLab dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHunterLab(sp); - } + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in Cmyk color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); } /// - /// Converts a into a + /// Converts a into a /// /// The color to convert. /// The - public HunterLab ToHunterLab(in YCbCr color) + public HunterLab ToHunterLab(in Hsl color) { var xyzColor = this.ToCieXyz(color); return this.ToHunterLab(xyzColor); } /// - /// Performs the bulk conversion from into + /// Converts a into a /// - /// The span to the source colors - /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + /// The color to convert. + /// The + public HunterLab ToHunterLab(in Hsv color) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } - ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); - ref HunterLab destRef = ref MemoryMarshal.GetReference(destination); + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in LinearRgb color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } - for (int i = 0; i < count; i++) - { - ref YCbCr sp = ref Unsafe.Add(ref sourceRef, i); - ref HunterLab dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHunterLab(sp); - } + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in Lms color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in Rgb color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public HunterLab ToHunterLab(in YCbCr color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToHunterLab(xyzColor); } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs index 98943c034..eef626be2 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -15,26 +16,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { private static readonly RgbToLinearRgbConverter RgbToLinearRgbConverter = new RgbToLinearRgbConverter(); - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -47,26 +37,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieLch color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -79,26 +58,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieLchuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -111,26 +79,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieLuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -143,26 +100,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieXyy color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -175,29 +121,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in CieXyz color) - { - // Adaptation - CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetRgbWorkingSpace.WhitePoint); - - // Conversion - return this.cieXyzToLinearRgbConverter.Convert(adapted); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -210,26 +142,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in Cmyk color) - { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -242,26 +163,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in Hsl color) - { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -274,26 +184,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in Hsv color) - { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -306,26 +205,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in HunterLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -338,26 +226,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in Lms color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLinearRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -370,26 +247,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in Rgb color) - { - // Conversion - return RgbToLinearRgbConverter.Convert(color); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -402,26 +268,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public LinearRgb ToLinearRgb(in YCbCr color) - { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref LinearRgb destRef = ref MemoryMarshal.GetReference(destination); @@ -433,5 +288,151 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion dp = this.ToLinearRgb(sp); } } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieLch color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieLchuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieLuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieXyy color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in CieXyz color) + { + // Adaptation + CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetRgbWorkingSpace.WhitePoint); + + // Conversion + return this.cieXyzToLinearRgbConverter.Convert(adapted); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in Cmyk color) + { + var rgb = this.ToRgb(color); + return this.ToLinearRgb(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in Hsl color) + { + var rgb = this.ToRgb(color); + return this.ToLinearRgb(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in Hsv color) + { + var rgb = this.ToRgb(color); + return this.ToLinearRgb(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in HunterLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in Lms color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLinearRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in Rgb color) + { + // Conversion + return RgbToLinearRgbConverter.Convert(color); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public LinearRgb ToLinearRgb(in YCbCr color) + { + var rgb = this.ToRgb(color); + return this.ToLinearRgb(rgb); + } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs index ffd0f88d1..3b8638f7d 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs @@ -12,26 +12,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -44,26 +33,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieLch color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -76,26 +54,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieLchuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -108,26 +75,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieLuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -140,26 +96,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieXyy color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -172,22 +117,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in CieXyz color) => this.cieXyzAndLmsConverter.Convert(color); - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -200,26 +138,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in Cmyk color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -232,26 +159,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in Hsl color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -264,26 +180,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in Hsv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -296,26 +201,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in HunterLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -328,26 +222,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in LinearRgb color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -360,26 +243,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in Rgb color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -392,26 +264,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Lms ToLms(in YCbCr color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToLms(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref Lms destRef = ref MemoryMarshal.GetReference(destination); @@ -423,5 +284,144 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion dp = this.ToLms(sp); } } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieLch color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieLchuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieLuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieXyy color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in CieXyz color) => this.cieXyzAndLmsConverter.Convert(color); + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in Cmyk color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in Hsl color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in Hsv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in HunterLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in LinearRgb color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in Rgb color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Lms ToLms(in YCbCr color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToLms(xyzColor); + } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs index cd40c966b..fc5665e5c 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -15,26 +16,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { private static readonly LinearRgbToRgbConverter LinearRgbToRgbConverter = new LinearRgbToRgbConverter(); - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -47,26 +37,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieLch color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -79,26 +58,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieLchuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLchuv sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -111,26 +79,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieLuv color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -143,26 +100,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieXyy color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -175,29 +121,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in CieXyz color) - { - // Conversion - var linear = this.ToLinearRgb(color); - - // Compand - return this.ToRgb(linear); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -210,26 +142,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in Cmyk color) - { - // Conversion - return CmykAndRgbConverter.Convert(color); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -242,26 +163,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in Hsv color) - { - // Conversion - return HsvAndRgbConverter.Convert(color); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -274,26 +184,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in Hsl color) - { - // Conversion - return HslAndRgbConverter.Convert(color); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -306,26 +205,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in HunterLab color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -338,26 +226,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in LinearRgb color) - { - // Conversion - return LinearRgbToRgbConverter.Convert(color); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -370,26 +247,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in Lms color) - { - var xyzColor = this.ToCieXyz(color); - return this.ToRgb(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -402,29 +268,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public Rgb ToRgb(in YCbCr color) - { - // Conversion - Rgb rgb = YCbCrAndRgbConverter.Convert(color); - - // Adaptation - return this.Adapt(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref YCbCr sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb destRef = ref MemoryMarshal.GetReference(destination); @@ -436,5 +288,154 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion dp = this.ToRgb(sp); } } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieLch color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieLchuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieLuv color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieXyy color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in CieXyz color) + { + // Conversion + var linear = this.ToLinearRgb(color); + + // Compand + return this.ToRgb(linear); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in Cmyk color) + { + // Conversion + return CmykAndRgbConverter.Convert(color); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in Hsv color) + { + // Conversion + return HsvAndRgbConverter.Convert(color); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in Hsl color) + { + // Conversion + return HslAndRgbConverter.Convert(color); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in HunterLab color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in LinearRgb color) + { + // Conversion + return LinearRgbToRgbConverter.Convert(color); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in Lms color) + { + var xyzColor = this.ToCieXyz(color); + return this.ToRgb(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public Rgb ToRgb(in YCbCr color) + { + // Conversion + Rgb rgb = YCbCrAndRgbConverter.Convert(color); + + // Adaptation + return this.Adapt(rgb); + } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs index 38e6d5fae..5780f4f54 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; namespace SixLabors.ImageSharp.ColorSpaces.Conversion @@ -15,27 +16,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { private static readonly YCbCrAndRgbConverter YCbCrAndRgbConverter = new YCbCrAndRgbConverter(); - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in CieLab color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLab sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -48,27 +37,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in CieLch color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLch sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -81,27 +58,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in CieLuv color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieLuv sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -114,27 +79,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in CieXyy color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyy sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -147,27 +100,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in CieXyz color) - { - var rgb = this.ToRgb(color); - - return YCbCrAndRgbConverter.Convert(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref CieXyz sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -180,27 +121,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in Cmyk color) - { - var rgb = this.ToRgb(color); - - return YCbCrAndRgbConverter.Convert(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Cmyk sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -213,27 +142,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in Hsl color) - { - var rgb = this.ToRgb(color); - - return YCbCrAndRgbConverter.Convert(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsl sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -246,27 +163,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in Hsv color) - { - var rgb = this.ToRgb(color); - - return YCbCrAndRgbConverter.Convert(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Hsv sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -279,27 +184,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in HunterLab color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref HunterLab sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -312,27 +205,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in LinearRgb color) - { - var rgb = this.ToRgb(color); - - return YCbCrAndRgbConverter.Convert(rgb); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref LinearRgb sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -345,27 +226,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in Lms color) - { - var xyzColor = this.ToCieXyz(color); - - return this.ToYCbCr(xyzColor); - } - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Lms sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -378,22 +247,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } } - /// - /// Converts a into a - /// - /// The color to convert. - /// The - public YCbCr ToYCbCr(in Rgb color) => YCbCrAndRgbConverter.Convert(color); - /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - /// The number of colors to convert. - public void Convert(ReadOnlySpan source, Span destination, int count) + public void Convert(ReadOnlySpan source, Span destination) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; ref Rgb sourceRef = ref MemoryMarshal.GetReference(source); ref YCbCr destRef = ref MemoryMarshal.GetReference(destination); @@ -405,5 +267,144 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion dp = this.ToYCbCr(sp); } } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in CieLab color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in CieLch color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in CieLuv color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in CieXyy color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in CieXyz color) + { + var rgb = this.ToRgb(color); + + return YCbCrAndRgbConverter.Convert(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in Cmyk color) + { + var rgb = this.ToRgb(color); + + return YCbCrAndRgbConverter.Convert(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in Hsl color) + { + var rgb = this.ToRgb(color); + + return YCbCrAndRgbConverter.Convert(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in Hsv color) + { + var rgb = this.ToRgb(color); + + return YCbCrAndRgbConverter.Convert(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in HunterLab color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in LinearRgb color) + { + var rgb = this.ToRgb(color); + + return YCbCrAndRgbConverter.Convert(rgb); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in Lms color) + { + var xyzColor = this.ToCieXyz(color); + + return this.ToYCbCr(xyzColor); + } + + /// + /// Converts a into a + /// + /// The color to convert. + /// The + public YCbCr ToYCbCr(in Rgb color) => YCbCrAndRgbConverter.Convert(color); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/IChromaticAdaptation.cs b/src/ImageSharp/ColorSpaces/Conversion/IChromaticAdaptation.cs index 1b14c6413..69877d8b5 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/IChromaticAdaptation.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/IChromaticAdaptation.cs @@ -30,7 +30,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The span to the destination colors. /// The source white point. /// The destination white point. - /// The number of colors to convert. - void Transform(Span source, Span destination, CieXyz sourceWhitePoint, in CieXyz destinationWhitePoint, int count); + void Transform( + ReadOnlySpan source, + Span destination, + CieXyz sourceWhitePoint, + in CieXyz destinationWhitePoint); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/VonKriesChromaticAdaptation.cs b/src/ImageSharp/ColorSpaces/Conversion/VonKriesChromaticAdaptation.cs index 9b200b873..85a36331b 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/VonKriesChromaticAdaptation.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/VonKriesChromaticAdaptation.cs @@ -65,9 +65,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion } /// - public void Transform(Span source, Span destination, CieXyz sourceWhitePoint, in CieXyz destinationWhitePoint, int count) + public void Transform( + ReadOnlySpan source, + Span destination, + CieXyz sourceWhitePoint, + in CieXyz destinationWhitePoint) { - Guard.SpansMustBeSizedAtLeast(source, nameof(source), destination, nameof(destination), count); + Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); + int count = source.Length; if (sourceWhitePoint.Equals(destinationWhitePoint)) { diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs index 34ba54472..ef928c280 100644 --- a/src/ImageSharp/Common/Helpers/Guard.cs +++ b/src/ImageSharp/Common/Helpers/Guard.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp { @@ -19,6 +20,7 @@ namespace SixLabors.ImageSharp /// The target object, which cannot be null. /// The name of the parameter that is to be checked. /// is null + [MethodImpl(InliningOptions.ShortMethod)] public static void NotNull(T value, string parameterName) where T : class { @@ -35,6 +37,7 @@ namespace SixLabors.ImageSharp /// Name of the parameter. /// is null. /// is empty or contains only blanks. + [MethodImpl(InliningOptions.ShortMethod)] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) @@ -56,6 +59,7 @@ namespace SixLabors.ImageSharp /// Name of the parameter. /// is null. /// is empty. + [MethodImpl(InliningOptions.ShortMethod)] public static void NotNullOrEmpty(ICollection value, string parameterName) { if (value is null) @@ -79,6 +83,7 @@ namespace SixLabors.ImageSharp /// /// is greater than the maximum value. /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -99,6 +104,7 @@ namespace SixLabors.ImageSharp /// /// is greater than the maximum value. /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -119,6 +125,7 @@ namespace SixLabors.ImageSharp /// /// is less than the minimum value. /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -141,6 +148,7 @@ namespace SixLabors.ImageSharp /// /// is less than the minimum value. /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -162,6 +170,7 @@ namespace SixLabors.ImageSharp /// /// is less than the minimum value of greater than the maximum value. /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { @@ -181,6 +190,7 @@ namespace SixLabors.ImageSharp /// /// is false /// + [MethodImpl(InliningOptions.ShortMethod)] public static void IsTrue(bool target, string parameterName, string message) { if (!target) @@ -199,6 +209,7 @@ namespace SixLabors.ImageSharp /// /// is true /// + [MethodImpl(InliningOptions.ShortMethod)] public static void IsFalse(bool target, string parameterName, string message) { if (target) @@ -217,6 +228,7 @@ namespace SixLabors.ImageSharp /// /// has less than items /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) @@ -225,6 +237,26 @@ namespace SixLabors.ImageSharp } } + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type + /// The destination element type + /// The source span + /// The destination span + /// The name of the argument for 'destination' + [MethodImpl(InliningOptions.ShortMethod)] + public static void DestinationShouldNotBeTooShort( + ReadOnlySpan source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + throw new ArgumentException($"Destination span is too short!", destinationParamName); + } + } + /// /// Verifies, that the `source` span has the length of 'minLength', or longer. /// @@ -235,6 +267,7 @@ namespace SixLabors.ImageSharp /// /// has less than items /// + [MethodImpl(InliningOptions.ShortMethod)] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) @@ -255,7 +288,7 @@ namespace SixLabors.ImageSharp /// The destination parameter name /// The minimum length public static void SpansMustBeSizedAtLeast( - Span source, + ReadOnlySpan source, string sourceParamName, Span dest, string destParamName, @@ -265,26 +298,16 @@ namespace SixLabors.ImageSharp MustBeSizedAtLeast(dest, minLength, destParamName); } - /// - /// Verifies that the given 'source' and 'dest' spans are at least of 'minLength' size. - /// Throwing an if the condition is not met. - /// - /// The source element type - /// The destination element type - /// The source span - /// The source parameter name - /// The destination span - /// The destination parameter name - /// The minimum length - public static void SpansMustBeSizedAtLeast( - ReadOnlySpan source, - string sourceParamName, - Span dest, - string destParamName, - int minLength) + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowArgumentException(string message, string parameterName) { - MustBeSizedAtLeast(source, minLength, sourceParamName); - MustBeSizedAtLeast(dest, minLength, destParamName); + throw new ArgumentException(message, parameterName); + } + + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowArgumentNullException(string message) + { + throw new ArgumentException(message); } } } diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchConversionTests.cs index eb9a50d18..38c0c21bc 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchConversionTests.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchuvConversionTests.cs index 7fb5770dd..96628977f 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLchuvConversionTests.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLchuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLuvConversionTests.cs index 14a1c6fd3..39011bb29 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieLuvConversionTests.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieXyyConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieXyyConversionTests.cs index 9a42a9d47..f7dc365b8 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieXyyConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCieXyyConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCmykConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCmykConversionTests.cs index 944fab574..43300ab88 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCmykConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndCmykConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHslConversionTests.cs index 836be1bf2..4ab309fe1 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHsvConversionTests.cs index fb1982bfc..e7ff34f49 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHunterLabConversionTests.cs index 7e3c4251b..844cda476 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHunterLabConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndHunterLabConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHunterLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLinearRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLinearRgbConversionTests.cs index a43f0095d..74ed180f3 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLinearRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLinearRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLinearRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLmsConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLmsConversionTests.cs index 62d08263a..a3db00e80 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLmsConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndLmsConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLms(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndRgbConversionTests.cs index 1b3041275..fc202ccc9 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndYCbCrConversionTests.cs index 53d33af2b..3e481d4f6 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLabAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieLuvConversionTests.cs index e465757ef..078ba44da 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieLuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieLuvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieXyyConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieXyyConversionTests.cs index 18b8a4739..a65f61883 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieXyyConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndCieXyyConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHslConversionTests.cs index d00a164c0..49990fb90 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHsvConversionTests.cs index d3ff04a75..924b45b4a 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHunterLabConversionTests.cs index 852e56110..099165731 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHunterLabConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndHunterLabConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHunterLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLinearRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLinearRgbConversionTests.cs index 80b72cb2c..a7a819d1f 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLinearRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLinearRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLinearRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLmsConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLmsConversionTests.cs index 314734ff2..b83b861be 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLmsConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndLmsConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLms(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndRgbConversionTests.cs index 389528dcd..932fdc410 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndYCbCrConversionTests.cs index a2bd7eadc..4d04418d9 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLchConversionTests.cs index e7f511bab..3cdaa4279 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLchConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLchConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLchuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLuvConversionTests.cs index 3bc4fd519..6829c62b5 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCieLuvConversionTests.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLchuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCmykConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCmykConversionTests.cs index f3940e4d1..0c62ffcc3 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCmykConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLchuvAndCmykConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLchuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndCieXyyConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndCieXyyConversionTests.cs index 61bfe7963..3b41204f7 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndCieXyyConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndCieXyyConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHslConversionTests.cs index 7bc430aa3..bfc0d2ecf 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHsvConversionTests.cs index 23cc5082c..f11b17fff 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHunterLabConversionTests.cs index 04699bde4..de2329c2e 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHunterLabConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndHunterLabConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHunterLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLinearRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLinearRgbConversionTests.cs index 98914a6b9..3a1bd10c4 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLinearRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLinearRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLinearRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLmsConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLmsConversionTests.cs index 306d60b53..f3881f10f 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLmsConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndLmsConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLms(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndRgbConversionTests.cs index 21cf08ded..644f4577b 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndYCbCrConversionTests.cs index 8c07c38d6..41b9dba09 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieLuvAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHslConversionTests.cs index fb415f43b..5b36beaab 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHsvConversionTests.cs index 3c8aee807..da7737875 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHunterLabConversionTests.cs index 1fcbb75cb..96d14c98a 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHunterLabConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndHunterLabConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHunterLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLinearRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLinearRgbConversionTests.cs index 8c45378ed..033973094 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLinearRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLinearRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLinearRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLmsConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLmsConversionTests.cs index 67ec26f6d..fb0e06e6b 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLmsConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndLmsConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToLms(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndRgbConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndRgbConversionTests.cs index e309e2d55..5bbcd9087 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndRgbConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndRgbConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndYCbCrConversionTests.cs index 3e33f0519..1ee84ef2e 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyyAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLabConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLabConversionTest.cs index 746e37c0e..49b99b705 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLabConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLabConversionTest.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieLab(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchConversionTests.cs index 89d78ece1..77f0c6969 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchConversionTests.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchuvConversionTests.cs index fbd602d9a..24e134d73 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLchuvConversionTests.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLchuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLuvConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLuvConversionTest.cs index c0856a2bc..761b9851e 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLuvConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieLuvConversionTest.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieLuv(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs index 3f5ea4cfd..2b0350cea 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHslConversionTests.cs index 844372264..cd1c9f2c3 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHsvConversionTests.cs index 327d660c6..8112f6a19 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHunterLabConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHunterLabConversionTest.cs index d16294015..2fed3e9c5 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHunterLabConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndHunterLabConversionTest.cs @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToHunterLab(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndLmsConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndLmsConversionTest.cs index 484d302e9..75634eb51 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndLmsConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndLmsConversionTest.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToLms(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndYCbCrConversionTests.cs index eacdc7ffb..9ea890f10 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLchConversionTests.cs index 4a0c88c84..dbb0c6e20 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLchConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLchConversionTests.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLch(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLuvConversionTests.cs index 2131ba630..5fcc59090 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieLuvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieLuv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyyConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyyConversionTests.cs index ac93aaf25..7ff80c170 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyyConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyyConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyzConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyzConversionTests.cs index cbb8f7dc4..801730205 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyzConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndCieXyzConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs index 1c9ad170d..3464fdbbd 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs index 6fd1ba88e..26af5ddd3 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHunterLabConversionTests.cs index e92ac2e52..dc40ee518 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHunterLabConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHunterLabConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHunterLab(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs index 575122661..00569ced2 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCieXyzConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCieXyzConversionTest.cs index a3b0cbd95..8a2cd1159 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCieXyzConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCieXyzConversionTest.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToRgb(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToRgb(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = converter.ToCieXyz(input); - converter.Convert(inputSpan, actualSpan, actualSpan.Length); + converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs index 2b03ee988..b01e3a854 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index 22f5c6d51..502df8413 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs index e84ce9723..9adc94af7 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs index f5c7dbae6..94879eee7 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion // Act var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan, actualSpan.Length); + Converter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/VonKriesChromaticAdaptationTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/VonKriesChromaticAdaptationTests.cs index cfd48b694..b1427f4d5 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/VonKriesChromaticAdaptationTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/VonKriesChromaticAdaptationTests.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion Span actualSpan = new CieXyz[5]; - adaptation.Transform(inputSpan, actualSpan, sourceWhitePoint, destinationWhitePoint, inputSpan.Length); + adaptation.Transform(inputSpan, actualSpan, sourceWhitePoint, destinationWhitePoint); for (int i = 0; i < inputSpan.Length; i++) { diff --git a/tests/ImageSharp.Tests/Helpers/GuardTests.cs b/tests/ImageSharp.Tests/Helpers/GuardTests.cs index 0d1bb5ce9..b847e581f 100644 --- a/tests/ImageSharp.Tests/Helpers/GuardTests.cs +++ b/tests/ImageSharp.Tests/Helpers/GuardTests.cs @@ -3,7 +3,10 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq; + using Xunit; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Helpers { @@ -16,6 +19,35 @@ namespace SixLabors.ImageSharp.Tests.Helpers { } + [Theory] + [InlineData(0, 0)] + [InlineData(0, 1)] + [InlineData(0, 42)] + [InlineData(1, 1)] + [InlineData(10, 42)] + [InlineData(42, 42)] + public void DestinationShouldNotBeTooShort_WhenOk(int sourceLength, int destLength) + { + ReadOnlySpan source = new int[sourceLength]; + Span dest = new float[destLength]; + + Guard.DestinationShouldNotBeTooShort(source, dest, nameof(dest)); + } + + [Theory] + [InlineData(1, 0)] + [InlineData(42, 41)] + public void DestinationShouldNotBeTooShort_WhenThrows(int sourceLength, int destLength) + { + Assert.ThrowsAny( + () => + { + ReadOnlySpan source = new int[sourceLength]; + Span dest = new float[destLength]; + Guard.DestinationShouldNotBeTooShort(source, dest, nameof(dest)); + }); + } + /// /// Tests that the method throws when the argument is null. /// From 54e6a007e531b46b6609fce7456b6b38b1cb8a64 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 16:50:15 +0200 Subject: [PATCH 062/238] Improve Guard --- src/ImageSharp/Common/Helpers/Guard.cs | 73 ++++++++++++-------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs index ef928c280..cd53e3d69 100644 --- a/src/ImageSharp/Common/Helpers/Guard.cs +++ b/src/ImageSharp/Common/Helpers/Guard.cs @@ -21,12 +21,13 @@ namespace SixLabors.ImageSharp /// The name of the parameter that is to be checked. /// is null [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void NotNull(T value, string parameterName) where T : class { if (value is null) { - throw new ArgumentNullException(parameterName); + ThrowArgumentNullException(parameterName); } } @@ -38,16 +39,17 @@ namespace SixLabors.ImageSharp /// is null. /// is empty or contains only blanks. [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) { - throw new ArgumentNullException(parameterName); + ThrowArgumentNullException(parameterName); } if (string.IsNullOrWhiteSpace(value)) { - throw new ArgumentException("Must not be empty or whitespace.", parameterName); + ThrowArgumentException("Must not be empty or whitespace.", parameterName); } } @@ -60,16 +62,17 @@ namespace SixLabors.ImageSharp /// is null. /// is empty. [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void NotNullOrEmpty(ICollection value, string parameterName) { if (value is null) { - throw new ArgumentNullException(parameterName); + ThrowArgumentNullException(parameterName); } if (value.Count == 0) { - throw new ArgumentException("Must not be empty.", parameterName); + ThrowArgumentException("Must not be empty.", parameterName); } } @@ -84,12 +87,13 @@ namespace SixLabors.ImageSharp /// is greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) >= 0) { - throw new ArgumentOutOfRangeException(parameterName, $"Value {value} must be less than {max}."); + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than {max}."); } } @@ -105,12 +109,13 @@ namespace SixLabors.ImageSharp /// is greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) > 0) { - throw new ArgumentOutOfRangeException(parameterName, $"Value {value} must be less than or equal to {max}."); + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than or equal to {max}."); } } @@ -126,12 +131,13 @@ namespace SixLabors.ImageSharp /// is less than the minimum value. /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) <= 0) { - throw new ArgumentOutOfRangeException( + ThrowArgumentOutOfRangeException( parameterName, $"Value {value} must be greater than {min}."); } @@ -149,12 +155,13 @@ namespace SixLabors.ImageSharp /// is less than the minimum value. /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0) { - throw new ArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min}."); + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min}."); } } @@ -171,12 +178,13 @@ namespace SixLabors.ImageSharp /// is less than the minimum value of greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) { - throw new ArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min} and less than or equal to {max}."); + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min} and less than or equal to {max}."); } } @@ -191,11 +199,12 @@ namespace SixLabors.ImageSharp /// is false /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void IsTrue(bool target, string parameterName, string message) { if (!target) { - throw new ArgumentException(message, parameterName); + ThrowArgumentException(message, parameterName); } } @@ -210,11 +219,12 @@ namespace SixLabors.ImageSharp /// is true /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void IsFalse(bool target, string parameterName, string message) { if (target) { - throw new ArgumentException(message, parameterName); + ThrowArgumentException(message, parameterName); } } @@ -229,11 +239,12 @@ namespace SixLabors.ImageSharp /// has less than items /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) { - throw new ArgumentException($"Span-s must be at least of length {minLength}!", parameterName); + ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); } } @@ -246,6 +257,7 @@ namespace SixLabors.ImageSharp /// The destination span /// The name of the argument for 'destination' [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( ReadOnlySpan source, Span destination, @@ -253,7 +265,7 @@ namespace SixLabors.ImageSharp { if (destination.Length < source.Length) { - throw new ArgumentException($"Destination span is too short!", destinationParamName); + ThrowArgumentException($"Destination span is too short!", destinationParamName); } } @@ -268,46 +280,31 @@ namespace SixLabors.ImageSharp /// has less than items /// [MethodImpl(InliningOptions.ShortMethod)] + [DebuggerStepThrough] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) { - throw new ArgumentException($"Span-s must be at least of length {minLength}!", parameterName); + ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); } } - /// - /// Verifies that the given 'source' and 'dest' spans are at least of 'minLength' size. - /// Throwing an if the condition is not met. - /// - /// The source element type - /// The destination element type - /// The source span - /// The source parameter name - /// The destination span - /// The destination parameter name - /// The minimum length - public static void SpansMustBeSizedAtLeast( - ReadOnlySpan source, - string sourceParamName, - Span dest, - string destParamName, - int minLength) + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowArgumentException(string message, string parameterName) { - MustBeSizedAtLeast(source, minLength, sourceParamName); - MustBeSizedAtLeast(dest, minLength, destParamName); + throw new ArgumentException(message, parameterName); } [MethodImpl(InliningOptions.ColdPath)] - private static void ThrowArgumentException(string message, string parameterName) + private static void ThrowArgumentOutOfRangeException(string parameterName, string message) { - throw new ArgumentException(message, parameterName); + throw new ArgumentOutOfRangeException(parameterName, message); } [MethodImpl(InliningOptions.ColdPath)] - private static void ThrowArgumentNullException(string message) + private static void ThrowArgumentNullException(string parameterName) { - throw new ArgumentException(message); + throw new ArgumentNullException(parameterName); } } } From 24493091590397baad76a238b055d7edb39cbaac Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 17:03:06 +0200 Subject: [PATCH 063/238] Span.CopyTo(...) semantics for bulk Vecto4 conversion in PixelOperations --- .../Decoder/JpegImagePostProcessor.cs | 3 +- .../PixelFormats/PixelBlender{TPixel}.cs | 12 ++++---- .../Rgba32.PixelOperations.cs | 25 ++++++++--------- .../RgbaVector.PixelOperations.cs | 20 +++++++------ .../PixelFormats/PixelOperations{TPixel}.cs | 28 ++++++++----------- .../Convolution/Convolution2DProcessor.cs | 4 +-- .../Convolution/Convolution2PassProcessor.cs | 4 +-- .../Convolution/ConvolutionProcessor.cs | 4 +-- .../Dithering/PaletteDitherProcessorBase.cs | 2 +- .../FrameQuantizerBase{TPixel}.cs | 2 +- .../PaletteFrameQuantizer{TPixel}.cs | 2 +- .../Processors/Transforms/ResizeProcessor.cs | 4 +-- .../PixelFormats/PixelOperationsTests.cs | 10 +++---- .../TestUtilities/TestImageExtensions.cs | 4 +-- 14 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs index eb618dff0..6bd287732 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs @@ -159,7 +159,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder Span destRow = destination.GetPixelRowSpan(yy); - PixelOperations.Instance.FromVector4(this.rgbaBuffer.GetSpan(), destRow, destination.Width); + // TODO: Investigate if slicing is actually necessary + PixelOperations.Instance.FromVector4(this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); } } } diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index 48a83335a..6c24ce05b 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -93,12 +93,12 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background, backgroundSpan, destination.Length); - PixelOperations.Instance.ToScaledVector4(source, sourceSpan, destination.Length); + PixelOperations.Instance.ToScaledVector4(background, backgroundSpan); + PixelOperations.Instance.ToScaledVector4(source, sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromScaledVector4(destinationSpan, destination); } } @@ -127,12 +127,12 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background, backgroundSpan, destination.Length); - PixelOperations.Instance.ToScaledVector4(source, sourceSpan, destination.Length); + PixelOperations.Instance.ToScaledVector4(background, backgroundSpan); + PixelOperations.Instance.ToScaledVector4(source, sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromScaledVector4(destinationSpan, destination); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 4da9f101b..c25baa451 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -19,13 +19,11 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations : PixelOperations { /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) { - Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); - Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); + Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); - sourceColors = sourceColors.Slice(0, count); - destinationVectors = destinationVectors.Slice(0, count); + destinationVectors = destinationVectors.Slice(0, sourceColors.Length); SimdUtils.BulkConvertByteToNormalizedFloat( MemoryMarshal.Cast(sourceColors), @@ -33,12 +31,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors) { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); - sourceVectors = sourceVectors.Slice(0, count); - destinationColors = destinationColors.Slice(0, count); + destinationColors = destinationColors.Slice(0, sourceVectors.Length); SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( MemoryMarshal.Cast(sourceVectors), @@ -46,15 +43,17 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors) { - this.ToVector4(sourceColors, destinationVectors, count); + this.ToVector4(sourceColors, destinationVectors); } /// - internal override void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromScaledVector4( + ReadOnlySpan sourceVectors, + Span destinationColors) { - this.FromVector4(sourceVectors, destinationColors, count); + this.FromVector4(sourceVectors, destinationColors); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index ae64ed4de..d1f326365 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -18,23 +18,27 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal override void FromScaledVector4( + ReadOnlySpan sourceVectors, + Span destinationColors) { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); - MemoryMarshal.Cast(sourceVectors).Slice(0, count).CopyTo(destinationColors); + MemoryMarshal.Cast(sourceVectors).CopyTo(destinationColors); } /// - internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) - => this.ToVector4(sourceColors, destinationVectors, count); + internal override void ToScaledVector4( + ReadOnlySpan sourceColors, + Span destinationVectors) + => this.ToVector4(sourceColors, destinationVectors); /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) { - GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); - MemoryMarshal.Cast(sourceColors).Slice(0, count).CopyTo(destinationVectors); + MemoryMarshal.Cast(sourceColors).CopyTo(destinationVectors); } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index af7690c62..e6ccaf914 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -26,15 +26,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The to the source vectors. /// The to the destination colors. - /// The number of pixels to convert. - internal virtual void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal virtual void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors) { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourceVectors.Length; i++) { ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i); @@ -47,15 +46,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The to the source colors. /// The to the destination vectors. - /// The number of pixels to convert. - internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) { - GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourceColors.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); ref Vector4 dp = ref Unsafe.Add(ref destRef, i); @@ -68,15 +66,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The to the source vectors. /// The to the destination colors. - /// The number of pixels to convert. - internal virtual void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) + internal virtual void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors) { - GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourceVectors.Length; i++) { ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i); @@ -89,15 +86,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The to the source colors. /// The to the destination vectors. - /// The number of pixels to convert. - internal virtual void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + internal virtual void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors) { - GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourceColors.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); ref Vector4 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs index df4df64ca..90049a994 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs @@ -75,14 +75,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan, length); + PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve2D(in matrixY, in matrixX, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs index 03447531e..f38f16f1a 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs @@ -93,14 +93,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan, length); + PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, sourcePixels, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs index a42b777fe..d1b3f0ccf 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs @@ -59,14 +59,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan, length); + PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan, length); + PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs index a1bbe7273..fd9380109 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering { this.Palette = palette ?? throw new ArgumentNullException(nameof(palette)); this.paletteVector = new Vector4[this.Palette.Length]; - PixelOperations.Instance.ToScaledVector4(this.Palette, this.paletteVector, this.Palette.Length); + PixelOperations.Instance.ToScaledVector4(this.Palette, this.paletteVector); } /// diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index 6e594f223..bc0ed0eab 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Collect the palette. Required before the second pass runs. TPixel[] palette = this.GetPalette(); this.paletteVector = new Vector4[palette.Length]; - PixelOperations.Instance.ToScaledVector4(palette, this.paletteVector, palette.Length); + PixelOperations.Instance.ToScaledVector4(palette, this.paletteVector); var quantizedFrame = new QuantizedFrame(image.MemoryAllocator, width, height, palette); if (this.Dither) diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs index cdf3514e2..625400413 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization Guard.MustBeBetweenOrEqualTo(colors.Length, 1, 256, nameof(colors)); this.palette = colors; this.paletteVector = new Vector4[this.palette.Length]; - PixelOperations.Instance.ToScaledVector4(this.palette, this.paletteVector, this.palette.Length); + PixelOperations.Instance.ToScaledVector4(this.palette, this.paletteVector); } /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index 5bd61aab1..05c4464f1 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Span sourceRow = source.GetPixelRowSpan(y); Span tempRowSpan = tempRowBuffer.Span; - PixelOperations.Instance.ToVector4(sourceRow, tempRowSpan, sourceRow.Length); + PixelOperations.Instance.ToVector4(sourceRow, tempRowSpan); Vector4Utils.Premultiply(tempRowSpan); ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y]; @@ -309,7 +309,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } Span targetRowSpan = destination.GetPixelRowSpan(y); - PixelOperations.Instance.FromVector4(tempRowSpan, targetRowSpan, tempRowSpan.Length); + PixelOperations.Instance.FromVector4(tempRowSpan, targetRowSpan); } }); } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 958c4744a..0082e6c0e 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -269,7 +269,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { this.Measure( times, - () => PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count)); + () => PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan())); } } } @@ -367,7 +367,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromVector4(s, d.GetSpan(), count) + (s, d) => Operations.FromVector4(s, d.GetSpan()) ); } @@ -381,7 +381,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromScaledVector4(s, d.GetSpan(), count) + (s, d) => Operations.FromScaledVector4(s, d.GetSpan()) ); } @@ -417,7 +417,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToVector4(s, d.GetSpan(), count) + (s, d) => Operations.ToVector4(s, d.GetSpan()) ); } @@ -431,7 +431,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToScaledVector4(s, d.GetSpan(), count) + (s, d) => Operations.ToScaledVector4(s, d.GetSpan()) ); } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 78927dece..f055ce548 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests { Span pixelSpan = frame.GetPixelSpan(); - PixelOperations.Instance.ToScaledVector4(pixelSpan, tempSpan, pixelSpan.Length); + PixelOperations.Instance.ToScaledVector4(pixelSpan, tempSpan); for (int i = 0; i < tempSpan.Length; i++) { @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests v.W = 1F; } - PixelOperations.Instance.FromScaledVector4(tempSpan, pixelSpan, pixelSpan.Length); + PixelOperations.Instance.FromScaledVector4(tempSpan, pixelSpan); } } }); From ada0225258e8ddf34aee593b06ceedc98c3eef9c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 17:25:12 +0200 Subject: [PATCH 064/238] Adapt Span.CopyTo(...) semantics for all pixel conversion methods in PixelOperations --- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 2 +- .../Encoder/YCbCrForwardConverter{TPixel}.cs | 4 +- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 8 +- src/ImageSharp/ImageFrame{TPixel}.cs | 2 +- .../Argb32.PixelOperations.Generated.cs | 60 ++--- .../Bgr24.PixelOperations.Generated.cs | 60 ++--- .../Bgra32.PixelOperations.Generated.cs | 60 ++--- .../Gray16.PixelOperations.Generated.cs | 60 ++--- .../Gray8.PixelOperations.Generated.cs | 60 ++--- .../Rgb24.PixelOperations.Generated.cs | 60 ++--- .../Rgb48.PixelOperations.Generated.cs | 60 ++--- .../Rgba32.PixelOperations.Generated.cs | 60 ++--- .../Rgba64.PixelOperations.Generated.cs | 60 ++--- .../Generated/_Common.ttinclude | 18 +- .../PixelOperations{TPixel}.Generated.cs | 234 ++++++++---------- .../PixelOperations{TPixel}.Generated.tt | 26 +- .../PixelFormats/PixelOperations{TPixel}.cs | 20 +- .../Quantization/WuFrameQuantizer{TPixel}.cs | 2 +- .../Color/Bulk/FromVector4.cs | 4 +- .../Color/Bulk/ToVector4.cs | 4 +- .../PixelBlenders/PorterDuffBulkVsPixel.cs | 6 +- .../ImageComparison/ExactImageComparer.cs | 4 +- .../ImageComparison/TolerantImageComparer.cs | 4 +- .../ReferenceCodecs/SystemDrawingBridge.cs | 6 +- 24 files changed, 433 insertions(+), 451 deletions(-) diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index f00a6b61e..7db347aa6 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -217,7 +217,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba32 paletteRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba32(quantized.Palette, rgbaSpan, length); + PixelOperations.Instance.ToRgba32(quantized.Palette, rgbaSpan); for (int i = quantized.Palette.Length - 1; i >= 0; i--) { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs index 311ffed24..b2a8fccf4 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// On-stack worker struct to efficiently encapsulate the TPixel -> Rgb24 -> YCbCr conversion chain of 8x8 pixel blocks. /// /// The pixel type to work on - internal struct YCbCrForwardConverter + internal ref struct YCbCrForwardConverter where TPixel : struct, IPixel { /// @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder this.pixelBlock.LoadAndStretchEdges(pixels, x, y); Span rgbSpan = this.rgbBlock.AsSpanUnsafe(); - PixelOperations.Instance.ToRgb24(this.pixelBlock.AsSpanUnsafe(), rgbSpan, 64); + PixelOperations.Instance.ToRgb24(this.pixelBlock.AsSpanUnsafe(), rgbSpan); ref float yBlockStart = ref Unsafe.As(ref this.Y); ref float cbBlockStart = ref Unsafe.As(ref this.Cb); diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index cf7b7b2c6..84f7cb6cc 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -327,7 +327,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span luminanceSpan = luminanceBuffer.GetSpan(); ref Gray16 luminanceRef = ref MemoryMarshal.GetReference(luminanceSpan); - PixelOperations.Instance.ToGray16(rowSpan, luminanceSpan, rowSpan.Length); + PixelOperations.Instance.ToGray16(rowSpan, luminanceSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < luminanceSpan.Length; x++, o += 2) @@ -370,7 +370,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan, rowSpan.Length); + PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4) @@ -430,7 +430,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan, rowSpan.Length); + PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 8) @@ -453,7 +453,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbSpan = rgbBuffer.GetSpan(); ref Rgb48 rgbRef = ref MemoryMarshal.GetReference(rgbSpan); - PixelOperations.Instance.ToRgb48(rowSpan, rgbSpan, rowSpan.Length); + PixelOperations.Instance.ToRgb48(rowSpan, rgbSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 6) diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index ecf9e13ce..25c517d44 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -296,7 +296,7 @@ namespace SixLabors.ImageSharp { Span sourceRow = this.GetPixelRowSpan(y); Span targetRow = target.GetPixelRowSpan(y); - PixelOperations.Instance.To(sourceRow, targetRow, sourceRow.Length); + PixelOperations.Instance.To(sourceRow, targetRow); } }); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 655c4c318..26e85e043 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromArgb32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 5d2ca335e..080a25429 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgr24(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 1121f4343..6a1bb6cdc 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromBgra32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index e27f8bc58..cbb9df445 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromGray16(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray16(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index 26ed91cff..b88f18e8d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromGray8(ReadOnlySpan source, Span destPixels, int count) + internal override void FromGray8(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 8a6c6bddc..49c56f4fa 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb24(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index 1701109ed..cda6dbf72 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgb48(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index fb817a29a..ab264f870 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index d49fb7ae5..4bc6b101a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -22,31 +22,31 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal override void FromRgba64(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Argb32 dp = ref Unsafe.Add(ref destRef, i); @@ -56,14 +56,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); @@ -73,14 +73,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); @@ -90,14 +90,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray8 dp = ref Unsafe.Add(ref destRef, i); @@ -107,14 +107,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Gray16 dp = ref Unsafe.Add(ref destRef, i); @@ -124,14 +124,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); @@ -141,14 +141,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); @@ -158,14 +158,14 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index af8c42357..176075a40 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -19,19 +19,19 @@ using System.Runtime.InteropServices; #> /// - internal override void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels, int count) + internal override void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); - source.Slice(0, count).CopyTo(destPixels); + source.CopyTo(destPixels); } /// - internal override void To<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels, int count) + internal override void To<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - sourcePixels.Slice(0, count).CopyTo(destPixels); + sourcePixels.CopyTo(destPixels); } <#+ @@ -42,14 +42,14 @@ using System.Runtime.InteropServices; #> /// - internal override void To<#=toPixelType#>(ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels, int count) + internal override void To<#=toPixelType#>(ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref <#=fromPixelType#> sourceRef = ref MemoryMarshal.GetReference(sourcePixels); ref <#=toPixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref <#=fromPixelType#> sp = ref Unsafe.Add(ref sourceRef, i); ref <#=toPixelType#> dp = ref Unsafe.Add(ref destRef, i); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs index f1d426389..1cbf487d7 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs @@ -11,19 +11,18 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations { /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromArgb32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Argb32 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -33,7 +32,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -42,23 +41,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromArgb32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -68,7 +66,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -77,23 +75,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToArgb32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToArgb32(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToArgb32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromBgr24(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Bgr24 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Bgr24 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -103,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -112,23 +109,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromBgr24(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -138,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -147,23 +143,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgr24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgr24(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToBgr24(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromBgra32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Bgra32 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Bgra32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -173,7 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -182,23 +177,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromBgra32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -208,7 +202,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -217,23 +211,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgra32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgra32(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToBgra32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromGray8(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromGray8(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Gray8 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Gray8 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -243,7 +236,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -252,23 +245,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromGray8(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -278,7 +270,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -287,23 +279,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToGray8Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray8(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToGray8(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromGray16(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromGray16(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Gray16 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Gray16 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -313,7 +304,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -322,23 +313,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromGray16(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -348,7 +338,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -357,23 +347,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToGray16Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray16(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToGray16(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgb24(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Rgb24 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Rgb24 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -383,7 +372,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -392,23 +381,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgb24(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -418,7 +406,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -427,23 +415,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb24(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToRgb24(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgba32(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Rgba32 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -453,7 +440,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -462,23 +449,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgba32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -488,7 +474,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -497,23 +483,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba32(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToRgba32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgb48(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Rgb48 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Rgb48 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -523,7 +508,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -532,23 +517,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgb48(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgb48 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -558,7 +542,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -567,23 +551,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb48Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb48(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToRgb48(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void FromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal virtual void FromRgba64(ReadOnlySpan source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref Rgba64 sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref Rgba64 sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -593,7 +576,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -602,23 +585,22 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void FromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.FromRgba64(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref Rgba64 destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); @@ -628,7 +610,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -637,7 +619,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba64Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba64(sourcePixels, MemoryMarshal.Cast(destBytes), count); + this.ToRgba64(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt index 723b0358f..484dde9ac 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt @@ -16,19 +16,18 @@ #> /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts all pixels in 'source` span of into a span of -s. /// /// The source of data. /// The to the destination pixels. - /// The number of pixels to convert. - internal virtual void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) + internal virtual void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); ref <#=pixelType#> sourceBaseRef = ref MemoryMarshal.GetReference(source); ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < source.Length; i++) { ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceBaseRef, i); ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); @@ -38,7 +37,7 @@ } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. @@ -47,7 +46,7 @@ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void From<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.From<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); + this.From<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes).Slice(0, count), destPixels); } <# @@ -57,19 +56,18 @@ { #> /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// /// The span of source pixels /// The destination span of data. - /// The number of pixels to convert. - internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels) { - GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(destPixels); - for (int i = 0; i < count; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i); @@ -79,7 +77,7 @@ } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source pixels. @@ -88,7 +86,7 @@ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void To<#=pixelType#>Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.To<#=pixelType#>(sourcePixels, MemoryMarshal.Cast>(destBytes), count); + this.To<#=pixelType#>(sourcePixels.Slice(count), MemoryMarshal.Cast>(destBytes)); } <# } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index e6ccaf914..510645c4e 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static PixelOperations Instance { get; } = default(TPixel).CreatePixelOperations(); /// - /// Bulk version of + /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. /// /// The to the source vectors. /// The to the destination colors. @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Bulk version of . + /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// /// The to the source colors. /// The to the destination vectors. @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Bulk version of + /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. /// /// The to the source vectors. /// The to the destination colors. @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Bulk version of . + /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// /// The to the source colors. /// The to the destination vectors. @@ -102,17 +102,19 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// Performs a bulk conversion of a collection of one pixel format into another. + /// Converts 'sourceColors.Length' pixels from 'sourceColors' into 'destinationColors'. /// - /// The pixel format. + /// The destination pixel type. /// The to the source colors. /// The to the destination colors. - /// The number of pixels to convert. - internal virtual void To(ReadOnlySpan sourceColors, Span destinationColors, int count) + internal virtual void To( + ReadOnlySpan sourceColors, + Span destinationColors) where TDestinationPixel : struct, IPixel { - GuardSpans(sourceColors, nameof(sourceColors), destinationColors, nameof(destinationColors), count); + Guard.DestinationShouldNotBeTooShort(sourceColors, destinationColors, nameof(destinationColors)); + int count = sourceColors.Length; ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); // Gray8 and Gray16 are special implementations of IPixel in that they do not conform to the diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index dd947f337..98a5d5eb5 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -448,7 +448,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization { Span row = source.GetPixelRowSpan(y); Span rgbaSpan = rgbaBuffer.GetSpan(); - PixelOperations.Instance.ToRgba32(row, rgbaSpan, source.Width); + PixelOperations.Instance.ToRgba32(row, rgbaSpan); ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan); // And loop through each column diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 72322f0d4..1cd8c0196 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -59,13 +59,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().FromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + new PixelOperations().FromVector4(this.source.GetSpan(), this.destination.GetSpan()); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.FromVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + PixelOperations.Instance.FromVector4(this.source.GetSpan(), this.destination.GetSpan()); } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 2cbe549e4..e313953a6 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -65,13 +65,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan()); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.ToVector4(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + PixelOperations.Instance.ToVector4(this.source.GetSpan(), this.destination.GetSpan()); } } diff --git a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs index 46b58f369..051646f90 100644 --- a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs +++ b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs @@ -35,15 +35,15 @@ namespace SixLabors.ImageSharp.Benchmarks Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length); - PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length); + PixelOperations.Instance.ToVector4(background, backgroundSpan); + PixelOperations.Instance.ToVector4(source, sourceSpan); for (int i = 0; i < destination.Length; i++) { destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]); } - PixelOperations.Instance.FromVector4(destinationSpan, destination, destination.Length); + PixelOperations.Instance.FromVector4(destinationSpan, destination); } } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs index 8dca11cae..886e02c13 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs @@ -34,8 +34,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison Span aSpan = expected.GetPixelRowSpan(y); Span bSpan = actual.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgba64(aSpan, aBuffer, width); - PixelOperations.Instance.ToRgba64(bSpan, bBuffer, width); + PixelOperations.Instance.ToRgba64(aSpan, aBuffer); + PixelOperations.Instance.ToRgba64(bSpan, bBuffer); for (int x = 0; x < width; x++) { diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs index 674603380..9563edbb5 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs @@ -80,8 +80,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison Span aSpan = expected.GetPixelRowSpan(y); Span bSpan = actual.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgba64(aSpan, aBuffer, width); - PixelOperations.Instance.ToRgba64(bSpan, bBuffer, width); + PixelOperations.Instance.ToRgba64(aSpan, aBuffer); + PixelOperations.Instance.ToRgba64(bSpan, bBuffer); for (int x = 0; x < width; x++) { diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index 1543e2c8f..03b77149b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.FromBgra32(workBuffer.GetSpan(), row, row.Length); + PixelOperations.Instance.FromBgra32(workBuffer.GetSpan().Slice(0, w), row); } } } @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.FromBgr24(workBuffer.GetSpan(), row, row.Length); + PixelOperations.Instance.FromBgr24(workBuffer.GetSpan().Slice(w), row); } } } @@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs for (int y = 0; y < h; y++) { Span row = image.Frames.RootFrame.GetPixelRowSpan(y); - PixelOperations.Instance.ToBgra32(row, workBuffer.GetSpan(), row.Length); + PixelOperations.Instance.ToBgra32(row, workBuffer.GetSpan()); byte* destPtr = destPtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); From c58126ff15cf3680b7adcaf64ee6d94d80ee3c42 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 17:39:02 +0200 Subject: [PATCH 065/238] fix span length issues related to Vector4 conversion --- src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs | 12 ++++++------ .../Processors/Convolution/Convolution2DProcessor.cs | 4 ++-- .../Convolution/Convolution2PassProcessor.cs | 4 ++-- .../Processors/Convolution/ConvolutionProcessor.cs | 4 ++-- .../Quantization/FrameQuantizerBase{TPixel}.cs | 2 +- tests/ImageSharp.Tests/Issues/Issue412.cs | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index 6c24ce05b..6f0bba5cf 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -93,12 +93,12 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background, backgroundSpan); - PixelOperations.Instance.ToScaledVector4(source, sourceSpan); + PixelOperations.Instance.ToScaledVector4(background.Slice(0, background.Length), backgroundSpan); + PixelOperations.Instance.ToScaledVector4(source.Slice(0, background.Length), sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan, destination); + PixelOperations.Instance.FromScaledVector4(destinationSpan.Slice(0, background.Length), destination); } } @@ -127,12 +127,12 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background, backgroundSpan); - PixelOperations.Instance.ToScaledVector4(source, sourceSpan); + PixelOperations.Instance.ToScaledVector4(background.Slice(0, background.Length), backgroundSpan); + PixelOperations.Instance.ToScaledVector4(source.Slice(0, background.Length), sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan, destination); + PixelOperations.Instance.FromScaledVector4(destinationSpan.Slice(0, background.Length), destination); } } } diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs index 90049a994..a26fe6bfd 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs @@ -75,14 +75,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); + PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve2D(in matrixY, in matrixX, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs index f38f16f1a..98accb606 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs @@ -93,14 +93,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); + PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, sourcePixels, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs index d1b3f0ccf..dcecf2b82 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs @@ -59,14 +59,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan, vectorSpan); + PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index bc0ed0eab..71999576b 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public virtual QuantizedFrame QuantizeFrame(ImageFrame image) { Guard.NotNull(image, nameof(image)); - + // Get the size of the source image int height = image.Height; int width = image.Width; diff --git a/tests/ImageSharp.Tests/Issues/Issue412.cs b/tests/ImageSharp.Tests/Issues/Issue412.cs index 6123c822b..b0374ce1f 100644 --- a/tests/ImageSharp.Tests/Issues/Issue412.cs +++ b/tests/ImageSharp.Tests/Issues/Issue412.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.Issues [WithBlankImages(40, 30, PixelTypes.Rgba32)] public void AllPixelsExpectedToBeRedWhenAntialiasedDisabled(TestImageProvider provider) where TPixel : struct, IPixel { - using (var image = provider.GetImage()) + using (Image image = provider.GetImage()) { image.Mutate( context => From 3d4ae63da5ba5c44fe6f4e50be2bad4f8f0e5948 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 22 Oct 2018 18:03:47 +0200 Subject: [PATCH 066/238] fix wrong Slice() usages --- .../PixelOperations{TPixel}.Generated.cs | 18 +++++++++--------- .../PixelOperations{TPixel}.Generated.tt | 2 +- .../Quantization/FrameQuantizerBase{TPixel}.cs | 2 +- .../ReferenceCodecs/SystemDrawingBridge.cs | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs index 1cbf487d7..07ecf8756 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToArgb32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToArgb32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToArgb32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgr24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgr24(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToBgr24(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -211,7 +211,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgra32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgra32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToBgra32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToGray8Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray8(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToGray8(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -347,7 +347,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToGray16Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray16(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToGray16(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -415,7 +415,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb24(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToRgb24(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -483,7 +483,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba32(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToRgba32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -551,7 +551,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb48Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb48(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToRgb48(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// @@ -619,7 +619,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba64Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba64(sourcePixels.Slice(count), MemoryMarshal.Cast(destBytes)); + this.ToRgba64(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt index 484dde9ac..ef73378a2 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt @@ -86,7 +86,7 @@ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void To<#=pixelType#>Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.To<#=pixelType#>(sourcePixels.Slice(count), MemoryMarshal.Cast>(destBytes)); + this.To<#=pixelType#>(sourcePixels.Slice(0, count), MemoryMarshal.Cast>(destBytes)); } <# } diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index 71999576b..bc0ed0eab 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public virtual QuantizedFrame QuantizeFrame(ImageFrame image) { Guard.NotNull(image, nameof(image)); - + // Get the size of the source image int height = image.Height; int width = image.Width; diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index 03b77149b..e96825db1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.FromBgr24(workBuffer.GetSpan().Slice(w), row); + PixelOperations.Instance.FromBgr24(workBuffer.GetSpan().Slice(0, w), row); } } } From 5a228ea56d132b741573c331cdfac266aad5294f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 22 Oct 2018 18:17:09 +0100 Subject: [PATCH 067/238] Bump build now Github should be returned to normal. --- .../TestUtilities/TestDataGenerator.cs | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs index 912b86e34..56cde41fc 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs @@ -1,10 +1,24 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Numerics; namespace SixLabors.ImageSharp.Tests { + /// + /// Helper methods that allow the creation of random test data. + /// internal static class TestDataGenerator { + /// + /// Creates an of the given length consisting of random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . public static float[] GenerateRandomFloatArray(this Random rnd, int length, float minVal, float maxVal) { float[] values = new float[length]; @@ -17,6 +31,14 @@ namespace SixLabors.ImageSharp.Tests return values; } + /// + /// Creates an of the given length consisting of random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . public static Vector4[] GenerateRandomVectorArray(this Random rnd, int length, float minVal, float maxVal) { var values = new Vector4[length]; @@ -33,20 +55,32 @@ namespace SixLabors.ImageSharp.Tests return values; } + /// + /// Creates an of the given length consisting of rounded random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . public static float[] GenerateRandomRoundedFloatArray(this Random rnd, int length, float minVal, float maxVal) { float[] values = new float[length]; for (int i = 0; i < length; i++) { - values[i] = (float) Math.Round(rnd.GetRandomFloat(minVal, maxVal)); + values[i] = (float)Math.Round(rnd.GetRandomFloat(minVal, maxVal)); } return values; } - - + /// + /// Creates an of the given length consisting of random values. + /// + /// The pseudo-random number generator. + /// The length. + /// The . public static byte[] GenerateRandomByteArray(this Random rnd, int length) { byte[] values = new byte[length]; @@ -54,9 +88,6 @@ namespace SixLabors.ImageSharp.Tests return values; } - private static float GetRandomFloat(this Random rnd, float minVal, float maxVal) - { - return (float)rnd.NextDouble() * (maxVal - minVal) + minVal; - } + private static float GetRandomFloat(this Random rnd, float minVal, float maxVal) => ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal; } } \ No newline at end of file From 492d2d6b1044049e740b670be8838f9f2f781b03 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 01:11:14 +0200 Subject: [PATCH 068/238] pass Configuration to Vector4 converters in PixelOperations --- .../Processing/BrushApplicator.cs | 2 +- .../Processing/ImageBrush{TPixel}.cs | 7 +- .../Processing/PatternBrush{TPixel}.cs | 7 +- .../Processors/Drawing/DrawImageProcessor.cs | 4 +- .../Processing/RecolorBrush{TPixel}.cs | 7 +- .../Processing/SolidBrush{TPixel}.cs | 10 ++- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 17 ++-- .../Decoder/JpegImagePostProcessor.cs | 12 ++- .../Formats/Jpeg/JpegDecoderCore.cs | 2 +- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 3 +- src/ImageSharp/ImageFrame{TPixel}.cs | 16 ++-- .../PixelFormats/PixelBlender{TPixel}.cs | 81 ++++++++++++++----- .../Rgba32.PixelOperations.cs | 20 +++-- .../RgbaVector.PixelOperations.cs | 9 ++- .../PixelFormats/PixelOperations{TPixel}.cs | 28 ++++++- .../Convolution/Convolution2DProcessor.cs | 4 +- .../Convolution/Convolution2PassProcessor.cs | 4 +- .../Convolution/ConvolutionProcessor.cs | 4 +- .../Dithering/PaletteDitherProcessorBase.cs | 19 ++++- .../Overlays/BackgroundColorProcessor.cs | 2 +- .../Processors/Overlays/GlowProcessor.cs | 2 +- .../Processors/Overlays/VignetteProcessor.cs | 2 +- .../FrameQuantizerBase{TPixel}.cs | 4 +- .../Processors/Quantization/IQuantizer.cs | 6 +- .../Quantization/OctreeQuantizer.cs | 5 +- .../PaletteFrameQuantizer{TPixel}.cs | 5 +- .../Quantization/PaletteQuantizer.cs | 15 ++-- .../Quantization/QuantizeProcessor.cs | 2 +- .../Processors/Quantization/WuQuantizer.cs | 5 +- .../Processors/Transforms/ResizeProcessor.cs | 4 +- .../Color/Bulk/FromVector4.cs | 10 ++- .../Color/Bulk/ToVector4.cs | 25 +++--- .../PixelBlenders/PorterDuffBulkVsPixel.cs | 8 +- .../Jpg/JpegImagePostProcessorTests.cs | 4 +- .../PorterDuffFunctionsTests_TPixel.cs | 20 ++--- .../PixelFormats/PixelOperationsTests.cs | 15 ++-- .../Quantization/QuantizedImageTests.cs | 25 ++++-- .../TestUtilities/TestImageExtensions.cs | 36 +++++---- 38 files changed, 301 insertions(+), 150 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/BrushApplicator.cs b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs index 770d44065..0c6e0d3b4 100644 --- a/src/ImageSharp.Drawing/Processing/BrushApplicator.cs +++ b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs @@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Processing } Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, overlaySpan, amountSpan); + this.Blender.Blend(this.Target.Configuration, destinationRow, destinationRow, overlaySpan, amountSpan); } } } diff --git a/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs index c3f81868b..1ef4bb9ec 100644 --- a/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs @@ -140,7 +140,12 @@ namespace SixLabors.ImageSharp.Processing } Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - this.Blender.Blend(this.source.MemoryAllocator, destinationRow, destinationRow, overlaySpan, amountSpan); + this.Blender.Blend( + this.source.Configuration, + destinationRow, + destinationRow, + overlaySpan, + amountSpan); } } } diff --git a/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs index 2ce9a7ce5..46ed36f68 100644 --- a/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs @@ -170,7 +170,12 @@ namespace SixLabors.ImageSharp.Processing } Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, overlaySpan, amountSpan); + this.Blender.Blend( + this.Target.Configuration, + destinationRow, + destinationRow, + overlaySpan, + amountSpan); } } } diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs index dc73420f3..0957904c6 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs @@ -79,8 +79,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing int width = maxX - minX; - MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator; - var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); ParallelHelper.IterateRows( @@ -93,7 +91,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing Span background = source.GetPixelRowSpan(y).Slice(minX, width); Span foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width); - blender.Blend(memoryAllocator, background, background, foreground, this.Opacity); + blender.Blend(configuration, background, background, foreground, this.Opacity); } }); } diff --git a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs index 2968b68b5..09a1ff71f 100644 --- a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs @@ -158,7 +158,12 @@ namespace SixLabors.ImageSharp.Processing } Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, overlaySpan, amountSpan); + this.Blender.Blend( + this.Target.Configuration, + destinationRow, + destinationRow, + overlaySpan, + amountSpan); } } } diff --git a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs index 6b69c33f0..a77c6728b 100644 --- a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs @@ -92,10 +92,11 @@ namespace SixLabors.ImageSharp.Processing Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; + Configuration configuration = this.Target.Configuration; if (this.Options.BlendPercentage == 1f) { - this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, this.Colors.GetSpan(), scanline); + this.Blender.Blend(configuration, destinationRow, destinationRow, this.Colors.GetSpan(), scanline); } else { @@ -108,7 +109,12 @@ namespace SixLabors.ImageSharp.Processing amountSpan[i] = scanline[i] * this.Options.BlendPercentage; } - this.Blender.Blend(memoryAllocator, destinationRow, destinationRow, this.Colors.GetSpan(), amountSpan); + this.Blender.Blend( + configuration, + destinationRow, + destinationRow, + this.Colors.GetSpan(), + amountSpan); } } } diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 7db347aa6..81adf52dd 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; @@ -88,7 +89,7 @@ namespace SixLabors.ImageSharp.Formats.Gif // Quantize the image returning a palette. QuantizedFrame quantized = - this.quantizer.CreateFrameQuantizer().QuantizeFrame(image.Frames.RootFrame); + this.quantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(image.Frames.RootFrame); // Get the number of bits. this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(quantized.Palette.Length).Clamp(1, 8); @@ -151,7 +152,7 @@ namespace SixLabors.ImageSharp.Formats.Gif else { using (QuantizedFrame paletteQuantized - = palleteQuantizer.CreateFrameQuantizer(() => quantized.Palette).QuantizeFrame(frame)) + = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration(), () => quantized.Palette).QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } @@ -171,15 +172,17 @@ namespace SixLabors.ImageSharp.Formats.Gif if (quantized is null) { // Allow each frame to be encoded at whatever color depth the frame designates if set. - if (previousFrame != null - && previousMeta.ColorTableLength != frameMetaData.ColorTableLength - && frameMetaData.ColorTableLength > 0) + if (previousFrame != null && previousMeta.ColorTableLength != frameMetaData.ColorTableLength + && frameMetaData.ColorTableLength > 0) { - quantized = this.quantizer.CreateFrameQuantizer(frameMetaData.ColorTableLength).QuantizeFrame(frame); + quantized = this.quantizer.CreateFrameQuantizer( + image.GetConfiguration(), + frameMetaData.ColorTableLength).QuantizeFrame(frame); } else { - quantized = this.quantizer.CreateFrameQuantizer().QuantizeFrame(frame); + quantized = this.quantizer.CreateFrameQuantizer(image.GetConfiguration()) + .QuantizeFrame(frame); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs index 6bd287732..1a6da2b2b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs @@ -26,6 +26,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// internal class JpegImagePostProcessor : IDisposable { + private readonly Configuration configuration; + /// /// The number of block rows to be processed in one Step. /// @@ -49,15 +51,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// /// Initializes a new instance of the class. /// - /// The to use for buffer allocations. + /// The to configure internal operations. /// The representing the uncompressed spectral Jpeg data - public JpegImagePostProcessor(MemoryAllocator memoryAllocator, IRawJpegData rawJpeg) + public JpegImagePostProcessor(Configuration configuration, IRawJpegData rawJpeg) { + this.configuration = configuration; this.RawJpeg = rawJpeg; IJpegComponent c0 = rawJpeg.Components.First(); this.NumberOfPostProcessorSteps = c0.SizeInBlocks.Height / BlockRowsPerStep; this.PostProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, PixelRowsPerStep); + MemoryAllocator memoryAllocator = configuration.MemoryAllocator; this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(memoryAllocator, this, c)).ToArray(); this.rgbaBuffer = memoryAllocator.Allocate(rawJpeg.ImageSizeInPixels.Width); this.colorConverter = JpegColorConverter.GetConverter(rawJpeg.ColorSpace); @@ -158,9 +162,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder this.colorConverter.ConvertToRgba(values, this.rgbaBuffer.GetSpan()); Span destRow = destination.GetPixelRowSpan(yy); - + // TODO: Investigate if slicing is actually necessary - PixelOperations.Instance.FromVector4(this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); + PixelOperations.Instance.FromVector4(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); } } } diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 22d9cbdee..36246c682 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -936,7 +936,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg private Image PostProcessIntoImage() where TPixel : struct, IPixel { - using (var postProcessor = new JpegImagePostProcessor(this.configuration.MemoryAllocator, this)) + using (var postProcessor = new JpegImagePostProcessor(this.configuration, this)) { var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData); postProcessor.PostProcess(image.Frames.RootFrame); diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 84f7cb6cc..71945d130 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -237,7 +237,8 @@ namespace SixLabors.ImageSharp.Formats.Png } // Create quantized frame returning the palette and set the bit depth. - quantized = this.quantizer.CreateFrameQuantizer().QuantizeFrame(image.Frames.RootFrame); + quantized = this.quantizer.CreateFrameQuantizer(image.GetConfiguration()) + .QuantizeFrame(image.Frames.RootFrame); byte quantizedBits = (byte)ImageMaths.GetBitsNeededForColorDepth(quantized.Palette.Length).Clamp(1, 8); bits = Math.Max(bits, quantizedBits); diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index 25c517d44..bb95bb7b6 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -21,7 +21,6 @@ namespace SixLabors.ImageSharp public sealed class ImageFrame : IPixelSource, IDisposable where TPixel : struct, IPixel { - private readonly Configuration configuration; private bool isDisposed; /// @@ -84,7 +83,7 @@ namespace SixLabors.ImageSharp Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); - this.configuration = configuration; + this.Configuration = configuration; this.MemoryAllocator = configuration.MemoryAllocator; this.PixelBuffer = this.MemoryAllocator.Allocate2D(width, height); this.MetaData = metaData ?? new ImageFrameMetaData(); @@ -118,7 +117,7 @@ namespace SixLabors.ImageSharp Guard.MustBeGreaterThan(height, 0, nameof(height)); Guard.NotNull(metaData, nameof(metaData)); - this.configuration = configuration; + this.Configuration = configuration; this.MemoryAllocator = configuration.MemoryAllocator; this.PixelBuffer = new Buffer2D(memorySource, width, height); this.MetaData = metaData; @@ -134,7 +133,7 @@ namespace SixLabors.ImageSharp Guard.NotNull(configuration, nameof(configuration)); Guard.NotNull(source, nameof(source)); - this.configuration = configuration; + this.Configuration = configuration; this.MemoryAllocator = configuration.MemoryAllocator; this.PixelBuffer = this.MemoryAllocator.Allocate2D(source.PixelBuffer.Width, source.PixelBuffer.Height); source.PixelBuffer.GetSpan().CopyTo(this.PixelBuffer.GetSpan()); @@ -146,6 +145,11 @@ namespace SixLabors.ImageSharp /// public MemoryAllocator MemoryAllocator { get; } + /// + /// Gets the instance associated with this . + /// + internal Configuration Configuration { get; } + /// /// Gets the image pixels. Not private as Buffer2D requires an array in its constructor. /// @@ -254,7 +258,7 @@ namespace SixLabors.ImageSharp /// Clones the current instance. /// /// The - internal ImageFrame Clone() => this.Clone(this.configuration); + internal ImageFrame Clone() => this.Clone(this.Configuration); /// /// Clones the current instance. @@ -269,7 +273,7 @@ namespace SixLabors.ImageSharp /// The pixel format. /// The internal ImageFrame CloneAs() - where TPixel2 : struct, IPixel => this.CloneAs(this.configuration); + where TPixel2 : struct, IPixel => this.CloneAs(this.Configuration); /// /// Returns a copy of the image frame in the given pixel format. diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index 6f0bba5cf..5c8e506ae 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -4,8 +4,8 @@ using System; using System.Buffers; using System.Numerics; + using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; namespace SixLabors.ImageSharp.PixelFormats { @@ -38,7 +38,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// A value between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - protected abstract void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount); + protected abstract void BlendFunction( + Span destination, + ReadOnlySpan background, + ReadOnlySpan source, + float amount); /// /// Blend 2 rows together. @@ -50,12 +54,16 @@ namespace SixLabors.ImageSharp.PixelFormats /// A span with values between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - protected abstract void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount); + protected abstract void BlendFunction( + Span destination, + ReadOnlySpan background, + ReadOnlySpan source, + ReadOnlySpan amount); /// /// Blends 2 rows together /// - /// memory manager to use internally + /// to use internally /// the destination span /// the background span /// the source span @@ -63,16 +71,21 @@ namespace SixLabors.ImageSharp.PixelFormats /// A span with values between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) + public void Blend( + Configuration configuration, + Span destination, + ReadOnlySpan background, + ReadOnlySpan source, + ReadOnlySpan amount) { - this.Blend(memoryManager, destination, background, source, amount); + this.Blend(configuration, destination, background, source, amount); } /// /// Blends 2 rows together /// /// the pixel format of the source span - /// memory manager to use internally + /// to use internally /// the destination span /// the background span /// the source span @@ -80,25 +93,40 @@ namespace SixLabors.ImageSharp.PixelFormats /// A span with values between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, ReadOnlySpan amount) + public void Blend( + Configuration configuration, + Span destination, + ReadOnlySpan background, + ReadOnlySpan source, + ReadOnlySpan amount) where TPixelSrc : struct, IPixel { Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3)) + using (IMemoryOwner buffer = + configuration.MemoryAllocator.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background.Slice(0, background.Length), backgroundSpan); - PixelOperations.Instance.ToScaledVector4(source.Slice(0, background.Length), sourceSpan); + PixelOperations.Instance.ToScaledVector4( + configuration, + background.Slice(0, background.Length), + backgroundSpan); + PixelOperations.Instance.ToScaledVector4( + configuration, + source.Slice(0, background.Length), + sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan.Slice(0, background.Length), destination); + PixelOperations.Instance.FromScaledVector4( + configuration, + destinationSpan.Slice(0, background.Length), + destination); } } @@ -106,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Blends 2 rows together /// /// the pixel format of the source span - /// memory manager to use internally + /// to use internally /// the destination span /// the background span /// the source span @@ -114,26 +142,41 @@ namespace SixLabors.ImageSharp.PixelFormats /// A value between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - public void Blend(MemoryAllocator memoryManager, Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount) + public void Blend( + Configuration configuration, + Span destination, + ReadOnlySpan background, + ReadOnlySpan source, + float amount) where TPixelSrc : struct, IPixel { Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); - using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3)) + using (IMemoryOwner buffer = + configuration.MemoryAllocator.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4(background.Slice(0, background.Length), backgroundSpan); - PixelOperations.Instance.ToScaledVector4(source.Slice(0, background.Length), sourceSpan); + PixelOperations.Instance.ToScaledVector4( + configuration, + background.Slice(0, background.Length), + backgroundSpan); + PixelOperations.Instance.ToScaledVector4( + configuration, + source.Slice(0, background.Length), + sourceSpan); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4(destinationSpan.Slice(0, background.Length), destination); + PixelOperations.Instance.FromScaledVector4( + configuration, + destinationSpan.Slice(0, background.Length), + destination); } } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index c25baa451..0f5ddf372 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -19,7 +19,10 @@ namespace SixLabors.ImageSharp.PixelFormats internal partial class PixelOperations : PixelOperations { /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) + internal override void ToVector4( + Configuration configuration, + ReadOnlySpan sourceColors, + Span destinationVectors) { Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); @@ -31,7 +34,10 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors) + internal override void FromVector4( + Configuration configuration, + ReadOnlySpan sourceVectors, + Span destinationColors) { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); @@ -43,17 +49,21 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors) + internal override void ToScaledVector4( + Configuration configuration, + ReadOnlySpan sourceColors, + Span destinationVectors) { - this.ToVector4(sourceColors, destinationVectors); + this.ToVector4(configuration, sourceColors, destinationVectors); } /// internal override void FromScaledVector4( + Configuration configuration, ReadOnlySpan sourceVectors, Span destinationColors) { - this.FromVector4(sourceVectors, destinationColors); + this.FromVector4(configuration, sourceVectors, destinationColors); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index d1f326365..cb12d944c 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -19,6 +19,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// internal override void FromScaledVector4( + Configuration configuration, ReadOnlySpan sourceVectors, Span destinationColors) { @@ -29,12 +30,16 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToScaledVector4( + Configuration configuration, ReadOnlySpan sourceColors, Span destinationVectors) - => this.ToVector4(sourceColors, destinationVectors); + => this.ToVector4(configuration, sourceColors, destinationVectors); /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) + internal override void ToVector4( + Configuration configuration, + ReadOnlySpan sourceColors, + Span destinationVectors) { Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 510645c4e..8f3ea6c11 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -24,10 +24,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. /// + /// A to configure internal operations /// The to the source vectors. /// The to the destination colors. - internal virtual void FromVector4(ReadOnlySpan sourceVectors, Span destinationColors) + internal virtual void FromVector4( + Configuration configuration, + ReadOnlySpan sourceVectors, + Span destinationColors) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); @@ -44,10 +49,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// + /// A to configure internal operations /// The to the source colors. /// The to the destination vectors. - internal virtual void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors) + internal virtual void ToVector4( + Configuration configuration, + ReadOnlySpan sourceColors, + Span destinationVectors) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); @@ -64,10 +74,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. /// + /// A to configure internal operations /// The to the source vectors. /// The to the destination colors. - internal virtual void FromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors) + internal virtual void FromScaledVector4( + Configuration configuration, + ReadOnlySpan sourceVectors, + Span destinationColors) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); @@ -84,10 +99,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// + /// A to configure internal operations /// The to the source colors. /// The to the destination vectors. - internal virtual void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors) + internal virtual void ToScaledVector4( + Configuration configuration, + ReadOnlySpan sourceColors, + Span destinationVectors) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs index a26fe6bfd..bd1419e4b 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs @@ -75,14 +75,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); + PixelOperations.Instance.ToVector4(configuration, targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve2D(in matrixY, in matrixX, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs index 98accb606..05007c370 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs @@ -93,14 +93,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); + PixelOperations.Instance.ToVector4(configuration, targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, sourcePixels, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs index dcecf2b82..8ef64bdac 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs @@ -59,14 +59,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution for (int y = rows.Min; y < rows.Max; y++) { Span targetRowSpan = targetPixels.GetRowSpan(y).Slice(startX); - PixelOperations.Instance.ToVector4(targetRowSpan.Slice(0, length), vectorSpan); + PixelOperations.Instance.ToVector4(configuration, targetRowSpan.Slice(0, length), vectorSpan); for (int x = 0; x < width; x++) { DenseMatrixUtils.Convolve(in matrix, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs index fd9380109..f01865ec0 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Numerics; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Dithering { @@ -21,7 +22,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// /// The vector representation of the image palette. /// - private readonly Vector4[] paletteVector; + private Vector4[] paletteVector; /// /// Initializes a new instance of the class. @@ -30,8 +31,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering protected PaletteDitherProcessorBase(TPixel[] palette) { this.Palette = palette ?? throw new ArgumentNullException(nameof(palette)); - this.paletteVector = new Vector4[this.Palette.Length]; - PixelOperations.Instance.ToScaledVector4(this.Palette, this.paletteVector); } /// @@ -40,7 +39,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering public TPixel[] Palette { get; } /// - /// Returns the two closest colors from the palette calcluated via Euclidean distance in the Rgba space. + /// Returns the two closest colors from the palette calculated via Euclidean distance in the Rgba space. /// /// The source color to match. /// The . @@ -90,5 +89,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering return pair; } + + protected override void BeforeFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) + { + base.BeforeFrameApply(source, sourceRectangle, configuration); + + // Lazy init paletteVector: + if (this.paletteVector == null) + { + this.paletteVector = new Vector4[this.Palette.Length]; + PixelOperations.Instance.ToScaledVector4(configuration, this.Palette, this.paletteVector); + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs index 4adddd153..25787ff92 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays // This switched color & destination in the 2nd and 3rd places because we are applying the target color under the current one blender.Blend( - source.MemoryAllocator, + source.Configuration, destination, colors.GetSpan(), destination, diff --git a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs index 93d6edff1..21f6be69f 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs @@ -145,7 +145,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays Span destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); this.blender.Blend( - source.MemoryAllocator, + source.Configuration, destination, destination, rowColors.GetSpan(), diff --git a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs index 52dade4ef..a8fa1d65c 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays Span destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); this.blender.Blend( - source.MemoryAllocator, + source.Configuration, destination, destination, rowColors.GetSpan(), diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index bc0ed0eab..a41127bfc 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public abstract class FrameQuantizerBase : IFrameQuantizer where TPixel : struct, IPixel { + private readonly Configuration configuration; + /// /// A lookup table for colors /// @@ -79,7 +81,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Collect the palette. Required before the second pass runs. TPixel[] palette = this.GetPalette(); this.paletteVector = new Vector4[palette.Length]; - PixelOperations.Instance.ToScaledVector4(palette, this.paletteVector); + PixelOperations.Instance.ToScaledVector4(image.Configuration, palette, this.paletteVector); var quantizedFrame = new QuantizedFrame(image.MemoryAllocator, width, height, palette); if (this.Dither) diff --git a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs index 3da09cde0..f1490a6d2 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs @@ -19,18 +19,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// Creates the generic frame quantizer /// + /// The to configure internal operations. /// The pixel format. /// The - IFrameQuantizer CreateFrameQuantizer() + IFrameQuantizer CreateFrameQuantizer(Configuration configuration) where TPixel : struct, IPixel; /// /// Creates the generic frame quantizer /// /// The pixel format. + /// The to configure internal operations. /// The maximum number of colors to hold in the color palette. /// The - IFrameQuantizer CreateFrameQuantizer(int maxColors) + IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) where TPixel : struct, IPixel; } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs index 22bb5223f..38962c768 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs @@ -74,13 +74,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public int MaxColors { get; } + /// /// - public IFrameQuantizer CreateFrameQuantizer() + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) where TPixel : struct, IPixel => new OctreeFrameQuantizer(this); /// - public IFrameQuantizer CreateFrameQuantizer(int maxColors) + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) where TPixel : struct, IPixel { maxColors = maxColors.Clamp(1, DefaultMaxColors); diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs index 625400413..cab3af6de 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteFrameQuantizer{TPixel}.cs @@ -31,9 +31,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// Initializes a new instance of the class. /// + /// The to configure internal operations. /// The palette quantizer. /// An array of all colors in the palette. - public PaletteFrameQuantizer(PaletteQuantizer quantizer, TPixel[] colors) + public PaletteFrameQuantizer(Configuration configuration, PaletteQuantizer quantizer, TPixel[] colors) : base(quantizer, true) { // TODO: Why is this value constrained? Gif has limitations but theoretically @@ -41,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization Guard.MustBeBetweenOrEqualTo(colors.Length, 1, 256, nameof(colors)); this.palette = colors; this.paletteVector = new Vector4[this.palette.Length]; - PixelOperations.Instance.ToScaledVector4(this.palette, this.paletteVector); + PixelOperations.Instance.ToScaledVector4(configuration, this.palette, this.paletteVector); } /// diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index 27ef05dfe..361791253 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -43,12 +43,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public IErrorDiffuser Diffuser { get; } /// - public virtual IFrameQuantizer CreateFrameQuantizer() + public virtual IFrameQuantizer CreateFrameQuantizer(Configuration configuration) where TPixel : struct, IPixel - => this.CreateFrameQuantizer(() => NamedColors.WebSafePalette); + => this.CreateFrameQuantizer(configuration, () => NamedColors.WebSafePalette); /// - public IFrameQuantizer CreateFrameQuantizer(int maxColors) + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) where TPixel : struct, IPixel { TPixel[] websafe = NamedColors.WebSafePalette; @@ -56,21 +56,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization if (max != websafe.Length) { - return this.CreateFrameQuantizer(() => NamedColors.WebSafePalette.AsSpan(0, max).ToArray()); + return this.CreateFrameQuantizer(configuration, () => NamedColors.WebSafePalette.AsSpan(0, max).ToArray()); } - return this.CreateFrameQuantizer(() => websafe); + return this.CreateFrameQuantizer(configuration, () => websafe); } /// /// Gets the palette to use to quantize the image. /// /// The pixel format. + /// The to configure internal operations /// The method to return the palette. /// The - public IFrameQuantizer CreateFrameQuantizer(Func paletteFunction) + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, Func paletteFunction) where TPixel : struct, IPixel - => new PaletteFrameQuantizer(this, paletteFunction.Invoke()); + => new PaletteFrameQuantizer(configuration, this, paletteFunction.Invoke()); private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; } diff --git a/src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor.cs b/src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor.cs index bd5a6e9ec..8da89bf94 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - IFrameQuantizer executor = this.Quantizer.CreateFrameQuantizer(); + IFrameQuantizer executor = this.Quantizer.CreateFrameQuantizer(configuration); using (QuantizedFrame quantized = executor.QuantizeFrame(source)) { int paletteCount = quantized.Palette.Length - 1; diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs index 5123e737d..4cd09a14f 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs @@ -73,13 +73,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public int MaxColors { get; } + /// /// - public IFrameQuantizer CreateFrameQuantizer() + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) where TPixel : struct, IPixel => new WuFrameQuantizer(this); /// - public IFrameQuantizer CreateFrameQuantizer(int maxColors) + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) where TPixel : struct, IPixel { maxColors = maxColors.Clamp(1, DefaultMaxColors); diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index 05c4464f1..4d4ed06ce 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Span sourceRow = source.GetPixelRowSpan(y); Span tempRowSpan = tempRowBuffer.Span; - PixelOperations.Instance.ToVector4(sourceRow, tempRowSpan); + PixelOperations.Instance.ToVector4(configuration, sourceRow, tempRowSpan); Vector4Utils.Premultiply(tempRowSpan); ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y]; @@ -309,7 +309,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } Span targetRowSpan = destination.GetPixelRowSpan(y); - PixelOperations.Instance.FromVector4(tempRowSpan, targetRowSpan); + PixelOperations.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan); } }); } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 1cd8c0196..2b9573ed7 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -24,6 +24,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk protected IMemoryOwner destination; + protected Configuration Configuration => Configuration.Default; + [Params( 64, 2048 @@ -33,8 +35,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [GlobalSetup] public void Setup() { - this.destination = Configuration.Default.MemoryAllocator.Allocate(this.Count); - this.source = Configuration.Default.MemoryAllocator.Allocate(this.Count); + this.destination = this.Configuration.MemoryAllocator.Allocate(this.Count); + this.source = this.Configuration.MemoryAllocator.Allocate(this.Count); } [GlobalCleanup] @@ -59,13 +61,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().FromVector4(this.source.GetSpan(), this.destination.GetSpan()); + new PixelOperations().FromVector4(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.FromVector4(this.source.GetSpan(), this.destination.GetSpan()); + PixelOperations.Instance.FromVector4(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index e313953a6..f0fee649a 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -10,10 +10,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Attributes.Jobs; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Environments; -using BenchmarkDotNet.Jobs; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -27,20 +23,21 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk protected IMemoryOwner destination; + protected Configuration Configuration => Configuration.Default; + [Params( - 64, + 64, //256, //512, //1024, - 2048 - )] + 2048)] public int Count { get; set; } [GlobalSetup] public void Setup() { - this.source = Configuration.Default.MemoryAllocator.Allocate(this.Count); - this.destination = Configuration.Default.MemoryAllocator.Allocate(this.Count); + this.source = this.Configuration.MemoryAllocator.Allocate(this.Count); + this.destination = this.Configuration.MemoryAllocator.Allocate(this.Count); } [GlobalCleanup] @@ -65,13 +62,19 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().ToVector4(this.source.GetSpan(), this.destination.GetSpan()); + new PixelOperations().ToVector4( + this.Configuration, + this.source.GetSpan(), + this.destination.GetSpan()); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.ToVector4(this.source.GetSpan(), this.destination.GetSpan()); + PixelOperations.Instance.ToVector4( + this.Configuration, + this.source.GetSpan(), + this.destination.GetSpan()); } } diff --git a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs index 051646f90..cdd56fa07 100644 --- a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs +++ b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs @@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Benchmarks public class PorterDuffBulkVsPixel : BenchmarkBase { + private Configuration Configuration => Configuration.Default; + private void BulkVectorConvert( Span destination, Span background, @@ -35,15 +37,15 @@ namespace SixLabors.ImageSharp.Benchmarks Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToVector4(background, backgroundSpan); - PixelOperations.Instance.ToVector4(source, sourceSpan); + PixelOperations.Instance.ToVector4(this.Configuration, background, backgroundSpan); + PixelOperations.Instance.ToVector4(this.Configuration, source, sourceSpan); for (int i = 0; i < destination.Length; i++) { destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]); } - PixelOperations.Instance.FromVector4(destinationSpan, destination); + PixelOperations.Instance.FromVector4(this.Configuration, destinationSpan, destination); } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs index cfa421a82..b3219115d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { string imageFile = provider.SourceFileOrDescription; using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) - using (var pp = new JpegImagePostProcessor(Configuration.Default.MemoryAllocator, decoder)) + using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder)) using (var imageFrame = new ImageFrame(Configuration.Default, decoder.ImageWidth, decoder.ImageHeight)) { pp.DoPostProcessorStep(imageFrame); @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { string imageFile = provider.SourceFileOrDescription; using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) - using (var pp = new JpegImagePostProcessor(Configuration.Default.MemoryAllocator, decoder)) + using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder)) using (var image = new Image(decoder.ImageWidth, decoder.ImageHeight)) { pp.PostProcess(image.Frames.RootFrame); diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs index 3ea9bcad4..7de1cbb19 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(0.6f, 0.6f, 0.6f, 1) }, }; - private MemoryAllocator MemoryAllocator { get; } = Configuration.Default.MemoryAllocator; + private Configuration Configuration => Configuration.Default; [Theory] [MemberData(nameof(NormalBlendFunctionData))] @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.NormalSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.NormalSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.MultiplySrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.MultiplySrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.AddSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.AddSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -167,7 +167,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.SubtractSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.SubtractSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -206,7 +206,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.ScreenSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.ScreenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.DarkenSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.DarkenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -284,7 +284,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.LightenSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.LightenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -323,7 +323,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.OverlaySrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.OverlaySrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } @@ -362,7 +362,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders where TPixel : struct, IPixel { var dest = new Span(new TPixel[1]); - new DefaultPixelBlenders.HardLightSrcOver().Blend(this.MemoryAllocator, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); + new DefaultPixelBlenders.HardLightSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 0082e6c0e..8314bd9b4 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -269,7 +269,10 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { this.Measure( times, - () => PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan())); + () => PixelOperations.Instance.ToVector4( + this.Configuration, + source.GetSpan(), + dest.GetSpan())); } } } @@ -333,6 +336,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public static TheoryData ArraySizesData => new TheoryData { 0, 1, 2, 7, 16, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 1111 }; + protected Configuration Configuration => Configuration.Default; + internal static PixelOperations Operations => PixelOperations.Instance; internal static TPixel[] CreateExpectedPixelData(Vector4[] source) @@ -367,7 +372,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromVector4(s, d.GetSpan()) + (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan()) ); } @@ -381,7 +386,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromScaledVector4(s, d.GetSpan()) + (s, d) => Operations.FromScaledVector4(this.Configuration, s, d.GetSpan()) ); } @@ -417,7 +422,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToVector4(s, d.GetSpan()) + (s, d) => Operations.ToVector4(this.Configuration, s, d.GetSpan()) ); } @@ -431,7 +436,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToScaledVector4(s, d.GetSpan()) + (s, d) => Operations.ToScaledVector4(this.Configuration, s, d.GetSpan()) ); } diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index 719e9793a..fa855aef7 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -10,6 +10,8 @@ namespace SixLabors.ImageSharp.Tests { public class QuantizedImageTests { + private Configuration Configuration => Configuration.Default; + [Fact] public void QuantizersDitherByDefault() { @@ -21,15 +23,17 @@ namespace SixLabors.ImageSharp.Tests Assert.NotNull(octree.Diffuser); Assert.NotNull(wu.Diffuser); - Assert.True(palette.CreateFrameQuantizer().Dither); - Assert.True(octree.CreateFrameQuantizer().Dither); - Assert.True(wu.CreateFrameQuantizer().Dither); + Assert.True(palette.CreateFrameQuantizer(this.Configuration).Dither); + Assert.True(octree.CreateFrameQuantizer(this.Configuration).Dither); + Assert.True(wu.CreateFrameQuantizer(this.Configuration).Dither); } [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] - public void PaletteQuantizerYieldsCorrectTransparentPixel(TestImageProvider provider, bool dither) + public void PaletteQuantizerYieldsCorrectTransparentPixel( + TestImageProvider provider, + bool dither) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) @@ -40,7 +44,8 @@ namespace SixLabors.ImageSharp.Tests foreach (ImageFrame frame in image.Frames) { - QuantizedFrame quantized = quantizer.CreateFrameQuantizer().QuantizeFrame(frame); + QuantizedFrame quantized = + quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); int index = this.GetTransparentIndex(quantized); Assert.Equal(index, quantized.GetPixelSpan()[0]); @@ -51,7 +56,9 @@ namespace SixLabors.ImageSharp.Tests [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] - public void OctreeQuantizerYieldsCorrectTransparentPixel(TestImageProvider provider, bool dither) + public void OctreeQuantizerYieldsCorrectTransparentPixel( + TestImageProvider provider, + bool dither) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) @@ -62,7 +69,8 @@ namespace SixLabors.ImageSharp.Tests foreach (ImageFrame frame in image.Frames) { - QuantizedFrame quantized = quantizer.CreateFrameQuantizer().QuantizeFrame(frame); + QuantizedFrame quantized = + quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); int index = this.GetTransparentIndex(quantized); Assert.Equal(index, quantized.GetPixelSpan()[0]); @@ -84,7 +92,8 @@ namespace SixLabors.ImageSharp.Tests foreach (ImageFrame frame in image.Frames) { - QuantizedFrame quantized = quantizer.CreateFrameQuantizer().QuantizeFrame(frame); + QuantizedFrame quantized = + quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); int index = this.GetTransparentIndex(quantized); Assert.Equal(index, quantized.GetPixelSpan()[0]); diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index f055ce548..29d39596b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -30,27 +30,29 @@ namespace SixLabors.ImageSharp.Tests { MemoryAllocator memoryAllocator = ctx.MemoryAllocator; - ctx.Apply(img => - { - using (Buffer2D temp = memoryAllocator.Allocate2D(img.Width, img.Height)) - { - Span tempSpan = temp.GetSpan(); - foreach (ImageFrame frame in img.Frames) + ctx.Apply( + img => { - Span pixelSpan = frame.GetPixelSpan(); + Configuration configuration = img.GetConfiguration(); + using (Buffer2D temp = memoryAllocator.Allocate2D(img.Width, img.Height)) + { + Span tempSpan = temp.GetSpan(); + foreach (ImageFrame frame in img.Frames) + { + Span pixelSpan = frame.GetPixelSpan(); - PixelOperations.Instance.ToScaledVector4(pixelSpan, tempSpan); + PixelOperations.Instance.ToScaledVector4(configuration, pixelSpan, tempSpan); - for (int i = 0; i < tempSpan.Length; i++) - { - ref Vector4 v = ref tempSpan[i]; - v.W = 1F; - } + for (int i = 0; i < tempSpan.Length; i++) + { + ref Vector4 v = ref tempSpan[i]; + v.W = 1F; + } - PixelOperations.Instance.FromScaledVector4(tempSpan, pixelSpan); - } - } - }); + PixelOperations.Instance.FromScaledVector4(configuration, tempSpan, pixelSpan); + } + } + }); } public static Image DebugSave( From bd78bff11330b1c098fb4ae3169b9862c495e9be Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 01:49:24 +0200 Subject: [PATCH 069/238] Feed Configuration to all methods in PixelOperations --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 12 +- src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs | 17 +- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 18 +- .../Encoder/YCbCrForwardConverter{TPixel}.cs | 6 +- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 2 + src/ImageSharp/Formats/Png/PngEncoderCore.cs | 46 +++-- .../Formats/Png/PngScanlineProcessor.cs | 8 +- src/ImageSharp/ImageFrame{TPixel}.cs | 4 +- .../PixelFormats/NamedColors{TPixel}.cs | 6 +- .../Argb32.PixelOperations.Generated.cs | 20 +- .../Bgr24.PixelOperations.Generated.cs | 20 +- .../Bgra32.PixelOperations.Generated.cs | 20 +- .../Gray16.PixelOperations.Generated.cs | 20 +- .../Gray8.PixelOperations.Generated.cs | 20 +- .../Rgb24.PixelOperations.Generated.cs | 20 +- .../Rgb48.PixelOperations.Generated.cs | 20 +- .../Rgba32.PixelOperations.Generated.cs | 20 +- .../Rgba64.PixelOperations.Generated.cs | 20 +- .../Generated/_Common.ttinclude | 6 +- .../PixelOperations{TPixel}.Generated.cs | 180 +++++++++++------- .../PixelOperations{TPixel}.Generated.tt | 20 +- .../PixelFormats/PixelOperations{TPixel}.cs | 2 + .../Quantization/WuFrameQuantizer{TPixel}.cs | 2 +- .../Color/Bulk/FromRgba32Bytes.cs | 11 +- .../ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs | 21 +- .../Color/Bulk/ToXyzw.cs | 21 +- .../PixelFormats/PixelOperationsTests.cs | 44 ++--- .../ImageComparison/ExactImageComparer.cs | 5 +- .../ImageComparison/TolerantImageComparer.cs | 5 +- .../ReferenceCodecs/MagickReferenceDecoder.cs | 12 +- .../ReferenceCodecs/SystemDrawingBridge.cs | 23 ++- 31 files changed, 405 insertions(+), 246 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 77cd32222..cea90cb45 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -436,7 +436,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.stream.Read(row); int newY = Invert(y, height, inverted); Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.FromBgr24Bytes(row.GetSpan(), pixelSpan, width); + PixelOperations.Instance.FromBgr24Bytes( + this.configuration, + row.GetSpan(), + pixelSpan, + width); } } } @@ -461,7 +465,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.stream.Read(row); int newY = Invert(y, height, inverted); Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.FromBgra32Bytes(row.GetSpan(), pixelSpan, width); + PixelOperations.Instance.FromBgra32Bytes( + this.configuration, + row.GetSpan(), + pixelSpan, + width); } } } diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 186ff812f..a67c581eb 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -3,6 +3,8 @@ using System; using System.IO; + +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.MetaData; @@ -23,6 +25,8 @@ namespace SixLabors.ImageSharp.Formats.Bmp private readonly MemoryAllocator memoryAllocator; + private Configuration configuration; + private BmpBitsPerPixel? bitsPerPixel; /// @@ -48,6 +52,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); + this.configuration = image.GetConfiguration(); ImageMetaData metaData = image.MetaData; BmpMetaData bmpMetaData = metaData.GetFormatMetaData(BmpFormat.Instance); this.bitsPerPixel = this.bitsPerPixel ?? bmpMetaData.BitsPerPixel; @@ -163,7 +168,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp for (int y = pixels.Height - 1; y >= 0; y--) { Span pixelSpan = pixels.GetRowSpan(y); - PixelOperations.Instance.ToBgra32Bytes(pixelSpan, row.GetSpan(), pixelSpan.Length); + PixelOperations.Instance.ToBgra32Bytes( + this.configuration, + pixelSpan, + row.GetSpan(), + pixelSpan.Length); stream.Write(row.Array, 0, row.Length()); } } @@ -183,7 +192,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp for (int y = pixels.Height - 1; y >= 0; y--) { Span pixelSpan = pixels.GetRowSpan(y); - PixelOperations.Instance.ToBgr24Bytes(pixelSpan, row.GetSpan(), pixelSpan.Length); + PixelOperations.Instance.ToBgr24Bytes( + this.configuration, + pixelSpan, + row.GetSpan(), + pixelSpan.Length); stream.Write(row.Array, 0, row.Length()); } } diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 81adf52dd..d7e2e40e2 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -27,6 +27,11 @@ namespace SixLabors.ImageSharp.Formats.Gif /// private readonly MemoryAllocator memoryAllocator; + /// + /// Configuration bound to the encoding operation. + /// + private Configuration configuration; + /// /// A reusable buffer used to reduce allocations. /// @@ -82,6 +87,8 @@ namespace SixLabors.ImageSharp.Formats.Gif Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); + this.configuration = image.GetConfiguration(); + ImageMetaData metaData = image.MetaData; this.gifMetaData = metaData.GetFormatMetaData(GifFormat.Instance); this.colorTableMode = this.colorTableMode ?? this.gifMetaData.ColorTableMode; @@ -220,7 +227,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba32 paletteRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba32(quantized.Palette, rgbaSpan); + PixelOperations.Instance.ToRgba32(this.configuration, quantized.Palette, rgbaSpan); for (int i = quantized.Palette.Length - 1; i >= 0; i--) { @@ -322,7 +329,8 @@ namespace SixLabors.ImageSharp.Formats.Gif /// The stream to write to. private void WriteComments(ImageMetaData metadata, Stream stream) { - if (!metadata.TryGetProperty(GifConstants.Comments, out ImageProperty property) || string.IsNullOrEmpty(property.Value)) + if (!metadata.TryGetProperty(GifConstants.Comments, out ImageProperty property) + || string.IsNullOrEmpty(property.Value)) { return; } @@ -420,7 +428,11 @@ namespace SixLabors.ImageSharp.Formats.Gif using (IManagedByteBuffer colorTable = this.memoryAllocator.AllocateManagedByteBuffer(colorTableLength)) { - PixelOperations.Instance.ToRgb24Bytes(image.Palette.AsSpan(), colorTable.GetSpan(), pixelCount); + PixelOperations.Instance.ToRgb24Bytes( + this.configuration, + image.Palette.AsSpan(), + colorTable.GetSpan(), + pixelCount); stream.Write(colorTable.Array, 0, colorTableLength); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs index b2a8fccf4..d775425c5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs @@ -53,12 +53,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// /// Converts a 8x8 image area inside 'pixels' at position (x,y) placing the result members of the structure (, , ) /// - public void Convert(IPixelSource pixels, int x, int y) + public void Convert(ImageFrame frame, int x, int y) { - this.pixelBlock.LoadAndStretchEdges(pixels, x, y); + this.pixelBlock.LoadAndStretchEdges(frame, x, y); Span rgbSpan = this.rgbBlock.AsSpanUnsafe(); - PixelOperations.Instance.ToRgb24(this.pixelBlock.AsSpanUnsafe(), rgbSpan); + PixelOperations.Instance.ToRgb24(frame.Configuration, this.pixelBlock.AsSpanUnsafe(), rgbSpan); ref float yBlockStart = ref Unsafe.As(ref this.Y); ref float cbBlockStart = ref Unsafe.As(ref this.Cb); diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index d66ac6c0d..11c4d831b 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -702,6 +702,7 @@ namespace SixLabors.ImageSharp.Formats.Png case PngColorType.Rgb: PngScanlineProcessor.ProcessRgbScanline( + this.configuration, this.header, scanlineSpan, rowSpan, @@ -715,6 +716,7 @@ namespace SixLabors.ImageSharp.Formats.Png case PngColorType.RgbWithAlpha: PngScanlineProcessor.ProcessRgbaScanline( + this.configuration, this.header, scanlineSpan, rowSpan, diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 71945d130..7ae716aa0 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -43,6 +43,11 @@ namespace SixLabors.ImageSharp.Formats.Png /// private readonly MemoryAllocator memoryAllocator; + /// + /// The configuration instance for the decoding operation + /// + private Configuration configuration; + /// /// The maximum block size, defaults at 64k for uncompressed blocks. /// @@ -201,6 +206,7 @@ namespace SixLabors.ImageSharp.Formats.Png Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); + this.configuration = image.GetConfiguration(); this.width = image.Width; this.height = image.Height; @@ -328,7 +334,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span luminanceSpan = luminanceBuffer.GetSpan(); ref Gray16 luminanceRef = ref MemoryMarshal.GetReference(luminanceSpan); - PixelOperations.Instance.ToGray16(rowSpan, luminanceSpan); + PixelOperations.Instance.ToGray16(this.configuration, rowSpan, luminanceSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < luminanceSpan.Length; x++, o += 2) @@ -343,19 +349,28 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.bitDepth == 8) { // 8 bit grayscale - PixelOperations.Instance.ToGray8Bytes(rowSpan, rawScanlineSpan, rowSpan.Length); + PixelOperations.Instance.ToGray8Bytes( + this.configuration, + rowSpan, + rawScanlineSpan, + rowSpan.Length); } else { // 1, 2, and 4 bit grayscale - using (IManagedByteBuffer temp = this.memoryAllocator.AllocateManagedByteBuffer(rowSpan.Length, AllocationOptions.Clean)) + using (IManagedByteBuffer temp = this.memoryAllocator.AllocateManagedByteBuffer( + rowSpan.Length, + AllocationOptions.Clean)) { int scaleFactor = 255 / (ImageMaths.GetColorCountForBitDepth(this.bitDepth) - 1); Span tempSpan = temp.GetSpan(); - ref byte tempSpanRef = ref MemoryMarshal.GetReference(tempSpan); // We need to first create an array of luminance bytes then scale them down to the correct bit depth. - PixelOperations.Instance.ToGray8Bytes(rowSpan, tempSpan, rowSpan.Length); + PixelOperations.Instance.ToGray8Bytes( + this.configuration, + rowSpan, + tempSpan, + rowSpan.Length); this.ScaleDownFrom8BitArray(tempSpan, rawScanlineSpan, this.bitDepth, scaleFactor); } } @@ -371,7 +386,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan); + PixelOperations.Instance.ToRgba64(this.configuration, rowSpan, rgbaSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4) @@ -391,7 +406,8 @@ namespace SixLabors.ImageSharp.Formats.Png for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 2) { Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba); - Unsafe.Add(ref rawScanlineSpanRef, o) = ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); + Unsafe.Add(ref rawScanlineSpanRef, o) = + ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A; } } @@ -413,14 +429,22 @@ namespace SixLabors.ImageSharp.Formats.Png case 4: { // 8 bit Rgba - PixelOperations.Instance.ToRgba32Bytes(rowSpan, rawScanlineSpan, this.width); + PixelOperations.Instance.ToRgba32Bytes( + this.configuration, + rowSpan, + rawScanlineSpan, + this.width); break; } case 3: { // 8 bit Rgb - PixelOperations.Instance.ToRgb24Bytes(rowSpan, rawScanlineSpan, this.width); + PixelOperations.Instance.ToRgb24Bytes( + this.configuration, + rowSpan, + rawScanlineSpan, + this.width); break; } @@ -431,7 +455,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbaSpan = rgbaBuffer.GetSpan(); ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan); - PixelOperations.Instance.ToRgba64(rowSpan, rgbaSpan); + PixelOperations.Instance.ToRgba64(this.configuration, rowSpan, rgbaSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 8) @@ -454,7 +478,7 @@ namespace SixLabors.ImageSharp.Formats.Png { Span rgbSpan = rgbBuffer.GetSpan(); ref Rgb48 rgbRef = ref MemoryMarshal.GetReference(rgbSpan); - PixelOperations.Instance.ToRgb48(rowSpan, rgbSpan); + PixelOperations.Instance.ToRgb48(this.configuration, rowSpan, rgbSpan); // Can't map directly to byte array as it's big endian. for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 6) diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index e4a2562e6..3fe590ee2 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -11,6 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Png { /// /// Provides methods to allow the decoding of raw scanlines to image rows of different pixel formats. + /// TODO: We should make this a stateful class or struct to reduce the number of arguments on methods (most are invariant). /// internal static class PngScanlineProcessor { @@ -346,6 +347,7 @@ namespace SixLabors.ImageSharp.Formats.Png } public static void ProcessRgbScanline( + Configuration configuration, in PngHeader header, ReadOnlySpan scanlineSpan, Span rowSpan, @@ -357,7 +359,6 @@ namespace SixLabors.ImageSharp.Formats.Png where TPixel : struct, IPixel { TPixel pixel = default; - ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan); ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan); if (!hasTrans) @@ -377,7 +378,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - PixelOperations.Instance.FromRgb24Bytes(scanlineSpan, rowSpan, header.Width); + PixelOperations.Instance.FromRgb24Bytes(configuration, scanlineSpan, rowSpan, header.Width); } return; @@ -500,6 +501,7 @@ namespace SixLabors.ImageSharp.Formats.Png } public static void ProcessRgbaScanline( + Configuration configuration, in PngHeader header, ReadOnlySpan scanlineSpan, Span rowSpan, @@ -526,7 +528,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - PixelOperations.Instance.FromRgba32Bytes(scanlineSpan, rowSpan, header.Width); + PixelOperations.Instance.FromRgba32Bytes(configuration, scanlineSpan, rowSpan, header.Width); } } diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index bb95bb7b6..f69ae3757 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -252,7 +252,7 @@ namespace SixLabors.ImageSharp } /// - public override string ToString() => $"ImageFrame<{typeof(TPixel).Name}>: {this.Width}x{this.Height}"; + public override string ToString() => $"ImageFrame<{typeof(TPixel).Name}>({this.Width}x{this.Height})"; /// /// Clones the current instance. @@ -300,7 +300,7 @@ namespace SixLabors.ImageSharp { Span sourceRow = this.GetPixelRowSpan(y); Span targetRow = target.GetPixelRowSpan(y); - PixelOperations.Instance.To(sourceRow, targetRow); + PixelOperations.Instance.To(configuration, sourceRow, targetRow); } }); diff --git a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs index 1923faa1f..08530c2bb 100644 --- a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs @@ -739,7 +739,11 @@ namespace SixLabors.ImageSharp.PixelFormats var safe = new TPixel[constants.Length + 1]; Span constantsBytes = MemoryMarshal.Cast(constants.AsSpan()); - PixelOperations.Instance.FromRgba32Bytes(constantsBytes, safe, constants.Length); + PixelOperations.Instance.FromRgba32Bytes( + Configuration.Default, + constantsBytes, + safe, + constants.Length); return safe; } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 26e85e043..09f10716e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromArgb32(ReadOnlySpan source, Span destPixels) + internal override void FromArgb32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 080a25429..f8c61e4fa 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromBgr24(ReadOnlySpan source, Span destPixels) + internal override void FromBgr24(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 6a1bb6cdc..9bddd18e9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromBgra32(ReadOnlySpan source, Span destPixels) + internal override void FromBgra32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index cbb9df445..31c575534 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromGray16(ReadOnlySpan source, Span destPixels) + internal override void FromGray16(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index b88f18e8d..14a2c858c 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromGray8(ReadOnlySpan source, Span destPixels) + internal override void FromGray8(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 49c56f4fa..f8b80020e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgb24(ReadOnlySpan source, Span destPixels) + internal override void FromRgb24(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index cda6dbf72..5741b1070 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgb48(ReadOnlySpan source, Span destPixels) + internal override void FromRgb48(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index ab264f870..9f7b624c0 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgba32(ReadOnlySpan source, Span destPixels) + internal override void FromRgba32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index 4bc6b101a..411178b82 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// - internal override void FromRgba64(ReadOnlySpan source, Span destPixels) + internal override void FromRgba64(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index 176075a40..bc23edb01 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -19,7 +19,7 @@ using System.Runtime.InteropServices; #> /// - internal override void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels) + internal override void From<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -27,7 +27,7 @@ using System.Runtime.InteropServices; } /// - internal override void To<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels) + internal override void To<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -42,7 +42,7 @@ using System.Runtime.InteropServices; #> /// - internal override void To<#=toPixelType#>(ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels) + internal override void To<#=toPixelType#>(Configuration configuration, ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs index 07ecf8756..207a8767d 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.cs @@ -13,9 +13,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromArgb32(ReadOnlySpan source, Span destPixels) + internal virtual void FromArgb32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -32,24 +33,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromArgb32Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromArgb32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromArgb32(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -66,24 +69,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToArgb32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToArgb32Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToArgb32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToArgb32(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromBgr24(ReadOnlySpan source, Span destPixels) + internal virtual void FromBgr24(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -100,24 +105,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromBgr24Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromBgr24(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromBgr24(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -134,24 +141,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgr24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToBgr24Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgr24(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToBgr24(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromBgra32(ReadOnlySpan source, Span destPixels) + internal virtual void FromBgra32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -168,24 +177,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromBgra32Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromBgra32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromBgra32(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -202,24 +213,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgra32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToBgra32Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgra32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToBgra32(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromGray8(ReadOnlySpan source, Span destPixels) + internal virtual void FromGray8(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -236,24 +249,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromGray8Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromGray8(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromGray8(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -270,24 +285,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray8Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToGray8Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray8(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToGray8(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromGray16(ReadOnlySpan source, Span destPixels) + internal virtual void FromGray16(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -304,24 +321,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromGray16Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromGray16(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromGray16(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -338,24 +357,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray16Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToGray16Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray16(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToGray16(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromRgb24(ReadOnlySpan source, Span destPixels) + internal virtual void FromRgb24(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -372,24 +393,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgb24Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgb24(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromRgb24(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -406,24 +429,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToRgb24Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb24(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToRgb24(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromRgba32(ReadOnlySpan source, Span destPixels) + internal virtual void FromRgba32(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -440,24 +465,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgba32Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgba32(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromRgba32(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -474,24 +501,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToRgba32Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba32(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToRgba32(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromRgb48(ReadOnlySpan source, Span destPixels) + internal virtual void FromRgb48(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -508,24 +537,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgb48Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgb48(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromRgb48(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -542,24 +573,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb48Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToRgb48Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb48(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToRgb48(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void FromRgba64(ReadOnlySpan source, Span destPixels) + internal virtual void FromRgba64(Configuration configuration, ReadOnlySpan source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -576,24 +609,26 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void FromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void FromRgba64Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.FromRgba64(MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); + this.FromRgba64(configuration, MemoryMarshal.Cast(sourceBytes).Slice(0, count), destPixels); } /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels) + internal virtual void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -610,16 +645,17 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba64Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void ToRgba64Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba64(sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); + this.ToRgba64(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast(destBytes)); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt index ef73378a2..8579423b3 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.Generated.tt @@ -18,9 +18,10 @@ /// /// Converts all pixels in 'source` span of into a span of -s. /// + /// A to configure internal operations /// The source of data. /// The to the destination pixels. - internal virtual void From<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels) + internal virtual void From<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> source, Span destPixels) { Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); @@ -37,16 +38,17 @@ } /// - /// A helper for that expects a byte span. + /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void From<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void From<#=pixelType#>Bytes(Configuration configuration, ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.From<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes).Slice(0, count), destPixels); + this.From<#=pixelType#>(configuration, MemoryMarshal.Cast>(sourceBytes).Slice(0, count), destPixels); } <# @@ -58,9 +60,10 @@ /// /// Converts all pixels of the 'sourcePixels` span to a span of -s. /// + /// A to configure internal operations /// The span of source pixels /// The destination span of data. - internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels) + internal virtual void To<#=pixelType#>(Configuration configuration, ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); @@ -77,16 +80,17 @@ } /// - /// A helper for that expects a byte span as destination. + /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// + /// A to configure internal operations /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void To<#=pixelType#>Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) + internal void To<#=pixelType#>Bytes(Configuration configuration, ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.To<#=pixelType#>(sourcePixels.Slice(0, count), MemoryMarshal.Cast>(destBytes)); + this.To<#=pixelType#>(configuration, sourcePixels.Slice(0, count), MemoryMarshal.Cast>(destBytes)); } <# } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 8f3ea6c11..ea03af683 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -125,9 +125,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// Converts 'sourceColors.Length' pixels from 'sourceColors' into 'destinationColors'. /// /// The destination pixel type. + /// A to configure internal operations /// The to the source colors. /// The to the destination colors. internal virtual void To( + Configuration configuration, ReadOnlySpan sourceColors, Span destinationColors) where TDestinationPixel : struct, IPixel diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index 98a5d5eb5..43d22597d 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -448,7 +448,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization { Span row = source.GetPixelRowSpan(y); Span rgbaSpan = rgbaBuffer.GetSpan(); - PixelOperations.Instance.ToRgba32(row, rgbaSpan); + PixelOperations.Instance.ToRgba32(source.Configuration, row, rgbaSpan); ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan); // And loop through each column diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs index f3245ebaf..32565c23d 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs @@ -20,14 +20,17 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk private IMemoryOwner source; + private Configuration configuration; + [Params(16, 128, 1024)] public int Count { get; set; } [GlobalSetup] public void Setup() { - this.destination = Configuration.Default.MemoryAllocator.Allocate(this.Count); - this.source = Configuration.Default.MemoryAllocator.Allocate(this.Count * 4); + this.configuration = Configuration.Default; + this.destination = this.configuration.MemoryAllocator.Allocate(this.Count); + this.source = this.configuration.MemoryAllocator.Allocate(this.Count * 4); } [GlobalCleanup] @@ -55,13 +58,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void CommonBulk() { - new PixelOperations().FromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + new PixelOperations().FromRgba32Bytes(this.configuration, this.source.GetSpan(), this.destination.GetSpan(), this.Count); } [Benchmark] public void OptimizedBulk() { - PixelOperations.Instance.FromRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + PixelOperations.Instance.FromRgba32Bytes(this.configuration, this.source.GetSpan(), this.destination.GetSpan(), this.Count); } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs index f96023f00..912c3e4b2 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs @@ -17,14 +17,17 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk private IMemoryOwner destination; + private Configuration configuration; + [Params(16, 128, 1024)] public int Count { get; set; } [GlobalSetup] public void Setup() { - this.source = Configuration.Default.MemoryAllocator.Allocate(this.Count); - this.destination = Configuration.Default.MemoryAllocator.Allocate(this.Count * 3); + this.configuration = Configuration.Default; + this.source = this.configuration.MemoryAllocator.Allocate(this.Count); + this.destination = this.configuration.MemoryAllocator.Allocate(this.Count * 3); } [GlobalCleanup] @@ -35,10 +38,20 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark(Baseline = true)] - public void CommonBulk() => new PixelOperations().ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + public void CommonBulk() => + new PixelOperations().ToRgb24Bytes( + this.configuration, + this.source.GetSpan(), + this.destination.GetSpan(), + this.Count); [Benchmark] - public void OptimizedBulk() => PixelOperations.Instance.ToRgb24Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + public void OptimizedBulk() => + PixelOperations.Instance.ToRgb24Bytes( + this.configuration, + this.source.GetSpan(), + this.destination.GetSpan(), + this.Count); } public class ToXyz_Rgba32 : ToXyz diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs index 0cf7087d4..37694f64c 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs @@ -19,14 +19,17 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk private IMemoryOwner destination; + private Configuration configuration; + [Params(16, 128, 1024)] public int Count { get; set; } [GlobalSetup] public void Setup() { - this.source = Configuration.Default.MemoryAllocator.Allocate(this.Count); - this.destination = Configuration.Default.MemoryAllocator.Allocate(this.Count * 4); + this.configuration = Configuration.Default; + this.source = this.configuration.MemoryAllocator.Allocate(this.Count); + this.destination = this.configuration.MemoryAllocator.Allocate(this.Count * 4); } [GlobalCleanup] @@ -56,10 +59,20 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } [Benchmark] - public void CommonBulk() => new PixelOperations().ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + public void CommonBulk() => + new PixelOperations().ToRgba32Bytes( + this.configuration, + this.source.GetSpan(), + this.destination.GetSpan(), + this.Count); [Benchmark] - public void OptimizedBulk() => PixelOperations.Instance.ToRgba32Bytes(this.source.GetSpan(), this.destination.GetSpan(), this.Count); + public void OptimizedBulk() => + PixelOperations.Instance.ToRgba32Bytes( + this.configuration, + this.source.GetSpan(), + this.destination.GetSpan(), + this.Count); } public class ToXyzw_Rgba32 : ToXyzw diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 8314bd9b4..e66ca9a71 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) ); } } @@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -198,7 +198,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -243,7 +243,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) ); } } @@ -457,7 +457,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromArgb32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -483,7 +483,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToArgb32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -504,7 +504,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromBgr24Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -528,7 +528,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgr24Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -549,7 +549,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromBgra32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -574,7 +574,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgra32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -595,7 +595,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgb24Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -619,7 +619,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb24Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -640,7 +640,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgba32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -665,7 +665,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba32Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -686,7 +686,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgb48Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -714,7 +714,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb48Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -735,7 +735,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.FromRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.FromRgba64Bytes(this.Configuration, s, d.GetSpan(), count) ); } @@ -765,7 +765,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats TestOperation( source, expected, - (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba64Bytes(this.Configuration, s, d.GetSpan(), count) ); } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs index 886e02c13..462782ba5 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs @@ -28,14 +28,15 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison var bBuffer = new Rgba64[width]; var differences = new List(); + Configuration configuration = expected.Configuration; for (int y = 0; y < actual.Height; y++) { Span aSpan = expected.GetPixelRowSpan(y); Span bSpan = actual.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgba64(aSpan, aBuffer); - PixelOperations.Instance.ToRgba64(bSpan, bBuffer); + PixelOperations.Instance.ToRgba64(configuration, aSpan, aBuffer); + PixelOperations.Instance.ToRgba64(configuration, bSpan, bBuffer); for (int x = 0; x < width; x++) { diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs index 9563edbb5..be12f5621 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs @@ -74,14 +74,15 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison float totalDifference = 0F; var differences = new List(); + Configuration configuration = expected.Configuration; for (int y = 0; y < actual.Height; y++) { Span aSpan = expected.GetPixelRowSpan(y); Span bSpan = actual.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgba64(aSpan, aBuffer); - PixelOperations.Instance.ToRgba64(bSpan, bBuffer); + PixelOperations.Instance.ToRgba64(configuration, aSpan, aBuffer); + PixelOperations.Instance.ToRgba64(configuration, bSpan, bBuffer); for (int x = 0; x < width; x++) { diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs index 2409ff9ad..3dd330e4d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs @@ -31,14 +31,22 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs { byte[] data = pixels.ToByteArray(PixelMapping.RGBA); - PixelOperations.Instance.FromRgba32Bytes(data, resultPixels, resultPixels.Length); + PixelOperations.Instance.FromRgba32Bytes( + configuration, + data, + resultPixels, + resultPixels.Length); } else if (magickImage.Depth == 16) { ushort[] data = pixels.ToShortArray(PixelMapping.RGBA); Span bytes = MemoryMarshal.Cast(data.AsSpan()); - PixelOperations.Instance.FromRgba64Bytes(bytes, resultPixels, resultPixels.Length); + PixelOperations.Instance.FromRgba64Bytes( + configuration, + bytes, + resultPixels, + resultPixels.Length); } else { diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index e96825db1..7e87c23db 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -33,7 +33,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs if (bmp.PixelFormat != PixelFormat.Format32bppArgb) { - throw new ArgumentException($"{nameof(From32bppArgbSystemDrawingBitmap)} : pixel format should be {PixelFormat.Format32bppArgb}!", nameof(bmp)); + throw new ArgumentException( + $"{nameof(From32bppArgbSystemDrawingBitmap)} : pixel format should be {PixelFormat.Format32bppArgb}!", + nameof(bmp)); } BitmapData data = bmp.LockBits(fullRect, ImageLockMode.ReadWrite, bmp.PixelFormat); @@ -43,6 +45,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs long destRowByteCount = w * sizeof(Bgra32); var image = new Image(w, h); + Configuration configuration = image.GetConfiguration(); using (IMemoryOwner workBuffer = Configuration.Default.MemoryAllocator.Allocate(w)) { @@ -55,7 +58,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.FromBgra32(workBuffer.GetSpan().Slice(0, w), row); + PixelOperations.Instance.FromBgra32( + configuration, + workBuffer.GetSpan().Slice(0, w), + row); } } } @@ -79,7 +85,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs if (bmp.PixelFormat != PixelFormat.Format24bppRgb) { - throw new ArgumentException($"{nameof(From24bppRgbSystemDrawingBitmap)}: pixel format should be {PixelFormat.Format24bppRgb}!", nameof(bmp)); + throw new ArgumentException( + $"{nameof(From24bppRgbSystemDrawingBitmap)}: pixel format should be {PixelFormat.Format24bppRgb}!", + nameof(bmp)); } BitmapData data = bmp.LockBits(fullRect, ImageLockMode.ReadWrite, bmp.PixelFormat); @@ -89,6 +97,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs long destRowByteCount = w * sizeof(Bgr24); var image = new Image(w, h); + Configuration configuration = image.GetConfiguration(); using (IMemoryOwner workBuffer = Configuration.Default.MemoryAllocator.Allocate(w)) { @@ -101,7 +110,10 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - PixelOperations.Instance.FromBgr24(workBuffer.GetSpan().Slice(0, w), row); + PixelOperations.Instance.FromBgr24( + configuration, + workBuffer.GetSpan().Slice(0, w), + row); } } } @@ -112,6 +124,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs internal static unsafe Bitmap To32bppArgbSystemDrawingBitmap(Image image) where TPixel : struct, IPixel { + Configuration configuration = image.GetConfiguration(); int w = image.Width; int h = image.Height; @@ -130,7 +143,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs for (int y = 0; y < h; y++) { Span row = image.Frames.RootFrame.GetPixelRowSpan(y); - PixelOperations.Instance.ToBgra32(row, workBuffer.GetSpan()); + PixelOperations.Instance.ToBgra32(configuration, row, workBuffer.GetSpan()); byte* destPtr = destPtrBase + (data.Stride * y); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); From 93709c1e4d1f3b2cc325b5f67f511a0200ecf83f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 11:32:22 +0200 Subject: [PATCH 070/238] revert addition of unnecessary `[DebuggerStepThrough]` --- src/ImageSharp/Common/Helpers/Guard.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs index cd53e3d69..d8cf69a52 100644 --- a/src/ImageSharp/Common/Helpers/Guard.cs +++ b/src/ImageSharp/Common/Helpers/Guard.cs @@ -21,7 +21,6 @@ namespace SixLabors.ImageSharp /// The name of the parameter that is to be checked. /// is null [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void NotNull(T value, string parameterName) where T : class { @@ -39,7 +38,6 @@ namespace SixLabors.ImageSharp /// is null. /// is empty or contains only blanks. [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) @@ -62,7 +60,6 @@ namespace SixLabors.ImageSharp /// is null. /// is empty. [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void NotNullOrEmpty(ICollection value, string parameterName) { if (value is null) @@ -87,7 +84,6 @@ namespace SixLabors.ImageSharp /// is greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -109,7 +105,6 @@ namespace SixLabors.ImageSharp /// is greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -131,7 +126,6 @@ namespace SixLabors.ImageSharp /// is less than the minimum value. /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -155,7 +149,6 @@ namespace SixLabors.ImageSharp /// is less than the minimum value. /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -178,7 +171,6 @@ namespace SixLabors.ImageSharp /// is less than the minimum value of greater than the maximum value. /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { @@ -199,7 +191,6 @@ namespace SixLabors.ImageSharp /// is false /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void IsTrue(bool target, string parameterName, string message) { if (!target) @@ -219,7 +210,6 @@ namespace SixLabors.ImageSharp /// is true /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void IsFalse(bool target, string parameterName, string message) { if (target) @@ -239,7 +229,6 @@ namespace SixLabors.ImageSharp /// has less than items /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) @@ -257,7 +246,6 @@ namespace SixLabors.ImageSharp /// The destination span /// The name of the argument for 'destination' [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( ReadOnlySpan source, Span destination, @@ -280,7 +268,6 @@ namespace SixLabors.ImageSharp /// has less than items /// [MethodImpl(InliningOptions.ShortMethod)] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) From ff757fb73361e1b2ab02401ccf03f5468f81aca7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 11:06:32 +0200 Subject: [PATCH 071/238] bitwise conversion + benchmarks WIP --- .../Decoder/JpegImagePostProcessor.cs | 2 +- src/ImageSharp/PixelFormats/PixelConverter.cs | 47 ++++++ .../FrameQuantizerBase{TPixel}.cs | 2 - .../PixelConversion_ConvertFromRgba32.cs | 144 +++++++++++++---- .../General/PixelConversion/TestArgb.cs | 62 ++++---- .../General/PixelConversion/TestRgba.cs | 14 +- .../PixelFormats/PixelConverterTests.cs | 150 ++++++++++++++++++ .../PixelFormats/Rgba32Tests.cs | 1 + 8 files changed, 347 insertions(+), 75 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/PixelConverter.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs index 1a6da2b2b..7ce86b4c9 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder this.colorConverter.ConvertToRgba(values, this.rgbaBuffer.GetSpan()); Span destRow = destination.GetPixelRowSpan(yy); - + // TODO: Investigate if slicing is actually necessary PixelOperations.Instance.FromVector4(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); } diff --git a/src/ImageSharp/PixelFormats/PixelConverter.cs b/src/ImageSharp/PixelFormats/PixelConverter.cs new file mode 100644 index 000000000..3686092cd --- /dev/null +++ b/src/ImageSharp/PixelFormats/PixelConverter.cs @@ -0,0 +1,47 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.PixelFormats +{ + /// + /// Contains optimized implementations for conversion between pixel formats. + /// + /// + /// Implementations are based on ideas in: + /// https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs#L84 + /// The JIT should be able to detect and optimize ROL and ROR patterns. + /// + internal static class PixelConverter + { + public static class Rgba32 + { + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToArgb32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // ROL(8, packedRgba): + return (packedRgba << 8) | (packedRgba >> 24); + } + } + + public static class Argb32 + { + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToRgba32(uint packedArgb) + { + // packedArgb = [bb gg rr aa] + // ROR(8, packedArgb): + return (packedArgb >> 8) | (packedArgb << 24); + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index a41127bfc..a8c6c5d7e 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -17,8 +17,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public abstract class FrameQuantizerBase : IFrameQuantizer where TPixel : struct, IPixel { - private readonly Configuration configuration; - /// /// A lookup table for colors /// diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index 6a96c8576..1be8347c3 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -1,6 +1,8 @@ // ReSharper disable InconsistentNaming +using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; @@ -8,14 +10,14 @@ using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion { - public class PixelConversion_ConvertFromRgba32 + public abstract class PixelConversion_ConvertFromRgba32 { - struct ConversionRunner + internal struct ConversionRunner where T : struct, ITestPixel { - private T[] dest; + public readonly T[] dest; - private Rgba32[] source; + public readonly Rgba32[] source; public ConversionRunner(int count) { @@ -67,72 +69,146 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } - private ConversionRunner compatibleMemLayoutRunner; + internal ConversionRunner compatibleMemLayoutRunner; - private ConversionRunner permutedRunner; + internal ConversionRunner permutedRunnerRgbaToArgb; - [Params(32)] + [Params( + 256, + 2048 + )] public int Count { get; set; } [GlobalSetup] public void Setup() { this.compatibleMemLayoutRunner = new ConversionRunner(this.Count); - this.permutedRunner = new ConversionRunner(this.Count); + this.permutedRunnerRgbaToArgb = new ConversionRunner(this.Count); } + } + public class PixelConversion_ConvertFromRgba32_Compatible : PixelConversion_ConvertFromRgba32 + { [Benchmark(Baseline = true)] - public void CompatibleByRef() + public void ByRef() { this.compatibleMemLayoutRunner.RunByRefConversion(); } [Benchmark] - public void CompatibleByVal() + public void ByVal() { this.compatibleMemLayoutRunner.RunByValConversion(); } [Benchmark] - public void CompatibleFromBytes() + public void FromBytes() { this.compatibleMemLayoutRunner.RunFromBytesConversion(); } + [Benchmark] + public void Inline() + { + ref Rgba32 sBase = ref this.compatibleMemLayoutRunner.source[0]; + ref Rgba32 dBase = ref Unsafe.As(ref this.compatibleMemLayoutRunner.dest[0]); + + for (int i = 0; i < this.Count; i++) + { + Unsafe.Add(ref dBase, i) = Unsafe.Add(ref sBase, i); + } + } + + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ---------- |------ |---------:|---------:|---------:|-------:|---------:| + // ByRef | 256 | 128.5 ns | 1.217 ns | 1.138 ns | 1.00 | 0.00 | + // ByVal | 256 | 196.7 ns | 2.792 ns | 2.612 ns | 1.53 | 0.02 | + // FromBytes | 256 | 321.7 ns | 2.180 ns | 1.820 ns | 2.50 | 0.03 | + // Inline | 256 | 129.9 ns | 2.759 ns | 2.581 ns | 1.01 | 0.02 | + } + + public class PixelConversion_ConvertFromRgba32_Permuted_RgbaToArgb : PixelConversion_ConvertFromRgba32 + { + [Benchmark(Baseline = true)] + public void ByRef() + { + this.permutedRunnerRgbaToArgb.RunByRefConversion(); + } + + [Benchmark] + public void ByVal() + { + this.permutedRunnerRgbaToArgb.RunByValConversion(); + } + + [Benchmark] + public void FromBytes() + { + this.permutedRunnerRgbaToArgb.RunFromBytesConversion(); + } [Benchmark] - public void PermutedByRef() + public void InlineShuffle() { - this.permutedRunner.RunByRefConversion(); + ref Rgba32 sBase = ref this.permutedRunnerRgbaToArgb.source[0]; + ref TestArgb dBase = ref this.permutedRunnerRgbaToArgb.dest[0]; + + for (int i = 0; i < this.Count; i++) + { + Rgba32 s = Unsafe.Add(ref sBase, i); + ref TestArgb d = ref Unsafe.Add(ref dBase, i); + + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + } } [Benchmark] - public void PermutedByVal() + public void PixelConverter_Rgba32_ToArgb32() { - this.permutedRunner.RunByValConversion(); + ref uint sBase = ref Unsafe.As(ref this.permutedRunnerRgbaToArgb.source[0]); + ref uint dBase = ref Unsafe.As(ref this.permutedRunnerRgbaToArgb.dest[0]); + + for (int i = 0; i < this.Count; i++) + { + uint s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s); + } } [Benchmark] - public void PermutedFromBytes() + public void PixelConverter_Rgba32_ToArgb32_CopyThenWorkOnSingleBuffer() { - this.permutedRunner.RunFromBytesConversion(); + Span source = MemoryMarshal.Cast(this.permutedRunnerRgbaToArgb.source); + Span dest = MemoryMarshal.Cast(this.permutedRunnerRgbaToArgb.dest); + source.CopyTo(dest); + + ref uint dBase = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < this.Count; i++) + { + uint s = Unsafe.Add(ref dBase, i); + Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s); + } } - } - /* - * Results: - * Method | Count | Mean | StdDev | Scaled | Scaled-StdDev | - * ------------------ |------ |----------- |---------- |------- |-------------- | - * CompatibleByRef | 32 | 20.6339 ns | 0.0742 ns | 1.00 | 0.00 | - * CompatibleByVal | 32 | 23.7425 ns | 0.0997 ns | 1.15 | 0.01 | - * CompatibleFromBytes | 32 | 38.7017 ns | 0.1103 ns | 1.88 | 0.01 | - * PermutedByRef | 32 | 39.2892 ns | 0.1366 ns | 1.90 | 0.01 | - * PermutedByVal | 32 | 38.5178 ns | 0.1946 ns | 1.87 | 0.01 | - * PermutedFromBytes | 32 | 38.6683 ns | 0.0801 ns | 1.87 | 0.01 | - * - * !!! Conclusion !!! - * All memory-incompatible (permuted) variants are equivalent with the the "FromBytes" solution. - * In memory compatible cases we should use the optimized Bulk-copying variant anyways, - * so there is no benefit introducing non-bulk API-s other than FromBytes() OR FromRgba32(). - */ + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // ---------------------------------------------------------- |------ |-----------:|-----------:|-----------:|-------:|---------:| + // ByRef | 256 | 328.7 ns | 6.6141 ns | 6.1868 ns | 1.00 | 0.00 | + // ByVal | 256 | 322.0 ns | 4.3541 ns | 4.0728 ns | 0.98 | 0.02 | + // FromBytes | 256 | 321.5 ns | 3.3499 ns | 3.1335 ns | 0.98 | 0.02 | + // InlineShuffle | 256 | 330.7 ns | 4.2525 ns | 3.9778 ns | 1.01 | 0.02 | + // PixelConverter_Rgba32_ToArgb32 | 256 | 167.4 ns | 0.6357 ns | 0.5309 ns | 0.51 | 0.01 | + // PixelConverter_Rgba32_ToArgb32_CopyThenWorkOnSingleBuffer | 256 | 196.6 ns | 0.8929 ns | 0.7915 ns | 0.60 | 0.01 | + // | | | | | | | + // ByRef | 2048 | 2,534.4 ns | 8.2947 ns | 6.9265 ns | 1.00 | 0.00 | + // ByVal | 2048 | 2,638.5 ns | 52.6843 ns | 70.3320 ns | 1.04 | 0.03 | + // FromBytes | 2048 | 2,517.2 ns | 40.8055 ns | 38.1695 ns | 0.99 | 0.01 | + // InlineShuffle | 2048 | 2,546.5 ns | 21.2506 ns | 19.8778 ns | 1.00 | 0.01 | + // PixelConverter_Rgba32_ToArgb32 | 2048 | 1,265.7 ns | 5.1397 ns | 4.5562 ns | 0.50 | 0.00 | + // PixelConverter_Rgba32_ToArgb32_CopyThenWorkOnSingleBuffer | 2048 | 1,410.3 ns | 11.1939 ns | 9.9231 ns | 0.56 | 0.00 |// + } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs index 61a7df81d..76de794ec 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs @@ -9,81 +9,81 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion [StructLayout(LayoutKind.Sequential)] struct TestArgb : ITestPixel { - private byte a, r, g, b; + public byte A, R, G, B; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromRgba32(Rgba32 p) { - this.r = p.R; - this.g = p.G; - this.b = p.B; - this.a = p.A; + this.R = p.R; + this.G = p.G; + this.B = p.B; + this.A = p.A; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromRgba32(ref Rgba32 p) { - this.r = p.R; - this.g = p.G; - this.b = p.B; - this.a = p.A; + this.R = p.R; + this.G = p.G; + this.B = p.B; + this.A = p.A; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromBytes(byte r, byte g, byte b, byte a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; + this.R = r; + this.G = g; + this.B = b; + this.A = a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromVector4(Vector4 p) { - this.r = (byte)p.X; - this.g = (byte)p.Y; - this.b = (byte)p.Z; - this.a = (byte)p.W; + this.R = (byte)p.X; + this.G = (byte)p.Y; + this.B = (byte)p.Z; + this.A = (byte)p.W; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromVector4(ref Vector4 p) { - this.r = (byte)p.X; - this.g = (byte)p.Y; - this.b = (byte)p.Z; - this.a = (byte)p.W; + this.R = (byte)p.X; + this.G = (byte)p.Y; + this.B = (byte)p.Z; + this.A = (byte)p.W; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Rgba32 ToRgba32() { - return new Rgba32(this.r, this.g, this.b, this.a); + return new Rgba32(this.R, this.G, this.B, this.A); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyToRgba32(ref Rgba32 dest) { - dest.R = this.r; - dest.G = this.g; - dest.B = this.b; - dest.A = this.a; + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = this.A; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() { - return new Vector4(this.r, this.g, this.b, this.a); + return new Vector4(this.R, this.G, this.B, this.A); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyToVector4(ref Vector4 dest) { - dest.X = this.r; - dest.Y = this.g; - dest.Z = this.b; - dest.W = this.a; + dest.X = this.R; + dest.Y = this.G; + dest.Z = this.B; + dest.W = this.A; } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs index cc8cf352a..36d5f3e5b 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion [StructLayout(LayoutKind.Sequential)] struct TestRgba : ITestPixel { - private byte r, g, b, a; + public byte R, G, B, A; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromRgba32(Rgba32 source) @@ -26,10 +26,10 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FromBytes(byte r, byte g, byte b, byte a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; + this.R = r; + this.G = g; + this.B = b; + this.A = a; } public void FromVector4(Vector4 source) @@ -57,13 +57,13 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() { - return new Vector4(this.r, this.g, this.b, this.a) * new Vector4(1f / 255f); + return new Vector4(this.R, this.G, this.B, this.A) * new Vector4(1f / 255f); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CopyToVector4(ref Vector4 dest) { - var tmp = new Vector4(this.r, this.g, this.b, this.a); + var tmp = new Vector4(this.R, this.G, this.B, this.A); tmp *= new Vector4(1f / 255f); dest = tmp; } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs new file mode 100644 index 000000000..83c4e34f2 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs @@ -0,0 +1,150 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests.PixelFormats +{ + public class PixelConverterTests + { + public static readonly TheoryData RgbaData = + new TheoryData + { + { 0, 0, 0, 0 }, + { 0, 0, 0, 255 }, + { 0, 0, 255, 0 }, + { 0, 255, 0, 0 }, + { 255, 0, 0, 0 }, + { 255, 255, 255, 255 }, + { 0, 0, 0, 1 }, + { 0, 0, 1, 0 }, + { 0, 1, 0, 0 }, + { 1, 0, 0, 0 }, + { 3, 5, 7, 11 }, + { 67, 71, 101, 109 } + }; + + [Theory] + [MemberData(nameof(RgbaData))] + public void Rgba32ToArgb32(byte r, byte g, byte b, byte a) + { + Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.Rgba32.ToArgb32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.ToArgb32(s).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } + + [Theory] + [MemberData(nameof(RgbaData))] + public void Argb32ToRgba32(byte r, byte g, byte b, byte a) + { + Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.Argb32.ToRgba32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.ToRgba32(s).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } + + + private static class ReferenceImplementations + { + public static Rgba32 MakeRgba32(byte r, byte g, byte b, byte a) + { + Rgba32 d = default; + d.R = r; + d.G = g; + d.B = b; + d.A = a; + return d; + } + + public static Argb32 MakeArgb32(byte r, byte g, byte b, byte a) + { + Argb32 d = default; + d.R = r; + d.G = g; + d.B = b; + d.A = a; + return d; + } + + public static Bgra32 MakeBgra32(byte r, byte g, byte b, byte a) + { + Bgra32 d = default; + d.R = r; + d.G = g; + d.B = b; + d.A = a; + return d; + } + + public static Argb32 ToArgb32(Rgba32 s) + { + Argb32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + + public static Argb32 ToArgb32(Bgra32 s) + { + Argb32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + + public static Rgba32 ToRgba32(Argb32 s) + { + Rgba32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + + public static Rgba32 ToRgba32(Bgra32 s) + { + Rgba32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + + public static Bgra32 ToBgra32(Rgba32 s) + { + Bgra32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + + public static Bgra32 ToBgra32(Argb32 s) + { + Bgra32 d = default; + d.R = s.R; + d.G = s.G; + d.B = s.B; + d.A = s.A; + return d; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs index 8c702f66d..ad1d13740 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; using Xunit; +using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.PixelFormats { From 7ab13d5059ccefd7860a1550e59ff52207cbf196 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 19:03:03 +0200 Subject: [PATCH 072/238] Update xmldoc --- src/ImageSharp/PixelFormats/IPixel.cs | 36 +++++++++---------- .../PixelFormats/PixelOperations{TPixel}.cs | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 13e35cce0..127740686 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -24,93 +24,93 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - /// An interface that represents a pixel type. + /// A base interface for all pixels, defining the mandatory operations to be implemented by a pixel type. /// public interface IPixel { /// - /// Sets the packed representation from a scaled . + /// Initializes the pixel instance from a generic ("scaled") . /// - /// The vector to create the packed representation from. + /// The vector to load the pixel from. void FromScaledVector4(Vector4 vector); /// - /// Expands the packed representation into a scaled - /// with values clamped between 0 and 1. + /// Expands the pixel into a generic ("scaled") representation + /// with values scaled and clamped between 0 and 1. /// The vector components are typically expanded in least to greatest significance order. /// /// The . Vector4 ToScaledVector4(); /// - /// Sets the packed representation from a . + /// Initializes the pixel instance from a which is specific to the current pixel type. /// - /// The vector to create the packed representation from. + /// The vector to load the pixel from. void FromVector4(Vector4 vector); /// - /// Expands the packed representation into a . + /// Expands the pixel into a which is specific to the current pixel type. /// The vector components are typically expanded in least to greatest significance order. /// /// The . Vector4 ToVector4(); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromArgb32(Argb32 source); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromBgr24(Bgr24 source); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromBgra32(Bgra32 source); /// - /// Packs the Pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromGray8(Gray8 source); /// - /// Packs the Pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromGray16(Gray16 source); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromRgb24(Rgb24 source); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromRgba32(Rgba32 source); /// - /// Expands the packed representation into an . + /// Convert the pixel instance into representation. /// /// The reference to the destination pixel void ToRgba32(ref Rgba32 dest); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromRgb48(Rgb48 source); /// - /// Packs the pixel from an value. + /// Initializes the pixel instance from an value. /// /// The value. void FromRgba64(Rgba64 source); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 510645c4e..126db8533 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.PixelFormats return; } - // Normal converson + // Normal conversion ref TDestinationPixel destRef = ref MemoryMarshal.GetReference(destinationColors); for (int i = 0; i < count; i++) { From eaa5a9779c71fbd625a63b5c7a5c487015a0341f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 20:14:05 +0200 Subject: [PATCH 073/238] Rgba32 <-> Argb32 <-> Bgra32 --- src/ImageSharp/PixelFormats/PixelConverter.cs | 76 +++++++- .../PixelFormats/PixelOperations{TPixel}.cs | 22 --- .../PixelConversion_ConvertFromRgba32.cs | 4 +- .../PixelFormats/PixelConverterTests.cs | 167 +++++++++--------- 4 files changed, 158 insertions(+), 111 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelConverter.cs b/src/ImageSharp/PixelFormats/PixelConverter.cs index 3686092cd..8fde490fd 100644 --- a/src/ImageSharp/PixelFormats/PixelConverter.cs +++ b/src/ImageSharp/PixelFormats/PixelConverter.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers.Binary; using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.PixelFormats @@ -16,32 +17,91 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal static class PixelConverter { - public static class Rgba32 + public static class FromRgba32 { /// - /// Converts a packed to . + /// Converts a packed to . /// [MethodImpl(InliningOptions.ShortMethod)] public static uint ToArgb32(uint packedRgba) { - // packedRgba = [aa bb gg rr] - // ROL(8, packedRgba): + // packedRgba = [aa bb gg rr] + // ROL(8, packedRgba) = [bb gg rr aa] return (packedRgba << 8) | (packedRgba >> 24); } + + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToBgra32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // tmp1 = [aa 00 gg 00] + // tmp2 = [00 bb 00 rr] + // tmp3=ROL(16, tmp2) = [00 rr 00 bb] + // tmp1 + tmp3 = [aa rr gg bb] + uint tmp1 = packedRgba & 0xFF00FF00; + uint tmp2 = packedRgba & 0x00FF00FF; + uint tmp3 = (tmp2 << 16) | (tmp2 >> 16); + return tmp1 + tmp3; + } } - public static class Argb32 + public static class FromArgb32 { /// - /// Converts a packed to . + /// Converts a packed to . /// [MethodImpl(InliningOptions.ShortMethod)] public static uint ToRgba32(uint packedArgb) { - // packedArgb = [bb gg rr aa] - // ROR(8, packedArgb): + // packedArgb = [bb gg rr aa] + // ROR(8, packedArgb) = [aa bb gg rr] return (packedArgb >> 8) | (packedArgb << 24); } + + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToBgra32(uint packedArgb) + { + // packedArgb = [bb gg rr aa] + // REVERSE(packedArgb) = [aa rr gg bb] + return BinaryPrimitives.ReverseEndianness(packedArgb); + } + } + + public static class FromBgra32 + { + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToArgb32(uint packedBgra) + { + // packedBgra = [aa rr gg bb] + // REVERSE(packedBgra) = [bb gg rr aa] + return BinaryPrimitives.ReverseEndianness(packedBgra); + } + + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToRgba32(uint packedBgra) + { + // packedRgba = [aa rr gg bb] + // tmp1 = [aa 00 gg 00] + // tmp2 = [00 rr 00 bb] + // tmp3=ROL(16, tmp2) = [00 bb 00 rr] + // tmp1 + tmp3 = [aa bb gg rr] + uint tmp1 = packedBgra & 0xFF00FF00; + uint tmp2 = packedBgra & 0x00FF00FF; + uint tmp3 = (tmp2 << 16) | (tmp2 >> 16); + return tmp1 + tmp3; + } } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 02b80de9b..ad5aee8c7 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -178,27 +178,5 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromScaledVector4(sp.ToScaledVector4()); } } - - /// - /// Verifies that the given 'source' and 'destination' spans are at least of 'minLength' size. - /// Throwing an if the condition is not met. - /// - /// The source element type - /// The destination element type - /// The source span - /// The source parameter name - /// The destination span - /// The destination parameter name - /// The minimum length - protected internal static void GuardSpans( - ReadOnlySpan source, - string sourceParamName, - Span destination, - string destinationParamName, - int minLength) - { - Guard.MustBeSizedAtLeast(source, minLength, sourceParamName); - Guard.MustBeSizedAtLeast(destination, minLength, destinationParamName); - } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index 1be8347c3..424020e2f 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion for (int i = 0; i < this.Count; i++) { uint s = Unsafe.Add(ref sBase, i); - Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s); + Unsafe.Add(ref dBase, i) = PixelConverter.FromRgba32.ToArgb32(s); } } @@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion for (int i = 0; i < this.Count; i++) { uint s = Unsafe.Add(ref dBase, i); - Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s); + Unsafe.Add(ref dBase, i) = PixelConverter.FromRgba32.ToArgb32(s); } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs index 83c4e34f2..9b32f7aee 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs @@ -4,7 +4,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.PixelFormats { - public class PixelConverterTests + public abstract class PixelConverterTests { public static readonly TheoryData RgbaData = new TheoryData @@ -23,34 +23,103 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { 67, 71, 101, 109 } }; - [Theory] - [MemberData(nameof(RgbaData))] - public void Rgba32ToArgb32(byte r, byte g, byte b, byte a) + public class FromRgba32 : PixelConverterTests { - Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a); + [Theory] + [MemberData(nameof(RgbaData))] + public void ToArgb32(byte r, byte g, byte b, byte a) + { + Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.FromRgba32.ToArgb32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.MakeArgb32(r, g, b, a).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } + + [Theory] + [MemberData(nameof(RgbaData))] + public void ToBgra32(byte r, byte g, byte b, byte a) + { + Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.FromRgba32.ToBgra32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.MakeBgra32(r, g, b, a).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } + } + + public class FromArgb32 : PixelConverterTests + { + [Theory] + [MemberData(nameof(RgbaData))] + public void ToRgba32(byte r, byte g, byte b, byte a) + { + Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a); - // Act: - uint actualPacked = PixelConverter.Rgba32.ToArgb32(s.PackedValue); + // Act: + uint actualPacked = PixelConverter.FromArgb32.ToRgba32(s.PackedValue); - // Assert: - uint expectedPacked = ReferenceImplementations.ToArgb32(s).PackedValue; + // Assert: + uint expectedPacked = ReferenceImplementations.MakeRgba32(r, g, b, a).PackedValue; - Assert.Equal(expectedPacked, actualPacked); + Assert.Equal(expectedPacked, actualPacked); + } + + [Theory] + [MemberData(nameof(RgbaData))] + public void ToBgra32(byte r, byte g, byte b, byte a) + { + Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.FromArgb32.ToBgra32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.MakeBgra32(r, g, b, a).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } } - [Theory] - [MemberData(nameof(RgbaData))] - public void Argb32ToRgba32(byte r, byte g, byte b, byte a) + public class FromBgra32 : PixelConverterTests { - Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a); + [Theory] + [MemberData(nameof(RgbaData))] + public void ToArgb32(byte r, byte g, byte b, byte a) + { + Bgra32 s = ReferenceImplementations.MakeBgra32(r, g, b, a); - // Act: - uint actualPacked = PixelConverter.Argb32.ToRgba32(s.PackedValue); + // Act: + uint actualPacked = PixelConverter.FromBgra32.ToArgb32(s.PackedValue); - // Assert: - uint expectedPacked = ReferenceImplementations.ToRgba32(s).PackedValue; + // Assert: + uint expectedPacked = ReferenceImplementations.MakeArgb32(r, g, b, a).PackedValue; - Assert.Equal(expectedPacked, actualPacked); + Assert.Equal(expectedPacked, actualPacked); + } + + [Theory] + [MemberData(nameof(RgbaData))] + public void ToRgba32(byte r, byte g, byte b, byte a) + { + Bgra32 s = ReferenceImplementations.MakeBgra32(r, g, b, a); + + // Act: + uint actualPacked = PixelConverter.FromBgra32.ToRgba32(s.PackedValue); + + // Assert: + uint expectedPacked = ReferenceImplementations.MakeRgba32(r, g, b, a).PackedValue; + + Assert.Equal(expectedPacked, actualPacked); + } } @@ -85,66 +154,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats d.A = a; return d; } - - public static Argb32 ToArgb32(Rgba32 s) - { - Argb32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } - - public static Argb32 ToArgb32(Bgra32 s) - { - Argb32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } - - public static Rgba32 ToRgba32(Argb32 s) - { - Rgba32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } - - public static Rgba32 ToRgba32(Bgra32 s) - { - Rgba32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } - - public static Bgra32 ToBgra32(Rgba32 s) - { - Bgra32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } - - public static Bgra32 ToBgra32(Argb32 s) - { - Bgra32 d = default; - d.R = s.R; - d.G = s.G; - d.B = s.B; - d.A = s.A; - return d; - } } } } \ No newline at end of file From 50867d84cbb57b660262791ecbb076a1de5d17a5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 23 Oct 2018 23:34:24 +0200 Subject: [PATCH 074/238] disappointing benchmark for Rgba32 -> Bgra32 --- .../PixelConversion_Rgba32_To_Argb32.cs | 278 +++++++++++++ .../PixelConversion_Rgba32_To_Bgra32.cs | 393 ++++++++++++++++++ 2 files changed, 671 insertions(+) create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs create mode 100644 tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs new file mode 100644 index 000000000..519014527 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs @@ -0,0 +1,278 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + public class PixelConversion_Rgba32_To_Argb32 + { + private Rgba32[] source; + + private Argb32[] dest; + + [Params(64)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.source = new Rgba32[this.Count]; + this.dest = new Argb32[this.Count]; + } + + [Benchmark(Baseline = true)] + public void Default() + { + ref Rgba32 sBase = ref this.source[0]; + ref Argb32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count; i++) + { + Rgba32 s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i).FromRgba32(s); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Default_GenericImpl(ReadOnlySpan source, Span dest) + where TPixel : struct, IPixel + { + ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); + ref TPixel dBase = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < source.Length; i++) + { + Rgba32 s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i).FromRgba32(s); + } + } + + [Benchmark] + public void Default_Generic() + { + Default_GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); + } + + [Benchmark] + public void Default_Group2() + { + ref Rgba32 sBase = ref this.source[0]; + ref Argb32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 2; i += 2) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + Rgba32 s1 = Unsafe.Add(ref s0, 1); + + ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); + d0.FromRgba32(s0); + Unsafe.Add(ref d0, 1).FromRgba32(s1); + } + } + + + [Benchmark] + public void Default_Group4() + { + ref Rgba32 sBase = ref this.source[0]; + ref Argb32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); + ref Argb32 d1 = ref Unsafe.Add(ref d0, 1); + ref Argb32 d2 = ref Unsafe.Add(ref d1, 1); + + d0.FromRgba32(s0); + d1.FromRgba32(s1); + d2.FromRgba32(s2); + Unsafe.Add(ref d2, 1).FromRgba32(s3); + } + } + + [Benchmark] + public void Default_Group4_ManualInline_V1() + { + ref Rgba32 sBase = ref this.source[0]; + ref Argb32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); + ref Argb32 d1 = ref Unsafe.Add(ref d0, 1); + ref Argb32 d2 = ref Unsafe.Add(ref d1, 1); + ref Argb32 d3 = ref Unsafe.Add(ref d2, 1); + + d0.R = s0.R; + d0.G = s0.G; + d0.B = s0.B; + d0.A = s0.A; + + d1.R = s1.R; + d1.G = s1.G; + d1.B = s1.B; + d1.A = s1.A; + + d2.R = s2.R; + d2.G = s2.G; + d2.B = s2.B; + d2.A = s2.A; + + d3.R = s3.R; + d3.G = s3.G; + d3.B = s3.B; + d3.A = s3.A; + } + } + + [Benchmark] + public void Default_Group4_ManualInline_V2() + { + ref Rgba32 sBase = ref this.source[0]; + ref Argb32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); + ref Argb32 d1 = ref Unsafe.Add(ref d0, 1); + ref Argb32 d2 = ref Unsafe.Add(ref d1, 1); + ref Argb32 d3 = ref Unsafe.Add(ref d2, 1); + + d0.R = s0.R; + d1.R = s1.R; + d2.R = s2.R; + d3.R = s3.R; + + d0.G = s0.G; + d1.G = s1.G; + d2.G = s2.G; + d3.G = s3.G; + + d0.B = s0.B; + d1.B = s1.B; + d2.B = s2.B; + d3.B = s3.B; + + d0.A = s0.A; + d1.A = s1.A; + d2.A = s2.A; + d3.A = s3.A; + } + } + + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Group4GenericImpl(ReadOnlySpan source, Span dest) + where TPixel : struct, IPixel + { + ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); + ref TPixel dBase = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < source.Length / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref TPixel d0 = ref Unsafe.Add(ref dBase, i); + ref TPixel d1 = ref Unsafe.Add(ref d0, 1); + ref TPixel d2 = ref Unsafe.Add(ref d1, 1); + + d0.FromRgba32(s0); + d1.FromRgba32(s1); + d2.FromRgba32(s2); + Unsafe.Add(ref d2, 1).FromRgba32(s3); + } + } + + [Benchmark] + public void Default_Group4_Generic() + { + Group4GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); + } + + [Benchmark] + public void BitOps() + { + ref uint sBase = ref Unsafe.As(ref this.source[0]); + ref uint dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count; i++) + { + uint s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i) = FromRgba32.ToArgb32(s); + } + } + + [Benchmark] + public void BitOps_GroupAsULong() + { + ref ulong sBase = ref Unsafe.As(ref this.source[0]); + ref ulong dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count / 2; i++) + { + ulong s = Unsafe.Add(ref sBase, i); + uint lo = (uint)s; + uint hi = (uint)(s >> 32); + lo = FromRgba32.ToArgb32(lo); + hi = FromRgba32.ToArgb32(hi); + + s = (ulong)(hi << 32) | lo; + + Unsafe.Add(ref dBase, i) = s; + } + } + + public static class FromRgba32 + { + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToArgb32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // ROL(8, packedRgba) = [bb gg rr aa] + return (packedRgba << 8) | (packedRgba >> 24); + } + + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToBgra32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // tmp1 = [aa 00 gg 00] + // tmp2 = [00 bb 00 rr] + // tmp3=ROL(16, tmp2) = [00 rr 00 bb] + // tmp1 + tmp3 = [aa rr gg bb] + uint tmp1 = packedRgba & 0xFF00FF00; + uint tmp2 = packedRgba & 0x00FF00FF; + uint tmp3 = (tmp2 << 16) | (tmp2 >> 16); + return tmp1 + tmp3; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs new file mode 100644 index 000000000..9e638dbcc --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs @@ -0,0 +1,393 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Jobs; + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tuples; + +namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion +{ + //[MonoJob] + [RyuJitX64Job] + public class PixelConversion_Rgba32_To_Bgra32 + { + private Rgba32[] source; + + private Bgra32[] dest; + + [StructLayout(LayoutKind.Sequential)] + struct Tuple4OfUInt32 + { + public uint V0, V1, V2, V3; + + public void ConvertMe() + { + this.V0 = FromRgba32.ToBgra32(this.V0); + this.V1 = FromRgba32.ToBgra32(this.V1); + this.V2 = FromRgba32.ToBgra32(this.V2); + this.V3 = FromRgba32.ToBgra32(this.V3); + } + } + + [Params(64)] + public int Count { get; set; } + + [GlobalSetup] + public void Setup() + { + this.source = new Rgba32[this.Count]; + this.dest = new Bgra32[this.Count]; + } + + [Benchmark(Baseline = true)] + public void Default() + { + ref Rgba32 sBase = ref this.source[0]; + ref Bgra32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count; i++) + { + Rgba32 s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i).FromRgba32(s); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Default_GenericImpl(ReadOnlySpan source, Span dest) + where TPixel : struct, IPixel + { + ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); + ref TPixel dBase = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < source.Length; i++) + { + Rgba32 s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i).FromRgba32(s); + } + } + + [Benchmark] + public void Default_Generic() + { + Default_GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); + } + + [Benchmark] + public void Default_Group2() + { + ref Rgba32 sBase = ref this.source[0]; + ref Bgra32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 2; i+=2) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + Rgba32 s1 = Unsafe.Add(ref s0, 1); + + ref Bgra32 d0 = ref Unsafe.Add(ref dBase, i); + d0.FromRgba32(s0); + Unsafe.Add(ref d0, 1).FromRgba32(s1); + } + } + + [Benchmark] + public void Default_Group4() + { + ref Rgba32 sBase = ref this.source[0]; + ref Bgra32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref Bgra32 d0 = ref Unsafe.Add(ref dBase, i); + ref Bgra32 d1 = ref Unsafe.Add(ref d0, 1); + ref Bgra32 d2 = ref Unsafe.Add(ref d1, 1); + + d0.FromRgba32(s0); + d1.FromRgba32(s1); + d2.FromRgba32(s2); + Unsafe.Add(ref d2, 1).FromRgba32(s3); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Group4GenericImpl(ReadOnlySpan source, Span dest) + where TPixel : struct, IPixel + { + ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); + ref TPixel dBase = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < source.Length / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + Rgba32 s3 = Unsafe.Add(ref s2, 1); + + ref TPixel d0 = ref Unsafe.Add(ref dBase, i); + ref TPixel d1 = ref Unsafe.Add(ref d0, 1); + ref TPixel d2 = ref Unsafe.Add(ref d1, 1); + + d0.FromRgba32(s0); + d1.FromRgba32(s1); + d2.FromRgba32(s2); + Unsafe.Add(ref d2, 1).FromRgba32(s3); + } + } + + [Benchmark] + public void Default_Group4_Generic() + { + Group4GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); + } + + //[Benchmark] + public void Default_Group8() + { + ref Rgba32 sBase = ref this.source[0]; + ref Bgra32 dBase = ref this.dest[0]; + + for (int i = 0; i < this.Count / 4; i += 4) + { + ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); + ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); + ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); + ref Rgba32 s3 = ref Unsafe.Add(ref s1, 1); + + ref Rgba32 s4 = ref Unsafe.Add(ref s3, 1); + ref Rgba32 s5 = ref Unsafe.Add(ref s4, 1); + ref Rgba32 s6 = ref Unsafe.Add(ref s5, 1); + Rgba32 s7 = Unsafe.Add(ref s6, 1); + + ref Bgra32 d0 = ref Unsafe.Add(ref dBase, i); + ref Bgra32 d1 = ref Unsafe.Add(ref d0, 1); + ref Bgra32 d2 = ref Unsafe.Add(ref d1, 1); + ref Bgra32 d3 = ref Unsafe.Add(ref d2, 1); + ref Bgra32 d4 = ref Unsafe.Add(ref d3, 1); + + ref Bgra32 d5 = ref Unsafe.Add(ref d4, 1); + ref Bgra32 d6 = ref Unsafe.Add(ref d5, 1); + + + d0.FromRgba32(s0); + d1.FromRgba32(s1); + d2.FromRgba32(s2); + d3.FromRgba32(s3); + + d4.FromRgba32(s4); + d5.FromRgba32(s5); + d6.FromRgba32(s6); + Unsafe.Add(ref d6, 1).FromRgba32(s7); + } + } + + [Benchmark] + public void BitOps() + { + ref uint sBase = ref Unsafe.As(ref this.source[0]); + ref uint dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count; i++) + { + uint s = Unsafe.Add(ref sBase, i); + Unsafe.Add(ref dBase, i) = FromRgba32.ToBgra32(s); + } + } + + [Benchmark] + public void Bitops_Tuple() + { + ref Tuple4OfUInt32 sBase = ref Unsafe.As(ref this.source[0]); + ref Tuple4OfUInt32 dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count / 4; i++) + { + ref Tuple4OfUInt32 d = ref Unsafe.Add(ref dBase, i); + d = Unsafe.Add(ref sBase, i); + d.ConvertMe(); + } + } + + [Benchmark] + public void Bitops_SingleTuple() + { + ref Tuple4OfUInt32 sBase = ref Unsafe.As(ref this.source[0]); + + for (int i = 0; i < this.Count / 4; i++) + { + Unsafe.Add(ref sBase, i).ConvertMe(); + } + } + + [Benchmark] + public void Bitops_Simd() + { + ref Octet.OfUInt32 sBase = ref Unsafe.As(ref this.source[0]); + ref Octet.OfUInt32 dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count / 8; i++) + { + BitopsSimdImpl(ref Unsafe.Add(ref sBase, i), ref Unsafe.Add(ref dBase, i)); + } + } + + [StructLayout(LayoutKind.Sequential)] + struct B + { + public uint tmp2, tmp5, tmp8, tmp11, tmp14, tmp17, tmp20, tmp23; + } + + [StructLayout(LayoutKind.Sequential)] + struct C + { + public uint tmp3, tmp6, tmp9, tmp12, tmp15, tmp18, tmp21, tmp24; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void BitopsSimdImpl(ref Octet.OfUInt32 s, ref Octet.OfUInt32 d) + { + Vector sVec = Unsafe.As>(ref s); + Vector aMask = new Vector(0xFF00FF00); + Vector bMask = new Vector(0x00FF00FF); + + Vector aa = sVec & aMask; + Vector bb = sVec & bMask; + + B b = Unsafe.As, B>(ref bb); + + C c = default; + + c.tmp3 = (b.tmp2 << 16) | (b.tmp2 >> 16); + c.tmp6 = (b.tmp5 << 16) | (b.tmp5 >> 16); + c.tmp9 = (b.tmp8 << 16) | (b.tmp8 >> 16); + c.tmp12 = (b.tmp11 << 16) | (b.tmp11 >> 16); + c.tmp15 = (b.tmp14 << 16) | (b.tmp14 >> 16); + c.tmp18 = (b.tmp17 << 16) | (b.tmp17 >> 16); + c.tmp21 = (b.tmp20 << 16) | (b.tmp20 >> 16); + c.tmp24 = (b.tmp23 << 16) | (b.tmp23 >> 16); + + Vector cc = Unsafe.As>(ref c); + Vector dd = aa + cc; + + d = Unsafe.As, Octet.OfUInt32>(ref dd); + } + + //[Benchmark] + public void BitOps_Group2() + { + ref uint sBase = ref Unsafe.As(ref this.source[0]); + ref uint dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count; i++) + { + ref uint s0 = ref Unsafe.Add(ref sBase, i); + uint s1 = Unsafe.Add(ref s0, 1); + + ref uint d0 = ref Unsafe.Add(ref dBase, i); + d0 = FromRgba32.ToBgra32(s0); + Unsafe.Add(ref d0, 1) = FromRgba32.ToBgra32(s1); + } + } + + [Benchmark] + public void BitOps_GroupAsULong() + { + ref ulong sBase = ref Unsafe.As(ref this.source[0]); + ref ulong dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count / 2; i++) + { + ulong s = Unsafe.Add(ref sBase, i); + uint lo = (uint)s; + uint hi = (uint)(s >> 32); + lo = FromRgba32.ToBgra32(lo); + hi = FromRgba32.ToBgra32(hi); + + s = (ulong)(hi << 32) | lo; + + Unsafe.Add(ref dBase, i) = s; + } + } + + //[Benchmark] + public void BitOps_GroupAsULong_V2() + { + ref ulong sBase = ref Unsafe.As(ref this.source[0]); + ref ulong dBase = ref Unsafe.As(ref this.dest[0]); + + for (int i = 0; i < this.Count / 2; i++) + { + ulong s = Unsafe.Add(ref sBase, i); + uint lo = (uint)s; + uint hi = (uint)(s >> 32); + + uint tmp1 = lo & 0xFF00FF00; + uint tmp4 = hi & 0xFF00FF00; + + uint tmp2 = lo & 0x00FF00FF; + uint tmp5 = hi & 0x00FF00FF; + + uint tmp3 = (tmp2 << 16) | (tmp2 >> 16); + uint tmp6 = (tmp5 << 16) | (tmp5 >> 16); + + lo = tmp1 + tmp3; + hi = tmp4 + tmp6; + + s = (ulong)(hi << 32) | lo; + + Unsafe.Add(ref dBase, i) = s; + } + } + + public static class FromRgba32 + { + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToArgb32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // ROL(8, packedRgba) = [bb gg rr aa] + return (packedRgba << 8) | (packedRgba >> 24); + } + + /// + /// Converts a packed to . + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static uint ToBgra32(uint packedRgba) + { + // packedRgba = [aa bb gg rr] + // tmp1 = [aa 00 gg 00] + // tmp2 = [00 bb 00 rr] + // tmp3=ROL(16, tmp2) = [00 rr 00 bb] + // tmp1 + tmp3 = [aa rr gg bb] + uint tmp1 = packedRgba & 0xFF00FF00; + uint tmp2 = packedRgba & 0x00FF00FF; + uint tmp3 = (tmp2 << 16) | (tmp2 >> 16); + return tmp1 + tmp3; + } + } + + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // ----------------------- |------ |----------:|----------:|----------:|-------:| + // Default | 64 | 107.13 ns | 0.7752 ns | 0.6872 ns | 1.00 | + // Default_Generic | 64 | 113.78 ns | 0.7713 ns | 0.6022 ns | 1.06 | + // Default_Group2 | 64 | 43.72 ns | 0.1711 ns | 0.1600 ns | 0.41 | + // Default_Group4 | 64 | 23.47 ns | 0.1901 ns | 0.1588 ns | 0.22 | + // Default_Group4_Generic | 64 | 32.46 ns | 0.4297 ns | 0.4019 ns | 0.30 | + // Bitops_Tuple | 64 | 77.71 ns | 0.2779 ns | 0.2599 ns | 0.73 | + // Bitops_SingleTuple | 64 | 58.64 ns | 0.4511 ns | 0.4220 ns | 0.55 | + // Bitops_Simd | 64 | 110.58 ns | 0.4686 ns | 0.4383 ns | 1.03 | + } +} \ No newline at end of file From ebaaa35324ac8df588c6e88b9d758f084256f183 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:13:17 -0700 Subject: [PATCH 075/238] Cross target NET472 and enable extended intrinisics behind SUPPORTS_EXTENDED_INTRINSICS symbol --- .../Common/Helpers/SimdUtils.ExtendedIntrinsics.cs | 4 +--- src/ImageSharp/Common/Helpers/SimdUtils.cs | 4 ++-- src/ImageSharp/Common/Helpers/TestHelpers.cs | 6 +++++- src/ImageSharp/ImageSharp.csproj | 13 +++++++++---- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 2 +- tests/ImageSharp.Tests/RunExtendedTests.cmd | 2 ++ 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index e0d6187dc..2ac577264 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -20,8 +19,7 @@ namespace SixLabors.ImageSharp public static class ExtendedIntrinsics { public static bool IsAvailable { get; } = -#if NETCOREAPP2_1 - // TODO: Also available in .NET 4.7.2, we need to add a build target! +#if SUPPORTS_EXTENDED_INTRINSICS Vector.IsHardwareAccelerated; #else false; diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 71eb88b1d..a989cc875 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if NETCOREAPP2_1 +#if SUPPORTS_EXTENDED_INTRINSICS ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); #else BasicIntrinsics256.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if NETCOREAPP2_1 +#if SUPPORTS_EXTENDED_INTRINSICS ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); #else BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); diff --git a/src/ImageSharp/Common/Helpers/TestHelpers.cs b/src/ImageSharp/Common/Helpers/TestHelpers.cs index 45ef7706d..fd16a577a 100644 --- a/src/ImageSharp/Common/Helpers/TestHelpers.cs +++ b/src/ImageSharp/Common/Helpers/TestHelpers.cs @@ -13,8 +13,12 @@ namespace SixLabors.ImageSharp.Common.Helpers /// Only intended to be used in tests! /// internal const string ImageSharpBuiltAgainst = -#if NETCOREAPP2_1 +#if NET472 + "netfx4.7.2"; +#elif NETCOREAPP2_1 "netcoreapp2.1"; +#elif NETSTANDARD1_3 + "netstandard1.3"; #else "netstandard2.0"; #endif diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 8d2ad2abe..29d29d50d 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,7 +5,7 @@ $(packageversion) 0.0.1 Six Labors and contributors - netstandard1.3;netstandard2.0;netcoreapp2.1 + netstandard1.3;netstandard2.0;netcoreapp2.1;net472 true true SixLabors.ImageSharp @@ -31,9 +31,15 @@ IOperation Latest + + + $(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS + + + @@ -43,15 +49,14 @@ - - - + + ..\..\ImageSharp.ruleset SixLabors.ImageSharp diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 5d163917c..04a680200 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,6 +1,6 @@  - net462;net471;netcoreapp2.1 + net462;net472;netcoreapp2.1 True latest full diff --git a/tests/ImageSharp.Tests/RunExtendedTests.cmd b/tests/ImageSharp.Tests/RunExtendedTests.cmd index 481e5fb3d..c2f4b9f53 100644 --- a/tests/ImageSharp.Tests/RunExtendedTests.cmd +++ b/tests/ImageSharp.Tests/RunExtendedTests.cmd @@ -5,3 +5,5 @@ dotnet xunit -nobuild -c Release -f net47 dotnet xunit -nobuild -c Release -f net47 -x86 dotnet xunit -nobuild -c Release -f net471 dotnet xunit -nobuild -c Release -f net471 -x86 +dotnet xunit -nobuild -c Release -f net472 +dotnet xunit -nobuild -c Release -f net472 -x86 From 38826e45a97f2f1e464887f9ea89672128542c93 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:30:30 -0700 Subject: [PATCH 076/238] Use Array.Empty --- .../Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs | 6 +++--- .../ICC/DataWriter/IccDataWriter.PrimitivesTests.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs index 38a2f4522..77a913b14 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// Initializes a new instance of the class. /// public IccCurveTagDataEntry() - : this(new float[0], IccProfileTag.Unknown) + : this(Array.Empty(), IccProfileTag.Unknown) { } @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Tag Signature public IccCurveTagDataEntry(IccProfileTag tagSignature) - : this(new float[0], tagSignature) + : this(Array.Empty(), tagSignature) { } @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc public IccCurveTagDataEntry(float[] curveData, IccProfileTag tagSignature) : base(IccTypeSignature.Curve, tagSignature) { - this.CurveData = curveData ?? new float[0]; + this.CurveData = curveData ?? Array.Empty(); } /// diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs index 56a4f8c0c..845a149b5 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Icc byte[] output = writer.GetData(); Assert.Equal(0, count); - Assert.Equal(new byte[0], output); + Assert.Equal(Array.Empty(), output); } [Fact] @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Icc byte[] output = writer.GetData(); Assert.Equal(0, count); - Assert.Equal(new byte[0], output); + Assert.Equal(Array.Empty(), output); } [Theory] From 1115e4d41d9e5d5c23f79fc8c505b833eafdc16b Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:40:24 -0700 Subject: [PATCH 077/238] [Exif] Eliminate invalidTag list allocation when there are no invalid tags --- .../MetaData/Profiles/Exif/ExifProfile.cs | 12 +++++++++-- .../MetaData/Profiles/Exif/ExifReader.cs | 20 ++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs index b48b146f1..32c1796d4 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif { this.Parts = ExifParts.All; this.data = data; - this.InvalidTags = new List(); + this.InvalidTags = Array.Empty(); } /// @@ -289,7 +289,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.values = reader.ReadValues(); - this.InvalidTags = new List(reader.InvalidTags); + if (reader.InvalidTags.Count > 0) + { + this.InvalidTags = new List(reader.InvalidTags); + } + else + { + this.InvalidTags = Array.Empty(); + } + this.thumbnailOffset = (int)reader.ThumbnailOffset; this.thumbnailLength = (int)reader.ThumbnailLength; } diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index 5f9549908..3326c3217 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Text; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Primitives; @@ -19,7 +18,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// internal sealed class ExifReader { - private readonly List invalidTags = new List(); + private List invalidTags; private readonly byte[] exifData; private int position; private Endianness endianness = Endianness.BigEndian; @@ -38,7 +37,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// /// Gets the invalid tags. /// - public IReadOnlyList InvalidTags => this.invalidTags; + public IReadOnlyList InvalidTags => this.invalidTags ?? (IReadOnlyList)Array.Empty(); /// /// Gets the thumbnail length in the byte stream @@ -338,7 +337,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif // Ensure that the new index does not overrun the data if (newIndex > int.MaxValue) { - this.invalidTags.Add(tag); + this.AddInvalidTag(tag); exifValue = default; @@ -349,7 +348,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif if (this.RemainingLength < size) { - this.invalidTags.Add(tag); + this.AddInvalidTag(tag); + this.position = oldIndex; exifValue = default; @@ -372,6 +372,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif return true; } + private void AddInvalidTag(ExifTag tag) + { + if (this.invalidTags == null) + { + this.invalidTags = new List(); + } + + this.invalidTags.Add(tag); + } + private TEnum ToEnum(int value, TEnum defaultValue) where TEnum : struct { From 79a06874911616fa3242a285913b2afbda7a22d2 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:45:47 -0700 Subject: [PATCH 078/238] Update IccProfile Entries to Array --- src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs | 11 ++++++----- src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs | 4 ++-- .../MetaData/Profiles/ICC/IccReaderTests.cs | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs index 72665bc69..1d3b27c5e 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Security.Cryptography; namespace SixLabors.ImageSharp.MetaData.Profiles.Icc @@ -20,7 +21,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// The backing file for the property /// - private List entries; + private IccTagDataEntry[] entries; /// /// ICC profile header @@ -52,7 +53,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc Guard.NotNull(entries, nameof(entries)); this.header = header; - this.entries = new List(entries); + this.entries = entries.ToArray(); } /// @@ -85,7 +86,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Gets the actual profile data /// - public List Entries + public IccTagDataEntry[] Entries { get { @@ -212,12 +213,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc if (this.data is null) { - this.entries = new List(); + this.entries = Array.Empty(); return; } var reader = new IccReader(); - this.entries = new List(reader.ReadTagData(this.data)); + this.entries = reader.ReadTagData(this.data); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs index b476e3195..91a3bba54 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs @@ -68,12 +68,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } } - private IccTagTableEntry[] WriteTagData(IccDataWriter writer, List entries) + private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries) { IEnumerable> grouped = entries.GroupBy(t => t); // (Header size) + (entry count) + (nr of entries) * (size of table entry) - writer.SetIndex(128 + 4 + (entries.Count * 12)); + writer.SetIndex(128 + 4 + (entries.Length * 12)); var table = new List(); foreach (IGrouping group in grouped) diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs index b3215ee7a..c91076afc 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Icc IccProfile output = reader.Read(IccTestDataProfiles.Header_Random_Array); - Assert.Equal(0, output.Entries.Count); + Assert.Equal(0, output.Entries.Length); Assert.NotNull(output.Header); IccProfileHeader header = output.Header; @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.Icc IccProfile output = reader.Read(IccTestDataProfiles.Profile_Random_Array); - Assert.Equal(2, output.Entries.Count); + Assert.Equal(2, output.Entries.Length); Assert.True(ReferenceEquals(output.Entries[0], output.Entries[1])); } From 5d791189256c767848e2637925ad8ed70b96adb4 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:57:30 -0700 Subject: [PATCH 079/238] Eliminate an allocation when cloning a valid ExifProfile --- src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs index 32c1796d4..6890cc535 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs @@ -63,7 +63,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.Parts = other.Parts; this.thumbnailLength = other.thumbnailLength; this.thumbnailOffset = other.thumbnailOffset; - this.InvalidTags = new List(other.InvalidTags); + + if (other.InvalidTags.Count > 0) + { + this.InvalidTags = new List(other.InvalidTags); + } + else + { + this.InvalidTags = Array.Empty(); + } + if (other.values != null) { this.values = new List(other.Values.Count); From 5110b1fdc82e472f3b5e35028933f4fe4fc92867 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 17:58:00 -0700 Subject: [PATCH 080/238] Eliminate allocation in invalid icc profile --- src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs index da47b565e..9f9d373ae 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Collections.Generic; namespace SixLabors.ImageSharp.MetaData.Profiles.Icc @@ -126,7 +127,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc // A normal profile usually has 5-15 entries if (tagCount > 100) { - return new IccTagTableEntry[0]; + return Array.Empty(); } var table = new List((int)tagCount); From ee98ee2fe452bcbbad1d70ecd7e5d9ae5f27f9af Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 18:00:08 -0700 Subject: [PATCH 081/238] Update appveyor target frameworks --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 821fd427c..34c733e68 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ environment: - target_framework: net471 is_32bit: False - - target_framework: net471 + - target_framework: net472 is_32bit: True - target_framework: net462 From 79202279c9075b6734832293388ddf610d378096 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 18:00:41 -0700 Subject: [PATCH 082/238] Update appveyor target frameworks (64bit) --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 34c733e68..2cc5182d3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - target_framework: netcoreapp2.1 is_32bit: True - - target_framework: net471 + - target_framework: net472 is_32bit: False - target_framework: net472 From c836c5ee82aac990d5e5004c7f6871e75570e95d Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 18:07:24 -0700 Subject: [PATCH 083/238] Update IccProfile constructor --- src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs index 1d3b27c5e..5d75a6df9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Collections.Generic; -using System.Linq; using System.Security.Cryptography; namespace SixLabors.ImageSharp.MetaData.Profiles.Icc @@ -47,13 +45,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// The profile header /// The actual profile data - internal IccProfile(IccProfileHeader header, IEnumerable entries) + internal IccProfile(IccProfileHeader header, IccTagDataEntry[] entries) { - Guard.NotNull(header, nameof(header)); - Guard.NotNull(entries, nameof(entries)); - - this.header = header; - this.entries = entries.ToArray(); + this.header = header ?? throw new ArgumentNullException(nameof(header)); + this.entries = entries ?? throw new ArgumentNullException(nameof(entries)); } /// From b29ff790d365b3dca959c295acfce21a5d7eeffc Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 18:16:21 -0700 Subject: [PATCH 084/238] [Exif] Make allowedParts and values readonly --- src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs index ade373341..9079526d5 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs @@ -17,8 +17,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// /// Which parts will be written. /// - private ExifParts allowedParts; - private IList values; + private readonly ExifParts allowedParts; + private readonly IList values; private List dataOffsets; private readonly List ifdIndexes; private readonly List exifIndexes; From f574cf94ae00ba1ccce6f380fed8bc00027e8920 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 23 Oct 2018 18:22:40 -0700 Subject: [PATCH 085/238] Use ternary operator --- .../MetaData/Profiles/Exif/ExifProfile.cs | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs index 6890cc535..37ceaf10f 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs @@ -64,14 +64,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.thumbnailLength = other.thumbnailLength; this.thumbnailOffset = other.thumbnailOffset; - if (other.InvalidTags.Count > 0) - { - this.InvalidTags = new List(other.InvalidTags); - } - else - { - this.InvalidTags = Array.Empty(); - } + this.InvalidTags = other.InvalidTags.Count > 0 + ? new List(other.InvalidTags) + : (IReadOnlyList)Array.Empty(); if (other.values != null) { @@ -298,14 +293,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.values = reader.ReadValues(); - if (reader.InvalidTags.Count > 0) - { - this.InvalidTags = new List(reader.InvalidTags); - } - else - { - this.InvalidTags = Array.Empty(); - } + this.InvalidTags = reader.InvalidTags.Count > 0 + ? new List(reader.InvalidTags) + : (IReadOnlyList)Array.Empty(); this.thumbnailOffset = (int)reader.ThumbnailOffset; this.thumbnailLength = (int)reader.ThumbnailLength; From fd0e1bda6e596686b1eaceb0ecdf800512fd11f0 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 24 Oct 2018 01:49:26 +0200 Subject: [PATCH 086/238] Fixed the benchmarks. All results make sense now! (cherry picked from commit 0d79d4eb58fa1002979f4157eb18c6291a164b06) --- .../PixelConversion_Rgba32_To_Argb32.cs | 128 ++---------------- .../PixelConversion_Rgba32_To_Bgra32.cs | 33 +++-- 2 files changed, 29 insertions(+), 132 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs index 519014527..40893914e 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion ref Rgba32 sBase = ref this.source[0]; ref Argb32 dBase = ref this.dest[0]; - for (int i = 0; i < this.Count / 2; i += 2) + for (int i = 0; i < this.Count; i += 2) { ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); Rgba32 s1 = Unsafe.Add(ref s0, 1); @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion ref Rgba32 sBase = ref this.source[0]; ref Argb32 dBase = ref this.dest[0]; - for (int i = 0; i < this.Count / 4; i += 4) + for (int i = 0; i < this.Count; i += 4) { ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); @@ -98,119 +98,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion Unsafe.Add(ref d2, 1).FromRgba32(s3); } } - - [Benchmark] - public void Default_Group4_ManualInline_V1() - { - ref Rgba32 sBase = ref this.source[0]; - ref Argb32 dBase = ref this.dest[0]; - - for (int i = 0; i < this.Count / 4; i += 4) - { - ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); - ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); - ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); - Rgba32 s3 = Unsafe.Add(ref s2, 1); - - ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); - ref Argb32 d1 = ref Unsafe.Add(ref d0, 1); - ref Argb32 d2 = ref Unsafe.Add(ref d1, 1); - ref Argb32 d3 = ref Unsafe.Add(ref d2, 1); - - d0.R = s0.R; - d0.G = s0.G; - d0.B = s0.B; - d0.A = s0.A; - - d1.R = s1.R; - d1.G = s1.G; - d1.B = s1.B; - d1.A = s1.A; - - d2.R = s2.R; - d2.G = s2.G; - d2.B = s2.B; - d2.A = s2.A; - - d3.R = s3.R; - d3.G = s3.G; - d3.B = s3.B; - d3.A = s3.A; - } - } - - [Benchmark] - public void Default_Group4_ManualInline_V2() - { - ref Rgba32 sBase = ref this.source[0]; - ref Argb32 dBase = ref this.dest[0]; - - for (int i = 0; i < this.Count / 4; i += 4) - { - ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); - ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); - ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); - Rgba32 s3 = Unsafe.Add(ref s2, 1); - - ref Argb32 d0 = ref Unsafe.Add(ref dBase, i); - ref Argb32 d1 = ref Unsafe.Add(ref d0, 1); - ref Argb32 d2 = ref Unsafe.Add(ref d1, 1); - ref Argb32 d3 = ref Unsafe.Add(ref d2, 1); - - d0.R = s0.R; - d1.R = s1.R; - d2.R = s2.R; - d3.R = s3.R; - - d0.G = s0.G; - d1.G = s1.G; - d2.G = s2.G; - d3.G = s3.G; - - d0.B = s0.B; - d1.B = s1.B; - d2.B = s2.B; - d3.B = s3.B; - - d0.A = s0.A; - d1.A = s1.A; - d2.A = s2.A; - d3.A = s3.A; - } - } - - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void Group4GenericImpl(ReadOnlySpan source, Span dest) - where TPixel : struct, IPixel - { - ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); - ref TPixel dBase = ref MemoryMarshal.GetReference(dest); - - for (int i = 0; i < source.Length / 4; i += 4) - { - ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); - ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); - ref Rgba32 s2 = ref Unsafe.Add(ref s1, 1); - Rgba32 s3 = Unsafe.Add(ref s2, 1); - - ref TPixel d0 = ref Unsafe.Add(ref dBase, i); - ref TPixel d1 = ref Unsafe.Add(ref d0, 1); - ref TPixel d2 = ref Unsafe.Add(ref d1, 1); - - d0.FromRgba32(s0); - d1.FromRgba32(s1); - d2.FromRgba32(s2); - Unsafe.Add(ref d2, 1).FromRgba32(s3); - } - } - - [Benchmark] - public void Default_Group4_Generic() - { - Group4GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); - } - + [Benchmark] public void BitOps() { @@ -274,5 +162,15 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion return tmp1 + tmp3; } } + + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // -------------------- |------ |----------:|----------:|----------:|-------:| + // Default | 64 | 107.33 ns | 1.0633 ns | 0.9426 ns | 1.00 | + // Default_Generic | 64 | 111.15 ns | 0.3789 ns | 0.3544 ns | 1.04 | + // Default_Group2 | 64 | 90.36 ns | 0.7779 ns | 0.6896 ns | 0.84 | + // Default_Group4 | 64 | 82.39 ns | 0.2726 ns | 0.2550 ns | 0.77 | + // BitOps | 64 | 39.25 ns | 0.3266 ns | 0.2895 ns | 0.37 | + // BitOps_GroupAsULong | 64 | 41.80 ns | 0.2227 ns | 0.2083 ns | 0.39 | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs index 9e638dbcc..9cf16ea19 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion ref Rgba32 sBase = ref this.source[0]; ref Bgra32 dBase = ref this.dest[0]; - for (int i = 0; i < this.Count / 2; i+=2) + for (int i = 0; i < this.Count; i+=2) { ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); Rgba32 s1 = Unsafe.Add(ref s0, 1); @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion ref Rgba32 sBase = ref this.source[0]; ref Bgra32 dBase = ref this.dest[0]; - for (int i = 0; i < this.Count / 4; i += 4) + for (int i = 0; i < this.Count; i += 4) { ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion Unsafe.Add(ref d2, 1).FromRgba32(s3); } } - + [MethodImpl(MethodImplOptions.NoInlining)] private static void Group4GenericImpl(ReadOnlySpan source, Span dest) where TPixel : struct, IPixel @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion ref Rgba32 sBase = ref MemoryMarshal.GetReference(source); ref TPixel dBase = ref MemoryMarshal.GetReference(dest); - for (int i = 0; i < source.Length / 4; i += 4) + for (int i = 0; i < source.Length; i += 4) { ref Rgba32 s0 = ref Unsafe.Add(ref sBase, i); ref Rgba32 s1 = ref Unsafe.Add(ref s0, 1); @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } - [Benchmark] + //[Benchmark] public void Default_Group4_Generic() { Group4GenericImpl(this.source.AsSpan(), this.dest.AsSpan()); @@ -215,7 +215,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } - [Benchmark] + //[Benchmark] public void Bitops_SingleTuple() { ref Tuple4OfUInt32 sBase = ref Unsafe.As(ref this.source[0]); @@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } - [Benchmark] + //[Benchmark] public void Bitops_Simd() { ref Octet.OfUInt32 sBase = ref Unsafe.As(ref this.source[0]); @@ -379,15 +379,14 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | - // ----------------------- |------ |----------:|----------:|----------:|-------:| - // Default | 64 | 107.13 ns | 0.7752 ns | 0.6872 ns | 1.00 | - // Default_Generic | 64 | 113.78 ns | 0.7713 ns | 0.6022 ns | 1.06 | - // Default_Group2 | 64 | 43.72 ns | 0.1711 ns | 0.1600 ns | 0.41 | - // Default_Group4 | 64 | 23.47 ns | 0.1901 ns | 0.1588 ns | 0.22 | - // Default_Group4_Generic | 64 | 32.46 ns | 0.4297 ns | 0.4019 ns | 0.30 | - // Bitops_Tuple | 64 | 77.71 ns | 0.2779 ns | 0.2599 ns | 0.73 | - // Bitops_SingleTuple | 64 | 58.64 ns | 0.4511 ns | 0.4220 ns | 0.55 | - // Bitops_Simd | 64 | 110.58 ns | 0.4686 ns | 0.4383 ns | 1.03 | + // Method | Count | Mean | Error | StdDev | Scaled | + // -------------------- |------ |----------:|----------:|----------:|-------:| + // Default | 64 | 106.84 ns | 0.4042 ns | 0.3583 ns | 1.00 | + // Default_Generic | 64 | 113.11 ns | 0.6998 ns | 0.6203 ns | 1.06 | + // Default_Group2 | 64 | 86.81 ns | 0.4976 ns | 0.4654 ns | 0.81 | + // Default_Group4 | 64 | 83.53 ns | 1.3826 ns | 1.2933 ns | 0.78 | + // BitOps | 64 | 54.23 ns | 0.1920 ns | 0.1796 ns | 0.51 | + // Bitops_Tuple | 64 | 73.45 ns | 0.5475 ns | 0.4853 ns | 0.69 | + // BitOps_GroupAsULong | 64 | 64.28 ns | 0.4046 ns | 0.3785 ns | 0.60 | } } \ No newline at end of file From 41aa2ad9a2bb0053b4e1146fe4f92bcff4137efe Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 25 Oct 2018 02:04:55 +0200 Subject: [PATCH 087/238] Optimized bulk conversion for common pixel types --- .../Argb32.PixelOperations.Generated.cs | 117 ++++++++++++++---- .../Bgr24.PixelOperations.Generated.cs | 37 ++++++ .../Bgra32.PixelOperations.Generated.cs | 111 +++++++++++++---- .../Gray16.PixelOperations.Generated.cs | 12 ++ .../Gray8.PixelOperations.Generated.cs | 12 ++ .../Rgb24.PixelOperations.Generated.cs | 37 ++++++ .../Rgb48.PixelOperations.Generated.cs | 12 ++ .../Rgba32.PixelOperations.Generated.cs | 76 +++++++++--- .../Rgba64.PixelOperations.Generated.cs | 12 ++ .../Generated/_Common.ttinclude | 100 ++++++++++++++- .../Rgba32.PixelOperations.cs | 20 +-- .../RgbaVector.PixelOperations.cs | 8 +- .../PixelFormats/PixelOperations{TPixel}.cs | 82 ++++++++++-- 13 files changed, 537 insertions(+), 99 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 09f10716e..e6b8922e9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromArgb32(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,109 +35,167 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - + /// - internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); for (int i = 0; i < sourcePixels.Length; i++) { - ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - - dp.FromArgb32(sp); + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToRgba32(sp); } } - + /// - internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void FromRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToArgb32(sp); + } + } + /// + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); for (int i = 0; i < sourcePixels.Length; i++) { - ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToBgra32(sp); + } + } - dp.FromArgb32(sp); + /// + internal override void FromBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToArgb32(sp); } } /// - internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); dp.FromArgb32(sp); } } /// - internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); dp.FromArgb32(sp); } } /// - internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); dp.FromArgb32(sp); } } /// - internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourcePixels.Length; i++) { ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); dp.FromArgb32(sp); } @@ -143,6 +204,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +222,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index f8c61e4fa..9b1740013 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromBgr24(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,15 +35,42 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } + + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +88,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +106,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +142,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +160,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +178,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +196,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 9bddd18e9..37d6b72d7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromBgra32(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,32 +35,104 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - + + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + /// - internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); for (int i = 0; i < sourcePixels.Length; i++) { - ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToRgba32(sp); + } + } - dp.FromBgra32(sp); + /// + internal override void FromRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToBgra32(sp); + } + } + /// + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToArgb32(sp); + } + } + + /// + internal override void FromArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToBgra32(sp); } } /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +150,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +168,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +186,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -119,23 +197,6 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp.FromBgra32(sp); - } - } - - /// - internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) - { - Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < sourcePixels.Length; i++) - { - ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.FromBgra32(sp); } } @@ -143,6 +204,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +222,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index 31c575534..638db1d0d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromGray16(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,6 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); @@ -41,6 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +135,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index 14a2c858c..6bf0693c2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromGray8(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,6 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); @@ -41,6 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +135,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index f8b80020e..6ff87eb38 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromRgb24(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,15 +35,42 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } + + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +88,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +106,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +124,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +142,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +160,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +178,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +196,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index 5741b1070..9b4584d76 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromRgb48(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,6 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); @@ -41,6 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +135,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index 9f7b624c0..8e15ca1f4 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromRgba32(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,58 +35,88 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// - internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); for (int i = 0; i < sourcePixels.Length; i++) { - ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destRef, i); - - dp.FromRgba32(sp); + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToArgb32(sp); } } - + /// - internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void FromArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); - ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToRgba32(sp); + } + } + /// + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); for (int i = 0; i < sourcePixels.Length; i++) { - ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToBgra32(sp); + } + } - dp.FromRgba32(sp); + /// + internal override void FromBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToRgba32(sp); } } /// - internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourcePixels.Length; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); dp.FromRgba32(sp); } @@ -92,6 +125,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +143,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +161,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +179,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +197,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index 411178b82..caaba7809 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -4,6 +4,8 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,6 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromRgba64(Configuration configuration, ReadOnlySpan source, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -32,6 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); @@ -41,6 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -58,6 +63,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -75,6 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -92,6 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -109,6 +117,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -126,6 +135,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -143,6 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -160,6 +171,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index bc23edb01..4501f4972 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -9,10 +9,17 @@ // using System; +using System.Buffers; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; <#+ - static readonly string[] CommonPixelTypeNames = { "Argb32", "Bgr24", "Bgra32", "Gray8", "Gray16", "Rgb24", "Rgba32", "Rgb48", "Rgba64" }; + static readonly string[] CommonPixelTypes = { "Argb32", "Bgr24", "Bgra32", "Gray8", "Gray16", "Rgb24", "Rgba32", "Rgb48", "Rgba64" }; + + static readonly string[] Optimized32BitTypes = { "Rgba32", "Argb32", "Bgra32" }; + + // Types with Rgba32-combatible to/from Vector4 conversion + static readonly string[] Rgba32CompatibleTypes = { "Argb32", "Bgra32", "Rgb24", "Bgr24" }; void GenerateDefaultSelfConversionMethods(string pixelType) { @@ -21,6 +28,7 @@ using System.Runtime.InteropServices; /// internal override void From<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -29,6 +37,7 @@ using System.Runtime.InteropServices; /// internal override void To<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); @@ -44,6 +53,7 @@ using System.Runtime.InteropServices; /// internal override void To<#=toPixelType#>(Configuration configuration, ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels) { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref <#=fromPixelType#> sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -60,13 +70,97 @@ using System.Runtime.InteropServices; <#+ } + void GenerateOptimized32BitConversionMethods(string thisPixelType, string otherPixelType) + { + #> + /// + internal override void To<#=otherPixelType#>(Configuration configuration, ReadOnlySpan<<#=thisPixelType#>> sourcePixels, Span<<#=otherPixelType#>> destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As<<#=thisPixelType#>,uint>(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As<<#=otherPixelType#>, uint>(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.From<#=thisPixelType#>.To<#=otherPixelType#>(sp); + } + } + + /// + internal override void From<#=otherPixelType#>(Configuration configuration, ReadOnlySpan<<#=otherPixelType#>> sourcePixels, Span<<#=thisPixelType#>> destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); + + ref uint sourceRef = ref Unsafe.As<<#=otherPixelType#>,uint>(ref MemoryMarshal.GetReference(sourcePixels)); + ref uint destRef = ref Unsafe.As<<#=thisPixelType#>, uint>(ref MemoryMarshal.GetReference(destPixels)); + + for (int i = 0; i < sourcePixels.Length; i++) + { + uint sp = Unsafe.Add(ref sourceRef, i); + Unsafe.Add(ref destRef, i) = PixelConverter.From<#=otherPixelType#>.To<#=thisPixelType#>(sp); + } + } + <#+ + } + + void GenerateRgba32CompatibleVector4ConversionMethods(string pixelType) + { + #> + + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + { + this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) + { + this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + } + + <#+ + } + void GenerateAllDefaultConversionMethods(string pixelType) { GenerateDefaultSelfConversionMethods(pixelType); - var allOtherPixelTypes = CommonPixelTypeNames.Where(p => p != pixelType); + if (Rgba32CompatibleTypes.Contains(pixelType)) + { + GenerateRgba32CompatibleVector4ConversionMethods(pixelType); + } + + var matching32BitTypes = Optimized32BitTypes.Contains(pixelType) ? + Optimized32BitTypes.Where(p => p != pixelType) : + Enumerable.Empty(); + + foreach (string destPixelType in matching32BitTypes) + { + GenerateOptimized32BitConversionMethods(pixelType, destPixelType); + } + + var otherCommonNon32Types = CommonPixelTypes + .Where(p => p != pixelType) + .Except(matching32BitTypes); - foreach (string destPixelType in allOtherPixelTypes) + foreach (string destPixelType in otherCommonNon32Types) { GenerateDefaultConvertToMethod(pixelType, destPixelType); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 0f5ddf372..004b25cd3 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -21,31 +21,31 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToVector4( Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) + ReadOnlySpan sourcePixels, + Span destVectors) { - Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - destinationVectors = destinationVectors.Slice(0, sourceColors.Length); + destVectors = destVectors.Slice(0, sourcePixels.Length); SimdUtils.BulkConvertByteToNormalizedFloat( - MemoryMarshal.Cast(sourceColors), - MemoryMarshal.Cast(destinationVectors)); + MemoryMarshal.Cast(sourcePixels), + MemoryMarshal.Cast(destVectors)); } /// internal override void FromVector4( Configuration configuration, ReadOnlySpan sourceVectors, - Span destinationColors) + Span destPixels) { - Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - destinationColors = destinationColors.Slice(0, sourceVectors.Length); + destPixels = destPixels.Slice(0, sourceVectors.Length); SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( MemoryMarshal.Cast(sourceVectors), - MemoryMarshal.Cast(destinationColors)); + MemoryMarshal.Cast(destPixels)); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index cb12d944c..bffaf57dd 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -38,12 +38,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToVector4( Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) + ReadOnlySpan sourcePixels, + Span destVectors) { - Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - MemoryMarshal.Cast(sourceColors).CopyTo(destinationVectors); + MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index ad5aee8c7..3cebf7b54 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -26,17 +27,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// A to configure internal operations /// The to the source vectors. - /// The to the destination colors. + /// The to the destination colors. internal virtual void FromVector4( Configuration configuration, ReadOnlySpan sourceVectors, - Span destinationColors) + Span destPixels) { Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < sourceVectors.Length; i++) { @@ -50,20 +51,20 @@ namespace SixLabors.ImageSharp.PixelFormats /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// /// A to configure internal operations - /// The to the source colors. - /// The to the destination vectors. + /// The to the source colors. + /// The to the destination vectors. internal virtual void ToVector4( Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) + ReadOnlySpan sourcePixels, + Span destVectors) { Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); - for (int i = 0; i < sourceColors.Length; i++) + for (int i = 0; i < sourcePixels.Length; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); ref Vector4 dp = ref Unsafe.Add(ref destRef, i); @@ -178,5 +179,62 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromScaledVector4(sp.ToScaledVector4()); } } + + /// + /// Provides an efficient default implementation for and + /// which is applicable for -compatible pixel types where + /// returns the same scaled result as . + /// The method is works by internally converting to a therefore it's not applicable for that type! + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal void RunRgba32CompatibleToVector4Conversion( + Configuration configuration, + ReadOnlySpan sourcePixels, + Span destVectors) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); + + int count = sourcePixels.Length; + + using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) + { + Span tempSpan = tempBuffer.Memory.Span; + this.ToRgba32(configuration, sourcePixels, tempSpan); + + SimdUtils.BulkConvertByteToNormalizedFloat( + MemoryMarshal.Cast(tempSpan), + MemoryMarshal.Cast(destVectors)); + } + } + + /// + /// Provides an efficient default implementation for and + /// which is applicable for -compatible pixel types where + /// returns the same scaled result as . + /// The method is works by internally converting to a therefore it's not applicable for that type! + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal void RunRgba32CompatibleFromVector4Conversion( + Configuration configuration, + ReadOnlySpan sourceVectors, + Span destPixels) + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); + + int count = sourceVectors.Length; + + using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) + { + Span tempSpan = tempBuffer.Memory.Span; + + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( + MemoryMarshal.Cast(sourceVectors), + MemoryMarshal.Cast(tempSpan)); + + this.FromRgba32(configuration, tempSpan, destPixels); + } + } } } \ No newline at end of file From 145593b133251c61a41a8e500fa7d10861721b96 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 25 Oct 2018 02:43:02 +0200 Subject: [PATCH 088/238] run default implementation for small buffers --- .../PixelFormats/PixelOperations{TPixel}.cs | 63 +++++++++++++------ .../Color/Bulk/ToVector4.cs | 28 ++++++--- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 3cebf7b54..c3d8e23b9 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -36,15 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < sourceVectors.Length; i++) - { - ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.FromVector4(sp); - } + FromVector4DefaultImpl(sourceVectors, destPixels); } /// @@ -61,15 +53,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); - - for (int i = 0; i < sourcePixels.Length; i++) - { - ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref Vector4 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToVector4(); - } + ToVector4DefaultImpl(sourcePixels, destVectors); } /// @@ -135,6 +119,7 @@ namespace SixLabors.ImageSharp.PixelFormats Span destinationColors) where TDestinationPixel : struct, IPixel { + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceColors, destinationColors, nameof(destinationColors)); int count = sourceColors.Length; @@ -197,6 +182,13 @@ namespace SixLabors.ImageSharp.PixelFormats int count = sourcePixels.Length; + // Not worth for small buffers: + if (count < 128) + { + ToVector4DefaultImpl(sourcePixels, destVectors); + return; + } + using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) { Span tempSpan = tempBuffer.Memory.Span; @@ -225,6 +217,13 @@ namespace SixLabors.ImageSharp.PixelFormats int count = sourceVectors.Length; + // Not worth for small buffers: + if (count < 128) + { + FromVector4DefaultImpl(sourceVectors, destPixels); + return; + } + using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) { Span tempSpan = tempBuffer.Memory.Span; @@ -236,5 +235,33 @@ namespace SixLabors.ImageSharp.PixelFormats this.FromRgba32(configuration, tempSpan, destPixels); } } + + [MethodImpl(InliningOptions.ShortMethod)] + private static void FromVector4DefaultImpl(ReadOnlySpan sourceVectors, Span destPixels) + { + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < sourceVectors.Length; i++) + { + ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.FromVector4(sp); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + private static void ToVector4DefaultImpl(ReadOnlySpan sourcePixels, Span destVectors) + { + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); + + for (int i = 0; i < sourcePixels.Length; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Vector4 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToVector4(); + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index f0fee649a..897badd9f 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Params( 64, - //256, + 256, //512, //1024, 2048)] @@ -58,20 +58,25 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk d[i] = s[i].ToVector4(); } } + [Benchmark] - public void PixelOperations_Base() + public void PixelOperations_Specialized() { - new PixelOperations().ToVector4( + PixelOperations.Instance.ToVector4( this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); } + } - [Benchmark] - public void PixelOperations_Specialized() + [Config(typeof(Config.ShortClr))] + public class ToVector4_Bgra32 : ToVector4 + { + [Benchmark(Baseline = true)] + public void PixelOperations_Base() { - PixelOperations.Instance.ToVector4( + new PixelOperations().ToVector4( this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); @@ -89,7 +94,16 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(sBytes, dFloats); } - + + [Benchmark] + public void PixelOperations_Base() + { + new PixelOperations().ToVector4( + this.Configuration, + this.source.GetSpan(), + this.destination.GetSpan()); + } + [Benchmark(Baseline = true)] public void BasicIntrinsics256() { From 59d548cfd3d6d229fe32431ef1b4c07f4101ca36 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 14:30:11 +0200 Subject: [PATCH 089/238] fix Gray8.ToString() --- src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs index d23fda799..4ed5904c2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs @@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.PixelFormats public bool Equals(Gray8 other) => this.PackedValue.Equals(other.PackedValue); /// - public override string ToString() => $"Gray8({this.PackedValue}"; + public override string ToString() => $"Gray8({this.PackedValue})"; /// [MethodImpl(InliningOptions.ShortMethod)] From 143bbaa369d7f9915c40efda91dd4a88ec4a5b3f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 15:18:26 +0200 Subject: [PATCH 090/238] benchmakrs --- .../Color/Bulk/FromRgba32Bytes.cs | 28 ++- .../Color/Bulk/{ToXyz.cs => Rgb24Bytes.cs} | 4 +- .../Bulk/{ToXyzw.cs => ToRgba32Bytes.cs} | 16 +- .../Color/Bulk/ToVector4.cs | 169 +----------------- .../Color/Bulk/ToVector4_Bgra32.cs | 20 +++ .../Color/Bulk/ToVector4_Rgba32.cs | 164 +++++++++++++++++ .../PixelConversion_Rgba32_To_Bgra32.cs | 24 +-- 7 files changed, 232 insertions(+), 193 deletions(-) rename tests/ImageSharp.Benchmarks/Color/Bulk/{ToXyz.cs => Rgb24Bytes.cs} (94%) rename tests/ImageSharp.Benchmarks/Color/Bulk/{ToXyzw.cs => ToRgba32Bytes.cs} (87%) create mode 100644 tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs create mode 100644 tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs index 32565c23d..b96422176 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromRgba32Bytes.cs @@ -22,7 +22,10 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk private Configuration configuration; - [Params(16, 128, 1024)] + [Params( + 128, + 1024, + 2048)] public int Count { get; set; } [GlobalSetup] @@ -40,8 +43,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.source.Dispose(); } - [Benchmark(Baseline = true)] - public void PerElement() + //[Benchmark] + public void Naive() { Span s = this.source.GetSpan(); Span d = this.destination.GetSpan(); @@ -55,7 +58,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + [Benchmark(Baseline = true)] public void CommonBulk() { new PixelOperations().FromRgba32Bytes(this.configuration, this.source.GetSpan(), this.destination.GetSpan(), this.Count); @@ -68,7 +71,22 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - public class FromRgba32BytesRgba32 : FromRgba32Bytes + public class FromRgba32Bytes_ToRgba32 : FromRgba32Bytes + { + } + + public class FromRgba32Bytes_ToBgra32 : FromRgba32Bytes { + // RESULTS: + // Method | Count | Mean | Error | StdDev | Scaled | + // -------------- |------ |-----------:|----------:|----------:|-------:| + // CommonBulk | 128 | 207.1 ns | 3.723 ns | 3.300 ns | 1.00 | + // OptimizedBulk | 128 | 166.5 ns | 1.204 ns | 1.005 ns | 0.80 | + // | | | | | | + // CommonBulk | 1024 | 1,333.9 ns | 12.426 ns | 11.624 ns | 1.00 | + // OptimizedBulk | 1024 | 974.1 ns | 18.803 ns | 16.669 ns | 0.73 | + // | | | | | | + // CommonBulk | 2048 | 2,625.4 ns | 30.143 ns | 26.721 ns | 1.00 | + // OptimizedBulk | 2048 | 1,843.0 ns | 20.505 ns | 18.177 ns | 0.70 | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/Rgb24Bytes.cs similarity index 94% rename from tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs rename to tests/ImageSharp.Benchmarks/Color/Bulk/Rgb24Bytes.cs index 912c3e4b2..294baa9d5 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/Rgb24Bytes.cs @@ -10,7 +10,7 @@ using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { - public abstract class ToXyz + public abstract class Rgb24Bytes where TPixel : struct, IPixel { private IMemoryOwner source; @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.Count); } - public class ToXyz_Rgba32 : ToXyz + public class Rgb24Bytes_Rgba32 : Rgb24Bytes { } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToRgba32Bytes.cs similarity index 87% rename from tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs rename to tests/ImageSharp.Benchmarks/Color/Bulk/ToRgba32Bytes.cs index 37694f64c..7f4b2bc41 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToRgba32Bytes.cs @@ -12,7 +12,7 @@ using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { - public abstract class ToXyzw + public abstract class ToRgba32Bytes where TPixel : struct, IPixel { private IMemoryOwner source; @@ -39,8 +39,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.destination.Dispose(); } - [Benchmark(Baseline = true)] - public void PerElement() + //[Benchmark] + public void Naive() { Span s = this.source.GetSpan(); Span d = this.destination.GetSpan(); @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } } - [Benchmark] + [Benchmark(Baseline = true)] public void CommonBulk() => new PixelOperations().ToRgba32Bytes( this.configuration, @@ -75,11 +75,15 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.Count); } - public class ToXyzw_Rgba32 : ToXyzw + public class ToRgba32Bytes_FromRgba32 : ToRgba32Bytes + { + } + + public class ToRgba32Bytes_FromArgb32 : ToRgba32Bytes { } - public class ToXyzw_Argb32 : ToXyzw + public class ToRgba32Bytes_FromBgra32 : ToRgba32Bytes { } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 897badd9f..70de8f4e2 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -6,8 +6,6 @@ using System.Buffers; using System; using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; @@ -48,7 +46,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk } //[Benchmark] - public void PerElement() + public void Naive() { Span s = this.source.GetSpan(); Span d = this.destination.GetSpan(); @@ -69,169 +67,4 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.destination.GetSpan()); } } - - [Config(typeof(Config.ShortClr))] - public class ToVector4_Bgra32 : ToVector4 - { - [Benchmark(Baseline = true)] - public void PixelOperations_Base() - { - new PixelOperations().ToVector4( - this.Configuration, - this.source.GetSpan(), - this.destination.GetSpan()); - } - } - - [Config(typeof(Config.ShortClr))] - public class ToVector4_Rgba32 : ToVector4 - { - [Benchmark] - public void FallbackIntrinsics128() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(sBytes, dFloats); - } - - [Benchmark] - public void PixelOperations_Base() - { - new PixelOperations().ToVector4( - this.Configuration, - this.source.GetSpan(), - this.destination.GetSpan()); - } - - [Benchmark(Baseline = true)] - public void BasicIntrinsics256() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(sBytes, dFloats); - } - - [Benchmark] - public void ExtendedIntrinsics() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); - } - - //[Benchmark] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - int n = dFloats.Length / Vector.Count; - - ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); - ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); - ref Vector destBaseU = ref Unsafe.As, Vector>(ref destBase); - - for (int i = 0; i < n; i++) - { - Vector b = Unsafe.Add(ref sourceBase, i); - - Vector.Widen(b, out Vector s0, out Vector s1); - Vector.Widen(s0, out Vector w0, out Vector w1); - Vector.Widen(s1, out Vector w2, out Vector w3); - - ref Vector d = ref Unsafe.Add(ref destBaseU, i * 4); - d = w0; - Unsafe.Add(ref d, 1) = w1; - Unsafe.Add(ref d, 2) = w2; - Unsafe.Add(ref d, 3) = w3; - } - - n = dFloats.Length / Vector.Count; - var scale = new Vector(1f / 255f); - - for (int i = 0; i < n; i++) - { - ref Vector dRef = ref Unsafe.Add(ref destBase, i); - - Vector du = Vector.AsVectorInt32(dRef); - Vector v = Vector.ConvertToSingle(du); - v *= scale; - - dRef = v; - } - } - - //[Benchmark] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - int n = dFloats.Length / Vector.Count; - - ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); - ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); - var scale = new Vector(1f / 255f); - - for (int i = 0; i < n; i++) - { - Vector b = Unsafe.Add(ref sourceBase, i); - - Vector.Widen(b, out Vector s0, out Vector s1); - Vector.Widen(s0, out Vector w0, out Vector w1); - Vector.Widen(s1, out Vector w2, out Vector w3); - - Vector f0 = ConvertToNormalizedSingle(w0, scale); - Vector f1 = ConvertToNormalizedSingle(w1, scale); - Vector f2 = ConvertToNormalizedSingle(w2, scale); - Vector f3 = ConvertToNormalizedSingle(w3, scale); - - ref Vector d = ref Unsafe.Add(ref destBase, i * 4); - d = f0; - Unsafe.Add(ref d, 1) = f1; - Unsafe.Add(ref d, 2) = f2; - Unsafe.Add(ref d, 3) = f3; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector ConvertToNormalizedSingle(Vector u, Vector scale) - { - Vector vi = Vector.AsVectorInt32(u); - Vector v = Vector.ConvertToSingle(vi); - v *= scale; - return v; - } - - // RESULTS (2018 October): - // - // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ---------------------------- |-------- |------ |------------:|-------------:|------------:|-------:|---------:|-------:|----------:| - // FallbackIntrinsics128 | Clr | 64 | 287.62 ns | 6.026 ns | 0.3405 ns | 1.19 | 0.00 | - | 0 B | - // BasicIntrinsics256 | Clr | 64 | 240.83 ns | 10.585 ns | 0.5981 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics | Clr | 64 | 168.28 ns | 11.478 ns | 0.6485 ns | 0.70 | 0.00 | - | 0 B | - // PixelOperations_Base | Clr | 64 | 334.08 ns | 38.048 ns | 2.1498 ns | 1.39 | 0.01 | 0.0072 | 24 B | - // PixelOperations_Specialized | Clr | 64 | 255.41 ns | 10.939 ns | 0.6181 ns | 1.06 | 0.00 | - | 0 B | <--- ceremonial overhead has been minimized! - // | | | | | | | | | | - // FallbackIntrinsics128 | Core | 64 | 183.29 ns | 8.931 ns | 0.5046 ns | 1.32 | 0.00 | - | 0 B | - // BasicIntrinsics256 | Core | 64 | 139.18 ns | 7.633 ns | 0.4313 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics | Core | 64 | 66.29 ns | 16.366 ns | 0.9247 ns | 0.48 | 0.01 | - | 0 B | - // PixelOperations_Base | Core | 64 | 257.75 ns | 16.959 ns | 0.9582 ns | 1.85 | 0.01 | 0.0072 | 24 B | - // PixelOperations_Specialized | Core | 64 | 90.14 ns | 9.955 ns | 0.5625 ns | 0.65 | 0.00 | - | 0 B | - // | | | | | | | | | | - // FallbackIntrinsics128 | Clr | 2048 | 5,011.84 ns | 347.991 ns | 19.6621 ns | 1.22 | 0.01 | - | 0 B | - // BasicIntrinsics256 | Clr | 2048 | 4,119.35 ns | 720.153 ns | 40.6900 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics | Clr | 2048 | 1,195.29 ns | 164.389 ns | 9.2883 ns |!! 0.29 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! - // PixelOperations_Base | Clr | 2048 | 6,820.58 ns | 823.433 ns | 46.5255 ns | 1.66 | 0.02 | - | 24 B | - // PixelOperations_Specialized | Clr | 2048 | 4,203.53 ns | 176.714 ns | 9.9847 ns | 1.02 | 0.01 | - | 0 B | <--- can't yet detect whether ExtendedIntrinsics are available :( - // | | | | | | | | | | - // FallbackIntrinsics128 | Core | 2048 | 5,017.89 ns | 4,021.533 ns | 227.2241 ns | 1.24 | 0.05 | - | 0 B | - // BasicIntrinsics256 | Core | 2048 | 4,046.51 ns | 1,150.390 ns | 64.9992 ns | 1.00 | 0.00 | - | 0 B | - // ExtendedIntrinsics | Core | 2048 | 1,130.59 ns | 832.588 ns | 47.0427 ns |!! 0.28 | 0.01 | - | 0 B | <--- ExtendedIntrinsics rock! - // PixelOperations_Base | Core | 2048 | 6,752.68 ns | 272.820 ns | 15.4148 ns | 1.67 | 0.02 | - | 24 B | - // PixelOperations_Specialized | Core | 2048 | 1,126.13 ns | 79.192 ns | 4.4745 ns |!! 0.28 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! - } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs new file mode 100644 index 000000000..028bfe46f --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs @@ -0,0 +1,20 @@ +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk +{ + [Config(typeof(Config.ShortClr))] + public class ToVector4_Bgra32 : ToVector4 + { + [Benchmark(Baseline = true)] + public void PixelOperations_Base() + { + new PixelOperations().ToVector4( + this.Configuration, + this.source.GetSpan(), + this.destination.GetSpan()); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs new file mode 100644 index 000000000..ab05a1407 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs @@ -0,0 +1,164 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk +{ + [Config(typeof(Config.ShortClr))] + public class ToVector4_Rgba32 : ToVector4 + { + [Benchmark] + public void FallbackIntrinsics128() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.FallbackIntrinsics128.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + } + + [Benchmark] + public void PixelOperations_Base() + { + new PixelOperations().ToVector4( + this.Configuration, + this.source.GetSpan(), + this.destination.GetSpan()); + } + + [Benchmark(Baseline = true)] + public void BasicIntrinsics256() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.BasicIntrinsics256.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + } + + [Benchmark] + public void ExtendedIntrinsics() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + SimdUtils.ExtendedIntrinsics.BulkConvertByteToNormalizedFloat(sBytes, dFloats); + } + + //[Benchmark] + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + int n = dFloats.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); + ref Vector destBaseU = ref Unsafe.As, Vector>(ref destBase); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + ref Vector d = ref Unsafe.Add(ref destBaseU, i * 4); + d = w0; + Unsafe.Add(ref d, 1) = w1; + Unsafe.Add(ref d, 2) = w2; + Unsafe.Add(ref d, 3) = w3; + } + + n = dFloats.Length / Vector.Count; + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + ref Vector dRef = ref Unsafe.Add(ref destBase, i); + + Vector du = Vector.AsVectorInt32(dRef); + Vector v = Vector.ConvertToSingle(du); + v *= scale; + + dRef = v; + } + } + + //[Benchmark] + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_ConvertInSameLoop() + { + Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); + Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); + + int n = dFloats.Length / Vector.Count; + + ref Vector sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference((ReadOnlySpan)sBytes)); + ref Vector destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dFloats)); + var scale = new Vector(1f / 255f); + + for (int i = 0; i < n; i++) + { + Vector b = Unsafe.Add(ref sourceBase, i); + + Vector.Widen(b, out Vector s0, out Vector s1); + Vector.Widen(s0, out Vector w0, out Vector w1); + Vector.Widen(s1, out Vector w2, out Vector w3); + + Vector f0 = ConvertToNormalizedSingle(w0, scale); + Vector f1 = ConvertToNormalizedSingle(w1, scale); + Vector f2 = ConvertToNormalizedSingle(w2, scale); + Vector f3 = ConvertToNormalizedSingle(w3, scale); + + ref Vector d = ref Unsafe.Add(ref destBase, i * 4); + d = f0; + Unsafe.Add(ref d, 1) = f1; + Unsafe.Add(ref d, 2) = f2; + Unsafe.Add(ref d, 3) = f3; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector ConvertToNormalizedSingle(Vector u, Vector scale) + { + Vector vi = Vector.AsVectorInt32(u); + Vector v = Vector.ConvertToSingle(vi); + v *= scale; + return v; + } + + // RESULTS (2018 October): + // + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ---------------------------- |-------- |------ |------------:|-------------:|------------:|-------:|---------:|-------:|----------:| + // FallbackIntrinsics128 | Clr | 64 | 287.62 ns | 6.026 ns | 0.3405 ns | 1.19 | 0.00 | - | 0 B | + // BasicIntrinsics256 | Clr | 64 | 240.83 ns | 10.585 ns | 0.5981 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Clr | 64 | 168.28 ns | 11.478 ns | 0.6485 ns | 0.70 | 0.00 | - | 0 B | + // PixelOperations_Base | Clr | 64 | 334.08 ns | 38.048 ns | 2.1498 ns | 1.39 | 0.01 | 0.0072 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 255.41 ns | 10.939 ns | 0.6181 ns | 1.06 | 0.00 | - | 0 B | <--- ceremonial overhead has been minimized! + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 64 | 183.29 ns | 8.931 ns | 0.5046 ns | 1.32 | 0.00 | - | 0 B | + // BasicIntrinsics256 | Core | 64 | 139.18 ns | 7.633 ns | 0.4313 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Core | 64 | 66.29 ns | 16.366 ns | 0.9247 ns | 0.48 | 0.01 | - | 0 B | + // PixelOperations_Base | Core | 64 | 257.75 ns | 16.959 ns | 0.9582 ns | 1.85 | 0.01 | 0.0072 | 24 B | + // PixelOperations_Specialized | Core | 64 | 90.14 ns | 9.955 ns | 0.5625 ns | 0.65 | 0.00 | - | 0 B | + // | | | | | | | | | | + // FallbackIntrinsics128 | Clr | 2048 | 5,011.84 ns | 347.991 ns | 19.6621 ns | 1.22 | 0.01 | - | 0 B | + // BasicIntrinsics256 | Clr | 2048 | 4,119.35 ns | 720.153 ns | 40.6900 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Clr | 2048 | 1,195.29 ns | 164.389 ns | 9.2883 ns |!! 0.29 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Clr | 2048 | 6,820.58 ns | 823.433 ns | 46.5255 ns | 1.66 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Clr | 2048 | 4,203.53 ns | 176.714 ns | 9.9847 ns | 1.02 | 0.01 | - | 0 B | <--- can't yet detect whether ExtendedIntrinsics are available :( + // | | | | | | | | | | + // FallbackIntrinsics128 | Core | 2048 | 5,017.89 ns | 4,021.533 ns | 227.2241 ns | 1.24 | 0.05 | - | 0 B | + // BasicIntrinsics256 | Core | 2048 | 4,046.51 ns | 1,150.390 ns | 64.9992 ns | 1.00 | 0.00 | - | 0 B | + // ExtendedIntrinsics | Core | 2048 | 1,130.59 ns | 832.588 ns | 47.0427 ns |!! 0.28 | 0.01 | - | 0 B | <--- ExtendedIntrinsics rock! + // PixelOperations_Base | Core | 2048 | 6,752.68 ns | 272.820 ns | 15.4148 ns | 1.67 | 0.02 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 1,126.13 ns | 79.192 ns | 4.4745 ns |!! 0.28 | 0.00 | - | 0 B | <--- ExtendedIntrinsics rock! + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs index 9cf16ea19..a8fea6866 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs @@ -12,7 +12,7 @@ using SixLabors.ImageSharp.Tuples; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion { //[MonoJob] - [RyuJitX64Job] + //[RyuJitX64Job] public class PixelConversion_Rgba32_To_Bgra32 { private Rgba32[] source; @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion for (int i = 0; i < this.Count; i++) { - Rgba32 s = Unsafe.Add(ref sBase, i); + ref Rgba32 s = ref Unsafe.Add(ref sBase, i); Unsafe.Add(ref dBase, i).FromRgba32(s); } } @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion for (int i = 0; i < source.Length; i++) { - Rgba32 s = Unsafe.Add(ref sBase, i); + ref Rgba32 s = ref Unsafe.Add(ref sBase, i); Unsafe.Add(ref dBase, i).FromRgba32(s); } } @@ -379,14 +379,14 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion // RESULTS: - // Method | Count | Mean | Error | StdDev | Scaled | - // -------------------- |------ |----------:|----------:|----------:|-------:| - // Default | 64 | 106.84 ns | 0.4042 ns | 0.3583 ns | 1.00 | - // Default_Generic | 64 | 113.11 ns | 0.6998 ns | 0.6203 ns | 1.06 | - // Default_Group2 | 64 | 86.81 ns | 0.4976 ns | 0.4654 ns | 0.81 | - // Default_Group4 | 64 | 83.53 ns | 1.3826 ns | 1.2933 ns | 0.78 | - // BitOps | 64 | 54.23 ns | 0.1920 ns | 0.1796 ns | 0.51 | - // Bitops_Tuple | 64 | 73.45 ns | 0.5475 ns | 0.4853 ns | 0.69 | - // BitOps_GroupAsULong | 64 | 64.28 ns | 0.4046 ns | 0.3785 ns | 0.60 | + // Method | Count | Mean | Error | StdDev | Scaled | ScaledSD | + // -------------------- |------ |---------:|----------:|----------:|-------:|---------:| + // Default | 64 | 82.67 ns | 0.6737 ns | 0.5625 ns | 1.00 | 0.00 | + // Default_Generic | 64 | 88.73 ns | 1.7959 ns | 1.7638 ns | 1.07 | 0.02 | + // Default_Group2 | 64 | 91.03 ns | 1.5237 ns | 1.3508 ns | 1.10 | 0.02 | + // Default_Group4 | 64 | 86.62 ns | 1.5737 ns | 1.4720 ns | 1.05 | 0.02 | + // BitOps | 64 | 57.45 ns | 0.6067 ns | 0.5066 ns | 0.69 | 0.01 | + // Bitops_Tuple | 64 | 75.47 ns | 1.1824 ns | 1.1060 ns | 0.91 | 0.01 | + // BitOps_GroupAsULong | 64 | 65.42 ns | 0.7157 ns | 0.6695 ns | 0.79 | 0.01 | } } \ No newline at end of file From eb6665dfc3016135d46429e840334e498609c516 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 15:18:40 +0200 Subject: [PATCH 091/238] Vector4ConversionThreshold --- .../PixelFormats/PixelOperations{TPixel}.cs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index c3d8e23b9..668b2d031 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -17,6 +17,12 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations where TPixel : struct, IPixel { + /// + /// It's not worth to bother the transitive pixel conversion method below this limit. + /// The value depends on the actual gain brought by the SIMD characteristics of the executing CPU and JIT. + /// + private static readonly int Vector4ConversionThreshold = CalculateVector4ConversionThreshold(); + /// /// Gets the global instance for the pixel type /// @@ -183,7 +189,7 @@ namespace SixLabors.ImageSharp.PixelFormats int count = sourcePixels.Length; // Not worth for small buffers: - if (count < 128) + if (count < Vector4ConversionThreshold) { ToVector4DefaultImpl(sourcePixels, destVectors); return; @@ -218,7 +224,7 @@ namespace SixLabors.ImageSharp.PixelFormats int count = sourceVectors.Length; // Not worth for small buffers: - if (count < 128) + if (count < Vector4ConversionThreshold) { FromVector4DefaultImpl(sourceVectors, destPixels); return; @@ -263,5 +269,15 @@ namespace SixLabors.ImageSharp.PixelFormats dp = sp.ToVector4(); } } + + private static int CalculateVector4ConversionThreshold() + { + if (!Vector.IsHardwareAccelerated) + { + return int.MaxValue; + } + + return SimdUtils.ExtendedIntrinsics.IsAvailable && SimdUtils.IsAvx2CompatibleArchitecture ? 256 : 128; + } } } \ No newline at end of file From 62da375f6391c06c3d3f73fc094f0be2fe05f946 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 15:51:53 +0200 Subject: [PATCH 092/238] avoid allocation in RunRgba32CompatibleToVector4Conversion --- .../PixelFormats/PixelOperations{TPixel}.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 668b2d031..9238e1b47 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -171,6 +171,8 @@ namespace SixLabors.ImageSharp.PixelFormats } } + // TODO: The Vector4 helpers should be moved to a utility class. + /// /// Provides an efficient default implementation for and /// which is applicable for -compatible pixel types where @@ -195,15 +197,19 @@ namespace SixLabors.ImageSharp.PixelFormats return; } - using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) - { - Span tempSpan = tempBuffer.Memory.Span; - this.ToRgba32(configuration, sourcePixels, tempSpan); + // Using the last quarter of 'destVectors' as a temporary buffer to avoid allocation: + int countWithoutLastItem = count - 1; + ReadOnlySpan reducedSource = sourcePixels.Slice(0, countWithoutLastItem); + Span lastQuarterOfDestBuffer = MemoryMarshal.Cast(destVectors).Slice((3 * count) + 1, countWithoutLastItem); + this.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer); - SimdUtils.BulkConvertByteToNormalizedFloat( - MemoryMarshal.Cast(tempSpan), - MemoryMarshal.Cast(destVectors)); - } + // 'destVectors' and 'lastQuarterOfDestBuffer' are ovelapping buffers, + // but we are always reading/writing at different positions: + SimdUtils.BulkConvertByteToNormalizedFloat( + MemoryMarshal.Cast(lastQuarterOfDestBuffer), + MemoryMarshal.Cast(destVectors.Slice(0, countWithoutLastItem))); + + destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4(); } /// @@ -230,6 +236,8 @@ namespace SixLabors.ImageSharp.PixelFormats return; } + // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion, + // so let's allocate a temporary buffer as usually: using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) { Span tempSpan = tempBuffer.Memory.Span; From 437d080180b2ee641d076223d6775e384360e016 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 16:35:02 +0200 Subject: [PATCH 093/238] refactor Vector4 implementation code from PixelOperation to Vector4Converters --- .../Argb32.PixelOperations.Generated.cs | 9 +- .../Bgr24.PixelOperations.Generated.cs | 9 +- .../Bgra32.PixelOperations.Generated.cs | 9 +- .../Gray16.PixelOperations.Generated.cs | 1 + .../Gray8.PixelOperations.Generated.cs | 1 + .../Rgb24.PixelOperations.Generated.cs | 9 +- .../Rgb48.PixelOperations.Generated.cs | 1 + .../Rgba32.PixelOperations.Generated.cs | 1 + .../Rgba64.PixelOperations.Generated.cs | 1 + .../Generated/_Common.ttinclude | 9 +- .../PixelFormats/PixelOperations{TPixel}.cs | 147 +---------------- .../{ => Utils}/PixelConverter.cs | 3 +- .../{ => Utils}/PixelExtensions.cs | 2 +- .../Utils/Vector4Converters.Default.cs | 89 ++++++++++ .../Utils/Vector4Converters.RgbaCompatible.cs | 154 ++++++++++++++++++ .../Color/Bulk/ToVector4_Bgra32.cs | 21 +++ .../PixelConversion_ConvertFromRgba32.cs | 1 + .../PixelFormats/PixelConverterTests.cs | 1 + 18 files changed, 302 insertions(+), 166 deletions(-) rename src/ImageSharp/PixelFormats/{ => Utils}/PixelConverter.cs (98%) rename src/ImageSharp/PixelFormats/{ => Utils}/PixelExtensions.cs (93%) create mode 100644 src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs create mode 100644 src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index e6b8922e9..6449351cc 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; @@ -45,25 +46,25 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } /// internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } /// internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 9b1740013..9232cf454 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; @@ -45,25 +46,25 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } /// internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } /// internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 37d6b72d7..4f56b75c5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; @@ -45,25 +46,25 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } /// internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } /// internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index 638db1d0d..81882185d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index 6bf0693c2..f6678a4f8 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 6ff87eb38..aae8b2f63 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; @@ -45,25 +46,25 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } /// internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } /// internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index 9b4584d76..c828053a4 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index 8e15ca1f4..9c29bd044 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index caaba7809..db9cb84be 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -3,6 +3,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index 4501f4972..cc8cb0e2f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -8,6 +8,7 @@ // +using SixLabors.ImageSharp.PixelFormats.Utils; using System; using System.Buffers; using System.Numerics; @@ -114,25 +115,25 @@ using System.Runtime.InteropServices; /// internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } /// internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) { - this.RunRgba32CompatibleFromVector4Conversion(configuration, sourceVectors, destPixels); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } /// internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) { - this.RunRgba32CompatibleToVector4Conversion(configuration, sourcePixels, destVectors); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); } <#+ diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 9238e1b47..f4eb19be3 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -17,12 +17,6 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations where TPixel : struct, IPixel { - /// - /// It's not worth to bother the transitive pixel conversion method below this limit. - /// The value depends on the actual gain brought by the SIMD characteristics of the executing CPU and JIT. - /// - private static readonly int Vector4ConversionThreshold = CalculateVector4ConversionThreshold(); - /// /// Gets the global instance for the pixel type /// @@ -42,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - FromVector4DefaultImpl(sourceVectors, destPixels); + Utils.Vector4Converters.Default.DangerousFromVector4(sourceVectors, destPixels); } /// @@ -59,7 +53,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - ToVector4DefaultImpl(sourcePixels, destVectors); + Utils.Vector4Converters.Default.DangerousToVector4(sourcePixels, destVectors); } /// @@ -76,15 +70,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); - - for (int i = 0; i < sourceVectors.Length; i++) - { - ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.FromScaledVector4(sp); - } + Utils.Vector4Converters.Default.DangerousFromScaledVector4(sourceVectors, destinationColors); } /// @@ -101,15 +87,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); - - for (int i = 0; i < sourceColors.Length; i++) - { - ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref Vector4 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToScaledVector4(); - } + Utils.Vector4Converters.Default.DangerousToScaledVector4(sourceColors, destinationVectors); } /// @@ -170,122 +148,5 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromScaledVector4(sp.ToScaledVector4()); } } - - // TODO: The Vector4 helpers should be moved to a utility class. - - /// - /// Provides an efficient default implementation for and - /// which is applicable for -compatible pixel types where - /// returns the same scaled result as . - /// The method is works by internally converting to a therefore it's not applicable for that type! - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal void RunRgba32CompatibleToVector4Conversion( - Configuration configuration, - ReadOnlySpan sourcePixels, - Span destVectors) - { - Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - - int count = sourcePixels.Length; - - // Not worth for small buffers: - if (count < Vector4ConversionThreshold) - { - ToVector4DefaultImpl(sourcePixels, destVectors); - return; - } - - // Using the last quarter of 'destVectors' as a temporary buffer to avoid allocation: - int countWithoutLastItem = count - 1; - ReadOnlySpan reducedSource = sourcePixels.Slice(0, countWithoutLastItem); - Span lastQuarterOfDestBuffer = MemoryMarshal.Cast(destVectors).Slice((3 * count) + 1, countWithoutLastItem); - this.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer); - - // 'destVectors' and 'lastQuarterOfDestBuffer' are ovelapping buffers, - // but we are always reading/writing at different positions: - SimdUtils.BulkConvertByteToNormalizedFloat( - MemoryMarshal.Cast(lastQuarterOfDestBuffer), - MemoryMarshal.Cast(destVectors.Slice(0, countWithoutLastItem))); - - destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4(); - } - - /// - /// Provides an efficient default implementation for and - /// which is applicable for -compatible pixel types where - /// returns the same scaled result as . - /// The method is works by internally converting to a therefore it's not applicable for that type! - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal void RunRgba32CompatibleFromVector4Conversion( - Configuration configuration, - ReadOnlySpan sourceVectors, - Span destPixels) - { - Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - - int count = sourceVectors.Length; - - // Not worth for small buffers: - if (count < Vector4ConversionThreshold) - { - FromVector4DefaultImpl(sourceVectors, destPixels); - return; - } - - // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion, - // so let's allocate a temporary buffer as usually: - using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) - { - Span tempSpan = tempBuffer.Memory.Span; - - SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( - MemoryMarshal.Cast(sourceVectors), - MemoryMarshal.Cast(tempSpan)); - - this.FromRgba32(configuration, tempSpan, destPixels); - } - } - - [MethodImpl(InliningOptions.ShortMethod)] - private static void FromVector4DefaultImpl(ReadOnlySpan sourceVectors, Span destPixels) - { - ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < sourceVectors.Length; i++) - { - ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.FromVector4(sp); - } - } - - [MethodImpl(InliningOptions.ShortMethod)] - private static void ToVector4DefaultImpl(ReadOnlySpan sourcePixels, Span destVectors) - { - ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); - - for (int i = 0; i < sourcePixels.Length; i++) - { - ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); - ref Vector4 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.ToVector4(); - } - } - - private static int CalculateVector4ConversionThreshold() - { - if (!Vector.IsHardwareAccelerated) - { - return int.MaxValue; - } - - return SimdUtils.ExtendedIntrinsics.IsAvailable && SimdUtils.IsAvx2CompatibleArchitecture ? 256 : 128; - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelConverter.cs b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs similarity index 98% rename from src/ImageSharp/PixelFormats/PixelConverter.cs rename to src/ImageSharp/PixelFormats/Utils/PixelConverter.cs index 8fde490fd..2336dbee7 100644 --- a/src/ImageSharp/PixelFormats/PixelConverter.cs +++ b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs @@ -1,11 +1,10 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Buffers.Binary; using System.Runtime.CompilerServices; -namespace SixLabors.ImageSharp.PixelFormats +namespace SixLabors.ImageSharp.PixelFormats.Utils { /// /// Contains optimized implementations for conversion between pixel formats. diff --git a/src/ImageSharp/PixelFormats/PixelExtensions.cs b/src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs similarity index 93% rename from src/ImageSharp/PixelFormats/PixelExtensions.cs rename to src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs index 175696ab6..2284b8fc2 100644 --- a/src/ImageSharp/PixelFormats/PixelExtensions.cs +++ b/src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -namespace SixLabors.ImageSharp.PixelFormats +namespace SixLabors.ImageSharp.PixelFormats.Utils { /// /// Low-performance extension methods to help conversion syntax, suitable for testing purposes. diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs new file mode 100644 index 000000000..139dbfa10 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs @@ -0,0 +1,89 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp.PixelFormats.Utils +{ + /// + /// Helper class for (bulk) conversion of buffers to/from other buffer types. + /// + internal static partial class Vector4Converters + { + /// + /// Provides default implementations for batched to/from conversion. + /// WARNING: The methods are operating without bounds checking and input validation! + /// Input validation is the responsibility of the caller! + /// + public static class Default + { + [MethodImpl(InliningOptions.ShortMethod)] + internal static void DangerousFromVector4( + ReadOnlySpan sourceVectors, + Span destPixels) + where TPixel : struct, IPixel + { + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < sourceVectors.Length; i++) + { + ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.FromVector4(sp); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void DangerousToVector4( + ReadOnlySpan sourcePixels, + Span destVectors) + where TPixel : struct, IPixel + { + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destVectors); + + for (int i = 0; i < sourcePixels.Length; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Vector4 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToVector4(); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void DangerousFromScaledVector4( + ReadOnlySpan sourceVectors, + Span destinationColors) + where TPixel : struct, IPixel + { + ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); + + for (int i = 0; i < sourceVectors.Length; i++) + { + ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.FromScaledVector4(sp); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void DangerousToScaledVector4( + ReadOnlySpan sourceColors, + Span destinationVectors) + where TPixel : struct, IPixel + { + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors); + + for (int i = 0; i < sourceColors.Length; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Vector4 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToScaledVector4(); + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs new file mode 100644 index 000000000..7c57fe4fb --- /dev/null +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -0,0 +1,154 @@ +using System; +using System.Buffers; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp.PixelFormats.Utils +{ + /// + /// Contains + /// + internal static partial class Vector4Converters + { + /// + /// Provides efficient implementations for batched to/from conversion. + /// which is applicable for -compatible pixel types where + /// returns the same scaled result as . + /// The method is works by internally converting to a therefore it's not applicable for that type! + /// + public static class RgbaCompatible + { + /// + /// It's not worth to bother the transitive pixel conversion method below this limit. + /// The value depends on the actual gain brought by the SIMD characteristics of the executing CPU and JIT. + /// + private static readonly int Vector4ConversionThreshold = CalculateVector4ConversionThreshold(); + + /// + /// Provides an efficient default implementation for + /// and + /// which is applicable for -compatible pixel types where + /// returns the same scaled result as . + /// The method is works by internally converting to a therefore it's not applicable for that type! + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal static void ToVector4( + Configuration configuration, + PixelOperations pixelOperations, + ReadOnlySpan sourcePixels, + Span destVectors, + bool scaled) + where TPixel : struct, IPixel + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); + + int count = sourcePixels.Length; + + // Not worth for small buffers: + if (count < Vector4ConversionThreshold) + { + ToVector4Fallback(sourcePixels, destVectors, scaled); + + return; + } + + // Using the last quarter of 'destVectors' as a temporary buffer to avoid allocation: + int countWithoutLastItem = count - 1; + ReadOnlySpan reducedSource = sourcePixels.Slice(0, countWithoutLastItem); + Span lastQuarterOfDestBuffer = MemoryMarshal.Cast(destVectors).Slice((3 * count) + 1, countWithoutLastItem); + pixelOperations.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer); + + // 'destVectors' and 'lastQuarterOfDestBuffer' are ovelapping buffers, + // but we are always reading/writing at different positions: + SimdUtils.BulkConvertByteToNormalizedFloat( + MemoryMarshal.Cast(lastQuarterOfDestBuffer), + MemoryMarshal.Cast(destVectors.Slice(0, countWithoutLastItem))); + + destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4(); + } + + /// + /// Provides an efficient default implementation for + /// and + /// which is applicable for -compatible pixel types where + /// returns the same scaled result as . + /// The method is works by internally converting to a therefore it's not applicable for that type! + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal static void FromVector4( + Configuration configuration, + PixelOperations pixelOperations, + ReadOnlySpan sourceVectors, + Span destPixels, + bool scaled) + where TPixel : struct, IPixel + { + Guard.NotNull(configuration, nameof(configuration)); + Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); + + int count = sourceVectors.Length; + + // Not worth for small buffers: + if (count < Vector4ConversionThreshold) + { + FromVector4Fallback(sourceVectors, destPixels, scaled); + + return; + } + + // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion, + // so let's allocate a temporary buffer as usually: + using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) + { + Span tempSpan = tempBuffer.Memory.Span; + + SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( + MemoryMarshal.Cast(sourceVectors), + MemoryMarshal.Cast(tempSpan)); + + pixelOperations.FromRgba32(configuration, tempSpan, destPixels); + } + } + + [MethodImpl(InliningOptions.ColdPath)] + private static void ToVector4Fallback(ReadOnlySpan sourcePixels, Span destVectors, bool scaled) + where TPixel : struct, IPixel + { + if (scaled) + { + Default.DangerousToScaledVector4(sourcePixels, destVectors); + } + else + { + Default.DangerousToVector4(sourcePixels, destVectors); + } + } + + [MethodImpl(InliningOptions.ColdPath)] + private static void FromVector4Fallback(ReadOnlySpan sourceVectors, Span destPixels, bool scaled) + where TPixel : struct, IPixel + { + if (scaled) + { + Default.DangerousFromScaledVector4(sourceVectors, destPixels); + } + else + { + Default.DangerousFromVector4(sourceVectors, destPixels); + } + } + + private static int CalculateVector4ConversionThreshold() + { + if (!Vector.IsHardwareAccelerated) + { + return int.MaxValue; + } + + return SimdUtils.ExtendedIntrinsics.IsAvailable && SimdUtils.IsAvx2CompatibleArchitecture ? 256 : 128; + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs index 028bfe46f..39702d525 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Bgra32.cs @@ -16,5 +16,26 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk this.source.GetSpan(), this.destination.GetSpan()); } + + // RESULTS: + // Method | Runtime | Count | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ---------------------------- |-------- |------ |-----------:|------------:|-----------:|-------:|---------:|-------:|----------:| + // PixelOperations_Base | Clr | 64 | 339.9 ns | 138.30 ns | 7.8144 ns | 1.00 | 0.00 | 0.0072 | 24 B | + // PixelOperations_Specialized | Clr | 64 | 338.1 ns | 13.30 ns | 0.7515 ns | 0.99 | 0.02 | - | 0 B | + // | | | | | | | | | | + // PixelOperations_Base | Core | 64 | 245.6 ns | 29.05 ns | 1.6413 ns | 1.00 | 0.00 | 0.0072 | 24 B | + // PixelOperations_Specialized | Core | 64 | 257.1 ns | 37.89 ns | 2.1407 ns | 1.05 | 0.01 | - | 0 B | + // | | | | | | | | | | + // PixelOperations_Base | Clr | 256 | 972.7 ns | 61.98 ns | 3.5020 ns | 1.00 | 0.00 | 0.0057 | 24 B | + // PixelOperations_Specialized | Clr | 256 | 882.9 ns | 126.21 ns | 7.1312 ns | 0.91 | 0.01 | - | 0 B | + // | | | | | | | | | | + // PixelOperations_Base | Core | 256 | 910.0 ns | 90.87 ns | 5.1346 ns | 1.00 | 0.00 | 0.0067 | 24 B | + // PixelOperations_Specialized | Core | 256 | 448.4 ns | 15.77 ns | 0.8910 ns | 0.49 | 0.00 | - | 0 B | + // | | | | | | | | | | + // PixelOperations_Base | Clr | 2048 | 6,951.8 ns | 1,299.01 ns | 73.3963 ns | 1.00 | 0.00 | - | 24 B | + // PixelOperations_Specialized | Clr | 2048 | 5,852.3 ns | 630.56 ns | 35.6279 ns | 0.84 | 0.01 | - | 0 B | + // | | | | | | | | | | + // PixelOperations_Base | Core | 2048 | 6,937.5 ns | 1,692.19 ns | 95.6121 ns | 1.00 | 0.00 | - | 24 B | + // PixelOperations_Specialized | Core | 2048 | 2,994.5 ns | 1,126.65 ns | 63.6578 ns | 0.43 | 0.01 | - | 0 B | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index 424020e2f..9f1b2721b 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -7,6 +7,7 @@ using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.PixelFormats.Utils; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion { diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs index 9b32f7aee..c539e9dcf 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs @@ -1,4 +1,5 @@ using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.PixelFormats.Utils; using Xunit; From 3b59b9ac2ce3de68ae022c29a473206f83b8beb1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 19:43:00 +0200 Subject: [PATCH 094/238] better docs, drop PixelExtensions, fix tests --- .../PixelFormats/Utils/PixelConverter.cs | 12 +++++----- .../PixelFormats/Utils/PixelExtensions.cs | 22 ------------------- .../Drawing/FillLinearGradientBrushTests.cs | 4 +++- .../PixelFormats/Alpha8Tests.cs | 3 ++- .../PixelFormats/Gray16Tests.cs | 3 ++- .../PixelFormats/Gray8Tests.cs | 5 +++-- .../PixelFormats/Rgb24Tests.cs | 3 ++- .../PixelFormats/Rgb48Tests.cs | 3 ++- .../PixelFormats/Rgba1010102Tests.cs | 3 ++- .../PixelFormats/Rgba64Tests.cs | 2 +- .../PixelFormats/Short2Tests.cs | 4 ++-- .../PixelFormats/Short4Tests.cs | 12 ++++++---- .../PixelFormats/UnPackedPixelTests.cs | 6 +++-- .../Quantization/QuantizedImageTests.cs | 3 ++- .../TestUtilities/TestUtils.cs | 7 ++++-- .../Tests/TestImageProviderTests.cs | 3 ++- 16 files changed, 47 insertions(+), 48 deletions(-) delete mode 100644 src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs diff --git a/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs index 2336dbee7..55a94fc81 100644 --- a/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs +++ b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs @@ -12,7 +12,9 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils /// /// Implementations are based on ideas in: /// https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs#L84 - /// The JIT should be able to detect and optimize ROL and ROR patterns. + /// The JIT can detect and optimize rotation idioms ROTL (Rotate Left) + /// and ROTR (Rotate Right) emitting efficient CPU instructions: + /// https://github.com/dotnet/coreclr/pull/1830 /// internal static class PixelConverter { @@ -25,7 +27,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils public static uint ToArgb32(uint packedRgba) { // packedRgba = [aa bb gg rr] - // ROL(8, packedRgba) = [bb gg rr aa] + // ROTL(8, packedRgba) = [bb gg rr aa] return (packedRgba << 8) | (packedRgba >> 24); } @@ -38,7 +40,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // packedRgba = [aa bb gg rr] // tmp1 = [aa 00 gg 00] // tmp2 = [00 bb 00 rr] - // tmp3=ROL(16, tmp2) = [00 rr 00 bb] + // tmp3=ROTL(16, tmp2) = [00 rr 00 bb] // tmp1 + tmp3 = [aa rr gg bb] uint tmp1 = packedRgba & 0xFF00FF00; uint tmp2 = packedRgba & 0x00FF00FF; @@ -56,7 +58,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils public static uint ToRgba32(uint packedArgb) { // packedArgb = [bb gg rr aa] - // ROR(8, packedArgb) = [aa bb gg rr] + // ROTR(8, packedArgb) = [aa bb gg rr] return (packedArgb >> 8) | (packedArgb << 24); } @@ -94,7 +96,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // packedRgba = [aa rr gg bb] // tmp1 = [aa 00 gg 00] // tmp2 = [00 rr 00 bb] - // tmp3=ROL(16, tmp2) = [00 bb 00 rr] + // tmp3=ROTL(16, tmp2) = [00 bb 00 rr] // tmp1 + tmp3 = [aa bb gg rr] uint tmp1 = packedBgra & 0xFF00FF00; uint tmp2 = packedBgra & 0x00FF00FF; diff --git a/src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs b/src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs deleted file mode 100644 index 2284b8fc2..000000000 --- a/src/ImageSharp/PixelFormats/Utils/PixelExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.PixelFormats.Utils -{ - /// - /// Low-performance extension methods to help conversion syntax, suitable for testing purposes. - /// - internal static class PixelExtensions - { - /// - /// Returns the result of as a new instance. - /// - public static Rgba32 ToRgba32(this TPixel pixel) - where TPixel : struct, IPixel - { - Rgba32 result = default; - pixel.ToRgba32(ref result); - return result; - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs index 9121649f4..556ec9c9c 100644 --- a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs +++ b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs @@ -328,7 +328,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing TPixel color = colors[stopColorCodes[i % colors.Length]]; float position = stopPositions[i]; colorStops[i] = new ColorStop(position, color); - coloringVariant.AppendFormat(CultureInfo.InvariantCulture, "{0}@{1};", color.ToRgba32().ToHex(), position); + Rgba32 rgba = default; + color.ToRgba32(ref rgba); + coloringVariant.AppendFormat(CultureInfo.InvariantCulture, "{0}@{1};", rgba.ToHex(), position); } FormattableString variant = $"({startX},{startY})_TO_({endX},{endY})__[{coloringVariant}]"; diff --git a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs index 148b928fa..8f68c9d03 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Alpha8Tests.cs @@ -90,7 +90,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var input = new Alpha8(128); var expected = new Rgba32(0, 0, 0, 128); - var actual = input.ToRgba32(); + Rgba32 actual = default; + input.ToRgba32(ref actual); Assert.Equal(expected, actual); } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs index 220ca2899..cb19c031d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray16Tests.cs @@ -117,7 +117,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var gray = new Gray16(input); // Act - var actual = gray.ToRgba32(); + Rgba32 actual = default; + gray.ToRgba32(ref actual); // Assert Assert.Equal(expected, actual.R); diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index 988002c09..6a7b20cbe 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -115,10 +115,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var gray = new Gray8(input); // Act - var actual = gray.ToRgba32(); + Rgba32 actual = default; + gray.ToRgba32(ref actual); // Assert - Assert.Equal(input, actual.R); + Assert.Equal(input, actual.R); Assert.Equal(input, actual.G); Assert.Equal(input, actual.B); Assert.Equal(byte.MaxValue, actual.A); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index a60509146..92e8d302d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -104,7 +104,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToRgba32() { var rgb = new Rgb24(1, 2, 3); - var rgba = rgb.ToRgba32(); + Rgba32 rgba = default; + rgb.ToRgba32(ref rgba); Assert.Equal(new Rgba32(1, 2, 3, 255), rgba); } diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs index a7f0e5edf..d30e49860 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb48Tests.cs @@ -52,7 +52,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(20, 38, 76, 255); // act - var actual = rgba48.ToRgba32(); + Rgba32 actual = default; + rgba48.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs index ad7df3076..a897dd4cd 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba1010102Tests.cs @@ -79,7 +79,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(25, 0, 128, 0); // act - var actual = rgba.ToRgba32(); + Rgba32 actual = default; + rgba.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs index 564c26b8b..3e5d7a56e 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba64Tests.cs @@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(20, 38, 76, 115); // act - actual = rgba64.ToRgba32(); + rgba64.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs index 725e1a0d1..c9a3b33c9 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short2Tests.cs @@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(128, 127, 0, 255); // act - actual = short2.ToRgba32(); + short2.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short2.FromRgba32(expected); - actual = short2.ToRgba32(); + short2.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs index b19917f34..247342a05 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Short4Tests.cs @@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats var expected = new Rgba32(172, 177, 243, 128); // act - actual = shortValue.ToRgba32(); + shortValue.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.FromRgba32(expected); - actual = short4.ToRgba32(); + short4.ToRgba32(ref actual); // assert Assert.Equal(expected, actual); @@ -124,7 +124,9 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.FromBgra32(expected); - actual.FromRgba32(short4.ToRgba32()); + Rgba32 temp = default; + short4.ToRgba32(ref temp); + actual.FromRgba32(temp); // assert Assert.Equal(expected, actual); @@ -140,7 +142,9 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats // act short4.FromArgb32(expected); - actual.FromRgba32(short4.ToRgba32()); + Rgba32 temp = default; + short4.ToRgba32(ref temp); + actual.FromRgba32(temp); // assert Assert.Equal(expected, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs index 29c97ce35..bd8c64742 100644 --- a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs @@ -84,8 +84,10 @@ namespace SixLabors.ImageSharp.Tests.Colors var color = new Rgba32(24, 48, 96, 192); var colorVector = new RgbaVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); - var rgba = color.ToRgba32(); - var rgbaVector = colorVector.ToRgba32(); + Rgba32 rgba = default; + Rgba32 rgbaVector = default; + color.ToRgba32(ref rgba); + colorVector.ToRgba32(ref rgbaVector); Assert.Equal(rgba, rgbaVector); } diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index fa855aef7..577dc83c5 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -106,9 +106,10 @@ namespace SixLabors.ImageSharp.Tests { // Transparent pixels are much more likely to be found at the end of a palette int index = -1; + Rgba32 trans = default; for (int i = quantized.Palette.Length - 1; i >= 0; i--) { - var trans = quantized.Palette[i].ToRgba32(); + quantized.Palette[i].ToRgba32(ref trans); if (trans.Equals(default)) { diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index e6a5ffc84..d7755ff7a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -80,8 +80,11 @@ namespace SixLabors.ImageSharp.Tests } else { - rgb1 = ca.ToRgba32().Rgb; - rgb2 = cb.ToRgba32().Rgb; + Rgba32 rgba = default; + ca.ToRgba32(ref rgba); + rgb1 = rgba.Rgb; + cb.ToRgba32(ref rgba); + rgb2 = rgba.Rgb; if (!rgb1.Equals(rgb2)) { diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 1d284af15..a8140e39d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -275,11 +275,12 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(20, img.Height); Buffer2D pixels = img.GetRootFramePixelBuffer(); + Rgba32 rgba = default; for (int y = 0; y < pixels.Height; y++) { for (int x = 0; x < pixels.Width; x++) { - var rgba = pixels[x, y].ToRgba32(); + pixels[x, y].ToRgba32(ref rgba); Assert.Equal(255, rgba.R); Assert.Equal(100, rgba.G); From 9e292fbeb72ad3a5c5103c76fa7a61a6302277ad Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 20:04:19 +0200 Subject: [PATCH 095/238] refactor PixelOperationsTests --- tests/ImageSharp.Tests/ConfigurationTests.cs | 1 + .../ImageSharp.Tests/GraphicsOptionsTests.cs | 21 + ...elOperationsTests.Argb32OperationsTests.cs | 22 + ...xelOperationsTests.Bgr24OperationsTests.cs | 21 + ...elOperationsTests.Bgra32OperationsTests.cs | 21 + ...elOperationsTests.Gray16OperationsTests.cs | 111 +++++ ...xelOperationsTests.Gray8OperationsTests.cs | 111 +++++ ...xelOperationsTests.Rgb48OperationsTests.cs | 21 + ...elOperationsTests.Rgba32OperationsTests.cs | 43 ++ ...elOperationsTests.Rgba64OperationsTests.cs | 21 + ...erationsTests.RgbaVectorOperationsTests.cs | 21 + .../PixelOperationsTests.cs | 394 +++--------------- 12 files changed, 476 insertions(+), 332 deletions(-) create mode 100644 tests/ImageSharp.Tests/GraphicsOptionsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs rename tests/ImageSharp.Tests/PixelFormats/{ => PixelOperations}/PixelOperationsTests.cs (63%) diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 963d67446..208387e6d 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Moq; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.IO; + using Xunit; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/GraphicsOptionsTests.cs b/tests/ImageSharp.Tests/GraphicsOptionsTests.cs new file mode 100644 index 000000000..6ff38626d --- /dev/null +++ b/tests/ImageSharp.Tests/GraphicsOptionsTests.cs @@ -0,0 +1,21 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests +{ + public class GraphicsOptionsTests + { + [Fact] + public void IsOpaqueColor() + { + Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Transparent)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs new file mode 100644 index 000000000..875ba0cba --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs @@ -0,0 +1,22 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Argb32OperationsTests : PixelOperationsTests + { + + public Argb32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs new file mode 100644 index 000000000..879712a3e --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs @@ -0,0 +1,21 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Bgr24OperationsTests : PixelOperationsTests + { + public Bgr24OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs new file mode 100644 index 000000000..963a9dae6 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs @@ -0,0 +1,21 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Bgra32OperationsTests : PixelOperationsTests + { + public Bgra32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs new file mode 100644 index 000000000..1afa65240 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs @@ -0,0 +1,111 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Gray16OperationsTests : PixelOperationsTests + { + public Gray16OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + expected[i].FromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.FromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.FromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs new file mode 100644 index 000000000..4112d201b --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs @@ -0,0 +1,111 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Gray8OperationsTests : PixelOperationsTests + { + public Gray8OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + expected[i].FromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.FromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.FromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) + ); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs new file mode 100644 index 000000000..68b67fce2 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs @@ -0,0 +1,21 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Rgb48OperationsTests : PixelOperationsTests + { + public Rgb48OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs new file mode 100644 index 000000000..38cc97893 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs @@ -0,0 +1,43 @@ +using System.Buffers; +using System.Numerics; + +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Rgba32OperationsTests : PixelOperationsTests + { + public Rgba32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Fact(Skip = SkipProfilingBenchmarks)] + public void Benchmark_ToVector4() + { + const int times = 200000; + const int count = 1024; + + using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) + using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) + { + this.Measure( + times, + () => PixelOperations.Instance.ToVector4( + this.Configuration, + source.GetSpan(), + dest.GetSpan())); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs new file mode 100644 index 000000000..47738ac60 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs @@ -0,0 +1,21 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Rgba64OperationsTests : PixelOperationsTests + { + public Rgba64OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs new file mode 100644 index 000000000..7272dfb78 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs @@ -0,0 +1,21 @@ +using SixLabors.ImageSharp.PixelFormats; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class RgbaVectorOperationsTests : PixelOperationsTests + { + public RgbaVectorOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs similarity index 63% rename from tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs rename to tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index e66ca9a71..d9845e474 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -6,335 +6,65 @@ using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; + using Xunit; using Xunit.Abstractions; -namespace SixLabors.ImageSharp.Tests.PixelFormats +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations { - public class PixelOperationsTests + public partial class PixelOperationsTests { - public const string SkipProfilingBenchmarks = -#if true - "Profiling benchmark - enable manually!"; -#else - null; -#endif - - public class Argb32OperationsTests : PixelOperationsTests - { - - public Argb32OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - - public class Bgr24OperationsTests : PixelOperationsTests - { - public Bgr24OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - - public class Bgra32OperationsTests : PixelOperationsTests - { - public Bgra32OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - - public class Gray8OperationsTests : PixelOperationsTests - { - public Gray8OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void FromGray8Bytes(int count) - { - byte[] source = CreateByteTestData(count); - var expected = new Gray8[count]; - - for (int i = 0; i < count; i++) - { - expected[i].FromGray8(new Gray8(source[i])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToGray8Bytes(int count) - { - Gray8[] source = CreatePixelTestData(count); - byte[] expected = new byte[count]; - var gray = default(Gray8); - - for (int i = 0; i < count; i++) - { - gray.FromScaledVector4(source[i].ToScaledVector4()); - expected[i] = gray.PackedValue; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void FromGray16Bytes(int count) - { - byte[] source = CreateByteTestData(count * 2); - Span sourceSpan = source.AsSpan(); - var expected = new Gray8[count]; - - for (int i = 0; i < count; i++) - { - int i2 = i * 2; - expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); - } - - TestOperation( - source, - expected, - (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToGray16Bytes(int count) - { - Gray8[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 2]; - Gray16 gray = default; - - for (int i = 0; i < count; i++) - { - int i2 = i * 2; - gray.FromScaledVector4(source[i].ToScaledVector4()); - OctetBytes bytes = Unsafe.As(ref gray); - expected[i2] = bytes[0]; - expected[i2 + 1] = bytes[1]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - } - - public class Gray16OperationsTests : PixelOperationsTests - { - public Gray16OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void FromGray8Bytes(int count) - { - byte[] source = CreateByteTestData(count); - var expected = new Gray16[count]; - - for (int i = 0; i < count; i++) - { - expected[i].FromGray8(new Gray8(source[i])); - } - - TestOperation( - source, - expected, - (s, d) => Operations.FromGray8Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToGray8Bytes(int count) - { - Gray16[] source = CreatePixelTestData(count); - byte[] expected = new byte[count]; - var gray = default(Gray8); - - for (int i = 0; i < count; i++) - { - gray.FromScaledVector4(source[i].ToScaledVector4()); - expected[i] = gray.PackedValue; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToGray8Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void FromGray16Bytes(int count) - { - byte[] source = CreateByteTestData(count * 2); - Span sourceSpan = source.AsSpan(); - var expected = new Gray16[count]; - - for (int i = 0; i < count; i++) - { - int i2 = i * 2; - expected[i].FromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); - } - - TestOperation( - source, - expected, - (s, d) => Operations.FromGray16Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - - [Theory] - [MemberData(nameof(ArraySizesData))] - public void ToGray16Bytes(int count) - { - Gray16[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 2]; - Gray16 gray = default; - - for (int i = 0; i < count; i++) - { - int i2 = i * 2; - gray.FromScaledVector4(source[i].ToScaledVector4()); - OctetBytes bytes = Unsafe.As(ref gray); - expected[i2] = bytes[0]; - expected[i2 + 1] = bytes[1]; - } - - TestOperation( - source, - expected, - (s, d) => Operations.ToGray16Bytes(this.Configuration, s, d.GetSpan(), count) - ); - } - } - - public class Rgba32OperationsTests : PixelOperationsTests - { - public Rgba32OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - - [Fact(Skip = SkipProfilingBenchmarks)] - public void Benchmark_ToVector4() - { - const int times = 200000; - const int count = 1024; - - using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) - using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) - { - this.Measure( - times, - () => PixelOperations.Instance.ToVector4( - this.Configuration, - source.GetSpan(), - dest.GetSpan())); - } - } - } - - public class Rgb48OperationsTests : PixelOperationsTests - { - public Rgb48OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - - public class Rgba64OperationsTests : PixelOperationsTests - { - public Rgba64OperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - - public class RgbaVectorOperationsTests : PixelOperationsTests - { - public RgbaVectorOperationsTests(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); - } - [Theory] [WithBlankImages(1, 1, PixelTypes.All)] - public void GetGlobalInstance(TestImageProvider _) - where TPixel : struct, IPixel => Assert.NotNull(PixelOperations.Instance); - - [Fact] - public void IsOpaqueColor() - { - Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Red)); - Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(Rgba32.Red)); - Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Transparent)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); - } + public void GetGlobalInstance(TestImageProvider _) + where T : struct, IPixel => Assert.NotNull(PixelOperations.Instance); } public abstract class PixelOperationsTests : MeasureFixture where TPixel : struct, IPixel { + public const string SkipProfilingBenchmarks = +#if true + "Profiling benchmark - enable manually!"; +#else + null; +#endif + protected PixelOperationsTests(ITestOutputHelper output) : base(output) { } - public static TheoryData ArraySizesData => new TheoryData { 0, 1, 2, 7, 16, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 1111 }; + public static TheoryData ArraySizesData => + new TheoryData + { + 0, + 1, + 2, + 7, + 16, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520, + 521, + 522, + 523, + 524, + 525, + 526, + 527, + 528, + 1111 + }; protected Configuration Configuration => Configuration.Default; @@ -390,28 +120,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ); } - internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToVector4(); - } - return expected; - } - - internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) - { - var expected = new Vector4[source.Length]; - - for (int i = 0; i < expected.Length; i++) - { - expected[i] = source[i].ToScaledVector4(); - } - return expected; - } - [Theory] [MemberData(nameof(ArraySizesData))] public void ToVector4(int count) @@ -769,6 +477,28 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ); } + internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToVector4(); + } + return expected; + } + + internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) + { + var expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToScaledVector4(); + } + return expected; + } + internal static void TestOperation( TSource[] source, TDest[] expected, From 8e843d1f6f04ec735fdd5ecfe1cdacd1d0cca6cb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 20:30:48 +0200 Subject: [PATCH 096/238] add header --- .../PixelOperationsTests.Argb32OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Bgr24OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Bgra32OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Gray16OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Gray8OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Rgb48OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Rgba32OperationsTests.cs | 5 ++++- .../PixelOperationsTests.Rgba64OperationsTests.cs | 5 ++++- .../PixelOperationsTests.RgbaVectorOperationsTests.cs | 5 ++++- 9 files changed, 36 insertions(+), 9 deletions(-) diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs index 875ba0cba..c881ae96b 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Argb32OperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs index 879712a3e..323d3914c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs index 963a9dae6..1c966951f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgra32OperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs index 1afa65240..c3de33547 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs index 4112d201b..acd6ef23a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs index 68b67fce2..0a28db6b0 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb48OperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs index 38cc97893..1ecbaf361 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba32OperationsTests.cs @@ -1,4 +1,7 @@ -using System.Buffers; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Buffers; using System.Numerics; using SixLabors.ImageSharp.Memory; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs index 47738ac60..6787602bb 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgba64OperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs index 7272dfb78..f9cc042a7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.RgbaVectorOperationsTests.cs @@ -1,4 +1,7 @@ -using SixLabors.ImageSharp.PixelFormats; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; From 7ac90a88b8eb2ffc67c76a42a8b3f0d3e3eb25ea Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 26 Oct 2018 20:33:25 +0200 Subject: [PATCH 097/238] fix Sandbox46 build --- tests/ImageSharp.Sandbox46/Program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index 4d89929a0..3a3a7d31c 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -3,6 +3,8 @@ // Licensed under the Apache License, Version 2.0. // +using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations; + namespace SixLabors.ImageSharp.Sandbox46 { using System; From b789db0ba62529c7e623a06a9baf99bf8de99534 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 26 Oct 2018 22:58:35 +0200 Subject: [PATCH 098/238] Added missing length check that caused an ArgumentNullException (#750) --- .../Common/Extensions/EncoderExtensions.cs | 5 +++ .../Common/EncoderExtensionsTests.cs | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs diff --git a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs index 82899863c..086dbee35 100644 --- a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs +++ b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs @@ -20,6 +20,11 @@ namespace SixLabors.ImageSharp /// The string. public static string GetString(this Encoding encoding, ReadOnlySpan buffer) { + if (buffer.Length == 0) + { + return null; + } + fixed (byte* bytes = buffer) { return encoding.GetString(bytes, buffer.Length); diff --git a/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs b/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs new file mode 100644 index 000000000..ec1ae65d6 --- /dev/null +++ b/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Text; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Common +{ + public class EncoderExtensionsTests + { + [Fact] + public void GetString_EmptyBuffer_ReturnsNull() + { + var buffer = new ReadOnlySpan(); + + string result = Encoding.UTF8.GetString(buffer); + + Assert.Null(result); + } + + [Fact] + public void GetString_Buffer_ReturnsString() + { + var buffer = new ReadOnlySpan(new byte[] { 73, 109, 97, 103, 101, 83, 104, 97, 114, 112 }); + + string result = Encoding.UTF8.GetString(buffer); + + Assert.Equal("ImageSharp", result); + } + } +} From 2d8e1fd5b28ffb3baa4d70f3910ebc3a87492f08 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 26 Oct 2018 23:32:35 +0200 Subject: [PATCH 099/238] Return empty string instead of null. --- src/ImageSharp/Common/Extensions/EncoderExtensions.cs | 2 +- tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs index 086dbee35..59c878485 100644 --- a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs +++ b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp { if (buffer.Length == 0) { - return null; + return string.Empty; } fixed (byte* bytes = buffer) diff --git a/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs b/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs index ec1ae65d6..e1b4fc790 100644 --- a/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Common/EncoderExtensionsTests.cs @@ -10,13 +10,13 @@ namespace SixLabors.ImageSharp.Tests.Common public class EncoderExtensionsTests { [Fact] - public void GetString_EmptyBuffer_ReturnsNull() + public void GetString_EmptyBuffer_ReturnsEmptyString() { var buffer = new ReadOnlySpan(); string result = Encoding.UTF8.GetString(buffer); - Assert.Null(result); + Assert.Equal(string.Empty, result); } [Fact] From e19b3593deaee42969781739f0b8e5be904fedf9 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 27 Oct 2018 00:09:33 +0200 Subject: [PATCH 100/238] imrpoved accuracy for Gray8 conversion --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 2 +- .../PixelImplementations/Gray8.cs | 15 +- .../PixelFormats/Gray8Tests.cs | 168 +++++++++++++++--- 3 files changed, 158 insertions(+), 27 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 6c52eded5..402aa79b5 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp /// The blue component. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static byte Get8BitBT709Luminance(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F)); + public static byte Get8BitBT709Luminance(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5f); /// /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709. diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs index d23fda799..b49eb2505 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs @@ -18,6 +18,11 @@ namespace SixLabors.ImageSharp.PixelFormats private static readonly Vector4 Half = new Vector4(0.5F); private const float Average = 1 / 3F; + private static readonly Vector4 Min = new Vector4(0, 0, 0, 1f); + private static readonly Vector4 Max = Vector4.One; + + private static readonly Vector4 Accumulator = new Vector4(255f * Average, 255f * Average, 255f * Average, 0.5f); + /// /// Initializes a new instance of the struct. /// @@ -64,10 +69,12 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void FromVector4(Vector4 vector) { - vector *= MaxBytes; - vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes) * Average; - this.PackedValue = (byte)(vector.X + vector.Y + vector.Z); + vector = Vector4.Max(Min, vector); + vector = Vector4.Min(Max, vector); + + float roundedSum = Vector4.Dot(vector, Accumulator); + + this.PackedValue = (byte)roundedSum; } /// diff --git a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs index 988002c09..fcd8da051 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Gray8Tests.cs @@ -1,14 +1,42 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Diagnostics; using System.Numerics; + +using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.PixelFormats; using Xunit; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.PixelFormats { public class Gray8Tests { + public static readonly TheoryData LuminanceData = new TheoryData() + { + 0, + 1, + 2, + 3, + 5, + 13, + 31, + 71, + 73, + 79, + 83, + 109, + 127, + 128, + 131, + 199, + 250, + 251, + 254, + 255 + }; + [Theory] [InlineData(0)] [InlineData(255)] @@ -34,9 +62,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [Theory] - [InlineData(0)] - [InlineData(255)] - [InlineData(30)] + [MemberData(nameof(LuminanceData))] public void Gray8_ToScaledVector4(byte input) { // Arrange @@ -53,26 +79,24 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(1, actual.W); } - [Fact] - public void Gray8_FromVector4() + [Theory] + [MemberData(nameof(LuminanceData))] + public void Gray8_FromVector4(byte luminance) { // Arrange Gray8 gray = default; - const int expected = 128; - var vector = new Gray8(expected).ToVector4(); + var vector = new Gray8(luminance).ToVector4(); // Act gray.FromVector4(vector); byte actual = gray.PackedValue; // Assert - Assert.Equal(expected, actual); + Assert.Equal(luminance, actual); } [Theory] - [InlineData(0)] - [InlineData(255)] - [InlineData(30)] + [MemberData(nameof(LuminanceData))] public void Gray8_ToVector4(byte input) { // Arrange @@ -89,12 +113,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(1, actual.W); } - [Fact] - public void Gray8_FromRgba32() + [Theory] + [MemberData(nameof(LuminanceData))] + public void Gray8_FromRgba32(byte rgb) { // Arrange Gray8 gray = default; - const byte rgb = 128; byte expected = ImageMaths.Get8BitBT709Luminance(rgb, rgb, rgb); // Act @@ -105,23 +129,123 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(expected, actual); } + [Theory] - [InlineData(0)] - [InlineData(255)] - [InlineData(30)] - public void Gray8_ToRgba32(byte input) + [MemberData(nameof(LuminanceData))] + public void Gray8_ToRgba32(byte luminance) { // Arrange - var gray = new Gray8(input); + var gray = new Gray8(luminance); // Act var actual = gray.ToRgba32(); // Assert - Assert.Equal(input, actual.R); - Assert.Equal(input, actual.G); - Assert.Equal(input, actual.B); + Assert.Equal(luminance, actual.R); + Assert.Equal(luminance, actual.G); + Assert.Equal(luminance, actual.B); Assert.Equal(byte.MaxValue, actual.A); } + + public class Rgba32Compatibility + { + // ReSharper disable once MemberHidesStaticFromOuterClass + public static readonly TheoryData LuminanceData = Gray8Tests.LuminanceData; + + [Theory] + [MemberData(nameof(LuminanceData))] + public void Gray8_FromRgba32_IsInverseOf_ToRgba32(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + Gray8 mirror = default; + mirror.FromRgba32(rgba); + + Assert.Equal(original, mirror); + } + + + [Theory] + [MemberData(nameof(LuminanceData))] + public void Rgba32_ToGray8_IsInverseOf_Gray8_ToRgba32(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + Gray8 mirror = default; + mirror.FromRgba32(rgba); + + Assert.Equal(original, mirror); + } + + [Theory] + [MemberData(nameof(LuminanceData))] + public void ToVector4_IsRgba32Compatible(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + var gray8Vector = original.ToVector4(); + var rgbaVector = original.ToVector4(); + + Assert.Equal(gray8Vector, rgbaVector, new ApproximateFloatComparer(1e-5f)); + } + + [Theory] + [MemberData(nameof(LuminanceData))] + public void FromVector4_IsRgba32Compatible(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + Vector4 rgbaVector = original.ToVector4(); + + Gray8 mirror = default; + mirror.FromVector4(rgbaVector); + + Assert.Equal(original, mirror); + } + + [Theory] + [MemberData(nameof(LuminanceData))] + public void ToScaledVector4_IsRgba32Compatible(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + Vector4 gray8Vector = original.ToScaledVector4(); + Vector4 rgbaVector = original.ToScaledVector4(); + + Assert.Equal(gray8Vector, rgbaVector, new ApproximateFloatComparer(1e-5f)); + } + + [Theory] + [MemberData(nameof(LuminanceData))] + public void FromScaledVector4_IsRgba32Compatible(byte luminance) + { + var original = new Gray8(luminance); + + Rgba32 rgba = default; + original.ToRgba32(ref rgba); + + Vector4 rgbaVector = original.ToScaledVector4(); + + Gray8 mirror = default; + mirror.FromScaledVector4(rgbaVector); + + Assert.Equal(original, mirror); + } + } } } \ No newline at end of file From b4689fd6f6d4633338e555d6c6e0fb414f65a0bc Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 27 Oct 2018 11:36:01 +0100 Subject: [PATCH 101/238] Add issue reference images --- tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs | 4 +++- tests/ImageSharp.Tests/TestImages.cs | 2 ++ tests/Images/External | 2 +- tests/Images/Input/Jpg/issues/issue750-exif-load.jpg | 3 +++ tests/Images/Input/Jpg/issues/issue750-exif-tranform.jpg | 3 +++ 5 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 tests/Images/Input/Jpg/issues/issue750-exif-load.jpg create mode 100644 tests/Images/Input/Jpg/issues/issue750-exif-tranform.jpg diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs index 6bc559978..17a0ff263 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs @@ -26,7 +26,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Issues.ExifDecodeOutOfRange694, TestImages.Jpeg.Issues.InvalidEOI695, TestImages.Jpeg.Issues.ExifResizeOutOfRange696, - TestImages.Jpeg.Issues.InvalidAPP0721 + TestImages.Jpeg.Issues.InvalidAPP0721, + TestImages.Jpeg.Issues.ExifGetString750Load, + TestImages.Jpeg.Issues.ExifGetString750Transform }; public static string[] ProgressiveTestJpegs = diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 758f25634..03f875485 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -160,6 +160,8 @@ namespace SixLabors.ImageSharp.Tests public const string OrderedInterleavedProgressive723A = "Jpg/issues/Issue723-Ordered-Interleaved-Progressive-A.jpg"; public const string OrderedInterleavedProgressive723B = "Jpg/issues/Issue723-Ordered-Interleaved-Progressive-B.jpg"; public const string OrderedInterleavedProgressive723C = "Jpg/issues/Issue723-Ordered-Interleaved-Progressive-C.jpg"; + public const string ExifGetString750Transform = "Jpg/issues/issue750-exif-tranform.jpg"; + public const string ExifGetString750Load = "Jpg/issues/issue750-exif-load.jpg"; } public static readonly string[] All = Baseline.All.Concat(Progressive.All).ToArray(); diff --git a/tests/Images/External b/tests/Images/External index ee90e5f32..c6980db77 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit ee90e5f32218027744b5d40058b587cc1047b76f +Subproject commit c6980db777e49d5e526b56cb986001d1a191acdf diff --git a/tests/Images/Input/Jpg/issues/issue750-exif-load.jpg b/tests/Images/Input/Jpg/issues/issue750-exif-load.jpg new file mode 100644 index 000000000..219e902dd --- /dev/null +++ b/tests/Images/Input/Jpg/issues/issue750-exif-load.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0919126bfa5be74782e6db4bd8fb82c6211ea2cca1f6b76cfa9cee7fdd418ff +size 36885 diff --git a/tests/Images/Input/Jpg/issues/issue750-exif-tranform.jpg b/tests/Images/Input/Jpg/issues/issue750-exif-tranform.jpg new file mode 100644 index 000000000..342a2dde6 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/issue750-exif-tranform.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14bd38b41f94e86c56ebc3b1612ced04fa4741982d916e01d6e3bf75e6c80f26 +size 5587341 From aee867c39fffd376ea167b3871f8d48256930419 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Sat, 27 Oct 2018 15:32:48 +0100 Subject: [PATCH 102/238] prevent text wandering from baseline --- .../Processors/Text/DrawTextProcessor.cs | 21 +++++++++++++------ .../Drawing/Text/DrawTextOnImageTests.cs | 4 ++-- tests/Images/External | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 1095de325..49a653063 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -97,7 +97,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text this.textRenderer = new CachingGlyphRenderer(source.GetMemoryAllocator(), this.Text.Length, this.Pen, this.Brush != null); this.textRenderer.Options = (GraphicsOptions)this.Options; - TextRenderer.RenderTextTo(this.textRenderer, this.Text, style); + var renderer = new TextRenderer(this.textRenderer); + renderer.RenderText(this.Text, style); } protected override void AfterImageApply(Image source, Rectangle sourceRectangle) @@ -164,14 +165,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text private class CachingGlyphRenderer : IGlyphRenderer, IDisposable { + // just enough accuracy to allow for half pixel differences which + // later are componded into full pixel offsets while rendering. + private const float AcuracyMultiple = 2; + private PathBuilder builder; private Point currentRenderPosition = default; - private GlyphRendererParameters currentGlyphRenderParams = default; + private (GlyphRendererParameters glyph, PointF subPixelOffset) currentGlyphRenderParams = default; private int offset = 0; private PointF currentPoint = default(PointF); - private readonly Dictionary glyphData = new Dictionary(); + private readonly Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> glyphData = new Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData>(); private bool renderOutline = false; private bool renderFill = false; @@ -216,11 +221,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters paramters) { this.currentRenderPosition = Point.Truncate(bounds.Location); + PointF dif = bounds.Location - this.currentRenderPosition; + + dif.X = ((int)(dif.X * AcuracyMultiple)) / AcuracyMultiple; + dif.Y = ((int)(dif.Y * AcuracyMultiple)) / AcuracyMultiple; // we have offset our rendering origion a little bit down to prevent edge cropping, move the draw origin up to compensate this.currentRenderPosition = new Point(this.currentRenderPosition.X - this.offset, this.currentRenderPosition.Y - this.offset); - this.currentGlyphRenderParams = paramters; - if (this.glyphData.ContainsKey(paramters)) + this.currentGlyphRenderParams = (paramters, dif); + if (this.glyphData.ContainsKey(this.currentGlyphRenderParams)) { // we have already drawn the glyph vectors skip trying again this.raterizationRequired = false; @@ -252,7 +261,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text public void Dispose() { - foreach (KeyValuePair kv in this.glyphData) + foreach (KeyValuePair<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> kv in this.glyphData) { kv.Value.Dispose(); } diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 44bb160ce..6d7c86409 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789"; - public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(0.01f); - public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(0.5f, 3); + public static ImageComparer TextDrawingComparer = ImageComparer.Exact;//.TolerantPercentage(0.01f); + public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.Exact;// TolerantPercentage(0.5f, 3); [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] diff --git a/tests/Images/External b/tests/Images/External index c6980db77..5634b8b2a 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit c6980db777e49d5e526b56cb986001d1a191acdf +Subproject commit 5634b8b2affa1158cec31ccbb67f9583e9137234 From 32aa6566d7b117f783ee70e01121942bac9cd0a3 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Sat, 27 Oct 2018 15:42:10 +0100 Subject: [PATCH 103/238] remove commented out tolerances --- tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 6d7c86409..a02b65ef0 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789"; - public static ImageComparer TextDrawingComparer = ImageComparer.Exact;//.TolerantPercentage(0.01f); - public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.Exact;// TolerantPercentage(0.5f, 3); + public static ImageComparer TextDrawingComparer = ImageComparer.Exact; + public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.Exact; [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] From 4a515982078308fe47c76a980a8b44fb4b8aff4d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 27 Oct 2018 17:22:52 +0200 Subject: [PATCH 104/238] fix typos & cleanup --- .../Processors/Text/DrawTextProcessor.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 49a653063..478358191 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -167,20 +167,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text { // just enough accuracy to allow for half pixel differences which // later are componded into full pixel offsets while rendering. - private const float AcuracyMultiple = 2; + private const float AccuracyMultiple = 2; - private PathBuilder builder; + private readonly PathBuilder builder; private Point currentRenderPosition = default; private (GlyphRendererParameters glyph, PointF subPixelOffset) currentGlyphRenderParams = default; - private int offset = 0; + private readonly int offset = 0; private PointF currentPoint = default(PointF); - private readonly Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> glyphData = new Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData>(); + private readonly Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> + glyphData = new Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData>(); - private bool renderOutline = false; - private bool renderFill = false; - private bool raterizationRequired = false; + private readonly bool renderOutline = false; + private readonly bool renderFill = false; + private bool rasterizationRequired = false; public CachingGlyphRenderer(MemoryAllocator memoryAllocator, int size, IPen pen, bool renderFill) { @@ -218,21 +219,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text this.builder.StartFigure(); } - public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters paramters) + public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters parameters) { this.currentRenderPosition = Point.Truncate(bounds.Location); PointF dif = bounds.Location - this.currentRenderPosition; - dif.X = ((int)(dif.X * AcuracyMultiple)) / AcuracyMultiple; - dif.Y = ((int)(dif.Y * AcuracyMultiple)) / AcuracyMultiple; + dif.X = ((int)(dif.X * AccuracyMultiple)) / AccuracyMultiple; + dif.Y = ((int)(dif.Y * AccuracyMultiple)) / AccuracyMultiple; // we have offset our rendering origion a little bit down to prevent edge cropping, move the draw origin up to compensate this.currentRenderPosition = new Point(this.currentRenderPosition.X - this.offset, this.currentRenderPosition.Y - this.offset); - this.currentGlyphRenderParams = (paramters, dif); + this.currentGlyphRenderParams = (parameters, dif); if (this.glyphData.ContainsKey(this.currentGlyphRenderParams)) { // we have already drawn the glyph vectors skip trying again - this.raterizationRequired = false; + this.rasterizationRequired = false; return false; } @@ -242,7 +243,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text // ensure all glyphs render around [zero, zero] so offset negative root positions so when we draw the glyph we can offet it back this.builder.SetOrigin(new PointF(-(int)bounds.X + this.offset, -(int)bounds.Y + this.offset)); - this.raterizationRequired = true; + this.rasterizationRequired = true; return true; } @@ -279,7 +280,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text GlyphRenderData renderData = default; // has the glyoh been rendedered already???? - if (this.raterizationRequired) + if (this.rasterizationRequired) { IPath path = this.builder.Build(); From 8be9e6df4d20043e8f2684003187ff9896edd821 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Sat, 27 Oct 2018 20:05:43 +0100 Subject: [PATCH 105/238] constrain destination span and scanline to same length --- .../Processing/SolidBrush{TPixel}.cs | 12 ++++++- .../Drawing/Text/DrawTextOnImageTests.cs | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs index a77c6728b..6a8028770 100644 --- a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs @@ -89,7 +89,17 @@ namespace SixLabors.ImageSharp.Processing /// internal override void Apply(Span scanline, int x, int y) { - Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); + Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x); + + // constrain the spans to eachother + if (destinationRow.Length > scanline.Length) + { + destinationRow = destinationRow.Slice(0, scanline.Length); + } + else + { + scanline = scanline.Slice(0, destinationRow.Length); + } MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; Configuration configuration = this.Target.Configuration; diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 44bb160ce..b05ada522 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -25,6 +25,41 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(0.01f); public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(0.5f, 3); + [Theory] + [WithSolidFilledImages(276, 336, "White", PixelTypes.Rgba32)] + public void DoesntThrowExceptionWhenOverlappingRightEdge_Issue688(TestImageProvider provider) + where TPixel : struct, IPixel + { + Font font = CreateFont("OpenSans-Regular.ttf", 36); + TPixel color = NamedColors.Black; + float padding = 5; + var text = "A short piece of text"; + + using (var img = provider.GetImage()) + { + float targetWidth = img.Width - (padding * 2); + float targetHeight = img.Height - (padding * 2); + + // measure the text size + SizeF size = TextMeasurer.Measure(text, new RendererOptions(font)); + + //find out how much we need to scale the text to fill the space (up or down) + float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height); + + //create a new font + Font scaledFont = new Font(font, scalingFactor * font.Size); + + var center = new PointF(img.Width / 2, img.Height / 2); + var textGraphicOptions = new TextGraphicsOptions(true) + { + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center + }; + + img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center)); + } + } + [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] [WithSolidFilledImages(900, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "OpenSans-Regular.ttf", TestText)] From 33436492b421d5a99cc0a96e6c01ea1892b5e05a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 28 Oct 2018 09:22:45 +0000 Subject: [PATCH 106/238] Comment TODO on palette changes. --- src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs index 24ddfba7b..a757a393e 100644 --- a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs @@ -746,6 +746,9 @@ namespace SixLabors.ImageSharp.PixelFormats private static TPixel[] GetPalette(Rgba32[] palette) { + // TODO: This should be the length only. + // We need to fix and update tests/reference images. + // If someone wants transparency they should add it to the palette. var converted = new TPixel[palette.Length + 1]; Span constantsBytes = MemoryMarshal.Cast(palette.AsSpan()); From 79c962c4c7194a17182e0b9378459586e7a45663 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 28 Oct 2018 15:51:11 +0100 Subject: [PATCH 107/238] use strict - but not exact - comparison in DrawTextOnImageTests --- tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index a02b65ef0..2acb3d5e3 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789"; - public static ImageComparer TextDrawingComparer = ImageComparer.Exact; - public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.Exact; + public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(1e-5f); + public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(1e-4f); [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] From a0abfffeb9c63efa9f157eabc5f27d35dc367cc3 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 28 Oct 2018 16:41:22 +0100 Subject: [PATCH 108/238] Failing test case based on #685 --- .../Drawing/Text/DrawTextOnImageTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 2acb3d5e3..09aeef35c 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -151,6 +151,27 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text appendSourceFileOrDescription: true); } + [Theory] + [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32)] + public static void TextPositioningIsRobust(TestImageProvider provider) + where TPixel : struct, IPixel + { + if (!TestEnvironment.IsWindows) + { + // Does the system font "Baskerville Old Face" exist on most Linux/MAC machines? + return; + } + + Font font = SystemFonts.CreateFont("Baskerville Old Face", 30, FontStyle.Regular); + + string text = Repeat("Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!\n", + 20); + var textOptions = new TextGraphicsOptions(true) { WrapTextWidth = 1000 }; + + provider.RunValidatingProcessorTest( + x => x.DrawText(textOptions, text, font, NamedColors.Black, new PointF(10, 50)), appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); + } + private static string Repeat(string str, int times) => string.Concat(Enumerable.Repeat(str, times)); private static string ToTestOutputDisplayText(string text) @@ -167,5 +188,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text Font font = fontCollection.Install(fontPath).CreateFont(size); return font; } + + } } From d2185efa4bc3dd302253bff93f6fde2d4827707e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 28 Oct 2018 18:06:28 +0100 Subject: [PATCH 109/238] Improve text rendering accuracy --- .../Processors/Text/DrawTextProcessor.cs | 18 ++++++---- .../Drawing/Text/DrawTextOnImageTests.cs | 34 ++++++++++++++++--- tests/Images/External | 2 +- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 478358191..f9a1d8739 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -165,9 +165,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text private class CachingGlyphRenderer : IGlyphRenderer, IDisposable { - // just enough accuracy to allow for half pixel differences which - // later are componded into full pixel offsets while rendering. - private const float AccuracyMultiple = 2; + // just enough accuracy to allow for 1/8 pixel differences which + // later are accumulated while rendering, but do not grow into full pixel offsets + // The value 8 is benchmarked to: + // - Provide a good accuracy (smaller than 0.2% image difference compared to the non-caching variant) + // - Cache hit ratio above 60% + private const float AccuracyMultiple = 8; private readonly PathBuilder builder; @@ -222,14 +225,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters parameters) { this.currentRenderPosition = Point.Truncate(bounds.Location); - PointF dif = bounds.Location - this.currentRenderPosition; + PointF subPixelOffset = bounds.Location - this.currentRenderPosition; - dif.X = ((int)(dif.X * AccuracyMultiple)) / AccuracyMultiple; - dif.Y = ((int)(dif.Y * AccuracyMultiple)) / AccuracyMultiple; + subPixelOffset.X = MathF.Round(subPixelOffset.X * AccuracyMultiple) / AccuracyMultiple; + subPixelOffset.Y = MathF.Round(subPixelOffset.Y * AccuracyMultiple) / AccuracyMultiple; // we have offset our rendering origion a little bit down to prevent edge cropping, move the draw origin up to compensate this.currentRenderPosition = new Point(this.currentRenderPosition.X - this.offset, this.currentRenderPosition.Y - this.offset); - this.currentGlyphRenderParams = (parameters, dif); + this.currentGlyphRenderParams = (parameters, subPixelOffset); + if (this.glyphData.ContainsKey(this.currentGlyphRenderParams)) { // we have already drawn the glyph vectors skip trying again diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 09aeef35c..c1aeebed8 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -11,6 +11,8 @@ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.Primitives; using Xunit; +using Xunit.Abstractions; + // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Drawing.Text @@ -25,6 +27,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(1e-5f); public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(1e-4f); + public DrawTextOnImageTests(ITestOutputHelper output) + { + this.Output = output; + } + + private ITestOutputHelper Output { get; } + [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] [WithSolidFilledImages(900, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "OpenSans-Regular.ttf", TestText)] @@ -87,8 +96,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text TPixel color = NamedColors.Black; + // Based on the reported 0.0270% difference with AccuracyMultiple = 8 + // We should avoid quality regressions leading to higher difference! + var comparer = ImageComparer.TolerantPercentage(0.03f); + provider.VerifyOperation( - TextDrawingComparer, + comparer, img => { img.Mutate(c => c.DrawText(textOptions, sb.ToString(), font, color, new PointF(10, 5))); @@ -152,8 +165,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text } [Theory] - [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32)] - public static void TextPositioningIsRobust(TestImageProvider provider) + [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32, "Baskerville Old Face")] + [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32, "Arial")] + public void TextPositioningIsRobust(TestImageProvider provider, string fontName) where TPixel : struct, IPixel { if (!TestEnvironment.IsWindows) @@ -162,14 +176,24 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text return; } - Font font = SystemFonts.CreateFont("Baskerville Old Face", 30, FontStyle.Regular); + Font font = SystemFonts.CreateFont(fontName, 30, FontStyle.Regular); string text = Repeat("Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!\n", 20); var textOptions = new TextGraphicsOptions(true) { WrapTextWidth = 1000 }; + string details = fontName.Replace(" ", ""); + + // Based on the reported 0.1755% difference with AccuracyMultiple = 8 + // We should avoid quality regressions leading to higher difference! + var comparer = ImageComparer.TolerantPercentage(0.2f); + provider.RunValidatingProcessorTest( - x => x.DrawText(textOptions, text, font, NamedColors.Black, new PointF(10, 50)), appendPixelTypeToFileName: false, appendSourceFileOrDescription: false); + x => x.DrawText(textOptions, text, font, NamedColors.Black, new PointF(10, 50)), + details, + comparer, + appendPixelTypeToFileName: false, + appendSourceFileOrDescription: false); } private static string Repeat(string str, int times) => string.Concat(Enumerable.Repeat(str, times)); diff --git a/tests/Images/External b/tests/Images/External index 5634b8b2a..b7a7eacc0 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 5634b8b2affa1158cec31ccbb67f9583e9137234 +Subproject commit b7a7eacc0446a1acc266f30ddadbda40fccde231 From b8a3245599305241b9fe69fb6b0b5feba6712025 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 28 Oct 2018 19:14:02 +0100 Subject: [PATCH 110/238] use OpenSans-Regular.ttf in tests --- .../Drawing/Text/DrawTextOnImageTests.cs | 11 ++--------- tests/Images/External | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index c1aeebed8..46251cdcf 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -165,18 +165,11 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text } [Theory] - [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32, "Baskerville Old Face")] - [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32, "Arial")] + [WithSolidFilledImages(1000, 1500, "White", PixelTypes.Rgba32, "OpenSans-Regular.ttf")] public void TextPositioningIsRobust(TestImageProvider provider, string fontName) where TPixel : struct, IPixel { - if (!TestEnvironment.IsWindows) - { - // Does the system font "Baskerville Old Face" exist on most Linux/MAC machines? - return; - } - - Font font = SystemFonts.CreateFont(fontName, 30, FontStyle.Regular); + Font font = CreateFont(fontName, 30); string text = Repeat("Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!\n", 20); diff --git a/tests/Images/External b/tests/Images/External index b7a7eacc0..f41ae0327 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit b7a7eacc0446a1acc266f30ddadbda40fccde231 +Subproject commit f41ae0327a3ab21ab2388c32160bda67debcc082 From 72da4463c90ad1deb36db402c21e534b362486ee Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 28 Oct 2018 20:21:29 +0100 Subject: [PATCH 111/238] increase tolerance to tolerate inaccuracies on legacy JIT --- tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 46251cdcf..71fddafa9 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789"; public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(1e-5f); - public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(1e-4f); + public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(5e-4f); public DrawTextOnImageTests(ITestOutputHelper output) { From ec930e1a43538441250f17212051850f6d4f5465 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Mon, 29 Oct 2018 20:39:07 +0100 Subject: [PATCH 112/238] Removed duplicate item from the list. --- tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs index 17a0ff263..748abdb99 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs @@ -10,7 +10,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public static string[] BaselineTestJpegs = { TestImages.Jpeg.Baseline.Calliphora, - TestImages.Jpeg.Baseline.Cmyk, TestImages.Jpeg.Baseline.Ycck, + TestImages.Jpeg.Baseline.Cmyk, + TestImages.Jpeg.Baseline.Ycck, TestImages.Jpeg.Baseline.Jpeg400, TestImages.Jpeg.Baseline.Testorig420, @@ -19,7 +20,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, TestImages.Jpeg.Baseline.Bad.BadEOF, - TestImages.Jpeg.Issues.MultiHuffmanBaseline394, TestImages.Jpeg.Baseline.MultiScanBaselineCMYK, TestImages.Jpeg.Baseline.Bad.BadRST, TestImages.Jpeg.Issues.MultiHuffmanBaseline394, From e221d089900fbe78f862194f8772897f6f51984b Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Mon, 29 Oct 2018 21:00:21 +0100 Subject: [PATCH 113/238] Replaced tabs with spaces. --- .../Argb32.PixelOperations.Generated.cs | 113 +++++++------- .../Argb32.PixelOperations.Generated.tt | 9 +- .../Bgr24.PixelOperations.Generated.cs | 109 +++++++------ .../Bgr24.PixelOperations.Generated.tt | 9 +- .../Bgra32.PixelOperations.Generated.cs | 113 +++++++------- .../Bgra32.PixelOperations.Generated.tt | 9 +- .../Gray16.PixelOperations.Generated.cs | 60 ++++--- .../Gray16.PixelOperations.Generated.tt | 9 +- .../Gray8.PixelOperations.Generated.cs | 60 ++++--- .../Gray8.PixelOperations.Generated.tt | 9 +- .../Rgb24.PixelOperations.Generated.cs | 109 +++++++------ .../Rgb24.PixelOperations.Generated.tt | 9 +- .../Rgb48.PixelOperations.Generated.cs | 60 ++++--- .../Rgb48.PixelOperations.Generated.tt | 9 +- .../Rgba32.PixelOperations.Generated.cs | 72 +++++---- .../Rgba32.PixelOperations.Generated.tt | 9 +- .../Rgba64.PixelOperations.Generated.cs | 60 ++++--- .../Rgba64.PixelOperations.Generated.tt | 9 +- .../Generated/_Common.ttinclude | 146 +++++++++--------- 19 files changed, 466 insertions(+), 517 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 6449351cc..2ec965dfb 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromArgb32(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,41 +35,40 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); - } + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + } - /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); - } + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + } - /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); + } - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); + } - /// - internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -83,12 +81,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -98,10 +96,10 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToArgb32(sp); } } - /// - internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -114,12 +112,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -129,11 +127,11 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToArgb32(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -147,11 +145,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -165,11 +163,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -183,11 +181,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -201,11 +199,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -219,11 +217,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -237,7 +235,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromArgb32(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt index 8c4c6b58a..0a58504e1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Argb32"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Argb32"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 9232cf454..711a9d1c1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromBgr24(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,42 +35,41 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); - } - - /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); - } - - /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - - - /// + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); + } + + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -85,11 +83,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -103,11 +101,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -121,11 +119,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -139,11 +137,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -157,11 +155,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -175,11 +173,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -193,11 +191,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -211,7 +209,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgr24(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt index 56e3bf9ba..84b89aa32 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Bgr24"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Bgr24"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 4f56b75c5..b669dd534 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromBgra32(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,41 +35,40 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); - } + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + } - /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); - } + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + } - /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); + } - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); + } - /// - internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -83,12 +81,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -98,10 +96,10 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromRgba32.ToBgra32(sp); } } - /// - internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -114,12 +112,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -129,11 +127,11 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToBgra32(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -147,11 +145,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -165,11 +163,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -183,11 +181,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -201,11 +199,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -219,11 +217,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -237,7 +235,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromBgra32(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt index 6563ff907..004ceff51 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Bgra32"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Bgra32"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs index 81882185d..288c5d92e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromGray16(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,17 +35,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -60,11 +59,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -78,11 +77,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -96,11 +95,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -114,11 +113,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -132,11 +131,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -150,11 +149,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -168,11 +167,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -186,7 +185,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray16(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt index 3db96d70a..3cbc01e88 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray16.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Gray16"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Gray16"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs index f6678a4f8..f7e94788e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromGray8(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,17 +35,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -60,11 +59,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -78,11 +77,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -96,11 +95,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -114,11 +113,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -132,11 +131,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -150,11 +149,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -168,11 +167,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -186,7 +185,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromGray8(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt index a65d8f263..d35843ccd 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Gray8.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Gray8"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Gray8"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index aae8b2f63..dbf3102c4 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromRgb24(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,42 +35,41 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); - } - - /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); - } - - /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - - - /// + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); + } + + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -85,11 +83,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -103,11 +101,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -121,11 +119,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -139,11 +137,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -157,11 +155,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -175,11 +173,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -193,11 +191,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -211,7 +209,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb24(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt index 796cdeb66..d96c3684b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Rgb24"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Rgb24"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs index c828053a4..30c9972bb 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromRgb48(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,17 +35,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -60,11 +59,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -78,11 +77,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -96,11 +95,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -114,11 +113,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -132,11 +131,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -150,11 +149,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -168,11 +167,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -186,7 +185,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgb48(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt index b8ee99fce..7bff33638 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb48.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Rgb48"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Rgb48"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs index 9c29bd044..da2ce3770 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal partial class PixelOperations : PixelOperations { - - /// + /// internal override void FromRgba32(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,16 +35,16 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - /// - internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -58,12 +57,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -73,10 +72,10 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromArgb32.ToRgba32(sp); } } - /// - internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) + /// + internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); @@ -89,12 +88,12 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// internal override void FromBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(destPixels)); @@ -104,11 +103,11 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref destRef, i) = PixelConverter.FromBgra32.ToRgba32(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -122,11 +121,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -140,11 +139,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -158,11 +157,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -176,11 +175,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -194,11 +193,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - /// + + /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -212,7 +211,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba32(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt index 0c4a4c0c0..6b9e2d124 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba32.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal partial class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Rgba32"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Rgba32"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs index db9cb84be..42c40ad5d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.cs @@ -23,11 +23,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - - /// + /// internal override void FromRgba64(Configuration configuration, ReadOnlySpan source, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -36,17 +35,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void ToRgba64(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - - /// + + /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -60,11 +59,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToBgr24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -78,11 +77,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToBgra32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -96,11 +95,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToGray8(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -114,11 +113,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToGray16(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -132,11 +131,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToRgb24(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -150,11 +149,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -168,11 +167,11 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - /// + + /// internal override void ToRgb48(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -186,7 +185,6 @@ namespace SixLabors.ImageSharp.PixelFormats dp.FromRgba64(sp); } } - - } - } + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt index 9409e1573..d15945f94 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgba64.PixelOperations.Generated.tt @@ -13,10 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal class PixelOperations : PixelOperations { - <# - GenerateAllDefaultConversionMethods("Rgba64"); - #> - - } - } + <# GenerateAllDefaultConversionMethods("Rgba64"); #> + } + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index cc8cb0e2f..f0675cb5b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -15,21 +15,20 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; <#+ - static readonly string[] CommonPixelTypes = { "Argb32", "Bgr24", "Bgra32", "Gray8", "Gray16", "Rgb24", "Rgba32", "Rgb48", "Rgba64" }; + static readonly string[] CommonPixelTypes = { "Argb32", "Bgr24", "Bgra32", "Gray8", "Gray16", "Rgb24", "Rgba32", "Rgb48", "Rgba64" }; - static readonly string[] Optimized32BitTypes = { "Rgba32", "Argb32", "Bgra32" }; - - // Types with Rgba32-combatible to/from Vector4 conversion - static readonly string[] Rgba32CompatibleTypes = { "Argb32", "Bgra32", "Rgb24", "Bgr24" }; + static readonly string[] Optimized32BitTypes = { "Rgba32", "Argb32", "Bgra32" }; - void GenerateDefaultSelfConversionMethods(string pixelType) - { - #> + // Types with Rgba32-combatible to/from Vector4 conversion + static readonly string[] Rgba32CompatibleTypes = { "Argb32", "Bgra32", "Rgb24", "Bgr24" }; - /// + void GenerateDefaultSelfConversionMethods(string pixelType) + { +#> +/// internal override void From<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> source, Span<<#=pixelType#>> destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(source, destPixels, nameof(destPixels)); source.CopyTo(destPixels); @@ -38,23 +37,23 @@ using System.Runtime.InteropServices; /// internal override void To<#=pixelType#>(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span<<#=pixelType#>> destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); sourcePixels.CopyTo(destPixels); } - <#+ +<#+ } - void GenerateDefaultConvertToMethod(string fromPixelType, string toPixelType) + void GenerateDefaultConvertToMethod(string fromPixelType, string toPixelType) { - #> +#> - /// + /// internal override void To<#=toPixelType#>(Configuration configuration, ReadOnlySpan<<#=fromPixelType#>> sourcePixels, Span<<#=toPixelType#>> destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref <#=fromPixelType#> sourceRef = ref MemoryMarshal.GetReference(sourcePixels); @@ -68,16 +67,16 @@ using System.Runtime.InteropServices; dp.From<#=fromPixelType#>(sp); } } - <#+ +<#+ } - void GenerateOptimized32BitConversionMethods(string thisPixelType, string otherPixelType) - { - #> - /// - internal override void To<#=otherPixelType#>(Configuration configuration, ReadOnlySpan<<#=thisPixelType#>> sourcePixels, Span<<#=otherPixelType#>> destPixels) + void GenerateOptimized32BitConversionMethods(string thisPixelType, string otherPixelType) + { +#> + /// + internal override void To<#=otherPixelType#>(Configuration configuration, ReadOnlySpan<<#=thisPixelType#>> sourcePixels, Span<<#=otherPixelType#>> destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); ref uint sourceRef = ref Unsafe.As<<#=thisPixelType#>,uint>(ref MemoryMarshal.GetReference(sourcePixels)); @@ -90,12 +89,12 @@ using System.Runtime.InteropServices; } } - /// + /// internal override void From<#=otherPixelType#>(Configuration configuration, ReadOnlySpan<<#=otherPixelType#>> sourcePixels, Span<<#=thisPixelType#>> destPixels) { - Guard.NotNull(configuration, nameof(configuration)); + Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destPixels, nameof(destPixels)); - + ref uint sourceRef = ref Unsafe.As<<#=otherPixelType#>,uint>(ref MemoryMarshal.GetReference(sourcePixels)); ref uint destRef = ref Unsafe.As<<#=thisPixelType#>, uint>(ref MemoryMarshal.GetReference(destPixels)); @@ -105,65 +104,64 @@ using System.Runtime.InteropServices; Unsafe.Add(ref destRef, i) = PixelConverter.From<#=otherPixelType#>.To<#=thisPixelType#>(sp); } } - <#+ +<#+ } - void GenerateRgba32CompatibleVector4ConversionMethods(string pixelType) - { - #> - - /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); - } - - /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); - } - - /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - - <#+ + void GenerateRgba32CompatibleVector4ConversionMethods(string pixelType) + { +#> + /// + internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + } + + /// + internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + } + + /// + internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + { + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); + } + + /// + internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) + { + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); + } + +<#+ } - void GenerateAllDefaultConversionMethods(string pixelType) - { - GenerateDefaultSelfConversionMethods(pixelType); + void GenerateAllDefaultConversionMethods(string pixelType) + { + GenerateDefaultSelfConversionMethods(pixelType); - if (Rgba32CompatibleTypes.Contains(pixelType)) - { - GenerateRgba32CompatibleVector4ConversionMethods(pixelType); + if (Rgba32CompatibleTypes.Contains(pixelType)) + { + GenerateRgba32CompatibleVector4ConversionMethods(pixelType); } - var matching32BitTypes = Optimized32BitTypes.Contains(pixelType) ? - Optimized32BitTypes.Where(p => p != pixelType) : - Enumerable.Empty(); + var matching32BitTypes = Optimized32BitTypes.Contains(pixelType) ? + Optimized32BitTypes.Where(p => p != pixelType) : + Enumerable.Empty(); - foreach (string destPixelType in matching32BitTypes) - { - GenerateOptimized32BitConversionMethods(pixelType, destPixelType); + foreach (string destPixelType in matching32BitTypes) + { + GenerateOptimized32BitConversionMethods(pixelType, destPixelType); } - var otherCommonNon32Types = CommonPixelTypes - .Where(p => p != pixelType) - .Except(matching32BitTypes); + var otherCommonNon32Types = CommonPixelTypes + .Where(p => p != pixelType) + .Except(matching32BitTypes); - foreach (string destPixelType in otherCommonNon32Types) - { - GenerateDefaultConvertToMethod(pixelType, destPixelType); + foreach (string destPixelType in otherCommonNon32Types) + { + GenerateDefaultConvertToMethod(pixelType, destPixelType); } } #> \ No newline at end of file From 7351b7500831e6ab2a7dbe2514a7fcf55ba1973a Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Mon, 29 Oct 2018 21:26:39 +0100 Subject: [PATCH 114/238] Upgraded Magick.NET to the latest release. --- tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj | 2 +- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index 0ca3cffa1..bb559b70d 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -19,7 +19,7 @@ - + diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 04a680200..86c1a7a25 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -27,7 +27,7 @@ - + From fe6953f34cb11608682cb85e76d8d9d7600dbaa5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 30 Oct 2018 00:22:32 +0100 Subject: [PATCH 115/238] remove yet another duplicate and drop the unused PdfJsOnly list --- .../Formats/Jpg/JpegDecoderTests.Images.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs index 748abdb99..40de25b30 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs @@ -44,22 +44,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Progressive.Bad.ExifUndefType, TestImages.Jpeg.Issues.NoEoiProgressive517, TestImages.Jpeg.Issues.BadRstProgressive518, - TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159, TestImages.Jpeg.Issues.DhtHasWrongLength624, TestImages.Jpeg.Issues.OrderedInterleavedProgressive723A, TestImages.Jpeg.Issues.OrderedInterleavedProgressive723B, TestImages.Jpeg.Issues.OrderedInterleavedProgressive723C }; - /// - /// Golang decoder is unable to decode these - /// - public static string[] PdfJsOnly = - { - TestImages.Jpeg.Issues.NoEoiProgressive517, TestImages.Jpeg.Issues.BadRstProgressive518, - TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159 - }; - private static readonly Dictionary CustomToleranceValues = new Dictionary { From a4fa2b142a969f41518abf90161d520449a221f7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 31 Oct 2018 00:25:38 +0100 Subject: [PATCH 116/238] add some benchmark results --- .../Codecs/Jpeg/DecodeJpeg.cs | 6 +- .../Codecs/Jpeg/LoadResizeSave.cs | 49 ++++++++---- .../Codecs/MultiImageBenchmarkBase.cs | 2 +- .../ImageSharp.Benchmarks/Samplers/Resize.cs | 74 ++++++++++++++++--- 4 files changed, 100 insertions(+), 31 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs index 9b968e4db..8eb1fdda6 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs @@ -14,13 +14,15 @@ using SDImage = System.Drawing.Image; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { [Config(typeof(Config.ShortClr))] - public class DecodeJpeg : BenchmarkBase + public class DecodeJpeg { private byte[] jpegBytes; private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - [Params(TestImages.Jpeg.Baseline.Jpeg420Exif, TestImages.Jpeg.Baseline.Calliphora)] + [Params(TestImages.Jpeg.Baseline.Jpeg420Exif + //, TestImages.Jpeg.Baseline.Calliphora + )] public string TestImage { get; set; } [GlobalSetup] diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs index 77ed828ef..d0d4d569a 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs @@ -15,7 +15,7 @@ using SixLabors.ImageSharp.Formats.Jpeg; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { [Config(typeof(Config.ShortClr))] - public class LoadResizeSave : BenchmarkBase + public class LoadResizeSave { private readonly Configuration configuration = new Configuration(new JpegConfigurationModule()); @@ -32,23 +32,17 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg public string TestImage { get; set; } [Params(false, true)] - public bool EnableParallelExecution { get; set; } + public bool ParallelExec { get; set; } [GlobalSetup] public void Setup() { this.configuration.MaxDegreeOfParallelism = - this.EnableParallelExecution ? Environment.ProcessorCount : 1; + this.ParallelExec ? Environment.ProcessorCount : 1; - if (this.sourceBytes == null) - { - this.sourceBytes = File.ReadAllBytes(this.TestImageFullPath); - } + this.sourceBytes = File.ReadAllBytes(this.TestImageFullPath); - if (this.destBytes == null) - { - this.destBytes = new byte[this.sourceBytes.Length]; - } + this.destBytes = new byte[this.sourceBytes.Length * 2]; } [Benchmark(Baseline = true)] @@ -59,12 +53,12 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg using (var source = SDImage.FromStream(sourceStream)) using (var destination = new Bitmap(source.Width / 4, source.Height / 4)) { - using (var graphics = Graphics.FromImage(destination)) + using (var g = Graphics.FromImage(destination)) { - graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - graphics.CompositingQuality = CompositingQuality.HighQuality; - graphics.DrawImage(source, 0, 0, 400, 400); + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.CompositingQuality = CompositingQuality.HighQuality; + g.DrawImage(source, 0, 0, 400, 400); } destination.Save(destStream, ImageFormat.Jpeg); @@ -82,5 +76,28 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg source.SaveAsJpeg(destStream); } } + + // RESULTS: + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-ZPEZGV : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-SGOCJT : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // Method | Runtime | TestImage | ParallelExec | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // -------------- |-------- |----------------------------- |------------- |----------:|----------:|----------:|-------:|---------:|---------:|----------:| + // SystemDrawing | Clr | Jpg/baseline/jpeg420exif.jpg | False | 64.88 ms | 3.735 ms | 0.2110 ms | 1.00 | 0.00 | 250.0000 | 791.07 KB | + // ImageSharp | Clr | Jpg/baseline/jpeg420exif.jpg | False | 129.53 ms | 23.423 ms | 1.3234 ms | 2.00 | 0.02 | - | 50.09 KB | + // | | | | | | | | | | | + // SystemDrawing | Core | Jpg/baseline/jpeg420exif.jpg | False | 65.87 ms | 10.488 ms | 0.5926 ms | 1.00 | 0.00 | 250.0000 | 789.79 KB | + // ImageSharp | Core | Jpg/baseline/jpeg420exif.jpg | False | 92.00 ms | 7.241 ms | 0.4091 ms | 1.40 | 0.01 | - | 46.36 KB | + // | | | | | | | | | | | + // SystemDrawing | Clr | Jpg/baseline/jpeg420exif.jpg | True | 64.23 ms | 5.998 ms | 0.3389 ms | 1.00 | 0.00 | 250.0000 | 791.07 KB | + // ImageSharp | Clr | Jpg/baseline/jpeg420exif.jpg | True | 82.63 ms | 29.320 ms | 1.6566 ms | 1.29 | 0.02 | - | 57.59 KB | + // | | | | | | | | | | | + // SystemDrawing | Core | Jpg/baseline/jpeg420exif.jpg | True | 64.20 ms | 6.560 ms | 0.3707 ms | 1.00 | 0.00 | 250.0000 | 789.79 KB | + // ImageSharp | Core | Jpg/baseline/jpeg420exif.jpg | True | 68.08 ms | 18.376 ms | 1.0383 ms | 1.06 | 0.01 | - | 50.49 KB | } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs index f046f3033..608d3604f 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs using CoreImage = ImageSharp.Image; - public abstract class MultiImageBenchmarkBase : BenchmarkBase + public abstract class MultiImageBenchmarkBase { protected Dictionary FileNamesToBytes = new Dictionary(); diff --git a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs index f53061d4e..2be892295 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs @@ -22,15 +22,17 @@ namespace SixLabors.ImageSharp.Benchmarks private Bitmap sourceBitmap; - public const int SourceSize = 3032; + [Params(3032)] + public int SourceSize { get; set; } - public const int DestSize = 400; + [Params(400)] + public int DestSize { get; set; } [GlobalSetup] public void Setup() { - this.sourceImage = new Image(this.Configuration, SourceSize, SourceSize); - this.sourceBitmap = new Bitmap(SourceSize, SourceSize); + this.sourceImage = new Image(this.Configuration, this.SourceSize, this.SourceSize); + this.sourceBitmap = new Bitmap(this.SourceSize, this.SourceSize); } [GlobalCleanup] @@ -43,14 +45,17 @@ namespace SixLabors.ImageSharp.Benchmarks [Benchmark(Baseline = true)] public int SystemDrawing() { - using (var destination = new Bitmap(DestSize, DestSize)) + using (var destination = new Bitmap(this.DestSize, this.DestSize)) { - using (var graphics = Graphics.FromImage(destination)) + using (var g = Graphics.FromImage(destination)) { - graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; - graphics.CompositingQuality = CompositingQuality.HighQuality; - graphics.DrawImage(this.sourceBitmap, 0, 0, DestSize, DestSize); + g.CompositingMode = CompositingMode.SourceCopy; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.CompositingQuality = CompositingQuality.HighQuality; + g.SmoothingMode = SmoothingMode.HighQuality; + + g.DrawImage(this.sourceBitmap, 0, 0, this.DestSize, this.DestSize); } return destination.Width; @@ -83,15 +88,60 @@ namespace SixLabors.ImageSharp.Benchmarks { protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { - ctx.Resize(DestSize, DestSize, KnownResamplers.Bicubic); + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); } + + // RESULTS: + // + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-IGUFBA : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-DZFERG : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // Method | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | + // ----------------------------------------- |-------- |----------- |--------- |----------:|----------:|----------:|-------:|---------:|----------:| + // SystemDrawing | Clr | 3032 | 400 | 101.13 ms | 18.659 ms | 1.0542 ms | 1.00 | 0.00 | 0 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | 3032 | 400 | 122.05 ms | 19.622 ms | 1.1087 ms | 1.21 | 0.01 | 21856 B | + // 'ImageSharp, MaxDegreeOfParallelism = 4' | Clr | 3032 | 400 | 41.34 ms | 54.841 ms | 3.0986 ms | 0.41 | 0.03 | 28000 B | + // 'ImageSharp, MaxDegreeOfParallelism = 8' | Clr | 3032 | 400 | 31.68 ms | 12.782 ms | 0.7222 ms | 0.31 | 0.01 | 28256 B | + // | | | | | | | | | | + // SystemDrawing | Core | 3032 | 400 | 100.37 ms | 18.479 ms | 1.0441 ms | 1.00 | 0.00 | 0 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | 3032 | 400 | 73.03 ms | 10.540 ms | 0.5955 ms | 0.73 | 0.01 | 21368 B | + // 'ImageSharp, MaxDegreeOfParallelism = 4' | Core | 3032 | 400 | 22.59 ms | 4.863 ms | 0.2748 ms | 0.23 | 0.00 | 25220 B | + // 'ImageSharp, MaxDegreeOfParallelism = 8' | Core | 3032 | 400 | 21.10 ms | 23.362 ms | 1.3200 ms | 0.21 | 0.01 | 25539 B | + } public class Resize_BicubicCompand : ResizeBenchmarkBase { protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { - ctx.Resize(DestSize, DestSize, KnownResamplers.Bicubic, true); + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true); } + + // RESULTS: + // + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-IGUFBA : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-DZFERG : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // Method | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | + // ----------------------------------------- |-------- |----------- |--------- |----------:|----------:|----------:|-------:|---------:|----------:| + // SystemDrawing | Clr | 3032 | 400 | 100.63 ms | 13.864 ms | 0.7833 ms | 1.00 | 0.00 | 0 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | 3032 | 400 | 156.83 ms | 28.631 ms | 1.6177 ms | 1.56 | 0.02 | 21856 B | + // 'ImageSharp, MaxDegreeOfParallelism = 4' | Clr | 3032 | 400 | 53.43 ms | 38.493 ms | 2.1749 ms | 0.53 | 0.02 | 28512 B | + // 'ImageSharp, MaxDegreeOfParallelism = 8' | Clr | 3032 | 400 | 38.47 ms | 11.969 ms | 0.6763 ms | 0.38 | 0.01 | 28000 B | + // | | | | | | | | | | + // SystemDrawing | Core | 3032 | 400 | 99.87 ms | 23.459 ms | 1.3255 ms | 1.00 | 0.00 | 0 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | 3032 | 400 | 108.19 ms | 38.562 ms | 2.1788 ms | 1.08 | 0.02 | 21368 B | + // 'ImageSharp, MaxDegreeOfParallelism = 4' | Core | 3032 | 400 | 36.21 ms | 53.802 ms | 3.0399 ms | 0.36 | 0.03 | 25300 B | + // 'ImageSharp, MaxDegreeOfParallelism = 8' | Core | 3032 | 400 | 26.52 ms | 2.173 ms | 0.1228 ms | 0.27 | 0.00 | 25589 B | } } From b49b509988dd63746cc74499aef7624633b9ae58 Mon Sep 17 00:00:00 2001 From: Devedse Date: Wed, 31 Oct 2018 00:41:07 +0100 Subject: [PATCH 117/238] Work in progress preserving isTrans data --- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 97 ++++++++------------ src/ImageSharp/Formats/Png/PngEncoderCore.cs | 5 + src/ImageSharp/Formats/Png/PngMetaData.cs | 27 ++++++ src/ImageSharp/MetaData/ImageMetaData.cs | 1 + 4 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 11c4d831b..024bd6221 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -124,31 +124,6 @@ namespace SixLabors.ImageSharp.Formats.Png /// private PngColorType pngColorType; - /// - /// Represents any color in an 8 bit Rgb24 encoded png that should be transparent - /// - private Rgb24 rgb24Trans; - - /// - /// Represents any color in a 16 bit Rgb24 encoded png that should be transparent - /// - private Rgb48 rgb48Trans; - - /// - /// Represents any color in an 8 bit grayscale encoded png that should be transparent - /// - private byte luminanceTrans; - - /// - /// Represents any color in a 16 bit grayscale encoded png that should be transparent - /// - private ushort luminance16Trans; - - /// - /// Whether the image has transparency chunk and markers were decoded - /// - private bool hasTrans; - /// /// The next chunk of data to return /// @@ -213,7 +188,7 @@ namespace SixLabors.ImageSharp.Formats.Png using (var deframeStream = new ZlibInflateStream(this.currentStream, this.ReadNextDataChunk)) { deframeStream.AllocateNewBytes(chunk.Length); - this.ReadScanlines(deframeStream.CompressedStream, image.Frames.RootFrame); + this.ReadScanlines(deframeStream.CompressedStream, image.Frames.RootFrame, pngMetaData); } break; @@ -226,7 +201,7 @@ namespace SixLabors.ImageSharp.Formats.Png byte[] alpha = new byte[chunk.Length]; Buffer.BlockCopy(chunk.Data.Array, 0, alpha, 0, chunk.Length); this.paletteAlpha = alpha; - this.AssignTransparentMarkers(alpha); + this.AssignTransparentMarkers(alpha, pngMetaData); break; case PngChunkType.Text: this.ReadTextChunk(metaData, chunk.Data.Array.AsSpan(0, chunk.Length)); @@ -331,7 +306,9 @@ namespace SixLabors.ImageSharp.Formats.Png /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] private static byte ReadByteLittleEndian(ReadOnlySpan buffer, int offset) - => (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF)); + { + return (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF)); + } /// /// Attempts to convert a byte array to a new array where each value in the original array is represented by the @@ -496,16 +473,17 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The containing data. /// The pixel data. - private void ReadScanlines(Stream dataStream, ImageFrame image) + /// The png meta data + private void ReadScanlines(Stream dataStream, ImageFrame image, PngMetaData pngMetaData) where TPixel : struct, IPixel { if (this.header.InterlaceMethod == PngInterlaceMode.Adam7) { - this.DecodeInterlacedPixelData(dataStream, image); + this.DecodeInterlacedPixelData(dataStream, image, pngMetaData); } else { - this.DecodePixelData(dataStream, image); + this.DecodePixelData(dataStream, image, pngMetaData); } } @@ -515,7 +493,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The compressed pixel data stream. /// The image to decode to. - private void DecodePixelData(Stream compressedStream, ImageFrame image) + /// The png meta data + private void DecodePixelData(Stream compressedStream, ImageFrame image, PngMetaData pngMetaData) where TPixel : struct, IPixel { while (this.currentRow < this.header.Height) @@ -555,7 +534,7 @@ namespace SixLabors.ImageSharp.Formats.Png throw new ImageFormatException("Unknown filter type."); } - this.ProcessDefilteredScanline(scanlineSpan, image); + this.ProcessDefilteredScanline(scanlineSpan, image, pngMetaData); this.SwapBuffers(); this.currentRow++; @@ -569,7 +548,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The compressed pixel data stream. /// The current image. - private void DecodeInterlacedPixelData(Stream compressedStream, ImageFrame image) + /// The png meta data + private void DecodeInterlacedPixelData(Stream compressedStream, ImageFrame image, PngMetaData pngMetaData) where TPixel : struct, IPixel { while (true) @@ -626,7 +606,7 @@ namespace SixLabors.ImageSharp.Formats.Png } Span rowSpan = image.GetPixelRowSpan(this.currentRow); - this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, Adam7.FirstColumn[this.pass], Adam7.ColumnIncrement[this.pass]); + this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, pngMetaData, Adam7.FirstColumn[this.pass], Adam7.ColumnIncrement[this.pass]); this.SwapBuffers(); @@ -654,7 +634,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The de-filtered scanline /// The image - private void ProcessDefilteredScanline(ReadOnlySpan defilteredScanline, ImageFrame pixels) + /// The png meta data + private void ProcessDefilteredScanline(ReadOnlySpan defilteredScanline, ImageFrame pixels, PngMetaData pngMetaData) where TPixel : struct, IPixel { Span rowSpan = pixels.GetPixelRowSpan(this.currentRow); @@ -674,9 +655,9 @@ namespace SixLabors.ImageSharp.Formats.Png this.header, scanlineSpan, rowSpan, - this.hasTrans, - this.luminance16Trans, - this.luminanceTrans); + pngMetaData.HasTrans, + pngMetaData.Luminance16Trans, + pngMetaData.LuminanceTrans); break; @@ -708,9 +689,9 @@ namespace SixLabors.ImageSharp.Formats.Png rowSpan, this.bytesPerPixel, this.bytesPerSample, - this.hasTrans, - this.rgb48Trans, - this.rgb24Trans); + pngMetaData.HasTrans, + pngMetaData.Rgb48Trans, + pngMetaData.Rgb24Trans); break; @@ -735,9 +716,10 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The de-filtered scanline /// The current image row. + /// The png meta data /// The column start index. Always 0 for none interlaced images. /// The column increment. Always 1 for none interlaced images. - private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defilteredScanline, Span rowSpan, int pixelOffset = 0, int increment = 1) + private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defilteredScanline, Span rowSpan, PngMetaData pngMetaData, int pixelOffset = 0, int increment = 1) where TPixel : struct, IPixel { // Trim the first marker byte from the buffer @@ -757,9 +739,9 @@ namespace SixLabors.ImageSharp.Formats.Png rowSpan, pixelOffset, increment, - this.hasTrans, - this.luminance16Trans, - this.luminanceTrans); + pngMetaData.HasTrans, + pngMetaData.Luminance16Trans, + pngMetaData.LuminanceTrans); break; @@ -796,9 +778,9 @@ namespace SixLabors.ImageSharp.Formats.Png increment, this.bytesPerPixel, this.bytesPerSample, - this.hasTrans, - this.rgb48Trans, - this.rgb24Trans); + pngMetaData.HasTrans, + pngMetaData.Rgb48Trans, + pngMetaData.Rgb24Trans); break; @@ -822,7 +804,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// Decodes and assigns marker colors that identify transparent pixels in non indexed images /// /// The alpha tRNS array - private void AssignTransparentMarkers(ReadOnlySpan alpha) + /// The png meta data + private void AssignTransparentMarkers(ReadOnlySpan alpha, PngMetaData pngMetaData) { if (this.pngColorType == PngColorType.Rgb) { @@ -834,16 +817,16 @@ namespace SixLabors.ImageSharp.Formats.Png ushort gc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(2, 2)); ushort bc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(4, 2)); - this.rgb48Trans = new Rgb48(rc, gc, bc); - this.hasTrans = true; + pngMetaData.Rgb48Trans = new Rgb48(rc, gc, bc); + pngMetaData.HasTrans = true; return; } byte r = ReadByteLittleEndian(alpha, 0); byte g = ReadByteLittleEndian(alpha, 2); byte b = ReadByteLittleEndian(alpha, 4); - this.rgb24Trans = new Rgb24(r, g, b); - this.hasTrans = true; + pngMetaData.Rgb24Trans = new Rgb24(r, g, b); + pngMetaData.HasTrans = true; } } else if (this.pngColorType == PngColorType.Grayscale) @@ -852,14 +835,14 @@ namespace SixLabors.ImageSharp.Formats.Png { if (this.header.BitDepth == 16) { - this.luminance16Trans = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2)); + pngMetaData.Luminance16Trans = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2)); } else { - this.luminanceTrans = ReadByteLittleEndian(alpha, 0); + pngMetaData.LuminanceTrans = ReadByteLittleEndian(alpha, 0); } - this.hasTrans = true; + pngMetaData.HasTrans = true; } } } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 7ae716aa0..411d5d69b 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -290,6 +290,11 @@ namespace SixLabors.ImageSharp.Formats.Png this.WritePaletteChunk(stream, quantized); } + if (pngMetaData.HasTrans) + { + //Write transparency header + } + this.WritePhysicalChunk(stream, metaData); this.WriteGammaChunk(stream); this.WriteExifChunk(stream, metaData); diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs index 9c7676514..0014defbb 100644 --- a/src/ImageSharp/Formats/Png/PngMetaData.cs +++ b/src/ImageSharp/Formats/Png/PngMetaData.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.PixelFormats; + namespace SixLabors.ImageSharp.Formats.Png { /// @@ -42,6 +44,31 @@ namespace SixLabors.ImageSharp.Formats.Png /// public float Gamma { get; set; } + /// + /// Gets or sets the Rgb 24 transparent color. This represents any color in an 8 bit Rgb24 encoded png that should be transparent + /// + public Rgb24 Rgb24Trans { get; set; } + + /// + /// Gets or sets the Rgb 48 transparent color. This represents any color in a 16 bit Rgb24 encoded png that should be transparent + /// + public Rgb48 Rgb48Trans { get; set; } + + /// + /// Gets or sets the 8 bit grayscale transparent color. This represents any color in an 8 bit grayscale encoded png that should be transparent + /// + public byte LuminanceTrans { get; set; } + + /// + /// Gets or sets the 16 bit grayscale transparent color. This represents any color in a 16 bit grayscale encoded png that should be transparent + /// + public ushort Luminance16Trans { get; set; } + + /// + /// Gets or sets a value indicating whether the image has transparency chunk and markers were decoded + /// + public bool HasTrans { get; set; } + /// public IDeepCloneable DeepClone() => new PngMetaData(this); } diff --git a/src/ImageSharp/MetaData/ImageMetaData.cs b/src/ImageSharp/MetaData/ImageMetaData.cs index 73549d98a..ec9037479 100644 --- a/src/ImageSharp/MetaData/ImageMetaData.cs +++ b/src/ImageSharp/MetaData/ImageMetaData.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.MetaData.Profiles.Icc; +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.MetaData { From 70e96992900cd6e1356b2a3fb23051ce192b7422 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 31 Oct 2018 00:54:40 +0100 Subject: [PATCH 118/238] results for DecodeJpeg --- .../Codecs/Jpeg/DecodeJpeg.cs | 19 +++++++++++++++++++ .../Codecs/Jpeg/LoadResizeSave.cs | 3 ++- .../ImageSharp.Benchmarks/Samplers/Resize.cs | 4 ++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs index 8eb1fdda6..2afacb1e4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs @@ -57,5 +57,24 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } } + + // RESULTS (2018 October): + // + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // + // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| + // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | + // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | + // | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs index d0d4d569a..72062fc7d 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs @@ -77,7 +77,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - // RESULTS: + // RESULTS (2018 October): + // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC diff --git a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs index 2be892295..148b25328 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Benchmarks ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); } - // RESULTS: + // RESULTS (2018 October): // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Benchmarks ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true); } - // RESULTS: + // RESULTS (2018 October): // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores From e286054fcf00ca06e64959cade5dca3adc92c468 Mon Sep 17 00:00:00 2001 From: Devedse Date: Wed, 31 Oct 2018 01:14:09 +0100 Subject: [PATCH 119/238] This should write transparency --- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 16 +++--- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 56 ++++++++++++++++++-- src/ImageSharp/Formats/Png/PngMetaData.cs | 8 +-- 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 024bd6221..87c22a2ad 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -656,8 +656,8 @@ namespace SixLabors.ImageSharp.Formats.Png scanlineSpan, rowSpan, pngMetaData.HasTrans, - pngMetaData.Luminance16Trans, - pngMetaData.LuminanceTrans); + pngMetaData.Luminance16Trans.GetValueOrDefault(), + pngMetaData.LuminanceTrans.GetValueOrDefault()); break; @@ -690,8 +690,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerPixel, this.bytesPerSample, pngMetaData.HasTrans, - pngMetaData.Rgb48Trans, - pngMetaData.Rgb24Trans); + pngMetaData.Rgb48Trans.GetValueOrDefault(), + pngMetaData.Rgb24Trans.GetValueOrDefault()); break; @@ -740,8 +740,8 @@ namespace SixLabors.ImageSharp.Formats.Png pixelOffset, increment, pngMetaData.HasTrans, - pngMetaData.Luminance16Trans, - pngMetaData.LuminanceTrans); + pngMetaData.Luminance16Trans.GetValueOrDefault(), + pngMetaData.LuminanceTrans.GetValueOrDefault()); break; @@ -779,8 +779,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerPixel, this.bytesPerSample, pngMetaData.HasTrans, - pngMetaData.Rgb48Trans, - pngMetaData.Rgb24Trans); + pngMetaData.Rgb48Trans.GetValueOrDefault(), + pngMetaData.Rgb24Trans.GetValueOrDefault()); break; diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 411d5d69b..c76dc308b 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -292,7 +292,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (pngMetaData.HasTrans) { - //Write transparency header + this.WriteTransparencyMarkers(stream, pngMetaData); } this.WritePhysicalChunk(stream, metaData); @@ -305,6 +305,50 @@ namespace SixLabors.ImageSharp.Formats.Png quantized?.Dispose(); } + /// + /// Writes the transparency markers to the stream + /// + /// The containing image data. + /// The image meta data. + private void WriteTransparencyMarkers(Stream stream, PngMetaData pngMetaData) + { + if (pngMetaData.ColorType == PngColorType.Rgb) + { + if (pngMetaData.Rgb48Trans != null) + { + var r = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); + var g = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); + var B = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.B); + + var alphaArray = r.Concat(g).Concat(B).ToArray(); + + this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); + } + else if (pngMetaData.Rgb24Trans != null) + { + var alphaArray = new byte[6]; + alphaArray[0] = pngMetaData.Rgb24Trans.Value.R; + alphaArray[2] = pngMetaData.Rgb24Trans.Value.G; + alphaArray[4] = pngMetaData.Rgb24Trans.Value.B; + this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); + } + } + else if (pngMetaData.ColorType == PngColorType.Grayscale) + { + if (pngMetaData.Luminance16Trans != null) + { + var alphaArray = BitConverter.GetBytes(pngMetaData.Luminance16Trans.Value); + + this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); + } + else if (pngMetaData.LuminanceTrans != null) + { + var alphaArray = new byte[2]; + alphaArray[0] = pngMetaData.LuminanceTrans.Value; + } + } + } + /// public void Dispose() { @@ -848,7 +892,10 @@ namespace SixLabors.ImageSharp.Formats.Png /// Writes the chunk end to the stream. /// /// The containing image data. - private void WriteEndChunk(Stream stream) => this.WriteChunk(stream, PngChunkType.End, null); + private void WriteEndChunk(Stream stream) + { + this.WriteChunk(stream, PngChunkType.End, null); + } /// /// Writes a chunk to the stream. @@ -856,7 +903,10 @@ namespace SixLabors.ImageSharp.Formats.Png /// The to write to. /// The type of chunk to write. /// The containing data. - private void WriteChunk(Stream stream, PngChunkType type, byte[] data) => this.WriteChunk(stream, type, data, 0, data?.Length ?? 0); + private void WriteChunk(Stream stream, PngChunkType type, byte[] data) + { + this.WriteChunk(stream, type, data, 0, data?.Length ?? 0); + } /// /// Writes a chunk of a specified length to the stream at the given offset. diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs index 0014defbb..765222795 100644 --- a/src/ImageSharp/Formats/Png/PngMetaData.cs +++ b/src/ImageSharp/Formats/Png/PngMetaData.cs @@ -47,22 +47,22 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// Gets or sets the Rgb 24 transparent color. This represents any color in an 8 bit Rgb24 encoded png that should be transparent /// - public Rgb24 Rgb24Trans { get; set; } + public Rgb24? Rgb24Trans { get; set; } /// /// Gets or sets the Rgb 48 transparent color. This represents any color in a 16 bit Rgb24 encoded png that should be transparent /// - public Rgb48 Rgb48Trans { get; set; } + public Rgb48? Rgb48Trans { get; set; } /// /// Gets or sets the 8 bit grayscale transparent color. This represents any color in an 8 bit grayscale encoded png that should be transparent /// - public byte LuminanceTrans { get; set; } + public byte? LuminanceTrans { get; set; } /// /// Gets or sets the 16 bit grayscale transparent color. This represents any color in a 16 bit grayscale encoded png that should be transparent /// - public ushort Luminance16Trans { get; set; } + public ushort? Luminance16Trans { get; set; } /// /// Gets or sets a value indicating whether the image has transparency chunk and markers were decoded From 2b93aa2c4aaf226125d78bd89aeaa83484e03b56 Mon Sep 17 00:00:00 2001 From: Devedse Date: Wed, 31 Oct 2018 01:27:11 +0100 Subject: [PATCH 120/238] Fixed bug, code now actually fixed my unit test --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index c76dc308b..edf6cecd7 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -327,9 +327,9 @@ namespace SixLabors.ImageSharp.Formats.Png else if (pngMetaData.Rgb24Trans != null) { var alphaArray = new byte[6]; - alphaArray[0] = pngMetaData.Rgb24Trans.Value.R; - alphaArray[2] = pngMetaData.Rgb24Trans.Value.G; - alphaArray[4] = pngMetaData.Rgb24Trans.Value.B; + alphaArray[1] = pngMetaData.Rgb24Trans.Value.R; + alphaArray[3] = pngMetaData.Rgb24Trans.Value.G; + alphaArray[5] = pngMetaData.Rgb24Trans.Value.B; this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } } @@ -344,7 +344,9 @@ namespace SixLabors.ImageSharp.Formats.Png else if (pngMetaData.LuminanceTrans != null) { var alphaArray = new byte[2]; - alphaArray[0] = pngMetaData.LuminanceTrans.Value; + alphaArray[1] = pngMetaData.LuminanceTrans.Value; + + this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } } } From 804b92f7943ac87fec6b63e70b9188adad1b8eb8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 31 Oct 2018 01:29:10 +0100 Subject: [PATCH 121/238] drop ComplexIntegrationTests, add ProfilingBenchmarks --- .../ComplexIntegrationTests.cs | 35 ------------- tests/ImageSharp.Tests/ProfilingBenchmarks.cs | 52 +++++++++++++++++++ 2 files changed, 52 insertions(+), 35 deletions(-) delete mode 100644 tests/ImageSharp.Tests/ComplexIntegrationTests.cs create mode 100644 tests/ImageSharp.Tests/ProfilingBenchmarks.cs diff --git a/tests/ImageSharp.Tests/ComplexIntegrationTests.cs b/tests/ImageSharp.Tests/ComplexIntegrationTests.cs deleted file mode 100644 index a260ec33c..000000000 --- a/tests/ImageSharp.Tests/ComplexIntegrationTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using SixLabors.Primitives; - -using Xunit; - -namespace SixLabors.ImageSharp.Tests -{ - /// - /// Might be useful to catch complex bugs - /// - public class ComplexIntegrationTests - { - [Theory] - [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)] - [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)] - [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)] - [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)] - public void LoadResizeSave(TestImageProvider provider, int quality, JpegSubsample subsample) - where TPixel : struct, IPixel - { - using (Image image = provider.GetImage(x => x.Resize(new ResizeOptions { Size = new Size(150, 100), Mode = ResizeMode.Max }))) - { - - image.MetaData.ExifProfile = null; // Reduce the size of the file - JpegEncoder options = new JpegEncoder { Subsample = subsample, Quality = quality }; - - provider.Utility.TestName += $"{subsample}_Q{quality}"; - provider.Utility.SaveTestOutputFile(image, "png"); - provider.Utility.SaveTestOutputFile(image, "jpg", options); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks.cs new file mode 100644 index 000000000..fa873ef85 --- /dev/null +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks.cs @@ -0,0 +1,52 @@ +using System.IO; + +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.Primitives; + +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests +{ + public class ProfilingBenchmarks : MeasureFixture + { + public const string SkipProfilingTests = +#if false + null; +#else + "Profiling benchmark, enable manually!"; +#endif + + + public ProfilingBenchmarks(ITestOutputHelper output) + : base(output) + { + } + + [Theory(Skip = SkipProfilingTests)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg420Exif)] + public void LoadResizeSave(string imagePath) + { + var configuration = Configuration.CreateDefaultInstance(); + configuration.MaxDegreeOfParallelism = 1; + + byte[] imageBytes = TestFile.Create(imagePath).Bytes; + + using (var ms = new MemoryStream()) + { + this.Measure(30, + () => + { + using (var image = Image.Load(configuration, imageBytes)) + { + image.Mutate(x => x.Resize(image.Size() / 4)); + image.SaveAsJpeg(ms); + } + ms.Seek(0, SeekOrigin.Begin); + }); + } + } + } +} \ No newline at end of file From 72e46b344f268ae6c1f8e9150b031237faf1bb02 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 31 Oct 2018 01:34:13 +0100 Subject: [PATCH 122/238] use InliningOptions.ShortMethod --- .../Formats/Jpeg/Components/Block8x8F.cs | 30 +++++++++---------- .../Jpeg/Components/Decoder/ScanDecoder.cs | 2 +- .../Formats/Jpeg/JpegDecoderCore.cs | 4 +-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 59fc234c4..3a912dc62 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// The float value at the specified index public float this[int idx] { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get { GuardBlockIndex(idx); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return Unsafe.Add(ref selfRef, idx); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] set { GuardBlockIndex(idx); @@ -149,7 +149,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Fill the block with defaults (zeroes) /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void Clear() { // The cheapest way to do this in C#: @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Load raw 32bit floating point data from source /// /// Source - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void LoadFrom(Span source) { ref byte s = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); @@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Block pointer /// Source - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static unsafe void LoadFrom(Block8x8F* blockPtr, Span source) { blockPtr->LoadFrom(source); @@ -200,7 +200,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Copy raw 32bit floating point data to dest /// /// Destination - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void CopyTo(Span dest) { ref byte d = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); @@ -214,7 +214,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Pointer to block /// Destination - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static unsafe void CopyTo(Block8x8F* blockPtr, Span dest) { float* fPtr = (float*)blockPtr; @@ -230,7 +230,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Block pointer /// Destination - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static unsafe void CopyTo(Block8x8F* blockPtr, Span dest) { blockPtr->CopyTo(dest); @@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Copy raw 32bit floating point data to dest /// /// Destination - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public unsafe void CopyTo(float[] dest) { fixed (void* ptr = &this.V0L) @@ -276,7 +276,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Multiply all elements of the block. /// /// The value to multiply by - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void MultiplyInplace(float value) { this.V0L *= value; @@ -300,7 +300,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Multiply all elements of the block by the corresponding elements of 'other' /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void MultiplyInplace(ref Block8x8F other) { this.V0L *= other.V0L; @@ -325,7 +325,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Adds a vector to all elements of the block. /// /// The added vector - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void AddToAllInplace(Vector4 diff) { this.V0L += diff; @@ -420,7 +420,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static void DivideRoundAll(ref Block8x8F a, ref Block8x8F b) { a.V0L = DivideRound(a.V0L, b.V0L); @@ -511,7 +511,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return sb.ToString(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static Vector NormalizeAndRound(Vector row, Vector off, Vector max) { row += off; @@ -520,7 +520,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return row.FastRound(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor) { // sign(dividend) = max(min(dividend, 1), -1) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs index 351e45348..39b9792ac 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static uint LRot(uint x, int y) => (x << y) | (x >> (32 - y)); private void ParseBaselineData() diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 36246c682..68252f624 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -913,7 +913,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// The table index /// The codelengths /// The values - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void BuildHuffmanTable(HuffmanTables tables, int index, ReadOnlySpan codeLengths, ReadOnlySpan values) => tables[index] = new HuffmanTable(this.configuration.MemoryAllocator, codeLengths, values); @@ -921,7 +921,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// Reads a from the stream advancing it by two bytes /// /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private ushort ReadUint16() { this.InputStream.Read(this.markerBuffer, 0, 2); From 6ac7b951a5a19a42c6f63294b77d680651c7e5a0 Mon Sep 17 00:00:00 2001 From: Devedse <2350015+devedse@users.noreply.github.com> Date: Wed, 31 Oct 2018 02:04:59 +0100 Subject: [PATCH 123/238] Update PngEncoderCore.cs Lowercase b --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index edf6cecd7..1179a6db3 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -318,9 +318,9 @@ namespace SixLabors.ImageSharp.Formats.Png { var r = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); var g = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); - var B = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.B); + var b = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.B); - var alphaArray = r.Concat(g).Concat(B).ToArray(); + var alphaArray = r.Concat(g).Concat(b).ToArray(); this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } @@ -1004,4 +1004,4 @@ namespace SixLabors.ImageSharp.Formats.Png return scanlineLength / mod; } } -} \ No newline at end of file +} From 42913b64b7d8ab9e4660129bff52d2394f3e2d41 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 31 Oct 2018 18:00:11 +0000 Subject: [PATCH 124/238] Don't force transparency --- .../PixelFormats/NamedColors{TPixel}.cs | 5 +--- src/ImageSharp/Processing/KnownQuantizers.cs | 4 --- .../Quantization/QuantizedImageTests.cs | 25 ------------------- tests/Images/External | 2 +- 4 files changed, 2 insertions(+), 34 deletions(-) diff --git a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs index a757a393e..7e093de04 100644 --- a/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/NamedColors{TPixel}.cs @@ -746,10 +746,7 @@ namespace SixLabors.ImageSharp.PixelFormats private static TPixel[] GetPalette(Rgba32[] palette) { - // TODO: This should be the length only. - // We need to fix and update tests/reference images. - // If someone wants transparency they should add it to the palette. - var converted = new TPixel[palette.Length + 1]; + var converted = new TPixel[palette.Length]; Span constantsBytes = MemoryMarshal.Cast(palette.AsSpan()); PixelOperations.Instance.FromRgba32Bytes( diff --git a/src/ImageSharp/Processing/KnownQuantizers.cs b/src/ImageSharp/Processing/KnownQuantizers.cs index e93a9921a..e4a7a75d5 100644 --- a/src/ImageSharp/Processing/KnownQuantizers.cs +++ b/src/ImageSharp/Processing/KnownQuantizers.cs @@ -12,26 +12,22 @@ namespace SixLabors.ImageSharp.Processing { /// /// Gets the adaptive Octree quantizer. Fast with good quality. - /// The quantizer only supports a single alpha value. /// public static IQuantizer Octree { get; } = new OctreeQuantizer(); /// /// Gets the Xiaolin Wu's Color Quantizer which generates high quality output. - /// The quantizer supports multiple alpha values. /// public static IQuantizer Wu { get; } = new WuQuantizer(); /// /// Gets the palette based quantizer consisting of web safe colors as defined in the CSS Color Module Level 4. - /// The quantizer supports a single alpha value. /// public static IQuantizer WebSafe { get; } = new WebSafePaletteQuantizer(); /// /// Gets the palette based quantizer consisting of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. /// The hex codes were collected and defined by Nicholas Rougeux - /// The quantizer supports a single alpha value. /// public static IQuantizer Werner { get; } = new WernerPaletteQuantizer(); } diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index 753c2c109..a0d7869e3 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -31,31 +31,6 @@ namespace SixLabors.ImageSharp.Tests Assert.True(wu.CreateFrameQuantizer(this.Configuration).Dither); } - [Theory] - [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] - [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] - public void PaletteQuantizerYieldsCorrectTransparentPixel( - TestImageProvider provider, - bool dither) - where TPixel : struct, IPixel - { - using (Image image = provider.GetImage()) - { - Assert.True(image[0, 0].Equals(default(TPixel))); - - var quantizer = new WebSafePaletteQuantizer(dither); - - foreach (ImageFrame frame in image.Frames) - { - QuantizedFrame quantized = - quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); - - int index = this.GetTransparentIndex(quantized); - Assert.Equal(index, quantized.GetPixelSpan()[0]); - } - } - } - [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] diff --git a/tests/Images/External b/tests/Images/External index f41ae0327..ed8a7b0b6 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit f41ae0327a3ab21ab2388c32160bda67debcc082 +Subproject commit ed8a7b0b6fe1b2e2a7c822aa617103ae31192655 From a459ff10772d4ae3d16676604471c13ad21548ff Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 1 Nov 2018 14:16:53 +0100 Subject: [PATCH 125/238] InliningOptions.ShortMethod --- .../Formats/Jpeg/Components/Block8x8F.Generated.cs | 4 ++-- .../Formats/Jpeg/Components/Block8x8F.Generated.tt | 4 ++-- .../Formats/Jpg/JpegProfilingBenchmarks.cs | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs index e83896f58..53f29734c 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Transpose the block into the destination block. /// /// The destination block - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void TransposeInto(ref Block8x8F d) { d.V0L.X = V0L.X; @@ -119,7 +119,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// AVX2-only variant for executing and in one step. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void NormalizeColorsAndRoundInplaceAvx2() { Vector off = new Vector(128f); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt index 82d82ef0c..76c61f6c3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// Transpose the block into the destination block. /// /// The destination block - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void TransposeInto(ref Block8x8F d) { <# @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// AVX2-only variant for executing and in one step. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void NormalizeColorsAndRoundInplaceAvx2() { Vector off = new Vector(128f); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs index 32538090d..f60f478e1 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs @@ -24,21 +24,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public static readonly TheoryData DecodeJpegData = new TheoryData() { - TestImages.Jpeg.Baseline.Cmyk, - TestImages.Jpeg.Baseline.Ycck, + //TestImages.Jpeg.Baseline.Cmyk, + //TestImages.Jpeg.Baseline.Ycck, TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Jpeg400, TestImages.Jpeg.Baseline.Jpeg420Exif, TestImages.Jpeg.Baseline.Jpeg444, }; - // [Theory] // Benchmark, enable manually - // [MemberData(nameof(DecodeJpegData))] + [Theory] // Benchmark, enable manually + [MemberData(nameof(DecodeJpegData))] public void DecodeJpeg(string fileName) { this.DecodeJpegBenchmarkImpl(fileName, new JpegDecoder()); } - + private void DecodeJpegBenchmarkImpl(string fileName, IImageDecoder decoder) { // do not run this on CI even by accident From 22cf54b38ad73236d277a17558ffd912be0d55ac Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 1 Nov 2018 14:21:42 +0000 Subject: [PATCH 126/238] Change tolerance for Net462 --- tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index a98ae164a..b74a7a85f 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif public class GifEncoderTests { private const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.RgbaVector | PixelTypes.Argb32; - private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.001F); + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.0015F); public static readonly TheoryData RatioFiles = new TheoryData From b4c1f8bf37ac6d11739cb57438aae0ca8108e9e8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 1 Nov 2018 16:00:17 +0100 Subject: [PATCH 127/238] AVX2 optimized Block8x8 -> Block8x8F conversion --- src/ImageSharp/Common/Helpers/DebugGuard.cs | 14 ++++++ .../Common/Helpers/InliningOptions.cs | 2 +- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 14 ++++++ .../Jpeg/Components/Block8x8F.Generated.cs | 2 +- .../Jpeg/Components/Block8x8F.Generated.tt | 2 +- .../Formats/Jpeg/Components/Block8x8F.cs | 45 +++++++++++++++++++ .../ImageSharp.Tests/Common/SimdUtilsTests.cs | 21 +++++++++ .../Formats/Jpg/Block8x8FTests.cs | 42 +++++++++++++++++ .../Formats/Jpg/JpegProfilingBenchmarks.cs | 4 +- .../Formats/Jpg/Utils/JpegFixture.cs | 7 ++- tests/ImageSharp.Tests/ProfilingBenchmarks.cs | 2 +- .../TestUtilities/TestDataGenerator.cs | 11 +++++ 12 files changed, 159 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/DebugGuard.cs b/src/ImageSharp/Common/Helpers/DebugGuard.cs index 2cf18b245..43eebeac8 100644 --- a/src/ImageSharp/Common/Helpers/DebugGuard.cs +++ b/src/ImageSharp/Common/Helpers/DebugGuard.cs @@ -163,6 +163,20 @@ namespace SixLabors.ImageSharp } } + /// + /// Verifies whether a specific condition is met, throwing an exception if it's false. + /// + /// The condition + /// The error message + [Conditional("DEBUG")] + public static void IsTrue(bool target, string message) + { + if (!target) + { + throw new InvalidOperationException(message); + } + } + /// /// Verifies, that the method parameter with specified target value is false /// and throws an exception if it is found to be so. diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index ad85c4fc8..f61e4f8ae 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. // Uncomment this for verbose profiler results: -// #define PROFILING +#define PROFILING using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 2ac577264..463961d86 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -25,6 +25,20 @@ namespace SixLabors.ImageSharp false; #endif + /// + /// Widen and convert a vector of values into 2 vectors of -s. + /// + [MethodImpl(InliningOptions.ShortMethod)] + internal static void ConvertToSingle( + Vector source, + out Vector dest1, + out Vector dest2) + { + Vector.Widen(source, out Vector i1, out Vector i2); + dest1 = Vector.ConvertToSingle(i1); + dest2 = Vector.ConvertToSingle(i2); + } + /// /// as many elements as possible, slicing them down (keeping the remainder). /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs index 53f29734c..09ed6408d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Fill the block from 'source' doing short -> float conversion. /// - public void LoadFrom(ref Block8x8 source) + public void LoadFromInt16Scalar(ref Block8x8 source) { ref short selfRef = ref Unsafe.As(ref source); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt index 76c61f6c3..f93ee6522 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Fill the block from 'source' doing short -> float conversion. /// - public void LoadFrom(ref Block8x8 source) + public void LoadFromInt16Scalar(ref Block8x8 source) { ref short selfRef = ref Unsafe.As(ref source); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 3a912dc62..137a8029d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -493,6 +493,51 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } + [MethodImpl(InliningOptions.ShortMethod)] + public void LoadFrom(ref Block8x8 source) + { +#if SUPPORTS_EXTENDED_INTRINSICS + if (SimdUtils.IsAvx2CompatibleArchitecture) + { + this.LoadFromInt16ExtendedAvx2(ref source); + return; + } +#endif + this.LoadFromInt16Scalar(ref source); + } + + /// + /// Loads values from using extended AVX2 intrinsics. + /// + /// The source + public void LoadFromInt16ExtendedAvx2(ref Block8x8 source) + { + DebugGuard.IsTrue( + SimdUtils.IsAvx2CompatibleArchitecture, + "LoadFromUInt16ExtendedAvx2 only works on AVX2 compatible architecture!"); + + ref Vector sRef = ref Unsafe.As>(ref source); + ref Vector dRef = ref Unsafe.As>(ref this); + + // Vector.Count == 16 on AVX2 + // We can process 2 block rows in a single step + SimdUtils.ExtendedIntrinsics.ConvertToSingle(sRef, out Vector top, out Vector bottom); + dRef = top; + Unsafe.Add(ref dRef, 1) = bottom; + + SimdUtils.ExtendedIntrinsics.ConvertToSingle(Unsafe.Add(ref sRef, 1), out top, out bottom); + Unsafe.Add(ref dRef, 2) = top; + Unsafe.Add(ref dRef, 3) = bottom; + + SimdUtils.ExtendedIntrinsics.ConvertToSingle(Unsafe.Add(ref sRef, 2), out top, out bottom); + Unsafe.Add(ref dRef, 4) = top; + Unsafe.Add(ref dRef, 5) = bottom; + + SimdUtils.ExtendedIntrinsics.ConvertToSingle(Unsafe.Add(ref sRef, 3), out top, out bottom); + Unsafe.Add(ref dRef, 6) = top; + Unsafe.Add(ref dRef, 7) = bottom; + } + /// public override string ToString() { diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index c63cb3438..4f8a2cdaf 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -257,6 +257,27 @@ namespace SixLabors.ImageSharp.Tests.Common ); } + [Theory] + [InlineData(1234)] + public void ExtendedIntrinsics_ConvertToSingle(short scale) + { + int n = Vector.Count; + short[] sData = new Random(scale).GenerateRandomInt16Array(2 * n, (short)-scale, scale); + float[] fData = sData.Select(u => (float)u).ToArray(); + + var source = new Vector(sData); + + var expected1 = new Vector(fData, 0); + var expected2 = new Vector(fData, n); + + // Act: + SimdUtils.ExtendedIntrinsics.ConvertToSingle(source, out Vector actual1, out Vector actual2); + + // Assert: + Assert.Equal(expected1, actual1); + Assert.Equal(expected2, actual2); + } + [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void BulkConvertNormalizedFloatToByteClampOverflows(int count) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index e72f4945b..81c76390c 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -408,5 +408,47 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(original[i] * 42f, actual[i]); } } + + [Fact] + public void LoadFromUInt16Scalar() + { + if (this.SkipOnNonAvx2Runner()) + { + return; + } + + short[] data = Create8x8ShortData(); + + var source = new Block8x8(data); + + Block8x8F dest = default; + dest.LoadFromInt16Scalar(ref source); + + for (int i = 0; i < Block8x8F.Size; i++) + { + Assert.Equal((float)data[i], dest[i]); + } + } + + [Fact] + public void LoadFromUInt16ExtendedAvx2() + { + if (this.SkipOnNonAvx2Runner()) + { + return; + } + + short[] data = Create8x8ShortData(); + + var source = new Block8x8(data); + + Block8x8F dest = default; + dest.LoadFromInt16ExtendedAvx2(ref source); + + for (int i = 0; i < Block8x8F.Size; i++) + { + Assert.Equal((float)data[i], dest[i]); + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs index f60f478e1..7d5130e1b 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs @@ -32,8 +32,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, }; - [Theory] // Benchmark, enable manually - [MemberData(nameof(DecodeJpegData))] + //[Theory] // Benchmark, enable manually + //[MemberData(nameof(DecodeJpegData))] public void DecodeJpeg(string fileName) { this.DecodeJpegBenchmarkImpl(fileName, new JpegDecoder()); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs index d14fbc3fc..89fdd5745 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs @@ -58,7 +58,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils { for (int j = 0; j < 8; j++) { - result[i * 8 + j] = (short)(i * 10 + j); + short val = (short)(i * 10 + j); + if ((i + j) % 2 == 0) + { + val *= -1; + } + result[i * 8 + j] = val; } } return result; diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks.cs index fa873ef85..bc9b2a947 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Tests public class ProfilingBenchmarks : MeasureFixture { public const string SkipProfilingTests = -#if false +#if true null; #else "Profiling benchmark, enable manually!"; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs index 56cde41fc..e3d8bf380 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestDataGenerator.cs @@ -88,6 +88,17 @@ namespace SixLabors.ImageSharp.Tests return values; } + public static short[] GenerateRandomInt16Array(this Random rnd, int length, short minVal, short maxVal) + { + short[] values = new short[length]; + for (int i = 0; i < values.Length; i++) + { + values[i] = (short)rnd.Next(minVal, maxVal); + } + + return values; + } + private static float GetRandomFloat(this Random rnd, float minVal, float maxVal) => ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal; } } \ No newline at end of file From cec2d1d67da8e791ba12313578702131c2dd6d05 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 2 Nov 2018 00:36:04 +0100 Subject: [PATCH 128/238] Moved IJpegComponent.GetBlockReference(...) to an extension method --- .../Jpeg/Components/Decoder/IJpegComponent.cs | 11 +----- .../Jpeg/Components/Decoder/JpegComponent.cs | 18 ++------- .../Decoder/JpegComponentExtensions.cs | 39 +++++++++++++++++++ 3 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs index c03398033..2492a985a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder @@ -43,16 +42,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// /// Gets the storing the "raw" frequency-domain decoded + unzigged blocks. - /// We need to apply IDCT and dequantiazition to transform them into color-space blocks. + /// We need to apply IDCT and dequantization to transform them into color-space blocks. /// Buffer2D SpectralBlocks { get; } - - /// - /// Gets a reference to the at the given row and column index from - /// - /// The column - /// The row - /// The - ref Block8x8 GetBlockReference(int column, int row); } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs index 65a584c4f..ef03582d6 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs @@ -128,21 +128,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); } - this.SpectralBlocks = this.memoryAllocator.Allocate2D(blocksPerColumnForMcu, blocksPerLineForMcu + 1, AllocationOptions.Clean); - } + int totalNumberOfBlocks = blocksPerColumnForMcu * (blocksPerLineForMcu + 1); + int width = this.WidthInBlocks + 1; + int height = totalNumberOfBlocks / width; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref Block8x8 GetBlockReference(int column, int row) - { - int offset = ((this.WidthInBlocks + 1) * row) + column; - return ref Unsafe.Add(ref MemoryMarshal.GetReference(this.SpectralBlocks.GetSpan()), offset); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref short GetBlockDataReference(int column, int row) - { - ref Block8x8 blockRef = ref this.GetBlockReference(column, row); - return ref Unsafe.As(ref blockRef); + this.SpectralBlocks = this.memoryAllocator.Allocate2D(width, height, AllocationOptions.Clean); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs new file mode 100644 index 000000000..d7fb52a79 --- /dev/null +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs @@ -0,0 +1,39 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Runtime.CompilerServices; + +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder +{ + /// + /// Extension methods for + /// + internal static class JpegComponentExtensions + { + /// + /// Gets a reference to the at the given row and column index from + /// + /// The + /// The column + /// The row + /// The + [MethodImpl(InliningOptions.ShortMethod)] + public static ref Block8x8 GetBlockReference(this IJpegComponent component, int column, int row) + { + return ref component.SpectralBlocks.GetRowSpan(row)[column]; + } + + /// + /// Gets a reference to the first item in a block + /// at the given row and column index from + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static ref short GetBlockDataReference(this IJpegComponent component, int column, int row) + { + ref Block8x8 blockRef = ref component.GetBlockReference(column, row); + return ref Unsafe.As(ref blockRef); + } + } +} \ No newline at end of file From ae0e0a2fc7eef615b852a5523fc82e5789c71497 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 2 Nov 2018 00:45:25 +0100 Subject: [PATCH 129/238] do not use GetBlockReference() on hot path --- .../Decoder/JpegComponentPostProcessor.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs index 890f40259..57a53549f 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using SixLabors.Memory; @@ -88,12 +90,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int yBuffer = y * this.blockAreaSize.Height; - for (int x = 0; x < this.SizeInBlocks.Width; x++) - { - int xBlock = x; - int xBuffer = x * this.blockAreaSize.Width; + Span blockRow = this.Component.SpectralBlocks.GetRowSpan(yBlock); + + ref Block8x8 blockRowBase = ref MemoryMarshal.GetReference(blockRow); - ref Block8x8 block = ref this.Component.GetBlockReference(xBlock, yBlock); + for (int xBlock = 0; xBlock < this.SizeInBlocks.Width; xBlock++) + { + ref Block8x8 block = ref Unsafe.Add(ref blockRowBase, xBlock); + int xBuffer = xBlock * this.blockAreaSize.Width; BufferArea destArea = this.ColorBuffer.GetArea( xBuffer, From 88e3ae4856c908dfa65c4a9125f61c248203edf6 Mon Sep 17 00:00:00 2001 From: Devedse Date: Fri, 2 Nov 2018 17:36:38 +0100 Subject: [PATCH 130/238] Removed unused using --- src/ImageSharp/MetaData/ImageMetaData.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ImageSharp/MetaData/ImageMetaData.cs b/src/ImageSharp/MetaData/ImageMetaData.cs index ec9037479..73549d98a 100644 --- a/src/ImageSharp/MetaData/ImageMetaData.cs +++ b/src/ImageSharp/MetaData/ImageMetaData.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.MetaData.Profiles.Icc; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.MetaData { From 1b5b85572b2e2b3fa2123619d0e91501dffc5dfb Mon Sep 17 00:00:00 2001 From: Devedse Date: Fri, 2 Nov 2018 17:49:35 +0100 Subject: [PATCH 131/238] Resolved findings in PR --- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 24 +++++++++---------- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 24 +++++++++---------- src/ImageSharp/Formats/Png/PngMetaData.cs | 8 +++---- .../Formats/Png/PngScanlineProcessor.cs | 16 ++++++------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 87c22a2ad..c446184d8 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -656,8 +656,8 @@ namespace SixLabors.ImageSharp.Formats.Png scanlineSpan, rowSpan, pngMetaData.HasTrans, - pngMetaData.Luminance16Trans.GetValueOrDefault(), - pngMetaData.LuminanceTrans.GetValueOrDefault()); + pngMetaData.TransparentGray16.GetValueOrDefault(), + pngMetaData.TransparentGray8.GetValueOrDefault()); break; @@ -690,8 +690,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerPixel, this.bytesPerSample, pngMetaData.HasTrans, - pngMetaData.Rgb48Trans.GetValueOrDefault(), - pngMetaData.Rgb24Trans.GetValueOrDefault()); + pngMetaData.TransparentRgb48.GetValueOrDefault(), + pngMetaData.TransparentRgb24.GetValueOrDefault()); break; @@ -740,8 +740,8 @@ namespace SixLabors.ImageSharp.Formats.Png pixelOffset, increment, pngMetaData.HasTrans, - pngMetaData.Luminance16Trans.GetValueOrDefault(), - pngMetaData.LuminanceTrans.GetValueOrDefault()); + pngMetaData.TransparentGray16.GetValueOrDefault(), + pngMetaData.TransparentGray8.GetValueOrDefault()); break; @@ -779,8 +779,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerPixel, this.bytesPerSample, pngMetaData.HasTrans, - pngMetaData.Rgb48Trans.GetValueOrDefault(), - pngMetaData.Rgb24Trans.GetValueOrDefault()); + pngMetaData.TransparentRgb48.GetValueOrDefault(), + pngMetaData.TransparentRgb24.GetValueOrDefault()); break; @@ -817,7 +817,7 @@ namespace SixLabors.ImageSharp.Formats.Png ushort gc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(2, 2)); ushort bc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(4, 2)); - pngMetaData.Rgb48Trans = new Rgb48(rc, gc, bc); + pngMetaData.TransparentRgb48 = new Rgb48(rc, gc, bc); pngMetaData.HasTrans = true; return; } @@ -825,7 +825,7 @@ namespace SixLabors.ImageSharp.Formats.Png byte r = ReadByteLittleEndian(alpha, 0); byte g = ReadByteLittleEndian(alpha, 2); byte b = ReadByteLittleEndian(alpha, 4); - pngMetaData.Rgb24Trans = new Rgb24(r, g, b); + pngMetaData.TransparentRgb24 = new Rgb24(r, g, b); pngMetaData.HasTrans = true; } } @@ -835,11 +835,11 @@ namespace SixLabors.ImageSharp.Formats.Png { if (this.header.BitDepth == 16) { - pngMetaData.Luminance16Trans = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2)); + pngMetaData.TransparentGray16 = new Gray16(BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2))); } else { - pngMetaData.LuminanceTrans = ReadByteLittleEndian(alpha, 0); + pngMetaData.TransparentGray8 = new Gray8(ReadByteLittleEndian(alpha, 0)); } pngMetaData.HasTrans = true; diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 1179a6db3..e953bc1f0 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -314,37 +314,37 @@ namespace SixLabors.ImageSharp.Formats.Png { if (pngMetaData.ColorType == PngColorType.Rgb) { - if (pngMetaData.Rgb48Trans != null) + if (pngMetaData.TransparentRgb48 != null) { - var r = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); - var g = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R); - var b = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.B); + var r = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.R); + var g = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.R); + var b = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.B); var alphaArray = r.Concat(g).Concat(b).ToArray(); this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } - else if (pngMetaData.Rgb24Trans != null) + else if (pngMetaData.TransparentRgb24 != null) { var alphaArray = new byte[6]; - alphaArray[1] = pngMetaData.Rgb24Trans.Value.R; - alphaArray[3] = pngMetaData.Rgb24Trans.Value.G; - alphaArray[5] = pngMetaData.Rgb24Trans.Value.B; + alphaArray[1] = pngMetaData.TransparentRgb24.Value.R; + alphaArray[3] = pngMetaData.TransparentRgb24.Value.G; + alphaArray[5] = pngMetaData.TransparentRgb24.Value.B; this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } } else if (pngMetaData.ColorType == PngColorType.Grayscale) { - if (pngMetaData.Luminance16Trans != null) + if (pngMetaData.TransparentGray16 != null) { - var alphaArray = BitConverter.GetBytes(pngMetaData.Luminance16Trans.Value); + var alphaArray = BitConverter.GetBytes(pngMetaData.TransparentGray16.Value.PackedValue); this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } - else if (pngMetaData.LuminanceTrans != null) + else if (pngMetaData.TransparentGray8 != null) { var alphaArray = new byte[2]; - alphaArray[1] = pngMetaData.LuminanceTrans.Value; + alphaArray[1] = pngMetaData.TransparentGray8.Value.PackedValue; this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); } diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs index 765222795..6a293f770 100644 --- a/src/ImageSharp/Formats/Png/PngMetaData.cs +++ b/src/ImageSharp/Formats/Png/PngMetaData.cs @@ -47,22 +47,22 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// Gets or sets the Rgb 24 transparent color. This represents any color in an 8 bit Rgb24 encoded png that should be transparent /// - public Rgb24? Rgb24Trans { get; set; } + public Rgb24? TransparentRgb24 { get; set; } /// /// Gets or sets the Rgb 48 transparent color. This represents any color in a 16 bit Rgb24 encoded png that should be transparent /// - public Rgb48? Rgb48Trans { get; set; } + public Rgb48? TransparentRgb48 { get; set; } /// /// Gets or sets the 8 bit grayscale transparent color. This represents any color in an 8 bit grayscale encoded png that should be transparent /// - public byte? LuminanceTrans { get; set; } + public Gray8? TransparentGray8 { get; set; } /// /// Gets or sets the 16 bit grayscale transparent color. This represents any color in a 16 bit grayscale encoded png that should be transparent /// - public ushort? Luminance16Trans { get; set; } + public Gray16? TransparentGray16 { get; set; } /// /// Gets or sets a value indicating whether the image has transparency chunk and markers were decoded diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 3fe590ee2..528c012c5 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -20,8 +20,8 @@ namespace SixLabors.ImageSharp.Formats.Png ReadOnlySpan scanlineSpan, Span rowSpan, bool hasTrans, - ushort luminance16Trans, - byte luminanceTrans) + Gray16 luminance16Trans, + Gray8 luminanceTrans) where TPixel : struct, IPixel { TPixel pixel = default; @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.R = luminance; rgba64.G = luminance; rgba64.B = luminance; - rgba64.A = luminance.Equals(luminance16Trans) ? ushort.MinValue : ushort.MaxValue; + rgba64.A = luminance.Equals(luminance16Trans.PackedValue) ? ushort.MinValue : ushort.MaxValue; pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - byte scaledLuminanceTrans = (byte)(luminanceTrans * scaleFactor); + byte scaledLuminanceTrans = (byte)(luminanceTrans.PackedValue * scaleFactor); Rgba32 rgba32 = default; for (int x = 0; x < header.Width; x++) { @@ -93,8 +93,8 @@ namespace SixLabors.ImageSharp.Formats.Png int pixelOffset, int increment, bool hasTrans, - ushort luminance16Trans, - byte luminanceTrans) + Gray16 luminance16Trans, + Gray8 luminanceTrans) where TPixel : struct, IPixel { TPixel pixel = default; @@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp.Formats.Png rgba64.R = luminance; rgba64.G = luminance; rgba64.B = luminance; - rgba64.A = luminance.Equals(luminance16Trans) ? ushort.MinValue : ushort.MaxValue; + rgba64.A = luminance.Equals(luminance16Trans.PackedValue) ? ushort.MinValue : ushort.MaxValue; pixel.FromRgba64(rgba64); Unsafe.Add(ref rowSpanRef, x) = pixel; @@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - byte scaledLuminanceTrans = (byte)(luminanceTrans * scaleFactor); + byte scaledLuminanceTrans = (byte)(luminanceTrans.PackedValue * scaleFactor); Rgba32 rgba32 = default; for (int x = pixelOffset; x < header.Width; x += increment) { From 5faf9025a6aa8f1a2f5a66d81d84c64723d820ac Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Fri, 2 Nov 2018 17:08:20 -0500 Subject: [PATCH 132/238] ImageSharp-762: Added methods to pre-seed AoT compiler on iOS --- src/ImageSharp/Formats/Gif/ImageExtensions.cs | 19 +++++++++++++++++++ .../OctreeFrameQuantizer{TPixel}.cs | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index 8ddd4247e..b22620108 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -5,6 +5,7 @@ using System.IO; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp { @@ -35,5 +36,23 @@ namespace SixLabors.ImageSharp public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) where TPixel : struct, IPixel => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); + + /// + /// This method doesn't actually do anything but serves an important purpose... + /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: + /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." + /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT + /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on + /// iOS so it bombs out. + /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the + /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! + /// + /// The pixel format. + public static void AotCompileOctreeQuantizer() + where TPixel : struct, IPixel + { + var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); + test.AotGetPalette(); + } } } diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 1eeb0be41..8f688e838 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -136,6 +136,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } + internal TPixel[] AotGetPalette() => this.octree.Palletize(this.colors); + /// protected override TPixel[] GetPalette() => this.octree.Palletize(this.colors); From a350621d76633d185b31f0c58d14bb332a19beea Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 00:19:09 +0100 Subject: [PATCH 133/238] benchmarks for current state --- .../Common/Helpers/InliningOptions.cs | 2 +- .../Helpers/SimdUtils.ExtendedIntrinsics.cs | 2 +- .../Codecs/Jpeg/DecodeJpeg.cs | 9 ++++ .../General/Block8x8F_LoadFromInt16.cs | 48 +++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index f61e4f8ae..ad85c4fc8 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. // Uncomment this for verbose profiler results: -#define PROFILING +// #define PROFILING using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 463961d86..9aeb20931 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp /// /// Widen and convert a vector of values into 2 vectors of -s. /// - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ConvertToSingle( Vector source, out Vector dest1, diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs index 2afacb1e4..57dcede88 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs @@ -76,5 +76,14 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg // | | | | | | | | | | // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | + + // RESULTS (2018 November 1): + // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| + // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.59 ms | 4.611 ms | 0.2605 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | + // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 55.33 ms | 2.133 ms | 0.1205 ms | 3.15 | 0.04 | 125.0000 | 566.01 KB | + // | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.83 ms | 24.326 ms | 1.3745 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 44.93 ms | 3.088 ms | 0.1745 ms | 2.53 | 0.15 | 125.0000 | 529.96 KB | } } diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs b/tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs new file mode 100644 index 000000000..34847148b --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs @@ -0,0 +1,48 @@ +using System; +using System.Numerics; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Formats.Jpeg.Components; + +namespace SixLabors.ImageSharp.Benchmarks.General +{ + public class Block8x8F_LoadFromInt16 + { + private Block8x8 source; + + private Block8x8F dest = default; + + [GlobalSetup] + public void Setup() + { + if (Vector.Count != 8) + { + throw new NotSupportedException("Vector.Count != 8"); + } + + for (short i = 0; i < Block8x8F.Size; i++) + { + this.source[i] = i; + } + } + + [Benchmark(Baseline = true)] + public void Scalar() + { + this.dest.LoadFromInt16Scalar(ref this.source); + } + + [Benchmark] + public void ExtendedAvx2() + { + this.dest.LoadFromInt16ExtendedAvx2(ref this.source); + } + + // RESULT: + // Method | Mean | Error | StdDev | Scaled | + // ------------- |---------:|----------:|----------:|-------:| + // Scalar | 34.88 ns | 0.3296 ns | 0.3083 ns | 1.00 | + // ExtendedAvx2 | 21.58 ns | 0.2125 ns | 0.1884 ns | 0.62 | + } +} \ No newline at end of file From 55ac40327ad6a6e516bd3f32d9d3d42bf508216d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 17:52:55 +0100 Subject: [PATCH 134/238] reimplement Block8x8F.CopyTo2x2 --- .../Jpeg/Components/Block8x8F.CopyTo.cs | 166 +++++----- .../BlockOperations/Block8x8F_CopyTo2x2.cs | 287 ++++++++++++++++++ .../BlockOperations}/Block8x8F_DivideRound.cs | 6 +- .../Block8x8F_LoadFromInt16.cs | 9 +- .../Jpeg/BlockOperations}/Block8x8F_Round.cs | 7 +- .../Jpg/Block8x8FTests.CopyToBufferArea.cs | 21 +- 6 files changed, 390 insertions(+), 106 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs rename tests/ImageSharp.Benchmarks/{General => Codecs/Jpeg/BlockOperations}/Block8x8F_DivideRound.cs (96%) rename tests/ImageSharp.Benchmarks/{General => Codecs/Jpeg/BlockOperations}/Block8x8F_LoadFromInt16.cs (83%) rename tests/ImageSharp.Benchmarks/{General => Codecs/Jpeg/BlockOperations}/Block8x8F_Round.cs (90%) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs index b7dd125a8..50f8b6121 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs @@ -12,55 +12,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components internal partial struct Block8x8F { /// - /// Copy block data into the destination color buffer pixel area with the provided horizontal and vertical. + /// Copy block data into the destination color buffer pixel area with the provided horizontal and vertical scale factors. /// + [MethodImpl(InliningOptions.ShortMethod)] public void CopyTo(in BufferArea area, int horizontalScale, int verticalScale) { if (horizontalScale == 1 && verticalScale == 1) { - this.CopyTo(area); + this.Copy1x1Scale(area); return; } - else if (horizontalScale == 2 && verticalScale == 2) + + if (horizontalScale == 2 && verticalScale == 2) { - this.CopyTo2x2(area); + this.Copy2x2Scale(area); return; } - ref float destBase = ref area.GetReferenceToOrigin(); - - // TODO: Optimize: implement all the cases with loopless special code! (T4?) - for (int y = 0; y < 8; y++) - { - int yy = y * verticalScale; - int y8 = y * 8; - - for (int x = 0; x < 8; x++) - { - int xx = x * horizontalScale; - - float value = this[y8 + x]; - - for (int i = 0; i < verticalScale; i++) - { - int baseIdx = ((yy + i) * area.Stride) + xx; - - for (int j = 0; j < horizontalScale; j++) - { - // area[xx + j, yy + i] = value; - Unsafe.Add(ref destBase, baseIdx + j) = value; - } - } - } - } + // TODO: Optimize: implement all the cases with scale-specific, loopless code! + this.CopyArbitraryScale(area, horizontalScale, verticalScale); } - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void CopyTo(in BufferArea area) + public void Copy1x1Scale(in BufferArea destination) { ref byte selfBase = ref Unsafe.As(ref this); - ref byte destBase = ref Unsafe.As(ref area.GetReferenceToOrigin()); - int destStride = area.Stride * sizeof(float); + ref byte destBase = ref Unsafe.As(ref destination.GetReferenceToOrigin()); + int destStride = destination.Stride * sizeof(float); CopyRowImpl(ref selfBase, ref destBase, destStride, 0); CopyRowImpl(ref selfBase, ref destBase, destStride, 1); @@ -80,10 +57,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components Unsafe.CopyBlock(ref d, ref s, 8 * sizeof(float)); } - private void CopyTo2x2(in BufferArea area) + private void Copy2x2Scale(in BufferArea area) { - ref float destBase = ref area.GetReferenceToOrigin(); - int destStride = area.Stride; + ref Vector2 destBase = ref Unsafe.As(ref area.GetReferenceToOrigin()); + int destStride = area.Stride / 2; this.WidenCopyImpl2x2(ref destBase, 0, destStride); this.WidenCopyImpl2x2(ref destBase, 1, destStride); @@ -96,60 +73,75 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WidenCopyImpl2x2(ref float destBase, int row, int destStride) + private void WidenCopyImpl2x2(ref Vector2 destBase, int row, int destStride) { - ref Vector4 selfLeft = ref Unsafe.Add(ref this.V0L, 2 * row); - ref Vector4 selfRight = ref Unsafe.Add(ref selfLeft, 1); - ref float destLocalOrigo = ref Unsafe.Add(ref destBase, row * 2 * destStride); - - Unsafe.Add(ref destLocalOrigo, 0) = selfLeft.X; - Unsafe.Add(ref destLocalOrigo, 1) = selfLeft.X; - Unsafe.Add(ref destLocalOrigo, 2) = selfLeft.Y; - Unsafe.Add(ref destLocalOrigo, 3) = selfLeft.Y; - Unsafe.Add(ref destLocalOrigo, 4) = selfLeft.Z; - Unsafe.Add(ref destLocalOrigo, 5) = selfLeft.Z; - Unsafe.Add(ref destLocalOrigo, 6) = selfLeft.W; - Unsafe.Add(ref destLocalOrigo, 7) = selfLeft.W; - - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 0) = selfRight.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 1) = selfRight.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 2) = selfRight.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 3) = selfRight.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 4) = selfRight.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 5) = selfRight.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 6) = selfRight.W; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 7) = selfRight.W; - - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 0) = selfLeft.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 1) = selfLeft.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 2) = selfLeft.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 3) = selfLeft.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 4) = selfLeft.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 5) = selfLeft.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 6) = selfLeft.W; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 7) = selfLeft.W; - - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 0) = selfRight.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 1) = selfRight.X; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 2) = selfRight.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 3) = selfRight.Y; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 4) = selfRight.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 5) = selfRight.Z; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 6) = selfRight.W; - Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 7) = selfRight.W; + ref Vector4 sLeft = ref Unsafe.Add(ref this.V0L, 2 * row); + ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); + + ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); + ref Vector2 dTopRight = ref Unsafe.Add(ref dTopLeft, 4); + ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); + ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4); + + var xLeft = new Vector4(sLeft.X); + var yLeft = new Vector4(sLeft.Y); + var zLeft = new Vector4(sLeft.Z); + var wLeft = new Vector4(sLeft.W); + + var xRight = new Vector4(sRight.X); + var yRight = new Vector4(sRight.Y); + var zRight = new Vector4(sRight.Z); + var wRight = new Vector4(sRight.W); + + Unsafe.As(ref dTopLeft) = xLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; + + Unsafe.As(ref dTopRight) = xRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 3)) = wRight; + + Unsafe.As(ref dBottomLeft) = xLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; + + Unsafe.As(ref dBottomRight) = xRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 3)) = wRight; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WidenCopyImpl(ref Vector4 s, ref float destBase) + [MethodImpl(InliningOptions.ColdPath)] + private void CopyArbitraryScale(BufferArea area, int horizontalScale, int verticalScale) { - Unsafe.Add(ref destBase, 0) = s.X; - Unsafe.Add(ref destBase, 1) = s.X; - Unsafe.Add(ref destBase, 2) = s.Y; - Unsafe.Add(ref destBase, 3) = s.Y; - Unsafe.Add(ref destBase, 4) = s.Z; - Unsafe.Add(ref destBase, 5) = s.Z; - Unsafe.Add(ref destBase, 6) = s.W; - Unsafe.Add(ref destBase, 7) = s.W; + ref float destBase = ref area.GetReferenceToOrigin(); + + for (int y = 0; y < 8; y++) + { + int yy = y * verticalScale; + int y8 = y * 8; + + for (int x = 0; x < 8; x++) + { + int xx = x * horizontalScale; + + float value = this[y8 + x]; + + for (int i = 0; i < verticalScale; i++) + { + int baseIdx = ((yy + i) * area.Stride) + xx; + + for (int j = 0; j < horizontalScale; j++) + { + // area[xx + j, yy + i] = value; + Unsafe.Add(ref destBase, baseIdx + j) = value; + } + } + } + } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs new file mode 100644 index 000000000..89de95ee9 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs @@ -0,0 +1,287 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Formats.Jpeg.Components; +using SixLabors.ImageSharp.Memory; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations +{ + public class Block8x8F_CopyTo2x2 + { + private Block8x8F block; + + private Buffer2D buffer; + + private BufferArea destArea; + + [GlobalSetup] + public void Setup() + { + this.buffer = Configuration.Default.MemoryAllocator.Allocate2D(1000, 500); + this.destArea = this.buffer.GetArea(200, 100, 128, 128); + } + + [Benchmark(Baseline = true)] + public void Original() + { + ref float destBase = ref this.destArea.GetReferenceToOrigin(); + int destStride = this.destArea.Stride; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2(ref src, ref destBase, 7, destStride); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WidenCopyImpl2x2(ref Block8x8F src, ref float destBase, int row, int destStride) + { + ref Vector4 selfRight = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 selfRight = ref Unsafe.Add(ref selfLeft, 1); + ref float destLocalOrigo = ref Unsafe.Add(ref destBase, row * 2 * destStride); + + Unsafe.Add(ref destLocalOrigo, 0) = selfLeft.X; + Unsafe.Add(ref destLocalOrigo, 1) = selfLeft.X; + Unsafe.Add(ref destLocalOrigo, 2) = selfLeft.Y; + Unsafe.Add(ref destLocalOrigo, 3) = selfLeft.Y; + Unsafe.Add(ref destLocalOrigo, 4) = selfLeft.Z; + Unsafe.Add(ref destLocalOrigo, 5) = selfLeft.Z; + Unsafe.Add(ref destLocalOrigo, 6) = selfLeft.W; + Unsafe.Add(ref destLocalOrigo, 7) = selfLeft.W; + + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 0) = selfRight.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 1) = selfRight.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 2) = selfRight.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 3) = selfRight.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 4) = selfRight.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 5) = selfRight.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 6) = selfRight.W; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, 8), 7) = selfRight.W; + + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 0) = selfLeft.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 1) = selfLeft.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 2) = selfLeft.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 3) = selfLeft.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 4) = selfLeft.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 5) = selfLeft.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 6) = selfLeft.W; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride), 7) = selfLeft.W; + + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 0) = selfRight.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 1) = selfRight.X; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 2) = selfRight.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 3) = selfRight.Y; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 4) = selfRight.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 5) = selfRight.Z; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 6) = selfRight.W; + Unsafe.Add(ref Unsafe.Add(ref destLocalOrigo, destStride + 8), 7) = selfRight.W; + } + + [Benchmark] + public void Original_V2() + { + ref float destBase = ref this.destArea.GetReferenceToOrigin(); + int destStride = this.destArea.Stride; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2_V2(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2_V2(ref src, ref destBase, 7, destStride); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WidenCopyImpl2x2_V2(ref Block8x8F src, ref float destBase, int row, int destStride) + { + ref Vector4 selfLeft = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 selfRight = ref Unsafe.Add(ref selfLeft, 1); + ref float dest0 = ref Unsafe.Add(ref destBase, row * 2 * destStride); + + Unsafe.Add(ref dest0, 0) = selfLeft.X; + Unsafe.Add(ref dest0, 1) = selfLeft.X; + Unsafe.Add(ref dest0, 2) = selfLeft.Y; + Unsafe.Add(ref dest0, 3) = selfLeft.Y; + Unsafe.Add(ref dest0, 4) = selfLeft.Z; + Unsafe.Add(ref dest0, 5) = selfLeft.Z; + Unsafe.Add(ref dest0, 6) = selfLeft.W; + Unsafe.Add(ref dest0, 7) = selfLeft.W; + + ref float dest1 = ref Unsafe.Add(ref dest0, 8); + + Unsafe.Add(ref dest1, 0) = selfRight.X; + Unsafe.Add(ref dest1, 1) = selfRight.X; + Unsafe.Add(ref dest1, 2) = selfRight.Y; + Unsafe.Add(ref dest1, 3) = selfRight.Y; + Unsafe.Add(ref dest1, 4) = selfRight.Z; + Unsafe.Add(ref dest1, 5) = selfRight.Z; + Unsafe.Add(ref dest1, 6) = selfRight.W; + Unsafe.Add(ref dest1, 7) = selfRight.W; + + ref float dest2 = ref Unsafe.Add(ref dest0, destStride); + + Unsafe.Add(ref dest2, 0) = selfLeft.X; + Unsafe.Add(ref dest2, 1) = selfLeft.X; + Unsafe.Add(ref dest2, 2) = selfLeft.Y; + Unsafe.Add(ref dest2, 3) = selfLeft.Y; + Unsafe.Add(ref dest2, 4) = selfLeft.Z; + Unsafe.Add(ref dest2, 5) = selfLeft.Z; + Unsafe.Add(ref dest2, 6) = selfLeft.W; + Unsafe.Add(ref dest2, 7) = selfLeft.W; + + ref float dest3 = ref Unsafe.Add(ref dest2, 8); + + Unsafe.Add(ref dest3, 0) = selfRight.X; + Unsafe.Add(ref dest3, 1) = selfRight.X; + Unsafe.Add(ref dest3, 2) = selfRight.Y; + Unsafe.Add(ref dest3, 3) = selfRight.Y; + Unsafe.Add(ref dest3, 4) = selfRight.Z; + Unsafe.Add(ref dest3, 5) = selfRight.Z; + Unsafe.Add(ref dest3, 6) = selfRight.W; + Unsafe.Add(ref dest3, 7) = selfRight.W; + } + + [Benchmark] + public void UseVector2() + { + ref Vector2 destBase = ref Unsafe.As(ref this.destArea.GetReferenceToOrigin()); + int destStride = this.destArea.Stride / 2; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2_Vector2(ref src, ref destBase, 7, destStride); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WidenCopyImpl2x2_Vector2(ref Block8x8F src, ref Vector2 destBase, int row, int destStride) + { + ref Vector4 sLeft = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); + + ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); + ref Vector2 dTopRight = ref Unsafe.Add(ref dTopLeft, 4); + ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); + ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4); + + var xLeft = new Vector2(sLeft.X); + var yLeft = new Vector2(sLeft.Y); + var zLeft = new Vector2(sLeft.Z); + var wLeft = new Vector2(sLeft.W); + + var xRight = new Vector2(sRight.X); + var yRight = new Vector2(sRight.Y); + var zRight = new Vector2(sRight.Z); + var wRight = new Vector2(sRight.W); + + dTopLeft = xLeft; + Unsafe.Add(ref dTopLeft, 1) = yLeft; + Unsafe.Add(ref dTopLeft, 2) = zLeft; + Unsafe.Add(ref dTopLeft, 3) = wLeft; + + dTopRight = xRight; + Unsafe.Add(ref dTopRight, 1) = yRight; + Unsafe.Add(ref dTopRight, 2) = zRight; + Unsafe.Add(ref dTopRight, 3) = wRight; + + dBottomLeft = xLeft; + Unsafe.Add(ref dBottomLeft, 1) = yLeft; + Unsafe.Add(ref dBottomLeft, 2) = zLeft; + Unsafe.Add(ref dBottomLeft, 3) = wLeft; + + dBottomRight = xRight; + Unsafe.Add(ref dBottomRight, 1) = yRight; + Unsafe.Add(ref dBottomRight, 2) = zRight; + Unsafe.Add(ref dBottomRight, 3) = wRight; + } + + [Benchmark] + public void UseVector4() + { + ref Vector2 destBase = ref Unsafe.As(ref this.destArea.GetReferenceToOrigin()); + int destStride = this.destArea.Stride / 2; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2_Vector4(ref src, ref destBase, 7, destStride); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WidenCopyImpl2x2_Vector4(ref Block8x8F src, ref Vector2 destBase, int row, int destStride) + { + ref Vector4 sLeft = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); + + ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); + ref Vector2 dTopRight = ref Unsafe.Add(ref dTopLeft, 4); + ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); + ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4); + + var xLeft = new Vector4(sLeft.X); + var yLeft = new Vector4(sLeft.Y); + var zLeft = new Vector4(sLeft.Z); + var wLeft = new Vector4(sLeft.W); + + var xRight = new Vector4(sRight.X); + var yRight = new Vector4(sRight.Y); + var zRight = new Vector4(sRight.Z); + var wRight = new Vector4(sRight.W); + + Unsafe.As(ref dTopLeft) = xLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; + + Unsafe.As(ref dTopRight) = xRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 3)) = wRight; + + Unsafe.As(ref dBottomLeft) = xLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; + + Unsafe.As(ref dBottomRight) = xRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 3)) = wRight; + } + + // RESULTS: + // Method | Mean | Error | StdDev | Scaled | + // ------------ |---------:|----------:|----------:|-------:| + // Original | 88.93 ns | 0.7783 ns | 0.6899 ns | 1.00 | + // Original_V2 | 88.39 ns | 0.9426 ns | 0.8356 ns | 0.99 | + // UseVector2 | 45.63 ns | 0.4248 ns | 0.3548 ns | 0.51 | + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs similarity index 96% rename from tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs index fcc5f9a59..5502475d4 100644 --- a/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs @@ -10,7 +10,7 @@ using SixLabors.ImageSharp.Formats.Jpeg.Components; // ReSharper disable InconsistentNaming -namespace SixLabors.ImageSharp.Benchmarks.General +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { /// /// The goal of this benchmark is to measure the following Jpeg-related scenario: @@ -24,8 +24,8 @@ namespace SixLabors.ImageSharp.Benchmarks.General private static readonly Vector4 MinusOne = new Vector4(-1); private static readonly Vector4 Half = new Vector4(0.5f); - private Block8x8F inputDividend = default(Block8x8F); - private Block8x8F inputDivisior = default(Block8x8F); + private Block8x8F inputDividend; + private Block8x8F inputDivisior; [GlobalSetup] public void Setup() diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs similarity index 83% rename from tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs index 34847148b..29ee402a0 100644 --- a/tests/ImageSharp.Benchmarks/General/Block8x8F_LoadFromInt16.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs @@ -1,11 +1,16 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// ReSharper disable InconsistentNaming + +using System; using System.Numerics; using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; -namespace SixLabors.ImageSharp.Benchmarks.General +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { public class Block8x8F_LoadFromInt16 { diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs similarity index 90% rename from tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs index 200af64c2..c7b5802c4 100644 --- a/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs @@ -1,4 +1,7 @@ -// ReSharper disable InconsistentNaming +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// ReSharper disable InconsistentNaming using System; using System.Numerics; @@ -8,7 +11,7 @@ using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; -namespace SixLabors.ImageSharp.Benchmarks.General +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { public class Block8x8F_Round { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs index c720fdd4a..3f426e232 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs @@ -11,10 +11,11 @@ using SixLabors.Primitives; using Xunit; using Xunit.Abstractions; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Jpg { - public partial class Block8x8FTests : JpegFixture + public partial class Block8x8FTests { public class CopyToBufferArea : JpegFixture { @@ -37,17 +38,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } - // TODO: This test occasionally fails from the same reason certain ICC tests are failing. Should be false negative. - [Fact(Skip = "This test occasionally fails from the same reason certain ICC tests are failing. Should be false negative.")] - //[Fact] - public void Unscaled() + [Fact] + public void Copy1x1Scale() { Block8x8F block = CreateRandomFloatBlock(0, 100); - using (var buffer = Configuration.Default.MemoryAllocator.Allocate2D(20, 20)) + using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(20, 20)) { BufferArea area = buffer.GetArea(5, 10, 8, 8); - block.CopyTo(area); + block.Copy1x1Scale(area); Assert.Equal(block[0, 0], buffer[5, 10]); Assert.Equal(block[1, 0], buffer[6, 10]); @@ -59,22 +58,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } - // TODO: This test occasionally fails from the same reason certain ICC tests are failing. Should be false negative. - [Theory(Skip = "This test occasionally fails from the same reason certain ICC tests are failing. Should be false negative.")] - //[Theory] + [Theory] [InlineData(1, 1)] [InlineData(1, 2)] [InlineData(2, 1)] [InlineData(2, 2)] [InlineData(4, 2)] [InlineData(4, 4)] - public void Scaled(int horizontalFactor, int verticalFactor) + public void CopyTo(int horizontalFactor, int verticalFactor) { Block8x8F block = CreateRandomFloatBlock(0, 100); var start = new Point(50, 50); - using (var buffer = Configuration.Default.MemoryAllocator.Allocate2D(100, 100)) + using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(100, 100)) { BufferArea area = buffer.GetArea(start.X, start.Y, 8 * horizontalFactor, 8 * verticalFactor); block.CopyTo(area, horizontalFactor, verticalFactor); From 165af7a261f8f4aade0b083b1050de3ef440472c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 18:31:43 +0100 Subject: [PATCH 135/238] Optimization: do not initialize pixel buffer in JpegDecoder --- .../Formats/Jpeg/JpegDecoderCore.cs | 10 ++++++-- src/ImageSharp/Image.Decode.cs | 24 ++++++++++++++++++ tests/ImageSharp.Tests/Image/ImageTests.cs | 25 ++++++++++++++++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 68252f624..ef73aab38 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -936,12 +936,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg private Image PostProcessIntoImage() where TPixel : struct, IPixel { + var image = Image.CreateUninitialized( + this.configuration, + this.ImageWidth, + this.ImageHeight, + this.MetaData); + using (var postProcessor = new JpegImagePostProcessor(this.configuration, this)) { - var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData); postProcessor.PostProcess(image.Frames.RootFrame); - return image; } + + return image; } } } \ No newline at end of file diff --git a/src/ImageSharp/Image.Decode.cs b/src/ImageSharp/Image.Decode.cs index 8b9f3fdb5..ffdab25e2 100644 --- a/src/ImageSharp/Image.Decode.cs +++ b/src/ImageSharp/Image.Decode.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Memory; @@ -15,6 +16,29 @@ namespace SixLabors.ImageSharp /// public static partial class Image { + /// + /// Creates an instance backed by an uninitialized memory buffer. + /// This is an optimized creation method intended to be used by decoders. + /// The image might be filled with memory garbage. + /// + /// The pixel type + /// The + /// The width of the image + /// The height of the image + /// The + /// The result + internal static Image CreateUninitialized( + Configuration configuration, + int width, + int height, + ImageMetaData metadata) + where TPixel : struct, IPixel + { + Buffer2D uninitializedMemoryBuffer = + configuration.MemoryAllocator.Allocate2D(width, height); + return new Image(configuration, uninitializedMemoryBuffer.MemorySource, width, height, metadata); + } + /// /// By reading the header on the provided stream this calculates the images format. /// diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs index f3c04d5e1..c5c7d19e1 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.cs @@ -2,7 +2,10 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.Memory; + using Xunit; // ReSharper disable InconsistentNaming @@ -46,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests } [Fact] - public void Configuration_Width_Height_BackroundColor() + public void Configuration_Width_Height_BackgroundColor() { Configuration configuration = Configuration.Default.Clone(); Rgba32 color = Rgba32.Aquamarine; @@ -61,6 +64,26 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(configuration, image.GetConfiguration()); } } + + [Fact] + public void CreateUninitialized() + { + Configuration configuration = Configuration.Default.Clone(); + + byte dirtyValue = 123; + configuration.MemoryAllocator = new TestMemoryAllocator(dirtyValue); + var metadata = new ImageMetaData(); + + using (Image image = Image.CreateUninitialized(configuration, 21, 22, metadata)) + { + Assert.Equal(21, image.Width); + Assert.Equal(22, image.Height); + Assert.Same(configuration, image.GetConfiguration()); + Assert.Same(metadata, image.MetaData); + + Assert.Equal(dirtyValue, image[5, 5].PackedValue); + } + } } } } From f57e1f062bf73c2d4bd858ca9ac8a9dc186fea7c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 20:43:50 +0100 Subject: [PATCH 136/238] improved Block8x8F.Copy2x2Scale --- .../Jpeg/Components/Block8x8F.CopyTo.cs | 42 +++---- .../BlockOperations/Block8x8F_CopyTo1x1.cs | 82 ++++++++++++++ .../BlockOperations/Block8x8F_CopyTo2x2.cs | 104 ++++++++++++++---- 3 files changed, 190 insertions(+), 38 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs index 50f8b6121..5fa3e91d7 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return; } - // TODO: Optimize: implement all the cases with scale-specific, loopless code! + // TODO: Optimize: implement all cases with scale-specific, loopless code! this.CopyArbitraryScale(area, horizontalScale, verticalScale); } @@ -79,9 +79,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); - ref Vector2 dTopRight = ref Unsafe.Add(ref dTopLeft, 4); ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); - ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4); var xLeft = new Vector4(sLeft.X); var yLeft = new Vector4(sLeft.Y); @@ -91,27 +89,33 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components var xRight = new Vector4(sRight.X); var yRight = new Vector4(sRight.Y); var zRight = new Vector4(sRight.Z); - var wRight = new Vector4(sRight.W); + var wRight = new Vector2(sRight.W); Unsafe.As(ref dTopLeft) = xLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; + AssignVector4Value(ref dTopLeft, 1, ref yLeft); + AssignVector4Value(ref dTopLeft, 2, ref zLeft); + AssignVector4Value(ref dTopLeft, 3, ref wLeft); - Unsafe.As(ref dTopRight) = xRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 1)) = yRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 2)) = zRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 3)) = wRight; + AssignVector4Value(ref dTopLeft, 4, ref xRight); + AssignVector4Value(ref dTopLeft, 5, ref yRight); + AssignVector4Value(ref dTopLeft, 6, ref zRight); + Unsafe.Add(ref dTopLeft, 7) = wRight; Unsafe.As(ref dBottomLeft) = xLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; - - Unsafe.As(ref dBottomRight) = xRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 1)) = yRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 2)) = zRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 3)) = wRight; + AssignVector4Value(ref dBottomLeft, 1, ref yLeft); + AssignVector4Value(ref dBottomLeft, 2, ref zLeft); + AssignVector4Value(ref dBottomLeft, 3, ref wLeft); + + AssignVector4Value(ref dBottomLeft, 4, ref xRight); + AssignVector4Value(ref dBottomLeft, 5, ref yRight); + AssignVector4Value(ref dBottomLeft, 6, ref zRight); + Unsafe.Add(ref dBottomLeft, 7) = wRight; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AssignVector4Value(ref Vector2 destBase, int offset, ref Vector4 value) + { + Unsafe.As(ref Unsafe.Add(ref destBase, offset)) = value; } [MethodImpl(InliningOptions.ColdPath)] diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs new file mode 100644 index 000000000..96eecc456 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs @@ -0,0 +1,82 @@ +using System; +using System.Numerics; +using System.Runtime.CompilerServices; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Formats.Jpeg.Components; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations +{ + public class Block8x8F_CopyTo1x1 + { + private Block8x8F block; + + private Buffer2D buffer; + + private BufferArea destArea; + + [GlobalSetup] + public void Setup() + { + if (!SimdUtils.IsAvx2CompatibleArchitecture) + { + throw new InvalidOperationException("Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); + } + + this.buffer = Configuration.Default.MemoryAllocator.Allocate2D(1000, 500); + this.destArea = this.buffer.GetArea(200, 100, 64, 64); + } + + [Benchmark(Baseline = true)] + public void Original() + { + ref byte selfBase = ref Unsafe.As(ref this.block); + ref byte destBase = ref Unsafe.As(ref this.destArea.GetReferenceToOrigin()); + int destStride = this.destArea.Stride * sizeof(float); + + CopyRowImpl(ref selfBase, ref destBase, destStride, 0); + CopyRowImpl(ref selfBase, ref destBase, destStride, 1); + CopyRowImpl(ref selfBase, ref destBase, destStride, 2); + CopyRowImpl(ref selfBase, ref destBase, destStride, 3); + CopyRowImpl(ref selfBase, ref destBase, destStride, 4); + CopyRowImpl(ref selfBase, ref destBase, destStride, 5); + CopyRowImpl(ref selfBase, ref destBase, destStride, 6); + CopyRowImpl(ref selfBase, ref destBase, destStride, 7); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void CopyRowImpl(ref byte selfBase, ref byte destBase, int destStride, int row) + { + ref byte s = ref Unsafe.Add(ref selfBase, row * 8 * sizeof(float)); + ref byte d = ref Unsafe.Add(ref destBase, row * destStride); + Unsafe.CopyBlock(ref d, ref s, 8 * sizeof(float)); + } + + [Benchmark] + public void UseVector8() + { + ref Block8x8F s = ref this.block; + ref Vector d = ref Unsafe.As>(ref this.destArea.GetReferenceToOrigin()); + + Vector row0 = Unsafe.As>(ref s.V0L); + Vector row1 = Unsafe.As>(ref s.V1L); + Vector row2 = Unsafe.As>(ref s.V2L); + Vector row3 = Unsafe.As>(ref s.V3L); + Vector row4 = Unsafe.As>(ref s.V4L); + Vector row5 = Unsafe.As>(ref s.V5L); + Vector row6 = Unsafe.As>(ref s.V6L); + Vector row7 = Unsafe.As>(ref s.V7L); + + d = row0; + Unsafe.Add(ref d, 1) = row1; + Unsafe.Add(ref d, 2) = row2; + Unsafe.Add(ref d, 3) = row3; + Unsafe.Add(ref d, 4) = row4; + Unsafe.Add(ref d, 5) = row5; + Unsafe.Add(ref d, 6) = row6; + Unsafe.Add(ref d, 7) = row7; + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs index 89de95ee9..269a3e0d8 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WidenCopyImpl2x2(ref Block8x8F src, ref float destBase, int row, int destStride) { - ref Vector4 selfRight = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 selfLeft = ref Unsafe.Add(ref src.V0L, 2 * row); ref Vector4 selfRight = ref Unsafe.Add(ref selfLeft, 1); ref float destLocalOrigo = ref Unsafe.Add(ref destBase, row * 2 * destStride); @@ -257,31 +257,97 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations var wRight = new Vector4(sRight.W); Unsafe.As(ref dTopLeft) = xLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; - Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; - + AssignVector4Value(ref dTopLeft, 1, ref yLeft); + AssignVector4Value(ref dTopLeft, 2, ref zLeft); + AssignVector4Value(ref dTopLeft, 3, ref wLeft); + Unsafe.As(ref dTopRight) = xRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 1)) = yRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 2)) = zRight; - Unsafe.As(ref Unsafe.Add(ref dTopRight, 3)) = wRight; + AssignVector4Value(ref dTopRight, 1, ref yRight); + AssignVector4Value(ref dTopRight, 2, ref zRight); + AssignVector4Value(ref dTopRight, 3, ref wRight); Unsafe.As(ref dBottomLeft) = xLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; - Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; + AssignVector4Value(ref dBottomLeft, 1, ref yLeft); + AssignVector4Value(ref dBottomLeft, 2, ref zLeft); + AssignVector4Value(ref dBottomLeft, 3, ref wLeft); Unsafe.As(ref dBottomRight) = xRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 1)) = yRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 2)) = zRight; - Unsafe.As(ref Unsafe.Add(ref dBottomRight, 3)) = wRight; + AssignVector4Value(ref dBottomRight, 1, ref yRight); + AssignVector4Value(ref dBottomRight, 2, ref zRight); + AssignVector4Value(ref dBottomRight, 3, ref wRight); + } + + [Benchmark] + public void UseVector4_SafeRightCorner() + { + ref Vector2 destBase = ref Unsafe.As(ref this.destArea.GetReferenceToOrigin()); + int destStride = this.destArea.Stride / 2; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2_Vector4_SafeRightCorner(ref src, ref destBase, 7, destStride); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WidenCopyImpl2x2_Vector4_SafeRightCorner(ref Block8x8F src, ref Vector2 destBase, int row, int destStride) + { + ref Vector4 sLeft = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); + + ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); + ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); + + var xLeft = new Vector4(sLeft.X); + var yLeft = new Vector4(sLeft.Y); + var zLeft = new Vector4(sLeft.Z); + var wLeft = new Vector4(sLeft.W); + + var xRight = new Vector4(sRight.X); + var yRight = new Vector4(sRight.Y); + var zRight = new Vector4(sRight.Z); + var wRight = new Vector2(sRight.W); + + Unsafe.As(ref dTopLeft) = xLeft; + AssignVector4Value(ref dTopLeft, 1, ref yLeft); + AssignVector4Value(ref dTopLeft, 2, ref zLeft); + AssignVector4Value(ref dTopLeft, 3, ref wLeft); + + AssignVector4Value(ref dTopLeft, 4, ref xRight); + AssignVector4Value(ref dTopLeft, 5, ref yRight); + AssignVector4Value(ref dTopLeft, 6, ref zRight); + Unsafe.Add(ref dTopLeft, 7) = wRight; + + Unsafe.As(ref dBottomLeft) = xLeft; + AssignVector4Value(ref dBottomLeft, 1, ref yLeft); + AssignVector4Value(ref dBottomLeft, 2, ref zLeft); + AssignVector4Value(ref dBottomLeft, 3, ref wLeft); + + AssignVector4Value(ref dBottomLeft, 4, ref xRight); + AssignVector4Value(ref dBottomLeft, 5, ref yRight); + AssignVector4Value(ref dBottomLeft, 6, ref zRight); + Unsafe.Add(ref dBottomLeft, 7) = wRight; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AssignVector4Value(ref Vector2 destBase, int offset, ref Vector4 value) + { + Unsafe.As(ref Unsafe.Add(ref destBase, offset)) = value; } // RESULTS: - // Method | Mean | Error | StdDev | Scaled | - // ------------ |---------:|----------:|----------:|-------:| - // Original | 88.93 ns | 0.7783 ns | 0.6899 ns | 1.00 | - // Original_V2 | 88.39 ns | 0.9426 ns | 0.8356 ns | 0.99 | - // UseVector2 | 45.63 ns | 0.4248 ns | 0.3548 ns | 0.51 | + // Method | Mean | Error | StdDev | Scaled | ScaledSD | + // --------------------------- |---------:|----------:|----------:|-------:|---------:| + // Original | 93.78 ns | 1.8419 ns | 1.9708 ns | 1.00 | 0.00 | + // Original_V2 | 89.85 ns | 0.8809 ns | 0.7356 ns | 0.96 | 0.02 | + // UseVector2 | 81.81 ns | 0.4441 ns | 0.3937 ns | 0.87 | 0.02 | + // UseVector4 | 55.74 ns | 0.3674 ns | 0.3068 ns | 0.59 | 0.01 | + // UseVector4_SafeRightCorner | 55.70 ns | 0.3239 ns | 0.2705 ns | 0.59 | 0.01 | } } \ No newline at end of file From 57cacaccb0106d7f13935119078313dfe125ba1f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 21:30:36 +0100 Subject: [PATCH 137/238] optimize ExifReader.ToEnum(...) --- .../MetaData/Profiles/Exif/ExifReader.cs | 21 +++++- .../BlockOperations/Block8x8F_CopyTo1x1.cs | 73 ++++++++++++++++--- .../Jpg/Block8x8FTests.CopyToBufferArea.cs | 3 +- .../Formats/Jpg/JpegProfilingBenchmarks.cs | 5 +- 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index 3326c3217..c6a5b7d23 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif private byte ConvertToByte(ReadOnlySpan buffer) => buffer[0]; - private unsafe string ConvertToString(ReadOnlySpan buffer) + private string ConvertToString(ReadOnlySpan buffer) { int nullCharIndex = buffer.IndexOf((byte)0); @@ -382,13 +382,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.invalidTags.Add(tag); } + [MethodImpl(InliningOptions.ShortMethod)] private TEnum ToEnum(int value, TEnum defaultValue) where TEnum : struct { - var enumValue = (TEnum)(object)value; - if (Enum.GetValues(typeof(TEnum)).Cast().Any(v => v.Equals(enumValue))) + if (EnumHelper.IsDefined(value)) { - return enumValue; + return Unsafe.As(ref value); } return defaultValue; @@ -557,5 +557,18 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif ? BinaryPrimitives.ReadInt16BigEndian(buffer) : BinaryPrimitives.ReadInt16LittleEndian(buffer); } + + private class EnumHelper + where TEnum : struct + { + private static readonly int[] Values = Enum.GetValues(typeof(TEnum)).Cast() + .Select(e => Convert.ToInt32(e)).OrderBy(e => e).ToArray(); + + [MethodImpl(InliningOptions.ShortMethod)] + public static bool IsDefined(int value) + { + return Array.BinarySearch(Values, 0, Values.Length, value) > 0; + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs index 96eecc456..bf9b1af33 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -6,6 +9,7 @@ using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Memory; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { @@ -22,7 +26,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { if (!SimdUtils.IsAvx2CompatibleArchitecture) { - throw new InvalidOperationException("Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); + throw new InvalidOperationException("Benchmark Block8x8F_CopyTo1x1 is invalid on platforms without AVX2 support."); } this.buffer = Configuration.Default.MemoryAllocator.Allocate2D(1000, 500); @@ -58,7 +62,17 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations public void UseVector8() { ref Block8x8F s = ref this.block; - ref Vector d = ref Unsafe.As>(ref this.destArea.GetReferenceToOrigin()); + ref float origin = ref this.destArea.GetReferenceToOrigin(); + int stride = this.destArea.Stride; + + ref Vector d0 = ref Unsafe.As>(ref origin); + ref Vector d1 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride)); + ref Vector d2 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 2)); + ref Vector d3 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 3)); + ref Vector d4 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 4)); + ref Vector d5 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 5)); + ref Vector d6 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 6)); + ref Vector d7 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 7)); Vector row0 = Unsafe.As>(ref s.V0L); Vector row1 = Unsafe.As>(ref s.V1L); @@ -69,14 +83,51 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations Vector row6 = Unsafe.As>(ref s.V6L); Vector row7 = Unsafe.As>(ref s.V7L); - d = row0; - Unsafe.Add(ref d, 1) = row1; - Unsafe.Add(ref d, 2) = row2; - Unsafe.Add(ref d, 3) = row3; - Unsafe.Add(ref d, 4) = row4; - Unsafe.Add(ref d, 5) = row5; - Unsafe.Add(ref d, 6) = row6; - Unsafe.Add(ref d, 7) = row7; + d0 = row0; + d1 = row1; + d2 = row2; + d3 = row3; + d4 = row4; + d5 = row5; + d6 = row6; + d7 = row7; + } + + [Benchmark] + public void UseVector8_V2() + { + ref Block8x8F s = ref this.block; + ref float origin = ref this.destArea.GetReferenceToOrigin(); + int stride = this.destArea.Stride; + + ref Vector d0 = ref Unsafe.As>(ref origin); + ref Vector d1 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride)); + ref Vector d2 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 2)); + ref Vector d3 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 3)); + ref Vector d4 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 4)); + ref Vector d5 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 5)); + ref Vector d6 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 6)); + ref Vector d7 = ref Unsafe.As>(ref Unsafe.Add(ref origin, stride * 7)); + + d0 = Unsafe.As>(ref s.V0L); + d1 = Unsafe.As>(ref s.V1L); + d2 = Unsafe.As>(ref s.V2L); + d3 = Unsafe.As>(ref s.V3L); + d4 = Unsafe.As>(ref s.V4L); + d5 = Unsafe.As>(ref s.V5L); + d6 = Unsafe.As>(ref s.V6L); + d7 = Unsafe.As>(ref s.V7L); } + + // RESULTS: + // + // Method | Mean | Error | StdDev | Scaled | + // -------------- |---------:|----------:|----------:|-------:| + // Original | 22.53 ns | 0.1660 ns | 0.1553 ns | 1.00 | + // UseVector8 | 21.59 ns | 0.3079 ns | 0.2571 ns | 0.96 | + // UseVector8_V2 | 22.57 ns | 0.1699 ns | 0.1506 ns | 1.00 | + // + // Conclusion: + // Doesn't worth to bother with this } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs index 3f426e232..d5eaaa294 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs @@ -7,6 +7,7 @@ using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; +using SixLabors.Memory; using SixLabors.Primitives; using Xunit; @@ -71,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var start = new Point(50, 50); - using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(100, 100)) + using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(100, 100, AllocationOptions.Clean)) { BufferArea area = buffer.GetArea(start.X, start.Y, 8 * horizontalFactor, 8 * verticalFactor); block.CopyTo(area, horizontalFactor, verticalFactor); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs index 7d5130e1b..88959bfab 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs @@ -32,8 +32,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, }; - //[Theory] // Benchmark, enable manually - //[MemberData(nameof(DecodeJpegData))] + [Theory] // Benchmark, enable manually + [MemberData(nameof(DecodeJpegData))] public void DecodeJpeg(string fileName) { this.DecodeJpegBenchmarkImpl(fileName, new JpegDecoder()); @@ -62,6 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg () => { var img = Image.Load(bytes, decoder); + img.Dispose(); }, // ReSharper disable once ExplicitCallerInfoArgument $"Decode {fileName}"); From c5a4ed85ff328a3b0e4a41a1b3713eb94018fe5d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 22:05:06 +0100 Subject: [PATCH 138/238] Even better Copy2x2. Tests: Group together & refactor profiling benchmarks --- .../Jpeg/Components/Block8x8F.CopyTo.cs | 85 ++++++------- .../BlockOperations/Block8x8F_CopyTo2x2.cs | 115 +++++++++++++----- tests/ImageSharp.Sandbox46/Program.cs | 5 +- .../JpegBenchmarks.cs} | 23 ++-- .../LoadResizeSaveBenchmarks.cs} | 24 ++-- .../ProfilingBenchmarks/ProfilingSetup.cs | 18 +++ 6 files changed, 164 insertions(+), 106 deletions(-) rename tests/ImageSharp.Tests/{Formats/Jpg/JpegProfilingBenchmarks.cs => ProfilingBenchmarks/JpegBenchmarks.cs} (84%) rename tests/ImageSharp.Tests/{ProfilingBenchmarks.cs => ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs} (67%) create mode 100644 tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs index 5fa3e91d7..6bf9c8483 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs @@ -3,9 +3,9 @@ using System.Numerics; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.Memory; +// ReSharper disable UseObjectOrCollectionInitializer // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Components { @@ -62,60 +62,51 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components ref Vector2 destBase = ref Unsafe.As(ref area.GetReferenceToOrigin()); int destStride = area.Stride / 2; - this.WidenCopyImpl2x2(ref destBase, 0, destStride); - this.WidenCopyImpl2x2(ref destBase, 1, destStride); - this.WidenCopyImpl2x2(ref destBase, 2, destStride); - this.WidenCopyImpl2x2(ref destBase, 3, destStride); - this.WidenCopyImpl2x2(ref destBase, 4, destStride); - this.WidenCopyImpl2x2(ref destBase, 5, destStride); - this.WidenCopyImpl2x2(ref destBase, 6, destStride); - this.WidenCopyImpl2x2(ref destBase, 7, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 0, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 1, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 2, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 3, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 4, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 5, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 6, destStride); + this.WidenCopyRowImpl2x2(ref destBase, 7, destStride); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WidenCopyImpl2x2(ref Vector2 destBase, int row, int destStride) + private void WidenCopyRowImpl2x2(ref Vector2 destBase, int row, int destStride) { ref Vector4 sLeft = ref Unsafe.Add(ref this.V0L, 2 * row); ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); - ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, 2 * row * destStride); - ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, destStride); - - var xLeft = new Vector4(sLeft.X); - var yLeft = new Vector4(sLeft.Y); - var zLeft = new Vector4(sLeft.Z); - var wLeft = new Vector4(sLeft.W); - - var xRight = new Vector4(sRight.X); - var yRight = new Vector4(sRight.Y); - var zRight = new Vector4(sRight.Z); - var wRight = new Vector2(sRight.W); - - Unsafe.As(ref dTopLeft) = xLeft; - AssignVector4Value(ref dTopLeft, 1, ref yLeft); - AssignVector4Value(ref dTopLeft, 2, ref zLeft); - AssignVector4Value(ref dTopLeft, 3, ref wLeft); - - AssignVector4Value(ref dTopLeft, 4, ref xRight); - AssignVector4Value(ref dTopLeft, 5, ref yRight); - AssignVector4Value(ref dTopLeft, 6, ref zRight); - Unsafe.Add(ref dTopLeft, 7) = wRight; - - Unsafe.As(ref dBottomLeft) = xLeft; - AssignVector4Value(ref dBottomLeft, 1, ref yLeft); - AssignVector4Value(ref dBottomLeft, 2, ref zLeft); - AssignVector4Value(ref dBottomLeft, 3, ref wLeft); - - AssignVector4Value(ref dBottomLeft, 4, ref xRight); - AssignVector4Value(ref dBottomLeft, 5, ref yRight); - AssignVector4Value(ref dBottomLeft, 6, ref zRight); - Unsafe.Add(ref dBottomLeft, 7) = wRight; - } + int offset = 2 * row * destStride; + ref Vector4 dTopLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, offset)); + ref Vector4 dBottomLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, offset + destStride)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AssignVector4Value(ref Vector2 destBase, int offset, ref Vector4 value) - { - Unsafe.As(ref Unsafe.Add(ref destBase, offset)) = value; + var xyLeft = new Vector4(sLeft.X); + xyLeft.Z = sLeft.Y; + xyLeft.W = sLeft.Y; + + var zwLeft = new Vector4(sLeft.Z); + zwLeft.Z = sLeft.W; + zwLeft.W = sLeft.W; + + var xyRight = new Vector4(sRight.X); + xyRight.Z = sRight.Y; + xyRight.W = sRight.Y; + + var zwRight = new Vector4(sRight.Z); + zwRight.Z = sRight.W; + zwRight.W = sRight.W; + + dTopLeft = xyLeft; + Unsafe.Add(ref dTopLeft, 1) = zwLeft; + Unsafe.Add(ref dTopLeft, 2) = xyRight; + Unsafe.Add(ref dTopLeft, 3) = zwRight; + + dBottomLeft = xyLeft; + Unsafe.Add(ref dBottomLeft, 1) = zwLeft; + Unsafe.Add(ref dBottomLeft, 2) = xyRight; + Unsafe.Add(ref dBottomLeft, 3) = zwRight; } [MethodImpl(InliningOptions.ColdPath)] diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs index 269a3e0d8..65176af5b 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs @@ -257,24 +257,24 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations var wRight = new Vector4(sRight.W); Unsafe.As(ref dTopLeft) = xLeft; - AssignVector4Value(ref dTopLeft, 1, ref yLeft); - AssignVector4Value(ref dTopLeft, 2, ref zLeft); - AssignVector4Value(ref dTopLeft, 3, ref wLeft); - + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; + Unsafe.As(ref dTopRight) = xRight; - AssignVector4Value(ref dTopRight, 1, ref yRight); - AssignVector4Value(ref dTopRight, 2, ref zRight); - AssignVector4Value(ref dTopRight, 3, ref wRight); + Unsafe.As(ref Unsafe.Add(ref dTopRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dTopRight, 3)) = wRight; Unsafe.As(ref dBottomLeft) = xLeft; - AssignVector4Value(ref dBottomLeft, 1, ref yLeft); - AssignVector4Value(ref dBottomLeft, 2, ref zLeft); - AssignVector4Value(ref dBottomLeft, 3, ref wLeft); + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; Unsafe.As(ref dBottomRight) = xRight; - AssignVector4Value(ref dBottomRight, 1, ref yRight); - AssignVector4Value(ref dBottomRight, 2, ref zRight); - AssignVector4Value(ref dBottomRight, 3, ref wRight); + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 1)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 2)) = zRight; + Unsafe.As(ref Unsafe.Add(ref dBottomRight, 3)) = wRight; } [Benchmark] @@ -315,39 +315,90 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations var wRight = new Vector2(sRight.W); Unsafe.As(ref dTopLeft) = xLeft; - AssignVector4Value(ref dTopLeft, 1, ref yLeft); - AssignVector4Value(ref dTopLeft, 2, ref zLeft); - AssignVector4Value(ref dTopLeft, 3, ref wLeft); + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 3)) = wLeft; - AssignVector4Value(ref dTopLeft, 4, ref xRight); - AssignVector4Value(ref dTopLeft, 5, ref yRight); - AssignVector4Value(ref dTopLeft, 6, ref zRight); + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 4)) = xRight; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 5)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dTopLeft, 6)) = zRight; Unsafe.Add(ref dTopLeft, 7) = wRight; Unsafe.As(ref dBottomLeft) = xLeft; - AssignVector4Value(ref dBottomLeft, 1, ref yLeft); - AssignVector4Value(ref dBottomLeft, 2, ref zLeft); - AssignVector4Value(ref dBottomLeft, 3, ref wLeft); + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 1)) = yLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 2)) = zLeft; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 3)) = wLeft; - AssignVector4Value(ref dBottomLeft, 4, ref xRight); - AssignVector4Value(ref dBottomLeft, 5, ref yRight); - AssignVector4Value(ref dBottomLeft, 6, ref zRight); + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 4)) = xRight; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 5)) = yRight; + Unsafe.As(ref Unsafe.Add(ref dBottomLeft, 6)) = zRight; Unsafe.Add(ref dBottomLeft, 7) = wRight; } + + [Benchmark] + public void UseVector4_V2() + { + ref Vector2 destBase = ref Unsafe.As(ref this.destArea.GetReferenceToOrigin()); + int destStride = this.destArea.Stride / 2; + + ref Block8x8F src = ref this.block; + + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 0, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 1, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 2, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 3, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 4, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 5, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 6, destStride); + WidenCopyImpl2x2_Vector4_V2(ref src, ref destBase, 7, destStride); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AssignVector4Value(ref Vector2 destBase, int offset, ref Vector4 value) + private static void WidenCopyImpl2x2_Vector4_V2(ref Block8x8F src, ref Vector2 destBase, int row, int destStride) { - Unsafe.As(ref Unsafe.Add(ref destBase, offset)) = value; + ref Vector4 sLeft = ref Unsafe.Add(ref src.V0L, 2 * row); + ref Vector4 sRight = ref Unsafe.Add(ref sLeft, 1); + + int offset = 2 * row * destStride; + ref Vector4 dTopLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, offset)); + ref Vector4 dBottomLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, offset + destStride)); + + var xyLeft = new Vector4(sLeft.X); + xyLeft.Z = sLeft.Y; + xyLeft.W = sLeft.Y; + + var zwLeft = new Vector4(sLeft.Z); + zwLeft.Z = sLeft.W; + zwLeft.W = sLeft.W; + + var xyRight = new Vector4(sRight.X); + xyRight.Z = sRight.Y; + xyRight.W = sRight.Y; + + var zwRight = new Vector4(sRight.Z); + zwRight.Z = sRight.W; + zwRight.W = sRight.W; + + dTopLeft = xyLeft; + Unsafe.Add(ref dTopLeft, 1) = zwLeft; + Unsafe.Add(ref dTopLeft, 2) = xyRight; + Unsafe.Add(ref dTopLeft, 3) = zwRight; + + dBottomLeft = xyLeft; + Unsafe.Add(ref dBottomLeft, 1) = zwLeft; + Unsafe.Add(ref dBottomLeft, 2) = xyRight; + Unsafe.Add(ref dBottomLeft, 3) = zwRight; } // RESULTS: // Method | Mean | Error | StdDev | Scaled | ScaledSD | // --------------------------- |---------:|----------:|----------:|-------:|---------:| - // Original | 93.78 ns | 1.8419 ns | 1.9708 ns | 1.00 | 0.00 | - // Original_V2 | 89.85 ns | 0.8809 ns | 0.7356 ns | 0.96 | 0.02 | - // UseVector2 | 81.81 ns | 0.4441 ns | 0.3937 ns | 0.87 | 0.02 | - // UseVector4 | 55.74 ns | 0.3674 ns | 0.3068 ns | 0.59 | 0.01 | - // UseVector4_SafeRightCorner | 55.70 ns | 0.3239 ns | 0.2705 ns | 0.59 | 0.01 | + // Original | 92.69 ns | 2.4722 ns | 2.7479 ns | 1.00 | 0.00 | + // Original_V2 | 91.72 ns | 1.2089 ns | 1.0095 ns | 0.99 | 0.03 | + // UseVector2 | 86.70 ns | 0.5873 ns | 0.5206 ns | 0.94 | 0.03 | + // UseVector4 | 55.42 ns | 0.2482 ns | 0.2322 ns | 0.60 | 0.02 | + // UseVector4_SafeRightCorner | 58.97 ns | 0.4152 ns | 0.3884 ns | 0.64 | 0.02 | + // UseVector4_V2 | 41.88 ns | 0.3531 ns | 0.3303 ns | 0.45 | 0.01 | } } \ No newline at end of file diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index 3a3a7d31c..c0bb25a1b 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -4,6 +4,7 @@ // using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations; +using SixLabors.ImageSharp.Tests.ProfilingBenchmarks; namespace SixLabors.ImageSharp.Sandbox46 { @@ -62,8 +63,8 @@ namespace SixLabors.ImageSharp.Sandbox46 private static void RunDecodeJpegProfilingTests() { Console.WriteLine("RunDecodeJpegProfilingTests..."); - var benchmarks = new JpegProfilingBenchmarks(new ConsoleOutput()); - foreach (object[] data in JpegProfilingBenchmarks.DecodeJpegData) + var benchmarks = new JpegBenchmarks(new ConsoleOutput()); + foreach (object[] data in JpegBenchmarks.DecodeJpegData) { string fileName = (string)data[0]; benchmarks.DecodeJpeg(fileName); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs similarity index 84% rename from tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs rename to tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index 88959bfab..3d439c5ce 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -13,11 +13,11 @@ using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; -namespace SixLabors.ImageSharp.Tests.Formats.Jpg +namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { - public class JpegProfilingBenchmarks : MeasureFixture + public class JpegBenchmarks : MeasureFixture { - public JpegProfilingBenchmarks(ITestOutputHelper output) + public JpegBenchmarks(ITestOutputHelper output) : base(output) { } @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, }; - [Theory] // Benchmark, enable manually + [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [MemberData(nameof(DecodeJpegData))] public void DecodeJpeg(string fileName) { @@ -69,11 +69,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } // Benchmark, enable manually! - // [Theory] - // [InlineData(1, 75, JpegSubsample.Ratio420)] - // [InlineData(30, 75, JpegSubsample.Ratio420)] - // [InlineData(30, 75, JpegSubsample.Ratio444)] - // [InlineData(30, 100, JpegSubsample.Ratio444)] + [Theory(Skip = ProfilingSetup.SkipProfilingTests)] + [InlineData(1, 75, JpegSubsample.Ratio420)] + [InlineData(30, 75, JpegSubsample.Ratio420)] + [InlineData(30, 75, JpegSubsample.Ratio444)] + [InlineData(30, 100, JpegSubsample.Ratio444)] public void EncodeJpeg(int executionCount, int quality, JpegSubsample subsample) { // do not run this on CI even by accident @@ -107,6 +107,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg $@"Encode {testFiles.Length} images" ); } + + foreach (Image image in testImages) + { + image.Dispose(); + } } } diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs similarity index 67% rename from tests/ImageSharp.Tests/ProfilingBenchmarks.cs rename to tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs index bc9b2a947..306072276 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs @@ -1,31 +1,23 @@ -using System.IO; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; -using SixLabors.Primitives; using Xunit; using Xunit.Abstractions; -namespace SixLabors.ImageSharp.Tests +namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { - public class ProfilingBenchmarks : MeasureFixture + public class LoadResizeSaveBenchmarks : MeasureFixture { - public const string SkipProfilingTests = -#if true - null; -#else - "Profiling benchmark, enable manually!"; -#endif - - - public ProfilingBenchmarks(ITestOutputHelper output) + public LoadResizeSaveBenchmarks(ITestOutputHelper output) : base(output) { } - [Theory(Skip = SkipProfilingTests)] + [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [InlineData(TestImages.Jpeg.Baseline.Jpeg420Exif)] public void LoadResizeSave(string imagePath) { diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs new file mode 100644 index 000000000..267c70219 --- /dev/null +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs @@ -0,0 +1,18 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// Uncomment to enable local profiling benchmarks. DO NOT PUSH TO MAIN! +#define PROFILING + +namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks +{ + public static class ProfilingSetup + { + public const string SkipProfilingTests = +#if PROFILING + null; +#else + "Profiling benchmark, enable manually!"; +#endif + } +} \ No newline at end of file From c4510585077f24819684a64de393dc5e19c508bc Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 3 Nov 2018 22:21:48 +0100 Subject: [PATCH 139/238] minor optimization in JpegColorConverter.FromGrayscale --- .../JpegColorConverter.FromGrayScale.cs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs index 5d7a31a12..7424145c3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs @@ -3,6 +3,8 @@ using System; using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters { @@ -17,24 +19,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters public override void ConvertToRgba(in ComponentValues values, Span result) { - // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! - ReadOnlySpan yVals = values.Component0; - - var v = new Vector4(0, 0, 0, 1); - var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); + ref float sBase = ref MemoryMarshal.GetReference(values.Component0); + ref Vector4 dBase = ref MemoryMarshal.GetReference(result); + for (int i = 0; i < result.Length; i++) { - float y = yVals[i]; - - v.X = y; - v.Y = y; - v.Z = y; - + var v = new Vector4(Unsafe.Add(ref sBase, i)); + v.W = 1f; v *= scale; - - result[i] = v; + Unsafe.Add(ref dBase, i) = v; } } } From 25f0f78874b17d207447e174bc93fde32c4cf52f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 00:19:29 +0100 Subject: [PATCH 140/238] add JpegSnoop reports for all current input Jpeg --- .../JpegSnoopReports/Calliphora.jpg.txt | 331 ++++++++ .../JpegSnoopReports/Floorplan.jpg.txt | 266 ++++++ .../JpegSnoopReports/Hiyamugi.jpg.txt | 319 ++++++++ .../baseline/JpegSnoopReports/Lake.jpg.txt | 683 ++++++++++++++++ .../MultiScanBaselineCMYK.jpg.txt | 282 +++++++ .../baseline/JpegSnoopReports/Snake.jpg.txt | 683 ++++++++++++++++ .../baseline/JpegSnoopReports/badeof.jpg.txt | 347 ++++++++ .../baseline/JpegSnoopReports/badrst.jpg.txt | 434 ++++++++++ .../baseline/JpegSnoopReports/cmyk.jpg.txt | 435 ++++++++++ .../baseline/JpegSnoopReports/exif.jpg.txt | 454 ++++++++++ .../gamma_dalai_lama_gray.jpg.txt | 339 ++++++++ .../JpegSnoopReports/jpeg400jfif.jpg.txt | 211 +++++ .../JpegSnoopReports/jpeg420exif.jpg.txt | 412 ++++++++++ .../JpegSnoopReports/jpeg420small.jpg.txt | 330 ++++++++ .../baseline/JpegSnoopReports/jpeg444.jpg.txt | 405 +++++++++ .../JpegSnoopReports/ratio-1x1.jpg.txt | 338 ++++++++ .../JpegSnoopReports/testimgint.jpg.txt | 342 ++++++++ .../JpegSnoopReports/testorig.jpg.txt | 342 ++++++++ .../baseline/JpegSnoopReports/turtle.jpg.txt | 367 +++++++++ .../baseline/JpegSnoopReports/ycck.jpg.txt | 640 +++++++++++++++ ...59-MissingFF00-Progressive-Bedroom.jpg.txt | 461 +++++++++++ ...ue159-MissingFF00-Progressive-Girl.jpg.txt | 520 ++++++++++++ ...ssue178-BadCoeffsProgressive-Lemon.jpg.txt | 471 +++++++++++ .../Issue214-CriticalEOF .jpg.txt | 94 +++ .../Issue385-BadZigZag-Progressive.jpg.txt | 468 +++++++++++ ...e394-MultiHuffmanBaseline-Speakers.jpg.txt | 438 ++++++++++ .../Issue517-No-EOI-Progressive.jpg.txt | 406 +++++++++ .../Issue518-Bad-RST-Progressive.jpg.txt | 759 +++++++++++++++++ .../Issue520-InvalidCast.jpg.txt | 364 +++++++++ ...24-DhtHasWrongLength-Progressive-N.jpg.txt | 284 +++++++ .../Issue694-Decode-Exif-OutOfRange.jpg.txt | 368 +++++++++ .../Issue695-Invalid-EOI.jpg.txt | 39 + .../Issue696-Resize-Exif-OutOfRange.jpg.txt | 377 +++++++++ .../Issue721-InvalidAPP0.jpg.txt | 446 ++++++++++ ...-Ordered-Interleaved-Progressive-A.jpg.txt | 519 ++++++++++++ ...-Ordered-Interleaved-Progressive-B.jpg.txt | 477 +++++++++++ ...-Ordered-Interleaved-Progressive-C.jpg.txt | 484 +++++++++++ .../issue750-exif-load.jpg.txt | 772 ++++++++++++++++++ .../issue750-exif-tranform.jpg.txt | 435 ++++++++++ .../BadEofProgressive.jpg.txt | 452 ++++++++++ .../JpegSnoopReports/ExifUndefType.jpg.txt | 535 ++++++++++++ .../JpegSnoopReports/Festzug.jpg.txt | 459 +++++++++++ .../progressive/JpegSnoopReports/fb.jpg.txt | 525 ++++++++++++ .../JpegSnoopReports/progress.jpg.txt | 468 +++++++++++ 44 files changed, 18581 insertions(+) create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/Calliphora.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/Floorplan.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/Hiyamugi.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/Lake.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/MultiScanBaselineCMYK.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/Snake.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/badeof.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/badrst.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/cmyk.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/exif.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/gamma_dalai_lama_gray.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg400jfif.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420exif.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420small.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg444.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/ratio-1x1.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/testimgint.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/testorig.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/turtle.jpg.txt create mode 100644 tests/Images/Input/Jpg/baseline/JpegSnoopReports/ycck.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Bedroom.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Girl.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue178-BadCoeffsProgressive-Lemon.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue214-CriticalEOF .jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue385-BadZigZag-Progressive.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue394-MultiHuffmanBaseline-Speakers.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue517-No-EOI-Progressive.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue518-Bad-RST-Progressive.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue520-InvalidCast.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue624-DhtHasWrongLength-Progressive-N.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue694-Decode-Exif-OutOfRange.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue695-Invalid-EOI.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue696-Resize-Exif-OutOfRange.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue721-InvalidAPP0.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-A.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-B.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-C.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-load.jpg.txt create mode 100644 tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-tranform.jpg.txt create mode 100644 tests/Images/Input/Jpg/progressive/JpegSnoopReports/BadEofProgressive.jpg.txt create mode 100644 tests/Images/Input/Jpg/progressive/JpegSnoopReports/ExifUndefType.jpg.txt create mode 100644 tests/Images/Input/Jpg/progressive/JpegSnoopReports/Festzug.jpg.txt create mode 100644 tests/Images/Input/Jpg/progressive/JpegSnoopReports/fb.jpg.txt create mode 100644 tests/Images/Input/Jpg/progressive/JpegSnoopReports/progress.jpg.txt diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Calliphora.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Calliphora.jpg.txt new file mode 100644 index 000000000..dc889ab10 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Calliphora.jpg.txt @@ -0,0 +1,331 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Calliphora.jpg] + Filesize: [254766] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 96 x 96 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x00000014 + Comment length = 80 + Comment=File source: http://commons.wikimedia.org/wiki/File:Calliphora_sp_Portrait.jpg + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000066 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 10 16 20 24 + DQT, Row #1: 5 5 6 8 10 23 24 22 + DQT, Row #2: 6 5 6 10 16 23 28 22 + DQT, Row #3: 6 7 9 12 20 35 32 25 + DQT, Row #4: 7 9 15 22 27 44 41 31 + DQT, Row #5: 10 14 22 26 32 42 45 37 + DQT, Row #6: 20 26 31 35 41 48 48 40 + DQT, Row #7: 29 37 38 39 45 40 41 40 + Approx quality factor = 79.94 (scaling=40.12 variance=1.43) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000000AB + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 10 19 40 40 40 40 + DQT, Row #1: 7 8 10 26 40 40 40 40 + DQT, Row #2: 10 10 22 40 40 40 40 40 + DQT, Row #3: 19 26 40 40 40 40 40 40 + DQT, Row #4: 40 40 40 40 40 40 40 40 + DQT, Row #5: 40 40 40 40 40 40 40 40 + DQT, Row #6: 40 40 40 40 40 40 40 40 + DQT, Row #7: 40 40 40 40 40 40 40 40 + Approx quality factor = 79.87 (scaling=40.26 variance=0.36) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000000F0 + Frame header length = 17 + Precision = 8 + Number of Lines = 1198 + Samples per Line = 804 + Image Size = 804 x 1198 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000103 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 04 + Codes of length 03 bits (005 total): 00 01 02 03 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000121 + Huffman table length = 79 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 06 31 + Codes of length 07 bits (004 total): 13 22 41 51 + Codes of length 08 bits (004 total): 14 32 61 71 + Codes of length 09 bits (003 total): 07 81 91 + Codes of length 10 bits (006 total): 15 23 42 52 A1 B1 + Codes of length 11 bits (003 total): 33 62 C1 + Codes of length 12 bits (007 total): 16 24 43 72 82 D1 F0 + Codes of length 13 bits (002 total): 25 E1 + Codes of length 14 bits (003 total): 34 53 92 + Codes of length 15 bits (002 total): A2 F1 + Codes of length 16 bits (015 total): 08 63 B2 26 44 C2 D2 73 27 35 55 74 84 93 A3 + Total number of codes: 060 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000172 + Huffman table length = 26 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000018E + Huffman table length = 59 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (002 total): 03 31 + Codes of length 06 bits (004 total): 12 41 51 F0 + Codes of length 07 bits (003 total): 04 61 71 + Codes of length 08 bits (008 total): 13 22 81 91 A1 B1 C1 D1 + Codes of length 09 bits (002 total): 32 E1 + Codes of length 10 bits (002 total): 42 F1 + Codes of length 11 bits (002 total): 05 23 + Codes of length 12 bits (002 total): 52 62 + Codes of length 13 bits (002 total): 14 33 + Codes of length 14 bits (001 total): 72 + Codes of length 15 bits (004 total): 24 82 92 A2 + Codes of length 16 bits (003 total): 43 B2 E2 + Total number of codes: 040 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000001CB + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000001D9 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0003E32C.0 + + Compression stats: + Compression Ratio: 11.36:1 + Bits per pixel: 2.11:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2628 ( 17%) + # codes of length 03 bits: 10491 ( 69%) + # codes of length 04 bits: 1319 ( 9%) + # codes of length 05 bits: 611 ( 4%) + # codes of length 06 bits: 101 ( 1%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 23843 ( 79%) + # codes of length 03 bits: 3770 ( 12%) + # codes of length 04 bits: 1945 ( 6%) + # codes of length 05 bits: 653 ( 2%) + # codes of length 06 bits: 89 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 118632 ( 45%) + # codes of length 03 bits: 34447 ( 13%) + # codes of length 04 bits: 57131 ( 22%) + # codes of length 05 bits: 27139 ( 10%) + # codes of length 06 bits: 8648 ( 3%) + # codes of length 07 bits: 9574 ( 4%) + # codes of length 08 bits: 4195 ( 2%) + # codes of length 09 bits: 1503 ( 1%) + # codes of length 10 bits: 1711 ( 1%) + # codes of length 11 bits: 386 ( 0%) + # codes of length 12 bits: 470 ( 0%) + # codes of length 13 bits: 66 ( 0%) + # codes of length 14 bits: 62 ( 0%) + # codes of length 15 bits: 38 ( 0%) + # codes of length 16 bits: 58 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 58553 ( 58%) + # codes of length 03 bits: 21076 ( 21%) + # codes of length 04 bits: 4270 ( 4%) + # codes of length 05 bits: 6075 ( 6%) + # codes of length 06 bits: 6016 ( 6%) + # codes of length 07 bits: 2009 ( 2%) + # codes of length 08 bits: 2750 ( 3%) + # codes of length 09 bits: 429 ( 0%) + # codes of length 10 bits: 213 ( 0%) + # codes of length 11 bits: 91 ( 0%) + # codes of length 12 bits: 44 ( 0%) + # codes of length 13 bits: 22 ( 0%) + # codes of length 14 bits: 5 ( 0%) + # codes of length 15 bits: 9 ( 0%) + # codes of length 16 bits: 3 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[119] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1008, 0, 0] RGB=[254,254,254] @ MCU[ 35, 37] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0003E32C.0 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0003E32C + + +*** Searching Compression Signatures *** + + Signature: 01DC499064BA9264D591FDE9071DFD89 + Signature (Rotated): 0175BAF3251040E0EFB2930B73328E7F + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C40Z,D40Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C700UZ ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + SW :[Apple ImageIO.framework ] [050 (Normal) ] + SW :[IJG Library ] [080 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [080 ] + SW :[IrfanView ] [080 ] + SW :[idImager ] [080 ] + SW :[FastStone Image Viewer ] [080 ] + SW :[NeatImage ] [080 ] + SW :[Paint.NET ] [080 ] + SW :[Photomatix ] [080 ] + SW :[XnView ] [080 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Floorplan.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Floorplan.jpg.txt new file mode 100644 index 000000000..2c03157af --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Floorplan.jpg.txt @@ -0,0 +1,266 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Floorplan.jpg] + Filesize: [161577] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 13464 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x000A + [Model ] = "Photosmart Plus B209a-m" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [Software ] = "Windows Photo Editor 10.0.10011.16384" + [DateTime ] = "2016:01:02 20:17:37" + [ExifOffset ] = @ 0x091A + Offset to Next IFD = 0x000011B6 + + EXIF IFD1 @ Absolute 0x000011D4 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 96/1 + [YResolution ] = 96/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x1214 = @ 0x1232 + [JpegIFByteCount ] = 0x[0000227C] / 8828 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x00000938 + Dir Length = 0x0008 + [DateTimeOriginal ] = "2016:01:02 19:22:28" + [DateTimeDigitized ] = "2016:01:02 19:22:28" + [SubSecTimeOriginal ] = "00" + [SubSecTimeDigitized ] = "00" + [ColorSpace ] = sRGB + [ExifImageWidth ] = 0x[00000922] / 2338 + [ExifImageHeight ] = 0x[000008C9] / 2249 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x000034AE + Length = 12772 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + | + |Windows Photo Editor 10.0.10011.163842016-01-02T19:22:28 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00006694 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 8 10 12 + DQT, Row #1: 2 2 3 4 5 12 12 11 + DQT, Row #2: 3 3 3 5 8 11 14 11 + DQT, Row #3: 3 3 4 6 10 17 16 12 + DQT, Row #4: 4 4 7 11 14 22 21 15 + DQT, Row #5: 5 7 11 13 16 21 23 18 + DQT, Row #6: 10 13 16 17 21 24 24 20 + DQT, Row #7: 14 18 19 20 22 20 21 20 + Approx quality factor = 90.06 (scaling=19.88 variance=1.14) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000066D9 + Frame header length = 11 + Precision = 8 + Number of Lines = 645 + Samples per Line = 976 + Image Size = 976 x 645 + Raw Image Orientation = Landscape + Number of Img components = 1 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000066E6 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00006707 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000067BE + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000067C8 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00027727.0 + + Compression stats: + Compression Ratio: 4.66:1 + Bits per pixel: 1.72:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 3571 ( 36%) + # codes of length 03 bits: 4320 ( 44%) + # codes of length 04 bits: 925 ( 9%) + # codes of length 05 bits: 456 ( 5%) + # codes of length 06 bits: 313 ( 3%) + # codes of length 07 bits: 291 ( 3%) + # codes of length 08 bits: 6 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 78118 ( 44%) + # codes of length 03 bits: 22349 ( 13%) + # codes of length 04 bits: 35264 ( 20%) + # codes of length 05 bits: 18811 ( 11%) + # codes of length 06 bits: 4312 ( 2%) + # codes of length 07 bits: 8245 ( 5%) + # codes of length 08 bits: 4682 ( 3%) + # codes of length 09 bits: 1584 ( 1%) + # codes of length 10 bits: 1900 ( 1%) + # codes of length 11 bits: 324 ( 0%) + # codes of length 12 bits: 116 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 6 ( 0%) + # codes of length 16 bits: 639 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[231] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1017, 0, 0] RGB=[255,255,255] @ MCU[ 7, 0] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00027726.4 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00027727 + + +*** Searching Compression Signatures *** + + Signature: 015C645021E37D3469A6B652789383DB + Signature (Rotated): 01D400C125EB43B05762A66347B271F7 + File Offset: 0 bytes + Chroma subsampling: Gray + EXIF Make/Model: OK [???] [Photosmart Plus B209a-m] + EXIF Makernotes: NONE + EXIF Software: OK [Windows Photo Editor 10.0.10011.16384] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[IJG Library ] [090 Gray ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [090 Gray ] + SW :[IrfanView ] [090 Gray ] + SW :[idImager ] [090 Gray ] + SW :[FastStone Image Viewer ] [090 Gray ] + SW :[NeatImage ] [090 Gray ] + SW :[Paint.NET ] [090 Gray ] + SW :[Photomatix ] [090 Gray ] + SW :[XnView ] [090 Gray ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 2 - Image has high probability of being processed/edited + + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Hiyamugi.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Hiyamugi.jpg.txt new file mode 100644 index 000000000..8538e13c8 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Hiyamugi.jpg.txt @@ -0,0 +1,319 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Hiyamugi.jpg] + Filesize: [540458] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.0] + density = 96 x 96 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000014 + Length = 65110 + Identifier = [JFXX] + Not known APP0 type. Skipping remainder. + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x0000FE6C + Comment length = 31 + Comment=LEAD Technologies Inc. V1.01. + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000FE8D + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 2 2 2 2 2 2 2 2 + DQT, Row #1: 2 2 2 2 2 2 2 2 + DQT, Row #2: 2 2 2 2 2 2 2 2 + DQT, Row #3: 2 2 2 2 2 3 3 2 + DQT, Row #4: 2 2 2 2 2 4 4 3 + DQT, Row #5: 2 2 2 2 3 4 4 3 + DQT, Row #6: 2 2 3 3 4 4 4 4 + DQT, Row #7: 2 3 3 3 4 4 4 3 + Approx quality factor = 96.75 (scaling=6.50 variance=21.01) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 2 2 2 2 3 3 3 3 + DQT, Row #1: 2 2 2 2 3 3 3 3 + DQT, Row #2: 2 2 2 3 3 3 3 3 + DQT, Row #3: 2 2 3 3 3 3 3 3 + DQT, Row #4: 3 3 3 3 3 3 3 3 + DQT, Row #5: 3 3 3 3 3 3 3 3 + DQT, Row #6: 3 3 3 3 3 3 3 3 + DQT, Row #7: 3 3 3 3 3 3 3 3 + Approx quality factor = 98.06 (scaling=3.88 variance=4.78) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000FF13 + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000100B7 + Frame header length = 17 + Precision = 8 + Number of Lines = 794 + Samples per Line = 1123 + Image Size = 1123 x 794 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000100CA + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000100D8 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00083F28.0 + + Compression stats: + Compression Ratio: 5.64:1 + Bits per pixel: 4.26:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 727 ( 5%) + # codes of length 03 bits: 7443 ( 52%) + # codes of length 04 bits: 2171 ( 15%) + # codes of length 05 bits: 1627 ( 11%) + # codes of length 06 bits: 1355 ( 10%) + # codes of length 07 bits: 785 ( 6%) + # codes of length 08 bits: 92 ( 1%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2590 ( 36%) + # codes of length 03 bits: 1357 ( 19%) + # codes of length 04 bits: 1187 ( 17%) + # codes of length 05 bits: 856 ( 12%) + # codes of length 06 bits: 616 ( 9%) + # codes of length 07 bits: 346 ( 5%) + # codes of length 08 bits: 109 ( 2%) + # codes of length 09 bits: 39 ( 1%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 223973 ( 44%) + # codes of length 03 bits: 69375 ( 14%) + # codes of length 04 bits: 93550 ( 19%) + # codes of length 05 bits: 58421 ( 12%) + # codes of length 06 bits: 13137 ( 3%) + # codes of length 07 bits: 22630 ( 4%) + # codes of length 08 bits: 9176 ( 2%) + # codes of length 09 bits: 6545 ( 1%) + # codes of length 10 bits: 3947 ( 1%) + # codes of length 11 bits: 1890 ( 0%) + # codes of length 12 bits: 1162 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 77 ( 0%) + # codes of length 16 bits: 1763 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 44319 ( 35%) + # codes of length 03 bits: 21048 ( 17%) + # codes of length 04 bits: 24019 ( 19%) + # codes of length 05 bits: 17303 ( 14%) + # codes of length 06 bits: 9470 ( 7%) + # codes of length 07 bits: 2699 ( 2%) + # codes of length 08 bits: 3432 ( 3%) + # codes of length 09 bits: 2092 ( 2%) + # codes of length 10 bits: 717 ( 1%) + # codes of length 11 bits: 679 ( 1%) + # codes of length 12 bits: 85 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 150 ( 0%) + # codes of length 15 bits: 75 ( 0%) + # codes of length 16 bits: 425 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[117] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 812, 102, -218] RGB=[189,244,250] @ MCU[ 19, 16] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00083F27.7 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00083F28 + + +*** Searching Compression Signatures *** + + Signature: 0193B6220463E5A621ED25A53EC2FE7D + Signature (Rotated): 010D9693F4FC34B402EFA979BED34733 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[LEAD Technologies Inc ] [002 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Lake.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Lake.jpg.txt new file mode 100644 index 000000000..900f52cb7 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Lake.jpg.txt @@ -0,0 +1,683 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Lake.jpg] + Filesize: [206342] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 10392 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0008 + [Make ] = "Canon" + [Model ] = "Canon EOS DIGITAL REBEL XSi" + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop Camera Raw 9.8 (Windows)" + [DateTime ] = "2016:12:29 12:57:54" + [ExifOffset ] = @ 0x00DE + Offset to Next IFD = 0x000002D6 + + EXIF IFD1 @ Absolute 0x000002E2 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x0334 = @ 0x0340 + [JpegIFByteCount ] = 0x[0000255C] / 9564 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000EA + Dir Length = 0x001B + [ExposureTime ] = 1/640 s + [FNumber ] = F8.0 + [ExposureProgram ] = Normal program + [ISOSpeedRatings ] = 200 + [ExifVersion ] = 02.30 + [DateTimeOriginal ] = "2009:07:19 17:00:36" + [DateTimeDigitized ] = "2009:07:19 17:00:36" + [ShutterSpeedValue ] = 9321928/1000000 + [ApertureValue ] = 6/1 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 4/1 + [MeteringMode ] = Pattern + [Flash ] = Flash did not fire + [FocalLength ] = 200 mm + [SubSecTimeOriginal ] = "73" + [SubSecTimeDigitized ] = "73" + [ColorSpace ] = Uncalibrated + [FocalPlaneXResolution ] = 4272000/878 + [FocalPlaneYResolution ] = 2848000/584 + [FocalPlaneResolutionUnit ] = Inch + [CustomRendered ] = Normal process + [ExposureMode ] = Auto exposure + [WhiteBalance ] = Auto white balance + [SceneCaptureType ] = Standard + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x0000289C + Length = 9752 + Identifier = [Photoshop 3.0] + 8BIM: [0x03ED] Name="" Len=[0x0010] DefinedName="ResolutionInfo structure" + Horizontal resolution = 300 pixels per inch + Width unit = inch + Vertical resolution = 300 pixels per inch + Height unit = inch + 8BIM: [0x0404] Name="" Len=[0x003F] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 4 + IPTC [002:055] Date Created = "20090719" + IPTC [002:060] Time Created = "170036" + IPTC [002:062] Digital Creation Date = "20090719" + IPTC [002:063] Digital Creation Time = "170036" + 8BIM: [0x040C] Name="" Len=[0x2578] DefinedName="Thumbnail resources" + Format = 1 + Width of thumbnail = 256 pixels + Height of thumbnail = 171 pixels + Widthbytes = 768 bytes + Total size = 131328 bytes + Size after compression = 9564 bytes + Bits per pixel = 24 bits + Number of planes = 1 + JFIF data @ 0x0000293E + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0x52 C5 4C EC 1E FE 25 B8 CA 88 F7 0D 2B 5F 09 F5 | R.L...%.....+_.. + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00004EB6 + Length = 576 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 560 bytes + Preferred CMM Type : 'ADBE' (0x41444245) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1999-06-03 00:00:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'none' (0x6E6F6E65) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'ADBE' (0x41444245) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x000050F8 + Length = 10738 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + | + | + | + | + | + | + | + | + | + | + | + | + | + | 0, 0 + | 32, 22 + | 64, 56 + | 128, 128 + | 192, 196 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00007AEC + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + Approx quality factor = 88.28 (scaling=23.43 variance=111.68) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 90.19 (scaling=19.62 variance=201.04) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00007B72 + Length = 4 + interval = 160 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x00007B78 + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 49152 + APP14Flags1 = 0 + ColorTransform = 1 [YCbCr] + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00007B88 + Frame header length = 17 + Precision = 8 + Number of Lines = 853 + Samples per Line = 1280 + Image Size = 1280 x 853 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007B9B + Huffman table length = 159 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 03 + Codes of length 03 bits (003 total): 01 02 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (001 total): 08 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 006 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (002 total): 05 41 + Codes of length 07 bits (003 total): 13 22 51 + Codes of length 08 bits (006 total): 32 61 71 81 91 A1 + Codes of length 09 bits (005 total): 06 14 23 42 B1 + Codes of length 10 bits (002 total): 52 C1 + Codes of length 11 bits (004 total): 15 33 62 D1 + Codes of length 12 bits (004 total): 07 72 E1 F1 + Codes of length 13 bits (005 total): 16 24 43 82 F0 + Codes of length 14 bits (003 total): 34 92 A2 + Codes of length 15 bits (000 total): + Codes of length 16 bits (011 total): 53 63 C2 25 73 B2 D2 26 54 93 E2 + Total number of codes: 054 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 02 + Codes of length 05 bits (000 total): + Codes of length 06 bits (002 total): 12 21 + Codes of length 07 bits (002 total): 03 31 + Codes of length 08 bits (003 total): 13 41 51 + Codes of length 09 bits (001 total): 61 + Codes of length 10 bits (000 total): + Codes of length 11 bits (002 total): 04 71 + Codes of length 12 bits (003 total): 14 22 81 + Codes of length 13 bits (001 total): 32 + Codes of length 14 bits (001 total): 42 + Codes of length 15 bits (001 total): 91 + Codes of length 16 bits (000 total): + Total number of codes: 020 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007C3C + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00007C4A + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00032604.0 + + Compression stats: + Compression Ratio: 18.77:1 + Bits per pixel: 1.28:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 8237 ( 48%) + # codes of length 03 bits: 7451 ( 44%) + # codes of length 04 bits: 930 ( 5%) + # codes of length 05 bits: 300 ( 2%) + # codes of length 06 bits: 197 ( 1%) + # codes of length 07 bits: 5 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 16681 ( 49%) + # codes of length 02 bits: 10125 ( 30%) + # codes of length 03 bits: 5138 ( 15%) + # codes of length 04 bits: 1825 ( 5%) + # codes of length 05 bits: 432 ( 1%) + # codes of length 06 bits: 39 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 104267 ( 49%) + # codes of length 03 bits: 23564 ( 11%) + # codes of length 04 bits: 44372 ( 21%) + # codes of length 05 bits: 19037 ( 9%) + # codes of length 06 bits: 5565 ( 3%) + # codes of length 07 bits: 5437 ( 3%) + # codes of length 08 bits: 5066 ( 2%) + # codes of length 09 bits: 2163 ( 1%) + # codes of length 10 bits: 491 ( 0%) + # codes of length 11 bits: 407 ( 0%) + # codes of length 12 bits: 211 ( 0%) + # codes of length 13 bits: 115 ( 0%) + # codes of length 14 bits: 36 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 26 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 34240 ( 51%) + # codes of length 02 bits: 15658 ( 24%) + # codes of length 03 bits: 7424 ( 11%) + # codes of length 04 bits: 3865 ( 6%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 3125 ( 5%) + # codes of length 07 bits: 1208 ( 2%) + # codes of length 08 bits: 744 ( 1%) + # codes of length 09 bits: 113 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 60 ( 0%) + # codes of length 12 bits: 60 ( 0%) + # codes of length 13 bits: 9 ( 0%) + # codes of length 14 bits: 4 ( 0%) + # codes of length 15 bits: 1 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[122] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 714, -42, 42] RGB=[224,215,206] @ MCU[113, 24] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 106 + Next position in scan buffer: Offset 0x00032604.0 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00032604 + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000340 + Length: 0x0000255C (9564) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: DQT + Length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + + * Embedded Thumb Marker: DRI + Length = 4 + + * Embedded Thumb Marker: APP14 + Length = 14 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 171 + Samples per Line = 256 + Image Size = 256 x 171 + + * Embedded Thumb Marker: DHT + Length = 148 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 9212 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 01180AF3DE63318828A86409EF4013DD + +*** Searching Compression Signatures *** + + Signature: 01180AF3DE63318828A86409EF4013DD + Signature (Rotated): 01180AF3DE63318828A86409EF4013DD + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: OK [Canon] [Canon EOS DIGITAL REBEL XSi] + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop Camera Raw 9.8 (Windows)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 08 ] + + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + Appears to be new signature for known software. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/MultiScanBaselineCMYK.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/MultiScanBaselineCMYK.jpg.txt new file mode 100644 index 000000000..cd415a201 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/MultiScanBaselineCMYK.jpg.txt @@ -0,0 +1,282 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\MultiScanBaselineCMYK.jpg] + Filesize: [47443] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x00000014 + Length = 14 + DCTEncodeVersion = 25600 + APP14Flags0 = 0 + APP14Flags1 = 0 + ColorTransform = 2 [YCCK] + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x00000024 + Comment length = 38 + Comment=Created by fCoder Graphics Processor + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000004C + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 5 3 3 5 7 12 15 18 + DQT, Row #1: 4 4 4 6 8 17 18 17 + DQT, Row #2: 4 4 5 7 12 17 21 17 + DQT, Row #3: 4 5 7 9 15 26 24 19 + DQT, Row #4: 5 7 11 17 20 33 31 23 + DQT, Row #5: 7 11 17 19 24 31 34 28 + DQT, Row #6: 15 19 23 26 31 36 36 30 + DQT, Row #7: 22 28 29 29 34 30 31 30 + Approx quality factor = 84.93 (scaling=30.13 variance=1.05) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000091 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 5 5 7 14 30 30 30 30 + DQT, Row #1: 5 6 8 20 30 30 30 30 + DQT, Row #2: 7 8 17 30 30 30 30 30 + DQT, Row #3: 14 20 30 30 30 30 30 30 + DQT, Row #4: 30 30 30 30 30 30 30 30 + DQT, Row #5: 30 30 30 30 30 30 30 30 + DQT, Row #6: 30 30 30 30 30 30 30 30 + DQT, Row #7: 30 30 30 30 30 30 30 30 + Approx quality factor = 84.93 (scaling=30.15 variance=0.29) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000000D6 + Frame header length = 20 + Precision = 8 + Number of Lines = 842 + Samples per Line = 595 + Image Size = 595 x 842 + Raw Image Orientation = Portrait + Number of Img components = 4 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Cr) + Component[4]: ID=0x04, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (K) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000EC + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000010D + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000001C4 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000001E5 + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000029C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00005825 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000766A + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000A1FA + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x04, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000B951 + + +*** Searching Compression Signatures *** + + Signature: 0155D875C95B74D0F3C5835A62516F48 + Signature (Rotated): 01D38A25358EB7649A254E19F1D46600 + File Offset: 0 bytes + Chroma subsampling: ?x? + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[Nokia ] [N73 ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 8100 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + SW :[IJG Library ] [085 ] + SW :[Picasa ] [085 (Normal) ] + SW :[ZoomBrowser EX ] [medium ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [085 ] + SW :[IrfanView ] [085 ] + SW :[idImager ] [085 ] + SW :[FastStone Image Viewer ] [085 ] + SW :[NeatImage ] [085 ] + SW :[Paint.NET ] [085 ] + SW :[Photomatix ] [085 ] + SW :[XnView ] [085 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Snake.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Snake.jpg.txt new file mode 100644 index 000000000..926da026f --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/Snake.jpg.txt @@ -0,0 +1,683 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Snake.jpg] + Filesize: [165200] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 11941 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0008 + [Make ] = "Canon" + [Model ] = "Canon EOS DIGITAL REBEL XSi" + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop Camera Raw 9.8 (Windows)" + [DateTime ] = "2016:12:29 12:57:50" + [ExifOffset ] = @ 0x00DE + Offset to Next IFD = 0x000002D6 + + EXIF IFD1 @ Absolute 0x000002E2 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x0334 = @ 0x0340 + [JpegIFByteCount ] = 0x[00002B69] / 11113 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000EA + Dir Length = 0x001B + [ExposureTime ] = 1/25 s + [FNumber ] = F4.0 + [ExposureProgram ] = Shutter priority + [ISOSpeedRatings ] = 250 + [ExifVersion ] = 02.30 + [DateTimeOriginal ] = "2009:07:19 13:25:29" + [DateTimeDigitized ] = "2009:07:19 13:25:29" + [ShutterSpeedValue ] = 4643856/1000000 + [ApertureValue ] = 4/1 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 4/1 + [MeteringMode ] = Pattern + [Flash ] = Flash did not fire + [FocalLength ] = 200 mm + [SubSecTimeOriginal ] = "03" + [SubSecTimeDigitized ] = "03" + [ColorSpace ] = Uncalibrated + [FocalPlaneXResolution ] = 4272000/878 + [FocalPlaneYResolution ] = 2848000/584 + [FocalPlaneResolutionUnit ] = Inch + [CustomRendered ] = Normal process + [ExposureMode ] = Auto exposure + [WhiteBalance ] = Auto white balance + [SceneCaptureType ] = Standard + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00002EA9 + Length = 11302 + Identifier = [Photoshop 3.0] + 8BIM: [0x03ED] Name="" Len=[0x0010] DefinedName="ResolutionInfo structure" + Horizontal resolution = 300 pixels per inch + Width unit = inch + Vertical resolution = 300 pixels per inch + Height unit = inch + 8BIM: [0x0404] Name="" Len=[0x003F] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 4 + IPTC [002:055] Date Created = "20090719" + IPTC [002:060] Time Created = "132529" + IPTC [002:062] Digital Creation Date = "20090719" + IPTC [002:063] Digital Creation Time = "132529" + 8BIM: [0x040C] Name="" Len=[0x2B85] DefinedName="Thumbnail resources" + Format = 1 + Width of thumbnail = 256 pixels + Height of thumbnail = 171 pixels + Widthbytes = 768 bytes + Total size = 131328 bytes + Size after compression = 11113 bytes + Bits per pixel = 24 bits + Number of planes = 1 + JFIF data @ 0x00002F4B + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0xEE 2F A2 47 C5 F8 ED 07 08 CD FF 82 A0 D1 7F F2 | ./.G............ + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00005AD1 + Length = 576 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 560 bytes + Preferred CMM Type : 'ADBE' (0x41444245) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1999-06-03 00:00:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'none' (0x6E6F6E65) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'ADBE' (0x41444245) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00005D13 + Length = 10733 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + | + | + | + | + | + | + | + | + | + | + | + | + | + | 0, 0 + | 32, 22 + | 64, 56 + | 128, 128 + | 192, 196 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | 0, 0 + | 255, 255 + | + | + | + | + | + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00008702 + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + Approx quality factor = 88.28 (scaling=23.43 variance=111.68) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 90.19 (scaling=19.62 variance=201.04) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00008788 + Length = 4 + interval = 160 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x0000878E + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 49152 + APP14Flags1 = 0 + ColorTransform = 1 [YCbCr] + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000879E + Frame header length = 17 + Precision = 8 + Number of Lines = 853 + Samples per Line = 1280 + Image Size = 1280 x 853 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000087B1 + Huffman table length = 153 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 02 03 + Codes of length 03 bits (003 total): 01 04 05 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (001 total): 08 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (001 total): 06 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (002 total): 00 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (001 total): 21 + Codes of length 06 bits (003 total): 05 12 31 + Codes of length 07 bits (003 total): 13 41 51 + Codes of length 08 bits (003 total): 06 22 61 + Codes of length 09 bits (003 total): 14 32 71 + Codes of length 10 bits (003 total): 42 81 91 + Codes of length 11 bits (003 total): 15 23 A1 + Codes of length 12 bits (004 total): 07 52 B1 C1 + Codes of length 13 bits (001 total): 33 + Codes of length 14 bits (002 total): 24 43 + Codes of length 15 bits (002 total): 62 D1 + Codes of length 16 bits (011 total): 16 34 72 E1 25 53 63 92 82 A2 F0 + Total number of codes: 045 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 02 + Codes of length 05 bits (000 total): + Codes of length 06 bits (003 total): 03 12 21 + Codes of length 07 bits (001 total): 31 + Codes of length 08 bits (000 total): + Codes of length 09 bits (002 total): 04 41 + Codes of length 10 bits (003 total): 13 22 51 + Codes of length 11 bits (000 total): + Codes of length 12 bits (003 total): 32 61 71 + Codes of length 13 bits (000 total): + Codes of length 14 bits (003 total): 05 14 42 + Codes of length 15 bits (000 total): + Codes of length 16 bits (003 total): 81 52 62 + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000884C + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000885A + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0002854E.0 + + Compression stats: + Compression Ratio: 25.14:1 + Bits per pixel: 0.95:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 7183 ( 42%) + # codes of length 03 bits: 7286 ( 43%) + # codes of length 04 bits: 1551 ( 9%) + # codes of length 05 bits: 856 ( 5%) + # codes of length 06 bits: 218 ( 1%) + # codes of length 07 bits: 26 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 12266 ( 36%) + # codes of length 02 bits: 11394 ( 33%) + # codes of length 03 bits: 6548 ( 19%) + # codes of length 04 bits: 2911 ( 9%) + # codes of length 05 bits: 875 ( 3%) + # codes of length 06 bits: 241 ( 1%) + # codes of length 07 bits: 5 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 59325 ( 45%) + # codes of length 03 bits: 31160 ( 24%) + # codes of length 04 bits: 18131 ( 14%) + # codes of length 05 bits: 4871 ( 4%) + # codes of length 06 bits: 9522 ( 7%) + # codes of length 07 bits: 4029 ( 3%) + # codes of length 08 bits: 2270 ( 2%) + # codes of length 09 bits: 1006 ( 1%) + # codes of length 10 bits: 515 ( 0%) + # codes of length 11 bits: 268 ( 0%) + # codes of length 12 bits: 195 ( 0%) + # codes of length 13 bits: 24 ( 0%) + # codes of length 14 bits: 29 ( 0%) + # codes of length 15 bits: 20 ( 0%) + # codes of length 16 bits: 26 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 34240 ( 51%) + # codes of length 02 bits: 16000 ( 24%) + # codes of length 03 bits: 5994 ( 9%) + # codes of length 04 bits: 5610 ( 8%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 3610 ( 5%) + # codes of length 07 bits: 600 ( 1%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 410 ( 1%) + # codes of length 10 bits: 200 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 70 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 17 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 6 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[110] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 954, 14, -14] RGB=[244,248,248] @ MCU[124, 21] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 106 + Next position in scan buffer: Offset 0x0002854D.3 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0002854E + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000340 + Length: 0x00002B69 (11113) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: DQT + Length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + + * Embedded Thumb Marker: DRI + Length = 4 + + * Embedded Thumb Marker: APP14 + Length = 14 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 171 + Samples per Line = 256 + Image Size = 256 x 171 + + * Embedded Thumb Marker: DHT + Length = 150 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 10759 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 01180AF3DE63318828A86409EF4013DD + +*** Searching Compression Signatures *** + + Signature: 01180AF3DE63318828A86409EF4013DD + Signature (Rotated): 01180AF3DE63318828A86409EF4013DD + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: OK [Canon] [Canon EOS DIGITAL REBEL XSi] + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop Camera Raw 9.8 (Windows)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 08 ] + + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + Appears to be new signature for known software. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badeof.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badeof.jpg.txt new file mode 100644 index 000000000..97be4853e --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badeof.jpg.txt @@ -0,0 +1,347 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\badeof.jpg] + Filesize: [5770] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 149 + Samples per Line = 227 + Image Size = 227 x 149 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000D2 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000189 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000001AA + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000261 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000026F + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + + Compression stats: + Compression Ratio: 19.73:1 + Bits per pixel: 1.22:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 88 ( 15%) + # codes of length 03 bits: 409 ( 68%) + # codes of length 04 bits: 66 ( 11%) + # codes of length 05 bits: 33 ( 6%) + # codes of length 06 bits: 4 ( 1%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 134 ( 45%) + # codes of length 03 bits: 68 ( 23%) + # codes of length 04 bits: 60 ( 20%) + # codes of length 05 bits: 26 ( 9%) + # codes of length 06 bits: 12 ( 4%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2706 ( 48%) + # codes of length 03 bits: 636 ( 11%) + # codes of length 04 bits: 1331 ( 23%) + # codes of length 05 bits: 473 ( 8%) + # codes of length 06 bits: 196 ( 3%) + # codes of length 07 bits: 169 ( 3%) + # codes of length 08 bits: 66 ( 1%) + # codes of length 09 bits: 60 ( 1%) + # codes of length 10 bits: 28 ( 0%) + # codes of length 11 bits: 14 ( 0%) + # codes of length 12 bits: 4 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 5 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 697 ( 46%) + # codes of length 03 bits: 243 ( 16%) + # codes of length 04 bits: 294 ( 19%) + # codes of length 05 bits: 164 ( 11%) + # codes of length 06 bits: 68 ( 4%) + # codes of length 07 bits: 5 ( 0%) + # codes of length 08 bits: 35 ( 2%) + # codes of length 09 bits: 4 ( 0%) + # codes of length 10 bits: 2 ( 0%) + # codes of length 11 bits: 1 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[107] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1008, -9, 0] RGB=[254,254,250] @ MCU[ 4, 8] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00001687.2 + + +*** Skipped 1 marker pad bytes *** +*** Marker: ??? (Unknown) (xFF00) *** + OFFSET: 0x00001689 + WARNING: Unknown marker [0xFF00] + Stopping decode + Use [Img Search Fwd/Rev] to locate other valid embedded JPEGs + +*** Searching Compression Signatures *** + + Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + Signature (Rotated): 012D821C6AB210E2A753BE053B8F55D0 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[SONY ] [CYBERSHOT U ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + SW :[Apple Quicktime ] [0466-0467 ] + SW :[Digital Photo Professiona] [05 ] + SW :[IJG Library ] [075 ] + SW :[MS Paint ] [ ] + SW :[MS Visio ] [ ] + SW :[ZoomBrowser EX ] [low ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [075 ] + SW :[IrfanView ] [075 ] + SW :[idImager ] [075 ] + SW :[FastStone Image Viewer ] [075 ] + SW :[NeatImage ] [075 ] + SW :[Paint.NET ] [075 ] + SW :[Photomatix ] [075 ] + SW :[XnView ] [075 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + + +*** Additional Info *** +NOTE: Data exists after EOF, range: 0x00000000-0x0000168A (5770 bytes) diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badrst.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badrst.jpg.txt new file mode 100644 index 000000000..cb74eb88f --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/badrst.jpg.txt @@ -0,0 +1,434 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\badrst.jpg] + Filesize: [74497] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 96 x 96 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 8628 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0003 + [Orientation ] = 1 = Row 0: top, Col 0: left + [ExifOffset ] = @ 0x083E + Offset to Next IFD = 0x000010B6 + + EXIF IFD1 @ Absolute 0x000010D4 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 96/1 + [YResolution ] = 96/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x1114 = @ 0x1132 + [JpegIFByteCount ] = 0x[00001097] / 4247 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x0000085C + Dir Length = 0x0005 + [DateTimeOriginal ] = "2016:02:28 11:17:08" + [DateTimeDigitized ] = "2016:02:28 11:17:08" + [SubSecTimeOriginal ] = "06" + [SubSecTimeDigitized ] = "06" + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x000021CA + Length = 2464 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + | + |2016-02-28T11:17:08.057 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00002B6C + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 8 10 12 + DQT, Row #1: 2 2 3 4 5 12 12 11 + DQT, Row #2: 3 3 3 5 8 11 14 11 + DQT, Row #3: 3 3 4 6 10 17 16 12 + DQT, Row #4: 4 4 7 11 14 22 21 15 + DQT, Row #5: 5 7 11 13 16 21 23 18 + DQT, Row #6: 10 13 16 17 21 24 24 20 + DQT, Row #7: 14 18 19 20 22 20 21 20 + Approx quality factor = 90.06 (scaling=19.88 variance=1.14) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00002BB1 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 4 5 9 20 20 20 20 + DQT, Row #1: 4 4 5 13 20 20 20 20 + DQT, Row #2: 5 5 11 20 20 20 20 20 + DQT, Row #3: 9 13 20 20 20 20 20 20 + DQT, Row #4: 20 20 20 20 20 20 20 20 + DQT, Row #5: 20 20 20 20 20 20 20 20 + DQT, Row #6: 20 20 20 20 20 20 20 20 + DQT, Row #7: 20 20 20 20 20 20 20 20 + Approx quality factor = 89.93 (scaling=20.14 variance=0.34) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00002BF6 + Frame header length = 17 + Precision = 8 + Number of Lines = 480 + Samples per Line = 640 + Image Size = 640 x 480 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002C09 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002C2A + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002CE1 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002D02 + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00002DB9 + Length = 4 + interval = 600 + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002DBF + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00002DCD + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Expect Restart interval elapsed @ 0x00008802.4 + ERROR: Restart marker not detected +*** ERROR: Can't find huffman bitstring @ 0x00008802.5, table 0, value [0xffffffe0] +*** ERROR: Bad huffman code @ 0x00008802.4 +*** ERROR: Bad scan data in MCU(0,15): Lum CSS(0,0) @ Offset 0x00008802.5 + MCU located at pixel=(0,240) +*** ERROR: Can't find huffman bitstring @ 0x00008802.6, table 0, value [0xffffffc0] +*** ERROR: Bad huffman code @ 0x00008802.5 +*** ERROR: Bad scan data in MCU(0,15): Lum CSS(1,0) @ Offset 0x00008802.6 + MCU located at pixel=(8,240) +*** ERROR: Can't find huffman bitstring @ 0x00008802.7, table 0, value [0xffffff80] +*** ERROR: Bad huffman code @ 0x00008802.6 +*** ERROR: Bad scan data in MCU(0,15): Lum CSS(0,1) @ Offset 0x00008802.7 + MCU located at pixel=(0,248) +*** ERROR: Can't find huffman bitstring @ 0x00008803.0, table 0, value [0xffffffff] +*** ERROR: Bad huffman code @ 0x00008802.7 +*** ERROR: Bad scan data in MCU(0,15): Lum CSS(1,1) @ Offset 0x00008803.0 + MCU located at pixel=(8,248) +*** ERROR: Can't find huffman bitstring @ 0x00008803.1, table 1, value [0xfffffffe] +*** ERROR: Bad huffman code @ 0x00008803.0 +*** ERROR: Bad scan data in MCU(0,15): Chr(Cb) CSS(0,0) @ Offset 0x00008803.1 + MCU located at pixel=(0,240) +*** ERROR: Can't find huffman bitstring @ 0x00008803.2, table 1, value [0xfffffffc] +*** ERROR: Bad huffman code @ 0x00008803.1 +*** ERROR: Bad scan data in MCU(0,15): Chr(Cr) CSS(0,0) @ Offset 0x00008803.2 + MCU located at pixel=(0,240) +*** ERROR: Can't find huffman bitstring @ 0x00008803.3, table 0, value [0xfffffff8] +*** ERROR: Bad huffman code @ 0x00008803.2 + Only reported first 20 instances of this message... + + Compression stats: + Compression Ratio: 14.80:1 + Bits per pixel: 1.62:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 40 ( 1%) + # codes of length 02 bits: 202 ( 4%) + # codes of length 03 bits: 3515 ( 73%) + # codes of length 04 bits: 423 ( 9%) + # codes of length 05 bits: 338 ( 7%) + # codes of length 06 bits: 228 ( 5%) + # codes of length 07 bits: 54 ( 1%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 20 ( 1%) + # codes of length 02 bits: 1657 ( 69%) + # codes of length 03 bits: 311 ( 13%) + # codes of length 04 bits: 232 ( 10%) + # codes of length 05 bits: 123 ( 5%) + # codes of length 06 bits: 49 ( 2%) + # codes of length 07 bits: 8 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 32135 ( 43%) + # codes of length 03 bits: 8668 ( 12%) + # codes of length 04 bits: 15771 ( 21%) + # codes of length 05 bits: 7559 ( 10%) + # codes of length 06 bits: 2518 ( 3%) + # codes of length 07 bits: 3834 ( 5%) + # codes of length 08 bits: 1387 ( 2%) + # codes of length 09 bits: 1122 ( 2%) + # codes of length 10 bits: 562 ( 1%) + # codes of length 11 bits: 234 ( 0%) + # codes of length 12 bits: 131 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 57 ( 0%) + # codes of length 16 bits: 286 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 4525 ( 57%) + # codes of length 03 bits: 1153 ( 14%) + # codes of length 04 bits: 1341 ( 17%) + # codes of length 05 bits: 543 ( 7%) + # codes of length 06 bits: 281 ( 4%) + # codes of length 07 bits: 14 ( 0%) + # codes of length 08 bits: 93 ( 1%) + # codes of length 09 bits: 23 ( 0%) + # codes of length 10 bits: 3 ( 0%) + # codes of length 11 bits: 3 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 2 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[103] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1014, -3, -27] RGB=[248,255,252] @ MCU[ 0, 13] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 1 + Next position in scan buffer: Offset 0x0001210E.0 + + +*** Skipped 10 marker pad bytes *** +*** Marker: RST# *** + OFFSET: 0x0000880D + WARNING: Restart marker [0xFFD0] detected outside scan + Stopping decode + Use [Img Search Fwd/Rev] to locate other valid embedded JPEGs + +*** Searching Compression Signatures *** + + Signature: 013BA18D5561625796E986FDBC09F846 + Signature (Rotated): 01AC57E12793DFA7C46C704625C5AF0F + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[??? ] [Treo 680 ] [ ] Yes + CAM:[Canon ] [Canon PowerShot Pro1 ] [fine ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E3100 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 9530 ] [Superfine ] Yes + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W1 ] [ ] No + CAM:[SONY ] [SONY ] [ ] No + SW :[ACDSee ] [ ] + SW :[FixFoto ] [fine ] + SW :[IJG Library ] [090 ] + SW :[ZoomBrowser EX ] [high ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [090 ] + SW :[IrfanView ] [090 ] + SW :[idImager ] [090 ] + SW :[FastStone Image Viewer ] [090 ] + SW :[NeatImage ] [090 ] + SW :[Paint.NET ] [090 ] + SW :[Photomatix ] [090 ] + SW :[XnView ] [090 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + + +*** Additional Info *** +NOTE: Data exists after EOF, range: 0x00000000-0x00012301 (74497 bytes) diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/cmyk.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/cmyk.jpg.txt new file mode 100644 index 000000000..68777cc04 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/cmyk.jpg.txt @@ -0,0 +1,435 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\cmyk.jpg] + Filesize: [2531270] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x00000014 + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 0 + APP14Flags1 = 0 + ColorTransform = 0 [Unknown (RGB or CMYK)] + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00000024 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 29 + Profile Size : 1829080 bytes + Preferred CMM Type : 'HDM ' (0x48444D20) + Profile Version : 0.2.4.0 (0x02400000) + Profile Device/Class : Output Device profile ('prtr' (0x70727472)) + Data Colour Space : cmykData ('CMYK' (0x434D594B)) + Profile connection space (PCS) : 'Lab ' (0x4C616220) + Profile creation date : 2007-02-28 08:00:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : ? (0x00000000) ('....' (0x00000000)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : '....' (0x00000000) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Media-Relative Colorimetric + Profile creator : 'HDM ' (0x48444D20) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0000FE1E + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 2 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0001FC18 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 3 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0002FA12 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 4 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0003F80C + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 5 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0004F606 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 6 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0005F400 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 7 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0006F1FA + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 8 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0007EFF4 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 9 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0008EDEE + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 10 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0009EBE8 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 11 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000AE9E2 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 12 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000BE7DC + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 13 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000CE5D6 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 14 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000DE3D0 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 15 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000EE1CA + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 16 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000FDFC4 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 17 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0010DDBE + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 18 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0011DBB8 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 19 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0012D9B2 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 20 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0013D7AC + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 21 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0014D5A6 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 22 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0015D3A0 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 23 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0016D19A + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 24 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0017CF94 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 25 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0018CD8E + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 26 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0019CB88 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 27 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x001AC982 + Length = 65016 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 28 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x001BC77C + Length = 9096 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 29 of 29 + Only support decode of 1st ICC Marker + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x001BEB06 + Length = 188 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x009F] DefinedName="IPTC-NAA record" + IPTC [002:025] Keywords = "jpeg, productbeelden, productie, ptc, ptc369x1, pulsar" + IPTC [002:210] ? = ??? + IPTC [002:211] ? = ??? + IPTC [002:212] ? = ??? + IPTC [002:213] ? = ??? + IPTC [002:214] ? = ??? + IPTC [002:215] ? = ??? + IPTC [002:216] ? = ??? + IPTC [002:217] ? = ??? + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x001BEBC4 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=2.99 variance=6.13) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x001BEC09 + Frame header length = 20 + Precision = 8 + Number of Lines = 900 + Samples per Line = 414 + Image Size = 414 x 900 + Raw Image Orientation = Portrait + Number of Img components = 4 + Component[1]: ID=0x43, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Y) + Component[2]: ID=0x4D, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Cb) + Component[3]: ID=0x59, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Cr) + Component[4]: ID=0x4B, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (K) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x001BEC1F + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x001BEC40 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x001BECF7 + Scan header length = 14 + Number of img components = 4 + Component[1]: selector=0x43, table=0(DC),0(AC) + Component[2]: selector=0x4D, table=0(DC),0(AC) + Component[3]: selector=0x59, table=0(DC),0(AC) + Component[4]: selector=0x4B, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00269FC4 + + +*** Searching Compression Signatures *** + + Signature: 01BC2BB6764A7F9709F829E766D93AAE + Signature (Rotated): 01BC2BB6764A7F9709F829E766D93AAE + File Offset: 0 bytes + Chroma subsampling: ?x? + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[IJG Library ] [100 Gray ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [100 Gray ] + SW :[IrfanView ] [100 Gray ] + SW :[idImager ] [100 Gray ] + SW :[FastStone Image Viewer ] [100 Gray ] + SW :[NeatImage ] [100 Gray ] + SW :[Paint.NET ] [100 Gray ] + SW :[Photomatix ] [100 Gray ] + SW :[XnView ] [100 Gray ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/exif.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/exif.jpg.txt new file mode 100644 index 000000000..df54994c5 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/exif.jpg.txt @@ -0,0 +1,454 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\exif.jpg] + Filesize: [32764] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 7678 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0009 + [Make ] = "Canon" + [Model ] = "Canon PowerShot S40" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 180/1 + [YResolution ] = 180/1 + [ResolutionUnit ] = Inch + [DateTime ] = "2003:12:14 12:01:44" + [YCbCrPositioning ] = Centered + [ExifOffset ] = @ 0x00C4 + Offset to Next IFD = 0x000005BE + + EXIF IFD1 @ Absolute 0x000005DC + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 180/1 + [YResolution ] = 180/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x07F4 = @ 0x0812 + [JpegIFByteCount ] = 0x[00001548] / 5448 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000E2 + Dir Length = 0x001F + [ExposureTime ] = 1/500 s + [FNumber ] = F4.9 + [ExifVersion ] = 02.20 + [DateTimeOriginal ] = "2003:12:14 12:01:44" + [DateTimeDigitized ] = "2003:12:14 12:01:44" + [ComponentsConfiguration ] = [Y Cb Cr .] + [CompressedBitsPerPixel ] = 5/1 + [ShutterSpeedValue ] = 287/32 + [ApertureValue ] = 149/32 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 194698/65536 + [MeteringMode ] = CenterWeightedAverage + [Flash ] = Flash did not fire + [FocalLength ] = 21 mm + [MakerNote ] = @ 0x03AE + [UserComment ] = "" + [FlashPixVersion ] = 01.00 + [ColorSpace ] = sRGB + [ExifImageWidth ] = 2272 + [ExifImageHeight ] = 1704 + [ExifInteroperabilityOffset ] = @ 0x0588 + [FocalPlaneXResolution ] = 2272000/280 + [FocalPlaneYResolution ] = 1704000/210 + [FocalPlaneResolutionUnit ] = Inch + [SensingMethod ] = One-chip color area sensor + [FileSource ] = DSC + [CustomRendered ] = Normal process + [ExposureMode ] = Auto exposure + [WhiteBalance ] = Auto white balance + [DigitalZoomRatio ] = 2272/2272 + [SceneCaptureType ] = Standard + + EXIF MakerIFD @ Absolute 0x000003CC + Makernote decode option not enabled. + + EXIF InteropIFD @ Absolute 0x000005A6 + Dir Length = 0x0004 + [InteroperabilityIndex ] = "R98" + [InteroperabilityVersion ] = 01.00 + [RelatedImageWidth ] = 2272 + [RelatedImageLength ] = 1704 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00001E14 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00001E59 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00001E9E + Frame header length = 17 + Precision = 8 + Number of Lines = 360 + Samples per Line = 480 + Image Size = 480 x 360 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001EB1 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (005 total): 01 02 04 05 06 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001ECF + Huffman table length = 65 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (002 total): 12 21 + Codes of length 06 bits (004 total): 05 31 41 51 + Codes of length 07 bits (004 total): 13 22 61 71 + Codes of length 08 bits (004 total): 06 32 81 91 + Codes of length 09 bits (004 total): 14 42 A1 B1 + Codes of length 10 bits (004 total): 23 52 C1 D1 + Codes of length 11 bits (005 total): 07 15 33 62 E1 + Codes of length 12 bits (003 total): 43 72 F0 + Codes of length 13 bits (003 total): 24 92 F1 + Codes of length 14 bits (004 total): 16 34 53 82 + Codes of length 15 bits (003 total): 25 83 C2 + Codes of length 16 bits (000 total): + Total number of codes: 046 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001F12 + Huffman table length = 26 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001F2E + Huffman table length = 45 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (004 total): 04 12 21 31 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (004 total): 13 22 51 61 + Codes of length 08 bits (002 total): 32 71 + Codes of length 09 bits (002 total): 05 14 + Codes of length 10 bits (002 total): 23 91 + Codes of length 11 bits (001 total): F0 + Codes of length 12 bits (005 total): 33 42 81 A1 B1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 026 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001F5D + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00001F6B + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00007FFA.0 + + Compression stats: + Compression Ratio: 20.97:1 + Bits per pixel: 1.14:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 509 ( 18%) + # codes of length 03 bits: 1910 ( 69%) + # codes of length 04 bits: 249 ( 9%) + # codes of length 05 bits: 87 ( 3%) + # codes of length 06 bits: 5 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 905 ( 66%) + # codes of length 03 bits: 213 ( 15%) + # codes of length 04 bits: 169 ( 12%) + # codes of length 05 bits: 84 ( 6%) + # codes of length 06 bits: 9 ( 1%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 14518 ( 48%) + # codes of length 03 bits: 2881 ( 10%) + # codes of length 04 bits: 6591 ( 22%) + # codes of length 05 bits: 2038 ( 7%) + # codes of length 06 bits: 2356 ( 8%) + # codes of length 07 bits: 926 ( 3%) + # codes of length 08 bits: 484 ( 2%) + # codes of length 09 bits: 220 ( 1%) + # codes of length 10 bits: 149 ( 0%) + # codes of length 11 bits: 76 ( 0%) + # codes of length 12 bits: 27 ( 0%) + # codes of length 13 bits: 14 ( 0%) + # codes of length 14 bits: 8 ( 0%) + # codes of length 15 bits: 3 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2784 ( 53%) + # codes of length 03 bits: 1230 ( 24%) + # codes of length 04 bits: 370 ( 7%) + # codes of length 05 bits: 582 ( 11%) + # codes of length 06 bits: 94 ( 2%) + # codes of length 07 bits: 121 ( 2%) + # codes of length 08 bits: 26 ( 0%) + # codes of length 09 bits: 14 ( 0%) + # codes of length 10 bits: 6 ( 0%) + # codes of length 11 bits: 2 ( 0%) + # codes of length 12 bits: 5 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[122] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1008, 9, 27] RGB=[255,251,255] @ MCU[ 15, 13] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00007FF9.7 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00007FFA + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000812 + Length: 0x00001548 (5448) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: DQT + Length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 9 6 5 9 13 22 29 35 + DQT, Row #1: 6 6 8 11 15 33 34 30 + DQT, Row #2: 8 7 9 13 22 33 39 31 + DQT, Row #3: 8 9 12 16 28 49 45 34 + DQT, Row #4: 10 12 21 32 39 61 58 42 + DQT, Row #5: 13 19 31 36 45 58 63 51 + DQT, Row #6: 28 36 44 49 58 68 66 55 + DQT, Row #7: 41 52 54 55 62 56 57 54 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 9 9 12 20 15 26 79 79 + DQT, Row #1: 9 10 12 10 26 26 79 79 + DQT, Row #2: 12 12 10 10 26 79 79 79 + DQT, Row #3: 20 10 10 26 79 79 79 79 + DQT, Row #4: 15 26 26 79 79 79 79 79 + DQT, Row #5: 26 26 79 79 79 79 79 79 + DQT, Row #6: 79 79 79 79 79 79 79 79 + DQT, Row #7: 79 79 79 79 79 79 79 79 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 120 + Samples per Line = 160 + Image Size = 160 x 120 + + * Embedded Thumb Marker: DHT + Length = 418 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 4869 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 01D91E583DD0037108266E42ED3A262C + +*** Searching Compression Signatures *** + + Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + Signature (Rotated): 012D821C6AB210E2A753BE053B8F55D0 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: OK [Canon] [Canon PowerShot S40] + EXIF Makernotes: OK + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[SONY ] [CYBERSHOT U ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + SW :[Apple Quicktime ] [0466-0467 ] + SW :[Digital Photo Professiona] [05 ] + SW :[IJG Library ] [075 ] + SW :[MS Paint ] [ ] + SW :[MS Visio ] [ ] + SW :[ZoomBrowser EX ] [low ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [075 ] + SW :[IrfanView ] [075 ] + SW :[idImager ] [075 ] + SW :[FastStone Image Viewer ] [075 ] + SW :[NeatImage ] [075 ] + SW :[Paint.NET ] [075 ] + SW :[Photomatix ] [075 ] + SW :[XnView ] [075 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 4 - Uncertain if processed or original + While the EXIF fields indicate original, no compression signatures + in the current database were found matching this make/model + + Appears to be new signature for known camera. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/gamma_dalai_lama_gray.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/gamma_dalai_lama_gray.jpg.txt new file mode 100644 index 000000000..a5adb0247 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/gamma_dalai_lama_gray.jpg.txt @@ -0,0 +1,339 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\gamma_dalai_lama_gray.jpg] + Filesize: [84887] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x00000014 + Comment length = 46 + Comment= Scaled 1:2 this image wrongly becomes gray. + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000044 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=2.99 variance=6.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000089 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=1.54 variance=1.58) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000000CE + Frame header length = 17 + Precision = 8 + Number of Lines = 222 + Samples per Line = 258 + Image Size = 258 x 222 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000E1 + Huffman table length = 25 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 01 02 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 006 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000FC + Huffman table length = 111 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (002 total): 05 21 + Codes of length 06 bits (007 total): 00 06 12 13 14 31 41 + Codes of length 07 bits (003 total): 22 51 61 + Codes of length 08 bits (007 total): 07 15 16 32 42 71 81 + Codes of length 09 bits (005 total): 08 23 52 62 91 + Codes of length 10 bits (008 total): 33 43 44 72 A1 A2 B1 E3 + Codes of length 11 bits (010 total): 17 24 53 54 55 66 82 92 95 C1 + Codes of length 12 bits (009 total): 18 25 28 34 45 56 63 64 65 + Codes of length 13 bits (014 total): 26 27 46 73 76 85 93 96 A3 A5 A6 C3 C7 D7 + Codes of length 14 bits (010 total): 83 86 B2 B3 B8 C6 D3 D6 E8 F0 + Codes of length 15 bits (011 total): 36 37 48 74 75 84 94 A8 B4 B6 D1 + Codes of length 16 bits (001 total): D2 + Total number of codes: 092 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000016D + Huffman table length = 27 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (001 total): 06 + Codes of length 08 bits (001 total): 07 + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000018A + Huffman table length = 121 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 02 03 04 + Codes of length 04 bits (002 total): 05 11 + Codes of length 05 bits (002 total): 06 21 + Codes of length 06 bits (005 total): 07 08 12 13 31 + Codes of length 07 bits (009 total): 00 09 14 16 17 22 32 41 51 + Codes of length 08 bits (005 total): 0A 15 23 42 61 + Codes of length 09 bits (005 total): 18 24 33 52 71 + Codes of length 10 bits (002 total): 62 81 + Codes of length 11 bits (007 total): 19 34 43 53 72 82 91 + Codes of length 12 bits (007 total): 25 44 54 56 63 A1 A2 + Codes of length 13 bits (014 total): 1A 26 27 28 46 47 55 57 64 73 97 B1 E3 E6 + Codes of length 14 bits (007 total): 35 45 48 58 92 A4 C1 + Codes of length 15 bits (002 total): D8 29 + Codes of length 16 bits (031 total): 67 74 83 85 93 94 B2 36 68 87 88 98 D6 F0 37 39 + 65 66 75 78 84 96 A3 A6 A8 C3 C9 D1 D3 D9 DA + Total number of codes: 102 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000205 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00000213 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00014B95.0 + + Compression stats: + Compression Ratio: 2.04:1 + Bits per pixel: 11.78:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 893 ( 97%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 23 ( 2%) + # codes of length 04 bits: 4 ( 0%) + # codes of length 05 bits: 4 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 1728 ( 94%) + # codes of length 02 bits: 46 ( 2%) + # codes of length 03 bits: 30 ( 2%) + # codes of length 04 bits: 18 ( 1%) + # codes of length 05 bits: 14 ( 1%) + # codes of length 06 bits: 6 ( 0%) + # codes of length 07 bits: 4 ( 0%) + # codes of length 08 bits: 2 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 14381 ( 45%) + # codes of length 03 bits: 3819 ( 12%) + # codes of length 04 bits: 4489 ( 14%) + # codes of length 05 bits: 2199 ( 7%) + # codes of length 06 bits: 3836 ( 12%) + # codes of length 07 bits: 911 ( 3%) + # codes of length 08 bits: 1089 ( 3%) + # codes of length 09 bits: 398 ( 1%) + # codes of length 10 bits: 294 ( 1%) + # codes of length 11 bits: 190 ( 1%) + # codes of length 12 bits: 84 ( 0%) + # codes of length 13 bits: 75 ( 0%) + # codes of length 14 bits: 21 ( 0%) + # codes of length 15 bits: 11 ( 0%) + # codes of length 16 bits: 1 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 17100 ( 23%) + # codes of length 03 bits: 31709 ( 42%) + # codes of length 04 bits: 7638 ( 10%) + # codes of length 05 bits: 4203 ( 6%) + # codes of length 06 bits: 6465 ( 9%) + # codes of length 07 bits: 5462 ( 7%) + # codes of length 08 bits: 1472 ( 2%) + # codes of length 09 bits: 804 ( 1%) + # codes of length 10 bits: 206 ( 0%) + # codes of length 11 bits: 296 ( 0%) + # codes of length 12 bits: 156 ( 0%) + # codes of length 13 bits: 164 ( 0%) + # codes of length 14 bits: 47 ( 0%) + # codes of length 15 bits: 7 ( 0%) + # codes of length 16 bits: 55 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[125] (range: 0..255) + + Brightest Pixel Search: + YCC=[ -8, 0, 0] RGB=[127,127,127] @ MCU[ 0, 0] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00014B94.4 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00014B95 + + +*** Searching Compression Signatures *** + + Signature: 01BBB1709AC9C1F89220D955A31A8F34 + Signature (Rotated): 01BBB1709AC9C1F89220D955A31A8F34 + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[CASIO COMPUTER CO.,LTD ] [EX-Z750 ] [ ] No + CAM:[CASIO COMPUTER CO.,LTD. ] [EX-Z1000 ] [ ] No + CAM:[PENTAX ] [PENTAX Optio S5i ] [ ] No + CAM:[SIGMA ] [SIGMA SD9 ] [ ] No + SW :[ACDSee ] [100 ] + SW :[Apple ImageIO.framework ] [100 (Best) ] + SW :[Digital Photo Professiona] [10 ] + SW :[IJG Library ] [100 ] + SW :[MS Office Pic Mgr ] [ ] + SW :[Nikon Scan ] [Excellent Qualit] + SW :[Picasa ] [100 (Maximum) ] + SW :[ZoomBrowser EX ] [highest ] + SW :[EOS Viewer Utility ] [ ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [100 ] + SW :[IrfanView ] [100 ] + SW :[idImager ] [100 ] + SW :[FastStone Image Viewer ] [100 ] + SW :[NeatImage ] [100 ] + SW :[Paint.NET ] [100 ] + SW :[Photomatix ] [100 ] + SW :[XnView ] [100 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg400jfif.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg400jfif.jpg.txt new file mode 100644 index 000000000..b686b3ce3 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg400jfif.jpg.txt @@ -0,0 +1,211 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\jpeg400jfif.jpg] + Filesize: [45066] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.2] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + Approx quality factor = 88.28 (scaling=23.43 variance=111.68) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00000059 + Frame header length = 11 + Precision = 8 + Number of Lines = 800 + Samples per Line = 600 + Image Size = 600 x 800 + Raw Image Orientation = Portrait + Number of Img components = 1 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00000066 + Length = 4 + interval = 75 + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000006C + Huffman table length = 210 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (007 total): 04 05 03 02 06 01 00 + Codes of length 04 bits (001 total): 07 + Codes of length 05 bits (001 total): 08 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (001 total): 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 11 04 00 + Codes of length 05 bits (003 total): 05 21 12 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 51 06 13 61 + Codes of length 08 bits (002 total): 22 71 + Codes of length 09 bits (006 total): 81 14 32 91 A1 07 + Codes of length 10 bits (007 total): 15 B1 42 23 C1 52 D1 + Codes of length 11 bits (003 total): E1 33 16 + Codes of length 12 bits (004 total): 62 F0 24 72 + Codes of length 13 bits (002 total): 82 F1 + Codes of length 14 bits (006 total): 25 43 34 53 92 A2 + Codes of length 15 bits (002 total): B2 63 + Codes of length 16 bits (115 total): 73 C2 35 44 27 93 A3 B3 36 17 54 64 74 C3 D2 E2 + 08 26 83 09 0A 18 19 84 94 45 46 A4 B4 56 D3 55 + 28 1A F2 E3 F3 C4 D4 E4 F4 65 75 85 95 A5 B5 C5 + D5 E5 F5 66 76 86 96 A6 B6 C6 D6 E6 F6 37 47 57 + 67 77 87 97 A7 B7 C7 D7 E7 F7 38 48 58 68 78 88 + 98 A8 B8 C8 D8 E8 F8 29 39 49 59 69 79 89 99 A9 + B9 C9 D9 E9 F9 2A 3A 4A 5A 6A 7A 8A 9A AA BA CA + DA EA FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000140 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000014A + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0000B008.0 + + Compression stats: + Compression Ratio: 10.73:1 + Bits per pixel: 0.75:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 7215 ( 96%) + # codes of length 04 bits: 146 ( 2%) + # codes of length 05 bits: 139 ( 2%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 26194 ( 42%) + # codes of length 03 bits: 2772 ( 4%) + # codes of length 04 bits: 16626 ( 27%) + # codes of length 05 bits: 5914 ( 9%) + # codes of length 06 bits: 4996 ( 8%) + # codes of length 07 bits: 2599 ( 4%) + # codes of length 08 bits: 988 ( 2%) + # codes of length 09 bits: 1360 ( 2%) + # codes of length 10 bits: 617 ( 1%) + # codes of length 11 bits: 60 ( 0%) + # codes of length 12 bits: 152 ( 0%) + # codes of length 13 bits: 60 ( 0%) + # codes of length 14 bits: 30 ( 0%) + # codes of length 15 bits: 5 ( 0%) + # codes of length 16 bits: 28 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[ 58] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 894, 0, 0] RGB=[239,239,239] @ MCU[ 35, 23] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 99 + Next position in scan buffer: Offset 0x0000B007.2 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000B008 + + +*** Searching Compression Signatures *** + + Signature: 01BE82BEB1019CB30EB122273E78E87C + Signature (Rotated): 01BE82BEB1019CB30EB122273E78E87C + File Offset: 0 bytes + Chroma subsampling: Gray + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420exif.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420exif.jpg.txt new file mode 100644 index 000000000..babe797d6 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420exif.jpg.txt @@ -0,0 +1,412 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\jpeg420exif.jpg] + Filesize: [768608] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 8817 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0008 + [Make ] = "Hewlett-Packard Company" + [Model ] = "HP PhotoSmart 715" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [YCbCrPositioning ] = Centered + [ExifOffset ] = @ 0x006E + Offset to Next IFD = 0x0000018E + + EXIF IFD1 @ Absolute 0x0000019A + Dir Length = 0x0007 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x0C07 = @ 0x0C13 + [JpegIFByteCount ] = 0x[00001658] / 5720 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x0000007A + Dir Length = 0x0015 + [ExposureTime ] = 48/10000 s + [FNumber ] = F8.2 + [ISOSpeedRatings ] = 100 + [ExifVersion ] = 02.10 + [DateTimeOriginal ] = "2001:10:02 14:57:31" + [DateTimeDigitized ] = "2001:10:02 14:57:31" + [ComponentsConfiguration ] = [Y Cb Cr .] + [CompressedBitsPerPixel ] = 20/10 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 20/10 + [SubjectDistance ] = 5043/1000 + [MeteringMode ] = CenterWeightedAverage + [LightSource ] = unknown + [Flash ] = Flash did not fire + [FocalLength ] = 7 mm + [MakerNote ] = @ 0x0282 + [FlashPixVersion ] = 01.00 + [ColorSpace ] = sRGB + [ExifImageWidth ] = 2048 + [ExifImageHeight ] = 1536 + [ExifInteroperabilityOffset ] = @ 0x0170 + + EXIF MakerIFD @ Absolute 0x0000028E + Makernote decode option not enabled. + + EXIF InteropIFD @ Absolute 0x0000017C + Dir Length = 0x0002 + [InteroperabilityIndex ] = "R98" + [InteroperabilityVersion ] = 01.00 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00002275 + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 9 11 14 + DQT, Row #1: 3 3 3 4 5 12 13 12 + DQT, Row #2: 3 3 3 5 9 12 15 12 + DQT, Row #3: 3 3 5 6 11 19 18 13 + DQT, Row #4: 3 5 7 12 15 24 23 17 + DQT, Row #5: 5 7 12 14 18 23 25 21 + DQT, Row #6: 11 14 17 19 23 27 27 22 + DQT, Row #7: 16 21 21 22 25 22 23 22 + Approx quality factor = 89.24 (scaling=21.52 variance=2.21) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 3 5 10 22 22 22 22 + DQT, Row #1: 3 5 5 14 22 22 22 22 + DQT, Row #2: 5 5 11 22 22 22 22 22 + DQT, Row #3: 10 14 22 22 22 22 22 22 + DQT, Row #4: 22 22 22 22 22 22 22 22 + DQT, Row #5: 22 22 22 22 22 22 22 22 + DQT, Row #6: 22 22 22 22 22 22 22 22 + DQT, Row #7: 22 22 22 22 22 22 22 22 + Approx quality factor = 89.12 (scaling=21.76 variance=1.62) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000022FB + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000249F + Frame header length = 17 + Precision = 8 + Number of Lines = 1536 + Samples per Line = 2048 + Image Size = 2048 x 1536 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000024B2 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000024C0 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x000BBA5E.0 + + Compression stats: + Compression Ratio: 12.43:1 + Bits per pixel: 1.93:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 4275 ( 9%) + # codes of length 03 bits: 32688 ( 67%) + # codes of length 04 bits: 5786 ( 12%) + # codes of length 05 bits: 3984 ( 8%) + # codes of length 06 bits: 2042 ( 4%) + # codes of length 07 bits: 377 ( 1%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 16194 ( 66%) + # codes of length 03 bits: 3495 ( 14%) + # codes of length 04 bits: 2416 ( 10%) + # codes of length 05 bits: 1460 ( 6%) + # codes of length 06 bits: 736 ( 3%) + # codes of length 07 bits: 261 ( 1%) + # codes of length 08 bits: 14 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 363342 ( 41%) + # codes of length 03 bits: 113855 ( 13%) + # codes of length 04 bits: 200569 ( 23%) + # codes of length 05 bits: 102577 ( 12%) + # codes of length 06 bits: 32874 ( 4%) + # codes of length 07 bits: 43593 ( 5%) + # codes of length 08 bits: 14054 ( 2%) + # codes of length 09 bits: 8847 ( 1%) + # codes of length 10 bits: 4365 ( 0%) + # codes of length 11 bits: 2009 ( 0%) + # codes of length 12 bits: 770 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 17 ( 0%) + # codes of length 16 bits: 780 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 60258 ( 49%) + # codes of length 03 bits: 17570 ( 14%) + # codes of length 04 bits: 20881 ( 17%) + # codes of length 05 bits: 14001 ( 11%) + # codes of length 06 bits: 6443 ( 5%) + # codes of length 07 bits: 842 ( 1%) + # codes of length 08 bits: 1737 ( 1%) + # codes of length 09 bits: 387 ( 0%) + # codes of length 10 bits: 169 ( 0%) + # codes of length 11 bits: 93 ( 0%) + # codes of length 12 bits: 31 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 2 ( 0%) + # codes of length 15 bits: 5 ( 0%) + # codes of length 16 bits: 1 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[108] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 996, 0, -33] RGB=[244,255,252] @ MCU[ 32, 59] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x000BBA5D.5 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000BBA5E + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000C13 + Length: 0x00001658 (5720) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: DQT + Length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 10 6 6 10 14 26 32 40 + DQT, Row #1: 8 8 8 12 16 36 38 36 + DQT, Row #2: 8 8 10 14 26 36 44 36 + DQT, Row #3: 8 10 14 18 32 56 52 40 + DQT, Row #4: 10 14 22 36 44 70 66 50 + DQT, Row #5: 14 22 36 42 52 68 74 60 + DQT, Row #6: 32 42 50 56 66 78 78 64 + DQT, Row #7: 46 60 62 64 74 64 66 64 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 10 10 14 30 64 64 64 64 + DQT, Row #1: 10 14 16 42 64 64 64 64 + DQT, Row #2: 14 16 36 64 64 64 64 64 + DQT, Row #3: 30 42 64 64 64 64 64 64 + DQT, Row #4: 64 64 64 64 64 64 64 64 + DQT, Row #5: 64 64 64 64 64 64 64 64 + DQT, Row #6: 64 64 64 64 64 64 64 64 + DQT, Row #7: 64 64 64 64 64 64 64 64 + + * Embedded Thumb Marker: DHT + Length = 418 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 120 + Samples per Line = 160 + Image Size = 160 x 120 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 5141 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 0158E595F22440126FB766B33F56B158 + +*** Searching Compression Signatures *** + + Signature: 010A5B03EB73D6AF719B39FCC8C3AE25 + Signature (Rotated): 011326BE69D2A27FCF4DBCC33DEB07A2 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: OK [Hewlett-Packard Company] [HP PhotoSmart 715] + EXIF Makernotes: OK + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 4 - Uncertain if processed or original + While the EXIF fields indicate original, no compression signatures + in the current database were found matching this make/model + + Appears to be new signature for known camera. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420small.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420small.jpg.txt new file mode 100644 index 000000000..c001d7297 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg420small.jpg.txt @@ -0,0 +1,330 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\jpeg420small.jpg] + Filesize: [5276] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 96 x 96 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 5 3 3 5 7 12 15 18 + DQT, Row #1: 4 4 4 6 8 17 18 17 + DQT, Row #2: 4 4 5 7 12 17 21 17 + DQT, Row #3: 4 5 7 9 15 26 24 19 + DQT, Row #4: 5 7 11 17 20 33 31 23 + DQT, Row #5: 7 11 17 19 24 31 34 28 + DQT, Row #6: 15 19 23 26 31 36 36 30 + DQT, Row #7: 22 28 29 29 34 30 31 30 + Approx quality factor = 84.93 (scaling=30.13 variance=1.05) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 5 5 7 14 30 30 30 30 + DQT, Row #1: 5 6 8 20 30 30 30 30 + DQT, Row #2: 7 8 17 30 30 30 30 30 + DQT, Row #3: 14 20 30 30 30 30 30 30 + DQT, Row #4: 30 30 30 30 30 30 30 30 + DQT, Row #5: 30 30 30 30 30 30 30 30 + DQT, Row #6: 30 30 30 30 30 30 30 30 + DQT, Row #7: 30 30 30 30 30 30 30 30 + Approx quality factor = 84.93 (scaling=30.15 variance=0.29) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 100 + Samples per Line = 200 + Image Size = 200 x 100 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 04 + Codes of length 03 bits (005 total): 00 02 03 05 07 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000CF + Huffman table length = 66 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 11 21 + Codes of length 05 bits (002 total): 04 12 + Codes of length 06 bits (004 total): 05 06 31 41 + Codes of length 07 bits (004 total): 07 13 22 51 + Codes of length 08 bits (002 total): 32 61 + Codes of length 09 bits (005 total): 71 72 B1 D1 D2 + Codes of length 10 bits (007 total): 14 23 33 62 81 91 A1 + Codes of length 11 bits (010 total): 15 16 24 25 34 42 44 82 92 A2 + Codes of length 12 bits (007 total): 26 52 53 54 64 94 C2 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 047 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000113 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 06 07 + Codes of length 03 bits (002 total): 04 05 + Codes of length 04 bits (003 total): 00 03 08 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 02 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000131 + Huffman table length = 63 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 02 + Codes of length 04 bits (002 total): 03 04 + Codes of length 05 bits (004 total): 05 06 11 21 + Codes of length 06 bits (007 total): 07 12 34 51 61 72 B1 + Codes of length 07 bits (014 total): 13 15 16 17 31 32 33 35 41 53 71 91 92 D1 + Codes of length 08 bits (004 total): 22 62 C1 E1 + Codes of length 09 bits (006 total): 14 52 54 81 82 B2 + Codes of length 10 bits (003 total): 36 42 C2 + Codes of length 11 bits (001 total): F0 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 044 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000172 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00000180 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0000149A.0 + + Compression stats: + Compression Ratio: 12.27:1 + Bits per pixel: 1.96:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 69 ( 19%) + # codes of length 03 bits: 232 ( 64%) + # codes of length 04 bits: 34 ( 9%) + # codes of length 05 bits: 19 ( 5%) + # codes of length 06 bits: 10 ( 3%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 76 ( 42%) + # codes of length 03 bits: 60 ( 33%) + # codes of length 04 bits: 36 ( 20%) + # codes of length 05 bits: 5 ( 3%) + # codes of length 06 bits: 5 ( 3%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2698 ( 51%) + # codes of length 03 bits: 506 ( 10%) + # codes of length 04 bits: 1064 ( 20%) + # codes of length 05 bits: 373 ( 7%) + # codes of length 06 bits: 334 ( 6%) + # codes of length 07 bits: 133 ( 3%) + # codes of length 08 bits: 37 ( 1%) + # codes of length 09 bits: 43 ( 1%) + # codes of length 10 bits: 33 ( 1%) + # codes of length 11 bits: 26 ( 0%) + # codes of length 12 bits: 7 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 276 ( 20%) + # codes of length 03 bits: 340 ( 25%) + # codes of length 04 bits: 214 ( 15%) + # codes of length 05 bits: 190 ( 14%) + # codes of length 06 bits: 141 ( 10%) + # codes of length 07 bits: 170 ( 12%) + # codes of length 08 bits: 29 ( 2%) + # codes of length 09 bits: 17 ( 1%) + # codes of length 10 bits: 6 ( 0%) + # codes of length 11 bits: 1 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[ 86] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 250, -405, 230] RGB=[198,156, 68] @ MCU[ 0, 6] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00001499.3 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000149A + + +*** Searching Compression Signatures *** + + Signature: 0155D875C95B74D0F3C5835A62516F48 + Signature (Rotated): 01D38A25358EB7649A254E19F1D46600 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[Nokia ] [N73 ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 8100 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + SW :[IJG Library ] [085 ] + SW :[Picasa ] [085 (Normal) ] + SW :[ZoomBrowser EX ] [medium ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [085 ] + SW :[IrfanView ] [085 ] + SW :[idImager ] [085 ] + SW :[FastStone Image Viewer ] [085 ] + SW :[NeatImage ] [085 ] + SW :[Paint.NET ] [085 ] + SW :[Photomatix ] [085 ] + SW :[XnView ] [085 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg444.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg444.jpg.txt new file mode 100644 index 000000000..06a1ee426 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/jpeg444.jpg.txt @@ -0,0 +1,405 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\jpeg444.jpg] + Filesize: [5667] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.0] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 68 + Identifier = [This is an unknown APP marker. Compliant decoders must ignore it.] +Identifier [This is an unknown APP marker. Compliant decoders must ignore it.] not supported. Skipping remainder. + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0000005A + Length = 68 + Identifier = [This is an unknown APP marker. Compliant decoders must ignore it.] + Not supported. Skipping remainder. + +*** Marker: APP3 (xFFE3) *** + OFFSET: 0x000000A0 + Length = 68 + +*** Marker: APP4 (xFFE4) *** + OFFSET: 0x000000E6 + Length = 68 + +*** Marker: APP5 (xFFE5) *** + OFFSET: 0x0000012C + Length = 68 + +*** Marker: APP6 (xFFE6) *** + OFFSET: 0x00000172 + Length = 68 + +*** Marker: APP7 (xFFE7) *** + OFFSET: 0x000001B8 + Length = 68 + +*** Marker: APP8 (xFFE8) *** + OFFSET: 0x000001FE + Length = 68 + +*** Marker: APP9 (xFFE9) *** + OFFSET: 0x00000244 + Length = 68 + +*** Marker: APP10 (xFFEA) *** + OFFSET: 0x0000028A + Length = 68 + +*** Marker: APP11 (xFFEB) *** + OFFSET: 0x000002D0 + Length = 68 + +*** Marker: APP12 (xFFEC) *** + OFFSET: 0x00000316 + Length = 68 + Identifier = [This is an unknown APP marker. Compliant decoders must ignore it.] + Not Photoshop DUCKY. Skipping remainder. + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x0000035C + Length = 68 + Identifier = [This is an unknown APP marker. Compliant decoders must ignore it.] + Not Photoshop. Skipping remainder. + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x000003A2 + Length = 68 + DCTEncodeVersion = 26995 + APP14Flags0 = 8289 + APP14Flags1 = 28192 + ColorTransform = 117 [???] + +*** Marker: APP15 (xFFEF) *** + OFFSET: 0x000003E8 + Length = 68 + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000042E + Frame header length = 17 + Precision = 8 + Number of Lines = 256 + Samples per Line = 256 + Image Size = 256 x 256 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x02 (Chrom: Cr) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000441 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000486 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000004CB + Table length = 67 + ---- + Precision=8 bits + Destination ID=2 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000510 + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000006B4 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000006C2 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00001620.0 + + Compression stats: + Compression Ratio: 49.99:1 + Bits per pixel: 0.48:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 992 ( 97%) + # codes of length 03 bits: 31 ( 3%) + # codes of length 04 bits: 0 ( 0%) + # codes of length 05 bits: 1 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 1023 ( 50%) + # codes of length 03 bits: 864 ( 42%) + # codes of length 04 bits: 128 ( 6%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 2 ( 0%) + # codes of length 08 bits: 31 ( 2%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 0 ( 0%) + # codes of length 04 bits: 1024 ( 50%) + # codes of length 05 bits: 1024 ( 50%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2048 ( 67%) + # codes of length 03 bits: 1024 ( 33%) + # codes of length 04 bits: 0 ( 0%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[126] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 984,-1026, -999] RGB=[ 75,255, 24] @ MCU[ 0, 31] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0000161F.6 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00001620 + + +*** Searching Compression Signatures *** + + Signature: 019DC7724B5425C464D28F2CF78F707E + Signature (Rotated): 016C4383FFABE35F063D8FCB331942C0 + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E4800 ] [NORMAL ] No + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + + +*** Additional Info *** +NOTE: Data exists after EOF, range: 0x00001622-0x00001623 (1 bytes) diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ratio-1x1.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ratio-1x1.jpg.txt new file mode 100644 index 000000000..b2ae24c46 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ratio-1x1.jpg.txt @@ -0,0 +1,338 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\ratio-1x1.jpg] + Filesize: [34674] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 4 6 8 10 + DQT, Row #1: 2 2 2 3 4 9 10 9 + DQT, Row #2: 2 2 3 4 6 9 11 9 + DQT, Row #3: 2 3 4 5 8 14 13 10 + DQT, Row #4: 3 4 6 9 11 17 16 12 + DQT, Row #5: 4 6 9 10 13 17 18 15 + DQT, Row #6: 8 10 12 14 16 19 19 16 + DQT, Row #7: 12 15 15 16 18 16 16 16 + Approx quality factor = 91.86 (scaling=16.28 variance=1.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 3 4 8 16 16 16 16 + DQT, Row #1: 3 3 4 11 16 16 16 16 + DQT, Row #2: 4 4 9 16 16 16 16 16 + DQT, Row #3: 8 11 16 16 16 16 16 16 + DQT, Row #4: 16 16 16 16 16 16 16 16 + DQT, Row #5: 16 16 16 16 16 16 16 16 + DQT, Row #6: 16 16 16 16 16 16 16 16 + DQT, Row #7: 16 16 16 16 16 16 16 16 + Approx quality factor = 91.90 (scaling=16.20 variance=0.15) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 769 + Samples per Line = 1900 + Image Size = 1900 x 769 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 29 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 07 08 + Codes of length 04 bits (002 total): 06 09 + Codes of length 05 bits (002 total): 04 05 + Codes of length 06 bits (003 total): 01 02 03 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000D0 + Huffman table length = 78 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 01 + Codes of length 04 bits (003 total): 02 03 04 + Codes of length 05 bits (003 total): 05 06 11 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (005 total): 08 12 21 31 41 + Codes of length 08 bits (005 total): 13 14 22 51 61 + Codes of length 09 bits (003 total): 15 32 71 + Codes of length 10 bits (009 total): 09 16 23 52 62 81 91 92 A1 + Codes of length 11 bits (005 total): 17 33 42 72 82 + Codes of length 12 bits (005 total): 24 43 54 93 B3 + Codes of length 13 bits (006 total): 63 73 83 A2 B2 C2 + Codes of length 14 bits (003 total): 25 44 A3 + Codes of length 15 bits (009 total): 34 35 36 37 64 76 B1 B4 C1 + Codes of length 16 bits (000 total): + Total number of codes: 059 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000120 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 05 06 07 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (000 total): + Codes of length 06 bits (003 total): 02 03 08 + Codes of length 07 bits (001 total): 01 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000013E + Huffman table length = 64 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 01 + Codes of length 04 bits (002 total): 02 03 + Codes of length 05 bits (003 total): 04 05 11 + Codes of length 06 bits (005 total): 06 21 31 71 81 + Codes of length 07 bits (003 total): 41 51 91 + Codes of length 08 bits (010 total): 12 13 14 22 32 61 A1 B1 C1 D1 + Codes of length 09 bits (005 total): 15 33 42 E1 F0 + Codes of length 10 bits (003 total): 07 23 52 + Codes of length 11 bits (004 total): 43 62 72 82 + Codes of length 12 bits (002 total): 92 F1 + Codes of length 13 bits (001 total): B2 + Codes of length 14 bits (005 total): 16 A2 C2 D2 E2 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 045 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000180 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000018E + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00008770.0 + + Compression stats: + Compression Ratio: 127.89:1 + Bits per pixel: 0.19:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 22539 ( 97%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 379 ( 2%) + # codes of length 04 bits: 246 ( 1%) + # codes of length 05 bits: 91 ( 0%) + # codes of length 06 bits: 69 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 11012 ( 94%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 445 ( 4%) + # codes of length 04 bits: 105 ( 1%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 81 ( 1%) + # codes of length 07 bits: 19 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 23301 ( 56%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 4265 ( 10%) + # codes of length 04 bits: 7407 ( 18%) + # codes of length 05 bits: 3364 ( 8%) + # codes of length 06 bits: 767 ( 2%) + # codes of length 07 bits: 1399 ( 3%) + # codes of length 08 bits: 642 ( 2%) + # codes of length 09 bits: 201 ( 0%) + # codes of length 10 bits: 285 ( 1%) + # codes of length 11 bits: 99 ( 0%) + # codes of length 12 bits: 42 ( 0%) + # codes of length 13 bits: 30 ( 0%) + # codes of length 14 bits: 6 ( 0%) + # codes of length 15 bits: 9 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 11662 ( 60%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 1971 ( 10%) + # codes of length 04 bits: 1938 ( 10%) + # codes of length 05 bits: 1525 ( 8%) + # codes of length 06 bits: 1005 ( 5%) + # codes of length 07 bits: 339 ( 2%) + # codes of length 08 bits: 727 ( 4%) + # codes of length 09 bits: 148 ( 1%) + # codes of length 10 bits: 41 ( 0%) + # codes of length 11 bits: 23 ( 0%) + # codes of length 12 bits: 8 ( 0%) + # codes of length 13 bits: 2 ( 0%) + # codes of length 14 bits: 5 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[250] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1017, 0, 0] RGB=[255,255,255] @ MCU[ 0, 0] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0000876F.5 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00008770 + + +*** Searching Compression Signatures *** + + Signature: 01557A9AE226A38386271DFE13D64298 + Signature (Rotated): 0167FCEDBA3A8E8CF822163DB3564762 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Konica Minolta Camera, In] [DiMAGE Z2 ] [ ] No + CAM:[Minolta Co., Ltd. ] [DiMAGE F100 ] [ ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E8700 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS CORPORATION ] [C8080WZ ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-P200 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[IJG Library ] [092 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [092 ] + SW :[IrfanView ] [092 ] + SW :[idImager ] [092 ] + SW :[FastStone Image Viewer ] [092 ] + SW :[NeatImage ] [092 ] + SW :[Paint.NET ] [092 ] + SW :[Photomatix ] [092 ] + SW :[XnView ] [092 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testimgint.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testimgint.jpg.txt new file mode 100644 index 000000000..ac2b2f9ad --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testimgint.jpg.txt @@ -0,0 +1,342 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\testimgint.jpg] + Filesize: [5756] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 149 + Samples per Line = 227 + Image Size = 227 x 149 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000D2 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000189 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000001AA + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000261 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000026F + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0000167A.0 + + Compression stats: + Compression Ratio: 19.78:1 + Bits per pixel: 1.21:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 86 ( 14%) + # codes of length 03 bits: 412 ( 69%) + # codes of length 04 bits: 65 ( 11%) + # codes of length 05 bits: 33 ( 6%) + # codes of length 06 bits: 4 ( 1%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 132 ( 44%) + # codes of length 03 bits: 70 ( 23%) + # codes of length 04 bits: 60 ( 20%) + # codes of length 05 bits: 26 ( 9%) + # codes of length 06 bits: 12 ( 4%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2692 ( 48%) + # codes of length 03 bits: 628 ( 11%) + # codes of length 04 bits: 1327 ( 23%) + # codes of length 05 bits: 471 ( 8%) + # codes of length 06 bits: 199 ( 4%) + # codes of length 07 bits: 170 ( 3%) + # codes of length 08 bits: 65 ( 1%) + # codes of length 09 bits: 58 ( 1%) + # codes of length 10 bits: 31 ( 1%) + # codes of length 11 bits: 15 ( 0%) + # codes of length 12 bits: 4 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 6 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 689 ( 46%) + # codes of length 03 bits: 244 ( 16%) + # codes of length 04 bits: 289 ( 19%) + # codes of length 05 bits: 158 ( 11%) + # codes of length 06 bits: 70 ( 5%) + # codes of length 07 bits: 5 ( 0%) + # codes of length 08 bits: 36 ( 2%) + # codes of length 09 bits: 5 ( 0%) + # codes of length 10 bits: 1 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[107] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1008, -9, 0] RGB=[254,254,250] @ MCU[ 4, 8] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00001679.6 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000167A + + +*** Searching Compression Signatures *** + + Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + Signature (Rotated): 012D821C6AB210E2A753BE053B8F55D0 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[SONY ] [CYBERSHOT U ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + SW :[Apple Quicktime ] [0466-0467 ] + SW :[Digital Photo Professiona] [05 ] + SW :[IJG Library ] [075 ] + SW :[MS Paint ] [ ] + SW :[MS Visio ] [ ] + SW :[ZoomBrowser EX ] [low ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [075 ] + SW :[IrfanView ] [075 ] + SW :[idImager ] [075 ] + SW :[FastStone Image Viewer ] [075 ] + SW :[NeatImage ] [075 ] + SW :[Paint.NET ] [075 ] + SW :[Photomatix ] [075 ] + SW :[XnView ] [075 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testorig.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testorig.jpg.txt new file mode 100644 index 000000000..8e339260b --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/testorig.jpg.txt @@ -0,0 +1,342 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\testorig.jpg] + Filesize: [5770] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 149 + Samples per Line = 227 + Image Size = 227 x 149 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000D2 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000189 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000001AA + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000261 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000026F + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00001688.0 + + Compression stats: + Compression Ratio: 19.73:1 + Bits per pixel: 1.22:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 88 ( 15%) + # codes of length 03 bits: 409 ( 68%) + # codes of length 04 bits: 66 ( 11%) + # codes of length 05 bits: 33 ( 6%) + # codes of length 06 bits: 4 ( 1%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 134 ( 45%) + # codes of length 03 bits: 68 ( 23%) + # codes of length 04 bits: 60 ( 20%) + # codes of length 05 bits: 26 ( 9%) + # codes of length 06 bits: 12 ( 4%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2706 ( 48%) + # codes of length 03 bits: 636 ( 11%) + # codes of length 04 bits: 1331 ( 23%) + # codes of length 05 bits: 473 ( 8%) + # codes of length 06 bits: 196 ( 3%) + # codes of length 07 bits: 169 ( 3%) + # codes of length 08 bits: 66 ( 1%) + # codes of length 09 bits: 60 ( 1%) + # codes of length 10 bits: 28 ( 0%) + # codes of length 11 bits: 14 ( 0%) + # codes of length 12 bits: 4 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 5 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 697 ( 46%) + # codes of length 03 bits: 243 ( 16%) + # codes of length 04 bits: 294 ( 19%) + # codes of length 05 bits: 164 ( 11%) + # codes of length 06 bits: 68 ( 4%) + # codes of length 07 bits: 5 ( 0%) + # codes of length 08 bits: 35 ( 2%) + # codes of length 09 bits: 4 ( 0%) + # codes of length 10 bits: 2 ( 0%) + # codes of length 11 bits: 1 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[107] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1008, -9, 0] RGB=[254,254,250] @ MCU[ 4, 8] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00001687.2 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00001688 + + +*** Searching Compression Signatures *** + + Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + Signature (Rotated): 012D821C6AB210E2A753BE053B8F55D0 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[SONY ] [CYBERSHOT U ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + SW :[Apple Quicktime ] [0466-0467 ] + SW :[Digital Photo Professiona] [05 ] + SW :[IJG Library ] [075 ] + SW :[MS Paint ] [ ] + SW :[MS Visio ] [ ] + SW :[ZoomBrowser EX ] [low ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [075 ] + SW :[IrfanView ] [075 ] + SW :[idImager ] [075 ] + SW :[FastStone Image Viewer ] [075 ] + SW :[NeatImage ] [075 ] + SW :[Paint.NET ] [075 ] + SW :[Photomatix ] [075 ] + SW :[XnView ] [075 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/turtle.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/turtle.jpg.txt new file mode 100644 index 000000000..a8231b19e --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/turtle.jpg.txt @@ -0,0 +1,367 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\turtle.jpg] + Filesize: [55126] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 28 x 28 DPcm (dots per cm) + thumbnail = 0 x 0 + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00000014 + Length = 3256 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 3240 bytes + Preferred CMM Type : 'appl' (0x6170706C) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 2012-05-11 16:46:50 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : '....' (0x00000000) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'appl' (0x6170706C) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000CCE + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 4 6 8 10 + DQT, Row #1: 2 2 2 3 4 9 10 9 + DQT, Row #2: 2 2 3 4 6 9 11 9 + DQT, Row #3: 2 3 4 5 8 14 13 10 + DQT, Row #4: 3 4 6 9 11 17 16 12 + DQT, Row #5: 4 6 9 10 13 17 18 15 + DQT, Row #6: 8 10 12 14 16 19 19 16 + DQT, Row #7: 12 15 15 16 18 16 16 16 + Approx quality factor = 91.86 (scaling=16.28 variance=1.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000D13 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 3 4 8 16 16 16 16 + DQT, Row #1: 3 3 4 11 16 16 16 16 + DQT, Row #2: 4 4 9 16 16 16 16 16 + DQT, Row #3: 8 11 16 16 16 16 16 16 + DQT, Row #4: 16 16 16 16 16 16 16 16 + DQT, Row #5: 16 16 16 16 16 16 16 16 + DQT, Row #6: 16 16 16 16 16 16 16 16 + DQT, Row #7: 16 16 16 16 16 16 16 16 + Approx quality factor = 91.90 (scaling=16.20 variance=0.15) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00000D58 + Frame header length = 17 + Precision = 8 + Number of Lines = 281 + Samples per Line = 450 + Image Size = 450 x 281 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000D6B + Huffman table length = 29 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 06 + Codes of length 03 bits (004 total): 00 04 05 07 + Codes of length 04 bits (003 total): 01 03 08 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000D8A + Huffman table length = 82 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 02 03 04 + Codes of length 04 bits (003 total): 05 06 11 + Codes of length 05 bits (002 total): 00 12 + Codes of length 06 bits (004 total): 07 13 21 31 + Codes of length 07 bits (003 total): 22 41 51 + Codes of length 08 bits (004 total): 08 14 61 71 + Codes of length 09 bits (006 total): 15 23 32 81 91 A1 + Codes of length 10 bits (007 total): 16 42 52 55 94 B1 D2 + Codes of length 11 bits (004 total): 33 62 72 C1 + Codes of length 12 bits (007 total): 24 34 82 92 A2 D1 F0 + Codes of length 13 bits (005 total): 17 43 53 54 E1 + Codes of length 14 bits (006 total): 09 25 35 83 93 B2 + Codes of length 15 bits (007 total): 18 26 44 64 73 A3 C2 + Codes of length 16 bits (001 total): A4 + Total number of codes: 063 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000DDE + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 04 05 06 07 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000DFC + Huffman table length = 76 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (004 total): 00 03 04 21 + Codes of length 05 bits (003 total): 05 12 31 + Codes of length 06 bits (004 total): 06 41 51 61 + Codes of length 07 bits (006 total): 13 22 71 81 91 A1 + Codes of length 08 bits (006 total): 07 14 32 52 B1 D1 + Codes of length 09 bits (007 total): 15 42 53 62 72 92 C1 + Codes of length 10 bits (005 total): 23 33 A2 E1 F0 + Codes of length 11 bits (005 total): 16 17 34 82 B2 + Codes of length 12 bits (007 total): 24 35 54 63 73 D2 F1 + Codes of length 13 bits (004 total): 08 25 93 C2 + Codes of length 14 bits (003 total): 43 C3 D3 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 057 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000E4A + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00000E58 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0000D754.0 + + Compression stats: + Compression Ratio: 7.37:1 + Bits per pixel: 3.26:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 344 ( 16%) + # codes of length 03 bits: 1157 ( 55%) + # codes of length 04 bits: 453 ( 22%) + # codes of length 05 bits: 102 ( 5%) + # codes of length 06 bits: 32 ( 2%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 216 ( 21%) + # codes of length 03 bits: 672 ( 64%) + # codes of length 04 bits: 77 ( 7%) + # codes of length 05 bits: 59 ( 6%) + # codes of length 06 bits: 20 ( 2%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 11146 ( 23%) + # codes of length 03 bits: 21025 ( 43%) + # codes of length 04 bits: 8376 ( 17%) + # codes of length 05 bits: 3259 ( 7%) + # codes of length 06 bits: 2911 ( 6%) + # codes of length 07 bits: 840 ( 2%) + # codes of length 08 bits: 696 ( 1%) + # codes of length 09 bits: 499 ( 1%) + # codes of length 10 bits: 295 ( 1%) + # codes of length 11 bits: 93 ( 0%) + # codes of length 12 bits: 85 ( 0%) + # codes of length 13 bits: 26 ( 0%) + # codes of length 14 bits: 15 ( 0%) + # codes of length 15 bits: 8 ( 0%) + # codes of length 16 bits: 1 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 5260 ( 31%) + # codes of length 03 bits: 4077 ( 24%) + # codes of length 04 bits: 4031 ( 24%) + # codes of length 05 bits: 1544 ( 9%) + # codes of length 06 bits: 912 ( 5%) + # codes of length 07 bits: 626 ( 4%) + # codes of length 08 bits: 335 ( 2%) + # codes of length 09 bits: 163 ( 1%) + # codes of length 10 bits: 58 ( 0%) + # codes of length 11 bits: 27 ( 0%) + # codes of length 12 bits: 18 ( 0%) + # codes of length 13 bits: 6 ( 0%) + # codes of length 14 bits: 3 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[167] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1017, 3, -3] RGB=[253,255,255] @ MCU[ 26, 8] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0000D753.1 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000D754 + + +*** Searching Compression Signatures *** + + Signature: 01557A9AE226A38386271DFE13D64298 + Signature (Rotated): 0167FCEDBA3A8E8CF822163DB3564762 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Konica Minolta Camera, In] [DiMAGE Z2 ] [ ] No + CAM:[Minolta Co., Ltd. ] [DiMAGE F100 ] [ ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E8700 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS CORPORATION ] [C8080WZ ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-P200 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[IJG Library ] [092 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [092 ] + SW :[IrfanView ] [092 ] + SW :[idImager ] [092 ] + SW :[FastStone Image Viewer ] [092 ] + SW :[NeatImage ] [092 ] + SW :[Paint.NET ] [092 ] + SW :[Photomatix ] [092 ] + SW :[XnView ] [092 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ycck.jpg.txt b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ycck.jpg.txt new file mode 100644 index 000000000..717f35f3c --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/JpegSnoopReports/ycck.jpg.txt @@ -0,0 +1,640 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\ycck.jpg] + Filesize: [611572] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 4452 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0007 + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 720000/10000 + [YResolution ] = 720000/10000 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop CC 2015.5 (Windows)" + [DateTime ] = "2016:08:23 18:21:25" + [ExifOffset ] = @ 0x00AC + Offset to Next IFD = 0x000000D8 + + EXIF IFD1 @ Absolute 0x000000E4 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x0136 = @ 0x0142 + [JpegIFByteCount ] = 0x[00001026] / 4134 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000B8 + Dir Length = 0x0003 + [ColorSpace ] = Uncalibrated + [ExifImageWidth ] = 0x[00000200] / 512 + [ExifImageHeight ] = 0x[00000200] / 512 + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00001168 + Length = 6522 + Identifier = [Photoshop 3.0] + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0x00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ + 8BIM: [0x043A] Name="" Len=[0x00E5] DefinedName="Print Information" + Print Information = + | 0x00 00 00 10 00 00 00 01 00 00 00 00 00 0B 70 72 | ..............pr + | 0x69 6E 74 4F 75 74 70 75 74 00 00 00 05 00 00 00 | intOutput....... + | 0x00 50 73 74 53 62 6F 6F 6C 01 00 00 00 00 49 6E | .PstSbool.....In + | 0x74 65 65 6E 75 6D 00 00 00 00 49 6E 74 65 00 00 | teenum....Inte.. + | 0x00 00 43 6C 72 6D 00 00 00 0F 70 72 69 6E 74 53 | ..Clrm....printS + | 0x69 78 74 65 65 6E 42 69 74 62 6F 6F 6C 00 00 00 | ixteenBitbool... + | 0x00 0B 70 72 69 6E 74 65 72 4E 61 6D 65 54 45 58 | ..printerNameTEX + | 0x54 00 00 00 01 00 00 00 00 00 0F 70 72 69 6E 74 | T..........print + | ... + 8BIM: [0x043B] Name="" Len=[0x022D] DefinedName="Print Style" + Print Style = + | 0x00 00 00 10 00 00 00 01 00 00 00 00 00 12 70 72 | ..............pr + | 0x69 6E 74 4F 75 74 70 75 74 4F 70 74 69 6F 6E 73 | intOutputOptions + | 0x00 00 00 17 00 00 00 00 43 70 74 6E 62 6F 6F 6C | ........Cptnbool + | 0x00 00 00 00 00 43 6C 62 72 62 6F 6F 6C 00 00 00 | .....Clbrbool... + | 0x00 00 52 67 73 4D 62 6F 6F 6C 00 00 00 00 00 43 | ..RgsMbool.....C + | 0x72 6E 43 62 6F 6F 6C 00 00 00 00 00 43 6E 74 43 | rnCbool.....CntC + | 0x62 6F 6F 6C 00 00 00 00 00 4C 62 6C 73 62 6F 6F | bool.....Lblsboo + | 0x6C 00 00 00 00 00 4E 67 74 76 62 6F 6F 6C 00 00 | l.....Ngtvbool.. + | ... + 8BIM: [0x03ED] Name="" Len=[0x0010] DefinedName="ResolutionInfo structure" + Horizontal resolution = 72 pixels per inch + Width unit = cm + Vertical resolution = 72 pixels per inch + Height unit = cm + 8BIM: [0x0426] Name="" Len=[0x000E] DefinedName="Print scale" + Style = centered + X location = 0.00000 + Y location = 0.00000 + Scale = 1.00000 + 8BIM: [0x040D] Name="" Len=[0x0004] DefinedName="Global Angle" + Global Angle = 30 degrees + 8BIM: [0x0419] Name="" Len=[0x0004] DefinedName="Global Altitude" + Global Altitude = 30 + 8BIM: [0x03F3] Name="" Len=[0x0009] DefinedName="Print flags" + Labels = false + Crop marks = false + Color bars = false + Registration marks = false + Negative = false + Flip = false + Interpolate = false + Caption = false + Print flags = true + 8BIM: [0x2710] Name="" Len=[0x000A] DefinedName="Print flags information" + Version = 1 + Center crop marks = 0 + Reserved = 0 + Bleed width value = 0 + Bleed width scale = 2 + 8BIM: [0x03F5] Name="" Len=[0x0048] DefinedName="Color halftoning information" + Color halftoning information = + | 0x00 2F 66 66 00 01 00 6C 66 66 00 06 00 00 00 00 | ./ff...lff...... + | 0x00 01 00 2F 66 66 00 01 00 A1 99 9A 00 06 00 00 | .../ff.......... + | 0x00 00 00 01 00 32 00 00 00 01 00 5A 00 00 00 06 | .....2.....Z.... + | 0x00 00 00 00 00 01 00 35 00 00 00 01 00 2D 00 00 | .......5.....-.. + | 0x00 06 00 00 00 00 00 01 | ........ + 8BIM: [0x03F8] Name="" Len=[0x0070] DefinedName="Color transfer functions" + Color transfer functions = + | 0x00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF 03 E8 00 00 00 00 FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF 03 E8 00 00 00 00 FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0x03 E8 00 00 00 00 FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF 03 E8 00 00 | ................ + 8BIM: [0x0400] Name="" Len=[0x0002] DefinedName="Layer state information" + Target layer = 0 + 8BIM: [0x0402] Name="" Len=[0x0002] DefinedName="Layers group information" + Layer #0: + Layer Group = 0 + 8BIM: [0x0430] Name="" Len=[0x0001] DefinedName="Layer Groups Enabled ID" + Layer #0: + Layer Group Enabled ID = 1 + 8BIM: [0x042D] Name="" Len=[0x0006] DefinedName="Layer Selection IDs" + Num selected = 1 + Layer ID = 3 + 8BIM: [0x0408] Name="" Len=[0x0010] DefinedName="Grid and guides information" + Version = 1 + Grid Horizontal = 576 + Grid Vertical = 576 + Number of Guide Resources = 0 + 8BIM: [0x041E] Name="" Len=[0x0004] DefinedName="URL List" + URL List = | 0x00 00 00 00 | .... + 8BIM: [0x041A] Name="" Len=[0x0363] DefinedName="Slices" + Slice Header: + Version = 6 + Bound Rect (top) = 0 + Bound Rect (left) = 0 + Bound Rect (bottom) = 512 + Bound Rect (right) = 512 + Name of group of slices = "imageprocessor-logo-512" + Number of slices = 1 + ----- + Slice #0: + Slice Resource: + ID = 0 + Group ID = 0 + Origin = 0 + Name = "" + Type = 1 + Position (top) = 0 + Position (left) = 0 + Position (bottom) = 512 + Position (right) = 512 + URL = "" + Target = "" + Message = "" + Alt Tag = "" + Cell text is HTML = true + Cell text = "" + Horizontal alignment = 0 + Vertical alignment = 0 + Alpha color = 0 + Red = 0 + Green = 0 + Blue = 0 + Descriptor version = 16 + Descriptor: + Name from classID = "" + classID = "null" + Num items in descriptor = 2 + ----- + Descriptor item #0: + Key = "bounds" + OSType key = "Objc" + Descriptor: + Name from classID = "" + classID = "Rct1" + Num items in descriptor = 4 + ----- + Descriptor item #0: + Key = "Top " + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "Left" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "Btom" + OSType key = "long" + Value = 512 + Descriptor item #3: + Key = "Rght" + OSType key = "long" + Value = 512 + ----- + Descriptor item #1: + Key = "slices" + OSType key = "VlLs" + Num items in list = 1 + ----- + Item #0: + OSType key = "" + Descriptor: + Name from classID = "" + classID = "slice" + Num items in descriptor = 18 + ----- + Descriptor item #0: + Key = "sliceID" + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "groupID" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "origin" + OSType key = "enum" + Type = "ESliceOrigin" + Enum = "autoGenerated" + Descriptor item #3: + Key = "Type" + OSType key = "enum" + Type = "ESliceType" + Enum = "Img " + Descriptor item #4: + Key = "bounds" + OSType key = "Objc" + Descriptor: + Name from classID = "" + classID = "Rct1" + Num items in descriptor = 4 + ----- + Descriptor item #0: + Key = "Top " + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "Left" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "Btom" + OSType key = "long" + Value = 512 + Descriptor item #3: + Key = "Rght" + OSType key = "long" + Value = 512 + ----- + Descriptor item #5: + Key = "url" + OSType key = "TEXT" + String = "" + Descriptor item #6: + Key = "null" + OSType key = "TEXT" + String = "" + Descriptor item #7: + Key = "Msge" + OSType key = "TEXT" + String = "" + Descriptor item #8: + Key = "altTag" + OSType key = "TEXT" + String = "" + Descriptor item #9: + Key = "cellTextIsHTML" + OSType key = "bool" + Value = true + Descriptor item #10: + Key = "cellText" + OSType key = "TEXT" + String = "" + Descriptor item #11: + Key = "horzAlign" + OSType key = "enum" + Type = "ESliceHorzAlign" + Enum = "default" + Descriptor item #12: + Key = "vertAlign" + OSType key = "enum" + Type = "ESliceVertAlign" + Enum = "default" + Descriptor item #13: + Key = "bgColorType" + OSType key = "enum" + Type = "ESliceBGColorType" + Enum = "None" + Descriptor item #14: + Key = "topOutset" + OSType key = "long" + Value = 0 + Descriptor item #15: + Key = "leftOutset" + OSType key = "long" + Value = 0 + Descriptor item #16: + Key = "bottomOutset" + OSType key = "long" + Value = 0 + Descriptor item #17: + Key = "rightOutset" + OSType key = "long" + Value = 0 + ----- + ----- + ----- + ----- + 8BIM: [0x0428] Name="" Len=[0x000C] DefinedName="Pixel Aspect Ratio" + Version = 2 + X/Y Ratio = 1.00000 + 8BIM: [0x0414] Name="" Len=[0x0004] DefinedName="Document-specific IDs seed number" + Base value = 3 + 8BIM: [0x040C] Name="" Len=[0x1042] DefinedName="Thumbnail resources" + Format = 1 + Width of thumbnail = 160 pixels + Height of thumbnail = 160 pixels + Widthbytes = 480 bytes + Total size = 76800 bytes + Size after compression = 4134 bytes + Bits per pixel = 24 bits + Number of planes = 1 + JFIF data @ 0x00001A3C + 8BIM: [0x0421] Name="" Len=[0x0061] DefinedName="Version Info" + Version = 1 + hasRealMergedData = 1 + Writer name = "Adobe Photoshop" + Reader name = "Adobe Photoshop CC 2015.5" + File version = 1 + 8BIM: [0x0406] Name="" Len=[0x0007] DefinedName="JPEG quality" + Photoshop Save As Quality = 8 + Photoshop Save Format = "Standard" + Photoshop Save Progressive Scans = "3 Scans" + ??? = 1 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00002AE4 + Length = 3685 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0000394B + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 9 + Profile Size : 557168 bytes + Preferred CMM Type : 'ADBE' (0x41444245) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Output Device profile ('prtr' (0x70727472)) + Data Colour Space : cmykData ('CMYK' (0x434D594B)) + Profile connection space (PCS) : 'Lab ' (0x4C616220) + Profile creation date : 2000-07-26 05:41:53 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'ADBE' (0x41444245) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Media-Relative Colorimetric + Profile creator : 'ADBE' (0x41444245) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0001392F + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 2 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00023913 + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 3 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000338F7 + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 4 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000438DB + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 5 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000538BF + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 6 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x000638A3 + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 7 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00073887 + Length = 65506 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 8 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0008386B + Length = 33264 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 9 of 9 + Only support decode of 1st ICC Marker + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x0008BA5D + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 0 + APP14Flags1 = 0 + ColorTransform = 2 [YCCK] + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0008BA6D + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + Approx quality factor = 88.28 (scaling=23.43 variance=111.68) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 90.19 (scaling=19.62 variance=201.04) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0008BAF3 + Frame header length = 20 + Precision = 8 + Number of Lines = 512 + Samples per Line = 512 + Image Size = 512 x 512 + Raw Image Orientation = Landscape + Number of Img components = 4 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Cr) + Component[4]: ID=0x04, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (K) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x0008BB09 + Length = 4 + interval = 64 + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0008BB0F + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (007 total): 04 05 03 02 06 01 00 + Codes of length 04 bits (001 total): 07 + Codes of length 05 bits (001 total): 08 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (001 total): 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 00 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (003 total): 04 05 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 11 04 00 + Codes of length 05 bits (003 total): 05 21 12 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 51 06 13 61 + Codes of length 08 bits (002 total): 22 71 + Codes of length 09 bits (006 total): 81 14 32 91 A1 07 + Codes of length 10 bits (007 total): 15 B1 42 23 C1 52 D1 + Codes of length 11 bits (003 total): E1 33 16 + Codes of length 12 bits (004 total): 62 F0 24 72 + Codes of length 13 bits (002 total): 82 F1 + Codes of length 14 bits (006 total): 25 43 34 53 92 A2 + Codes of length 15 bits (002 total): B2 63 + Codes of length 16 bits (115 total): 73 C2 35 44 27 93 A3 B3 36 17 54 64 74 C3 D2 E2 + 08 26 83 09 0A 18 19 84 94 45 46 A4 B4 56 D3 55 + 28 1A F2 E3 F3 C4 D4 E4 F4 65 75 85 95 A5 B5 C5 + D5 E5 F5 66 76 86 96 A6 B6 C6 D6 E6 F6 37 47 57 + 67 77 87 97 A7 B7 C7 D7 E7 F7 38 48 58 68 78 88 + 98 A8 B8 C8 D8 E8 F8 29 39 49 59 69 79 89 99 A9 + B9 C9 D9 E9 F9 2A 3A 4A 5A 6A 7A 8A 9A AA BA CA + DA EA FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 00 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (002 total): 04 21 + Codes of length 06 bits (003 total): 12 31 41 + Codes of length 07 bits (005 total): 05 51 13 61 22 + Codes of length 08 bits (005 total): 06 71 81 91 32 + Codes of length 09 bits (004 total): A1 B1 F0 14 + Codes of length 10 bits (005 total): C1 D1 E1 23 42 + Codes of length 11 bits (006 total): 15 52 62 72 F1 33 + Codes of length 12 bits (004 total): 24 34 43 82 + Codes of length 13 bits (008 total): 16 92 53 25 A2 63 B2 C2 + Codes of length 14 bits (003 total): 07 73 D2 + Codes of length 15 bits (003 total): 35 E2 44 + Codes of length 16 bits (109 total): 83 17 54 93 08 09 0A 18 19 26 36 45 1A 27 64 74 + 55 37 F2 A3 B3 C3 28 29 D3 E3 F3 84 94 A4 B4 C4 + D4 E4 F4 65 75 85 95 A5 B5 C5 D5 E5 F5 46 56 66 + 76 86 96 A6 B6 C6 D6 E6 F6 47 57 67 77 87 97 A7 + B7 C7 D7 E7 F7 38 48 58 68 78 88 98 A8 B8 C8 D8 + E8 F8 39 49 59 69 79 89 99 A9 B9 C9 D9 E9 F9 2A + 3A 4A 5A 6A 7A 8A 9A AA BA CA DA EA FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0008BCB3 + Scan header length = 14 + Number of img components = 4 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Component[4]: selector=0x04, table=0(DC),0(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support CMYK files yet. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000954F2 + + +*** Searching Compression Signatures *** + + Signature: 01180AF3DE63318828A86409EF4013DD + Signature (Rotated): 01180AF3DE63318828A86409EF4013DD + File Offset: 0 bytes + Chroma subsampling: ?x? + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop CC 2015.5 (Windows)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 08 ] + + NOTE: Photoshop IRB detected + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Bedroom.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Bedroom.jpg.txt new file mode 100644 index 000000000..ea1f5e0f7 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Bedroom.jpg.txt @@ -0,0 +1,461 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue159-MissingFF00-Progressive-Bedroom.jpg] + Filesize: [338422] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 14 18 22 + DQT, Row #1: 4 4 5 7 9 21 22 20 + DQT, Row #2: 5 5 6 9 14 21 25 20 + DQT, Row #3: 5 6 8 10 18 31 29 22 + DQT, Row #4: 6 8 13 20 24 39 37 28 + DQT, Row #5: 9 13 20 23 29 37 41 33 + DQT, Row #6: 18 23 28 31 37 44 43 36 + DQT, Row #7: 26 33 34 35 40 36 37 36 + Approx quality factor = 81.99 (scaling=36.03 variance=1.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 6 6 9 17 36 36 36 36 + DQT, Row #1: 6 8 9 24 36 36 36 36 + DQT, Row #2: 9 9 20 36 36 36 36 36 + DQT, Row #3: 17 24 36 36 36 36 36 36 + DQT, Row #4: 36 36 36 36 36 36 36 36 + DQT, Row #5: 36 36 36 36 36 36 36 36 + DQT, Row #6: 36 36 36 36 36 36 36 36 + DQT, Row #7: 36 36 36 36 36 36 36 36 + Approx quality factor = 81.88 (scaling=36.24 variance=0.48) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 2300 + Samples per Line = 2300 + Image Size = 2300 x 2300 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 27 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 01 02 + Codes of length 04 bits (003 total): 03 04 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000CE + Huffman table length = 26 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (001 total): 06 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000EA + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000CBBB + Huffman table length = 56 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (004 total): 00 01 02 03 + Codes of length 04 bits (005 total): 04 10 11 12 41 + Codes of length 05 bits (002 total): 21 31 + Codes of length 06 bits (005 total): 05 13 20 22 32 + Codes of length 07 bits (003 total): 15 30 42 + Codes of length 08 bits (005 total): 14 23 33 34 50 + Codes of length 09 bits (000 total): + Codes of length 10 bits (002 total): 24 40 + Codes of length 11 bits (002 total): 06 16 + Codes of length 12 bits (002 total): 43 60 + Codes of length 13 bits (002 total): 70 A0 + Codes of length 14 bits (003 total): 44 80 90 + Codes of length 15 bits (001 total): B0 + Codes of length 16 bits (001 total): 35 + Total number of codes: 037 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000CBF5 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0001A2A8 + Huffman table length = 51 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (005 total): 02 03 10 20 30 + Codes of length 05 bits (003 total): 12 13 31 + Codes of length 06 bits (004 total): 04 21 32 40 + Codes of length 07 bits (002 total): 14 51 + Codes of length 08 bits (002 total): 05 41 + Codes of length 09 bits (002 total): 33 50 + Codes of length 10 bits (001 total): 22 + Codes of length 11 bits (004 total): 15 52 61 70 + Codes of length 12 bits (003 total): 23 42 60 + Codes of length 13 bits (000 total): + Codes of length 14 bits (003 total): 71 A0 B0 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001A2DD + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0001BB1E + Huffman table length = 50 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (005 total): 02 03 10 20 30 + Codes of length 05 bits (003 total): 12 13 31 + Codes of length 06 bits (004 total): 04 21 32 40 + Codes of length 07 bits (002 total): 14 51 + Codes of length 08 bits (003 total): 05 41 50 + Codes of length 09 bits (001 total): 22 + Codes of length 10 bits (000 total): + Codes of length 11 bits (001 total): 61 + Codes of length 12 bits (004 total): 23 33 60 70 + Codes of length 13 bits (002 total): 15 43 + Codes of length 14 bits (003 total): 52 A0 B0 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 031 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001BB52 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0001D49C + Huffman table length = 67 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (000 total): + Codes of length 04 bits (004 total): 10 11 21 31 + Codes of length 05 bits (005 total): 02 41 51 71 81 + Codes of length 06 bits (001 total): 20 + Codes of length 07 bits (006 total): 12 22 30 61 91 A1 + Codes of length 08 bits (004 total): 03 32 33 C1 + Codes of length 09 bits (002 total): 40 50 + Codes of length 10 bits (010 total): 13 23 42 52 72 82 B1 D1 E1 F0 + Codes of length 11 bits (002 total): 34 62 + Codes of length 12 bits (003 total): 60 92 F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (002 total): 24 80 + Codes of length 15 bits (000 total): + Codes of length 16 bits (007 total): 04 70 43 A2 14 C0 D0 + Total number of codes: 048 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001D4E1 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000291D6 + Huffman table length = 44 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 11 21 + Codes of length 04 bits (002 total): 31 41 + Codes of length 05 bits (001 total): 51 + Codes of length 06 bits (003 total): 10 61 71 + Codes of length 07 bits (003 total): 81 91 A1 + Codes of length 08 bits (003 total): 20 B1 F0 + Codes of length 09 bits (004 total): 30 C1 D1 E1 + Codes of length 10 bits (003 total): 40 50 F1 + Codes of length 11 bits (001 total): 60 + Codes of length 12 bits (001 total): 70 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 025 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00029204 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00044080 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00047DC7 + Huffman table length = 45 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (004 total): 10 30 31 61 + Codes of length 05 bits (006 total): 20 21 40 41 51 71 + Codes of length 06 bits (002 total): 50 60 + Codes of length 07 bits (003 total): 81 91 A1 + Codes of length 08 bits (001 total): B1 + Codes of length 09 bits (000 total): + Codes of length 10 bits (002 total): 70 F0 + Codes of length 11 bits (002 total): C1 D1 + Codes of length 12 bits (003 total): A0 B0 F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 026 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00047DF6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00048BD6 + Huffman table length = 45 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (004 total): 20 30 31 61 + Codes of length 05 bits (006 total): 10 21 40 41 51 71 + Codes of length 06 bits (002 total): 50 81 + Codes of length 07 bits (003 total): 60 91 B1 + Codes of length 08 bits (001 total): A1 + Codes of length 09 bits (000 total): + Codes of length 10 bits (002 total): 70 C1 + Codes of length 11 bits (002 total): 80 F0 + Codes of length 12 bits (003 total): A0 B0 D1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 026 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00048C05 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00049AE7 + Huffman table length = 48 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 70 + Codes of length 03 bits (001 total): 00 + Codes of length 04 bits (007 total): 01 11 31 41 51 80 91 + Codes of length 05 bits (003 total): 10 21 81 + Codes of length 06 bits (002 total): 50 60 + Codes of length 07 bits (005 total): 20 40 61 71 D1 + Codes of length 08 bits (004 total): 30 B1 E1 F1 + Codes of length 09 bits (002 total): A1 F0 + Codes of length 10 bits (003 total): A0 C0 C1 + Codes of length 11 bits (001 total): D0 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 029 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00049B19 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000529F4 + + +*** Searching Compression Signatures *** + + Signature: 0138A8D4ECE59F41D2EB9AF5168B6675 + Signature (Rotated): 01CA9A809F737BA668C16DDE52E74092 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C700UZ ] [ ] No + SW :[IJG Library ] [082 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [082 ] + SW :[IrfanView ] [082 ] + SW :[idImager ] [082 ] + SW :[FastStone Image Viewer ] [082 ] + SW :[NeatImage ] [082 ] + SW :[Paint.NET ] [082 ] + SW :[Photomatix ] [082 ] + SW :[XnView ] [082 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Girl.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Girl.jpg.txt new file mode 100644 index 000000000..4858b4ea1 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue159-MissingFF00-Progressive-Girl.jpg.txt @@ -0,0 +1,520 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue159-MissingFF00-Progressive-Girl.jpg] + Filesize: [60927] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.2] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00000014 + Length = 132 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x0067] DefinedName="IPTC-NAA record" + IPTC [002:040] Special Instructions = "FBMD01000a820d0000192d00007a4400006e460000a9470000a44e00000b7b0000cc830000e0880000a08c0000ffed0000" + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0000009A + Length = 3064 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 3048 bytes + Preferred CMM Type : '....' (0x00000000) + Profile Version : 0.2.0.0 (0x02000000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 2009-03-27 21:36:31 + Profile file signature : 'acsp' (0x61637370) + Primary platform : ? (0x00000000) ('....' (0x00000000)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : '....' (0x00000000) + Device Model : '....' (0x00000000) + Device attributes : 0x00000001_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : '....' (0x00000000) + Profile ID : 0x29F83DDE_AFF255AE_7842FAE4_CA83390D + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000C94 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 9 6 6 9 14 23 30 35 + DQT, Row #1: 7 7 8 11 15 34 35 32 + DQT, Row #2: 8 8 9 14 23 33 40 32 + DQT, Row #3: 8 10 13 17 30 50 46 36 + DQT, Row #4: 10 13 21 32 39 63 60 45 + DQT, Row #5: 14 20 32 37 47 60 66 53 + DQT, Row #6: 28 37 45 50 60 70 70 59 + DQT, Row #7: 42 53 55 57 65 58 60 57 + Approx quality factor = 71.07 (scaling=57.86 variance=0.92) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000CD9 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 10 10 14 27 57 57 57 57 + DQT, Row #1: 10 12 15 38 57 57 57 57 + DQT, Row #2: 14 15 32 57 57 57 57 57 + DQT, Row #3: 27 38 57 57 57 57 57 57 + DQT, Row #4: 57 57 57 57 57 57 57 57 + DQT, Row #5: 57 57 57 57 57 57 57 57 + DQT, Row #6: 57 57 57 57 57 57 57 57 + DQT, Row #7: 57 57 57 57 57 57 57 57 + Approx quality factor = 71.23 (scaling=57.54 variance=0.18) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x00000D1E + Frame header length = 17 + Precision = 8 + Number of Lines = 990 + Samples per Line = 750 + Image Size = 750 x 990 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000D31 + Huffman table length = 27 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000D4E + Huffman table length = 24 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 005 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000D68 + Huffman table length = 24 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 005 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000D82 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002CED + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (003 total): 03 10 11 + Codes of length 05 bits (003 total): 04 12 20 + Codes of length 06 bits (004 total): 21 30 31 40 + Codes of length 07 bits (002 total): 32 41 + Codes of length 08 bits (002 total): 13 22 + Codes of length 09 bits (003 total): 05 14 50 + Codes of length 10 bits (001 total): 33 + Codes of length 11 bits (001 total): 42 + Codes of length 12 bits (001 total): 23 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002D19 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00004455 + Huffman table length = 35 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 00 + Codes of length 04 bits (005 total): 02 10 11 20 30 + Codes of length 05 bits (001 total): 40 + Codes of length 06 bits (000 total): + Codes of length 07 bits (002 total): 12 50 + Codes of length 08 bits (003 total): 03 31 41 + Codes of length 09 bits (001 total): 21 + Codes of length 10 bits (001 total): 51 + Codes of length 11 bits (001 total): 60 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 016 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000447A + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000464C + Huffman table length = 32 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (000 total): + Codes of length 04 bits (007 total): 00 10 11 20 30 40 50 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 12 + Codes of length 07 bits (000 total): + Codes of length 08 bits (003 total): 21 31 70 + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 013 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000466E + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00004775 + Huffman table length = 50 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (003 total): 02 21 40 + Codes of length 05 bits (007 total): 10 12 30 31 32 50 91 + Codes of length 06 bits (003 total): 20 41 51 + Codes of length 07 bits (003 total): 60 61 71 + Codes of length 08 bits (004 total): 03 22 42 81 + Codes of length 09 bits (002 total): 13 62 + Codes of length 10 bits (001 total): 43 + Codes of length 11 bits (005 total): 23 52 70 80 A1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 031 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000047A9 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00004E79 + Huffman table length = 41 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (003 total): 10 21 31 + Codes of length 05 bits (004 total): 41 61 71 81 + Codes of length 06 bits (002 total): 20 51 + Codes of length 07 bits (002 total): 30 91 + Codes of length 08 bits (003 total): A1 D1 F0 + Codes of length 09 bits (001 total): 40 + Codes of length 10 bits (001 total): B1 + Codes of length 11 bits (001 total): C1 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (001 total): E1 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00004EA4 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007B0B + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000083AB + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (000 total): + Codes of length 04 bits (003 total): 10 11 20 + Codes of length 05 bits (000 total): + Codes of length 06 bits (003 total): 21 30 31 + Codes of length 07 bits (001 total): 41 + Codes of length 08 bits (001 total): 51 + Codes of length 09 bits (001 total): 40 + Codes of length 10 bits (001 total): 61 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000083CC + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000088BF + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 00 10 11 + Codes of length 04 bits (001 total): 20 + Codes of length 05 bits (001 total): 30 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 21 31 41 + Codes of length 08 bits (001 total): 40 + Codes of length 09 bits (001 total): 51 + Codes of length 10 bits (001 total): 71 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000088E0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00008C75 + Huffman table length = 41 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (001 total): 61 + Codes of length 07 bits (003 total): 10 71 81 + Codes of length 08 bits (003 total): 91 A1 B1 + Codes of length 09 bits (005 total): 20 30 C1 D1 F1 + Codes of length 10 bits (001 total): E1 + Codes of length 11 bits (001 total): F0 + Codes of length 12 bits (001 total): 40 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008CA0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000EDFD + + +*** Searching Compression Signatures *** + + Signature: 01B8FDD60747E53114DC15797CC09B4E + Signature (Rotated): 011975EE86201F10E48E4F365C73A839 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[IJG Library ] [071 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [071 ] + SW :[IrfanView ] [071 ] + SW :[idImager ] [071 ] + SW :[FastStone Image Viewer ] [071 ] + SW :[NeatImage ] [071 ] + SW :[Paint.NET ] [071 ] + SW :[Photomatix ] [071 ] + SW :[XnView ] [071 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue178-BadCoeffsProgressive-Lemon.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue178-BadCoeffsProgressive-Lemon.jpg.txt new file mode 100644 index 000000000..af39df365 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue178-BadCoeffsProgressive-Lemon.jpg.txt @@ -0,0 +1,471 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue178-BadCoeffsProgressive-Lemon.jpg] + Filesize: [279270] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 2 2 1 + DQT, Row #4: 1 1 1 1 1 2 2 2 + DQT, Row #5: 1 1 1 1 2 2 2 2 + DQT, Row #6: 1 1 2 2 2 2 2 2 + DQT, Row #7: 1 2 2 2 2 2 2 2 + Approx quality factor = 98.32 (scaling=3.35 variance=5.00) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 1 2 2 2 2 + DQT, Row #1: 1 1 1 1 2 2 2 2 + DQT, Row #2: 1 1 1 2 2 2 2 2 + DQT, Row #3: 1 1 2 2 2 2 2 2 + DQT, Row #4: 2 2 2 2 2 2 2 2 + DQT, Row #5: 2 2 2 2 2 2 2 2 + DQT, Row #6: 2 2 2 2 2 2 2 2 + DQT, Row #7: 2 2 2 2 2 2 2 2 + Approx quality factor = 98.83 (scaling=2.34 variance=0.89) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 710 + Samples per Line = 710 + Image Size = 710 x 710 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 30 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 05 + Codes of length 03 bits (004 total): 03 04 06 07 + Codes of length 04 bits (003 total): 00 02 08 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000D1 + Huffman table length = 29 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (005 total): 00 01 02 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000F0 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002D06 + Huffman table length = 49 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 02 + Codes of length 03 bits (004 total): 00 01 03 04 + Codes of length 04 bits (002 total): 05 11 + Codes of length 05 bits (002 total): 06 12 + Codes of length 06 bits (002 total): 13 21 + Codes of length 07 bits (002 total): 07 14 + Codes of length 08 bits (001 total): 22 + Codes of length 09 bits (003 total): 10 15 31 + Codes of length 10 bits (004 total): 16 23 32 41 + Codes of length 11 bits (001 total): 20 + Codes of length 12 bits (004 total): 08 30 33 50 + Codes of length 13 bits (003 total): 24 40 42 + Codes of length 14 bits (001 total): 34 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 030 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002D39 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007ADB + Huffman table length = 72 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (005 total): 05 22 41 51 61 + Codes of length 07 bits (005 total): 06 13 71 81 A1 + Codes of length 08 bits (005 total): 14 32 91 B1 F0 + Codes of length 09 bits (006 total): 23 42 52 C1 D1 E1 + Codes of length 10 bits (004 total): 10 15 33 62 + Codes of length 11 bits (003 total): 07 82 F1 + Codes of length 12 bits (006 total): 20 24 30 43 72 A2 + Codes of length 13 bits (006 total): 16 34 53 92 B2 E2 + Codes of length 14 bits (003 total): 25 44 93 + Codes of length 15 bits (001 total): D2 + Codes of length 16 bits (000 total): + Total number of codes: 053 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007B25 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000A7E3 + Huffman table length = 74 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (005 total): 05 12 21 31 41 + Codes of length 06 bits (005 total): 06 13 22 51 61 + Codes of length 07 bits (004 total): 32 71 81 91 + Codes of length 08 bits (006 total): 14 42 52 A1 B1 F0 + Codes of length 09 bits (008 total): 07 10 15 23 62 C1 D1 E1 + Codes of length 10 bits (004 total): 33 43 72 92 + Codes of length 11 bits (004 total): 24 82 A2 F1 + Codes of length 12 bits (004 total): 16 34 63 D2 + Codes of length 13 bits (006 total): 20 40 53 B2 C2 E2 + Codes of length 14 bits (003 total): 17 25 30 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 055 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000A82F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000E96D + Huffman table length = 84 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (003 total): 00 03 21 + Codes of length 05 bits (005 total): 04 12 31 41 51 + Codes of length 06 bits (004 total): 05 22 61 71 + Codes of length 07 bits (006 total): 13 32 81 91 A1 F0 + Codes of length 08 bits (008 total): 10 14 23 42 52 B1 C1 D1 + Codes of length 09 bits (003 total): 33 62 E1 + Codes of length 10 bits (005 total): 06 72 82 92 F1 + Codes of length 11 bits (006 total): 15 20 24 43 53 A2 + Codes of length 12 bits (004 total): 30 34 63 73 + Codes of length 13 bits (004 total): 44 83 B2 C2 + Codes of length 14 bits (005 total): 40 50 93 A3 D2 + Codes of length 15 bits (002 total): 16 25 + Codes of length 16 bits (007 total): 26 35 54 60 64 B3 E2 + Total number of codes: 065 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000E9C3 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0001AD55 + Huffman table length = 40 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 11 21 + Codes of length 04 bits (002 total): 00 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (002 total): 61 71 + Codes of length 07 bits (002 total): 81 91 + Codes of length 08 bits (002 total): A1 B1 + Codes of length 09 bits (003 total): C1 D1 F0 + Codes of length 10 bits (000 total): + Codes of length 11 bits (003 total): 10 E1 F1 + Codes of length 12 bits (001 total): 20 + Codes of length 13 bits (001 total): 30 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 021 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001AD7F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000287B1 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00028DB3 + Huffman table length = 39 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 11 21 + Codes of length 04 bits (002 total): 00 31 + Codes of length 05 bits (001 total): 41 + Codes of length 06 bits (003 total): 51 61 71 + Codes of length 07 bits (003 total): 81 91 F0 + Codes of length 08 bits (005 total): A1 B1 C1 D1 E1 + Codes of length 09 bits (001 total): F1 + Codes of length 10 bits (001 total): 10 + Codes of length 11 bits (001 total): 20 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 020 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00028DDC + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0002CD0C + Huffman table length = 41 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 11 21 + Codes of length 04 bits (002 total): 00 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (001 total): 61 + Codes of length 07 bits (004 total): 71 81 91 F0 + Codes of length 08 bits (002 total): A1 B1 + Codes of length 09 bits (003 total): C1 D1 E1 + Codes of length 10 bits (001 total): F1 + Codes of length 11 bits (001 total): 30 + Codes of length 12 bits (001 total): 10 + Codes of length 13 bits (001 total): 20 + Codes of length 14 bits (001 total): 40 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0002CD37 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00031187 + Huffman table length = 38 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (001 total): 21 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 00 31 41 + Codes of length 06 bits (000 total): + Codes of length 07 bits (002 total): 51 61 + Codes of length 08 bits (002 total): 71 81 + Codes of length 09 bits (002 total): 91 A1 + Codes of length 10 bits (002 total): B1 C1 + Codes of length 11 bits (003 total): D1 E1 F0 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (001 total): 10 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 019 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000311AF + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000442E4 + + +*** Searching Compression Signatures *** + + Signature: 01C7F83908166C226C06A44017421732 + Signature (Rotated): 01D3EFDD3855C42AE3E0E6289F1A6726 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Canon ] [Canon EOS-1Ds Mark II ] [fine ] No + CAM:[CASIO COMPUTER CO.,LTD. ] [EX-Z1000 ] [ ] Yes + CAM:[NIKON ] [NIKON D2X ] [FINE ] No + CAM:[NIKON ] [NIKON D3 ] [FINE ] No + CAM:[SIGMA ] [SIGMA SD10 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD10 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD14 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD14 ] [Qual:12 ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-R1 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[Digital Photo Professiona] [09 ] + SW :[IJG Library ] [099 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [099 ] + SW :[IrfanView ] [099 ] + SW :[idImager ] [099 ] + SW :[FastStone Image Viewer ] [099 ] + SW :[NeatImage ] [099 ] + SW :[Paint.NET ] [099 ] + SW :[Photomatix ] [099 ] + SW :[XnView ] [099 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue214-CriticalEOF .jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue214-CriticalEOF .jpg.txt new file mode 100644 index 000000000..f5b6d277d --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue214-CriticalEOF .jpg.txt @@ -0,0 +1,94 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue214-CriticalEOF .jpg] + Filesize: [35601] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 39251 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0015 + [Make ] = "NIKON CORPORATION" + [Model ] = "NIKON D40" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [Software ] = "Ver.1.10 " + [DateTime ] = "2009:02:17 08:30:16" + [YCbCrPositioning ] = Co-sited + [ExifOffset ] = @ 0x015C + [CustomRendered ] = Normal process + [ExposureMode ] = Auto exposure + [WhiteBalance ] = Auto white balance + [SceneCaptureType ] = Standard + Offset to Next IFD = 0x00007652 + + EXIF IFD1 @ Absolute 0x00007670 + Dir Length = 0x0007 + [Compression ] = JPEG + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x76BC = @ 0x76DA + [JpegIFByteCount ] = 0x[0000228F] / 8847 + [YCbCrPositioning ] = Co-sited + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x0000017A + Dir Length = 0x001C + [ExposureTime ] = 10/1250 s + [FNumber ] = F5.6 + [ExposureProgram ] = Not defined + [ISOSpeedRatings ] = 220 + [ExifVersion ] = 02.21 + [DateTimeOriginal ] = "2009:02:17 08:30:16" + [DateTimeDigitized ] = "2009:02:17 08:30:15" + [ComponentsConfiguration ] = [Y Cb Cr .] + [CompressedBitsPerPixel ] = 1/1 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 41/10 + [MeteringMode ] = Pattern + [LightSource ] = unknown + [Flash ] = Flash did not fire + [FocalLength ] = 30 mm + [MakerNote ] = @ 0x030A + [UserComment ] = " " + [SubSecTime ] = "60" + [SubSecTimeOriginal ] = "60" + [SubSecTimeDigitized ] = "60" + [FlashPixVersion ] = 01.00 + [ColorSpace ] = sRGB + [ExifImageWidth ] = 3008 + [ExifImageHeight ] = 2000 + [SensingMethod ] = One-chip color area sensor + [FileSource ] = DSC + [SceneType ] = A directly photographed image + [CFAPattern ] = + = [ Blu Grn ] + = [ Grn Red ] + + EXIF MakerIFD @ Absolute 0x00000328 + Makernote decode option not enabled. + +ERROR: Early EOF - file may be missing EOI diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue385-BadZigZag-Progressive.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue385-BadZigZag-Progressive.jpg.txt new file mode 100644 index 000000000..1f98e67dc --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue385-BadZigZag-Progressive.jpg.txt @@ -0,0 +1,468 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue385-BadZigZag-Progressive.jpg] + Filesize: [388517] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 5 3 3 5 7 12 15 18 + DQT, Row #1: 4 4 4 6 8 17 18 17 + DQT, Row #2: 4 4 5 7 12 17 21 17 + DQT, Row #3: 4 5 7 9 15 26 24 19 + DQT, Row #4: 5 7 11 17 20 33 31 23 + DQT, Row #5: 7 11 17 19 24 31 34 28 + DQT, Row #6: 15 19 23 26 31 36 36 30 + DQT, Row #7: 22 28 29 29 34 30 31 30 + Approx quality factor = 84.93 (scaling=30.13 variance=1.05) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 5 5 7 14 30 30 30 30 + DQT, Row #1: 5 6 8 20 30 30 30 30 + DQT, Row #2: 7 8 17 30 30 30 30 30 + DQT, Row #3: 14 20 30 30 30 30 30 30 + DQT, Row #4: 30 30 30 30 30 30 30 30 + DQT, Row #5: 30 30 30 30 30 30 30 30 + DQT, Row #6: 30 30 30 30 30 30 30 30 + DQT, Row #7: 30 30 30 30 30 30 30 30 + Approx quality factor = 84.93 (scaling=30.15 variance=0.29) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 1440 + Samples per Line = 1920 + Image Size = 1920 x 1440 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (003 total): 02 03 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (001 total): 08 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000CF + Huffman table length = 25 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 006 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000EA + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007E0B + Huffman table length = 55 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (003 total): 04 12 21 + Codes of length 06 bits (002 total): 05 10 + Codes of length 07 bits (004 total): 13 20 22 31 + Codes of length 08 bits (004 total): 06 14 30 41 + Codes of length 09 bits (005 total): 15 32 33 34 40 + Codes of length 10 bits (005 total): 23 24 35 42 50 + Codes of length 11 bits (000 total): + Codes of length 12 bits (002 total): 25 70 + Codes of length 13 bits (003 total): 16 44 60 + Codes of length 14 bits (001 total): 36 + Codes of length 15 bits (001 total): 45 + Codes of length 16 bits (001 total): 43 + Total number of codes: 036 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007E44 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00012C0C + Huffman table length = 46 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (004 total): 02 10 12 20 + Codes of length 05 bits (000 total): + Codes of length 06 bits (004 total): 03 21 30 31 + Codes of length 07 bits (006 total): 13 32 40 41 50 51 + Codes of length 08 bits (002 total): 22 61 + Codes of length 09 bits (002 total): 04 60 + Codes of length 10 bits (003 total): 23 33 71 + Codes of length 11 bits (001 total): 42 + Codes of length 12 bits (001 total): 05 + Codes of length 13 bits (001 total): 43 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 027 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00012C3C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00013C45 + Huffman table length = 43 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (004 total): 02 10 12 20 + Codes of length 05 bits (001 total): 30 + Codes of length 06 bits (004 total): 03 21 31 40 + Codes of length 07 bits (002 total): 41 50 + Codes of length 08 bits (002 total): 13 51 + Codes of length 09 bits (002 total): 22 60 + Codes of length 10 bits (003 total): 32 42 61 + Codes of length 11 bits (001 total): 04 + Codes of length 12 bits (001 total): 81 + Codes of length 13 bits (001 total): 71 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00013C72 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000148F2 + Huffman table length = 75 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (000 total): + Codes of length 04 bits (004 total): 02 11 21 31 + Codes of length 05 bits (002 total): 03 10 + Codes of length 06 bits (006 total): 12 20 22 32 41 51 + Codes of length 07 bits (007 total): 04 30 33 61 71 81 91 + Codes of length 08 bits (005 total): 13 40 50 52 72 + Codes of length 09 bits (007 total): 23 34 42 62 82 92 A1 + Codes of length 10 bits (001 total): B1 + Codes of length 11 bits (006 total): 14 60 70 73 C1 E1 + Codes of length 12 bits (005 total): 05 63 83 A2 D1 + Codes of length 13 bits (004 total): 24 43 53 93 + Codes of length 14 bits (002 total): 74 F0 + Codes of length 15 bits (002 total): 15 B2 + Codes of length 16 bits (003 total): 35 E2 F1 + Total number of codes: 056 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001493F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0001BD13 + Huffman table length = 44 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (002 total): 10 61 + Codes of length 07 bits (001 total): 71 + Codes of length 08 bits (004 total): 20 81 91 A1 + Codes of length 09 bits (002 total): 30 B1 + Codes of length 10 bits (002 total): C1 F0 + Codes of length 11 bits (003 total): 40 D1 F1 + Codes of length 12 bits (001 total): E1 + Codes of length 13 bits (001 total): 50 + Codes of length 14 bits (001 total): 60 + Codes of length 15 bits (001 total): 70 + Codes of length 16 bits (000 total): + Total number of codes: 025 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0001BD41 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0002C20D + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0002E1DF + Huffman table length = 37 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (000 total): + Codes of length 05 bits (002 total): 21 31 + Codes of length 06 bits (002 total): 10 41 + Codes of length 07 bits (003 total): 20 51 61 + Codes of length 08 bits (001 total): 71 + Codes of length 09 bits (001 total): 30 + Codes of length 10 bits (001 total): 81 + Codes of length 11 bits (001 total): 40 + Codes of length 12 bits (001 total): 91 + Codes of length 13 bits (001 total): A1 + Codes of length 14 bits (001 total): B1 + Codes of length 15 bits (001 total): C1 + Codes of length 16 bits (000 total): + Total number of codes: 018 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0002E206 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000313D7 + Huffman table length = 36 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (003 total): 10 21 31 + Codes of length 05 bits (000 total): + Codes of length 06 bits (003 total): 20 41 51 + Codes of length 07 bits (001 total): 61 + Codes of length 08 bits (001 total): 71 + Codes of length 09 bits (001 total): 30 + Codes of length 10 bits (001 total): 81 + Codes of length 11 bits (001 total): 40 + Codes of length 12 bits (001 total): 91 + Codes of length 13 bits (001 total): B1 + Codes of length 14 bits (001 total): A1 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 017 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000313FD + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00033E31 + Huffman table length = 40 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (002 total): 61 71 + Codes of length 07 bits (002 total): 81 91 + Codes of length 08 bits (002 total): A1 B1 + Codes of length 09 bits (003 total): 10 C1 D1 + Codes of length 10 bits (001 total): F0 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (001 total): 20 + Codes of length 14 bits (001 total): 30 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 021 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00033E5B + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0005EDA3 + + +*** Searching Compression Signatures *** + + Signature: 0155D875C95B74D0F3C5835A62516F48 + Signature (Rotated): 01D38A25358EB7649A254E19F1D46600 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[Nokia ] [N73 ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 8100 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + SW :[IJG Library ] [085 ] + SW :[Picasa ] [085 (Normal) ] + SW :[ZoomBrowser EX ] [medium ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [085 ] + SW :[IrfanView ] [085 ] + SW :[idImager ] [085 ] + SW :[FastStone Image Viewer ] [085 ] + SW :[NeatImage ] [085 ] + SW :[Paint.NET ] [085 ] + SW :[Photomatix ] [085 ] + SW :[XnView ] [085 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue394-MultiHuffmanBaseline-Speakers.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue394-MultiHuffmanBaseline-Speakers.jpg.txt new file mode 100644 index 000000000..22e9a99dd --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue394-MultiHuffmanBaseline-Speakers.jpg.txt @@ -0,0 +1,438 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue394-MultiHuffmanBaseline-Speakers.jpg] + Filesize: [257401] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00000002 + Length = 576 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 560 bytes + Preferred CMM Type : 'ADBE' (0x41444245) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1999-06-03 00:00:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'none' (0x6E6F6E65) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'ADBE' (0x41444245) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00000244 + Length = 90 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x003D] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 3 + IPTC [002:055] Date Created = "20161215" + IPTC [002:060] Time Created = "043026-0600" + IPTC [002:221] ? = ??? + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000002A0 + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 9 11 12 16 + DQT, Row #1: 4 5 5 6 8 10 12 12 + DQT, Row #2: 4 5 5 6 10 12 12 12 + DQT, Row #3: 6 6 6 11 12 12 12 12 + DQT, Row #4: 9 8 10 12 12 12 12 12 + DQT, Row #5: 11 10 12 12 12 12 12 12 + DQT, Row #6: 12 12 12 12 12 12 12 12 + DQT, Row #7: 16 12 12 12 12 12 12 12 + Approx quality factor = 88.28 (scaling=23.43 variance=111.68) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 13 24 20 20 17 17 + DQT, Row #1: 7 12 16 14 14 12 12 12 + DQT, Row #2: 13 16 14 14 12 12 12 12 + DQT, Row #3: 24 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 90.19 (scaling=19.62 variance=201.04) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00000326 + Length = 4 + interval = 115 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x0000032C + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 49152 + APP14Flags1 = 0 + ColorTransform = 1 [YCbCr] + +*** Marker: SOF1 (Extended Sequential DCT, Huffman) (xFFC1) *** + OFFSET: 0x0000033C + Frame header length = 17 + Precision = 8 + Number of Lines = 496 + Samples per Line = 920 + Image Size = 920 x 496 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000034F + Huffman table length = 626 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 05 + Codes of length 03 bits (005 total): 02 03 04 06 07 + Codes of length 04 bits (001 total): 01 + Codes of length 05 bits (001 total): 08 + Codes of length 06 bits (001 total): 00 + Codes of length 07 bits (000 total): + Codes of length 08 bits (003 total): 09 0A 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 02 03 + Codes of length 03 bits (003 total): 01 04 05 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (000 total): + Codes of length 07 bits (002 total): 07 08 + Codes of length 08 bits (003 total): 09 0A 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 2 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (003 total): 00 03 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (000 total): + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (005 total): 07 08 09 0A 0B + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (002 total): 03 11 + Codes of length 04 bits (002 total): 04 12 + Codes of length 05 bits (001 total): 21 + Codes of length 06 bits (003 total): 00 05 13 + Codes of length 07 bits (002 total): 22 31 + Codes of length 08 bits (004 total): 06 14 32 41 + Codes of length 09 bits (002 total): 23 51 + Codes of length 10 bits (003 total): 15 42 61 + Codes of length 11 bits (005 total): 07 16 33 52 71 + Codes of length 12 bits (006 total): 24 43 62 81 91 F0 + Codes of length 13 bits (006 total): 25 34 72 A1 B1 C1 + Codes of length 14 bits (012 total): 08 18 26 46 53 63 82 92 93 D1 D2 F1 + Codes of length 15 bits (111 total): 09 0A 17 19 1A 27 28 29 2A 35 36 37 38 39 3A 44 + 45 47 48 49 4A 54 55 56 57 58 59 5A 64 65 66 67 + 68 69 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 + 88 89 8A 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 + A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 + C6 C7 C8 C9 CA D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 + E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 + Codes of length 16 bits (001 total): FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (003 total): 02 21 31 + Codes of length 05 bits (004 total): 41 51 61 F0 + Codes of length 06 bits (006 total): 03 12 13 71 81 91 + Codes of length 07 bits (006 total): 14 A1 B1 C1 D1 E1 + Codes of length 08 bits (002 total): 04 F1 + Codes of length 09 bits (002 total): 22 32 + Codes of length 10 bits (002 total): 52 62 + Codes of length 11 bits (004 total): 05 42 72 A2 + Codes of length 12 bits (125 total): 06 07 08 09 0A 15 16 17 18 19 1A 23 24 25 26 27 + 28 29 2A 33 34 35 36 37 38 39 3A 43 44 45 46 47 + 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 + 68 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 + 87 88 89 8A 92 93 94 95 96 97 98 99 9A A3 A4 A5 + A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 + C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA + E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 + Codes of length 13 bits (005 total): F6 F7 F8 F9 FA + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 162 + + ---- + Destination ID = 2 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 02 + Codes of length 05 bits (005 total): 12 21 31 41 51 + Codes of length 06 bits (004 total): 03 61 71 F0 + Codes of length 07 bits (004 total): 13 81 91 A1 + Codes of length 08 bits (006 total): 04 14 C1 D1 E1 F1 + Codes of length 09 bits (002 total): 22 B1 + Codes of length 10 bits (001 total): 42 + Codes of length 11 bits (004 total): 32 52 92 D2 + Codes of length 12 bits (131 total): 05 06 07 08 09 0A 15 16 17 18 19 1A 23 24 25 26 + 27 28 29 2A 33 34 35 36 37 38 39 3A 43 44 45 46 + 47 48 49 4A 53 54 55 56 57 58 59 5A 62 63 64 65 + 66 67 68 69 6A 72 73 74 75 76 77 78 79 7A 82 83 + 84 85 86 87 88 89 8A 93 94 95 96 97 98 99 9A A2 + A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 + BA C2 C3 C4 C5 C6 C7 C8 C9 CA D3 D4 D5 D6 D7 D8 + D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 + F7 F8 F9 + Codes of length 13 bits (001 total): FA + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000005C3 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=2(DC),2(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000005D1 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0003ED77.0 + + Compression stats: + Compression Ratio: 5.35:1 + Bits per pixel: 4.49:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 1109 ( 16%) + # codes of length 03 bits: 4934 ( 69%) + # codes of length 04 bits: 705 ( 10%) + # codes of length 05 bits: 22 ( 0%) + # codes of length 06 bits: 360 ( 5%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 2599 ( 36%) + # codes of length 03 bits: 2938 ( 41%) + # codes of length 04 bits: 1592 ( 22%) + # codes of length 05 bits: 1 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 2, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 3838 ( 54%) + # codes of length 03 bits: 3132 ( 44%) + # codes of length 04 bits: 156 ( 2%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 4 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 170962 ( 54%) + # codes of length 03 bits: 67518 ( 21%) + # codes of length 04 bits: 33616 ( 11%) + # codes of length 05 bits: 9306 ( 3%) + # codes of length 06 bits: 15458 ( 5%) + # codes of length 07 bits: 7462 ( 2%) + # codes of length 08 bits: 6393 ( 2%) + # codes of length 09 bits: 1640 ( 1%) + # codes of length 10 bits: 1220 ( 0%) + # codes of length 11 bits: 975 ( 0%) + # codes of length 12 bits: 581 ( 0%) + # codes of length 13 bits: 213 ( 0%) + # codes of length 14 bits: 134 ( 0%) + # codes of length 15 bits: 75 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 11236 ( 26%) + # codes of length 03 bits: 12123 ( 28%) + # codes of length 04 bits: 7424 ( 17%) + # codes of length 05 bits: 5864 ( 13%) + # codes of length 06 bits: 4420 ( 10%) + # codes of length 07 bits: 1997 ( 5%) + # codes of length 08 bits: 545 ( 1%) + # codes of length 09 bits: 244 ( 1%) + # codes of length 10 bits: 61 ( 0%) + # codes of length 11 bits: 41 ( 0%) + # codes of length 12 bits: 31 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 2, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 15434 ( 46%) + # codes of length 03 bits: 3540 ( 11%) + # codes of length 04 bits: 2524 ( 8%) + # codes of length 05 bits: 5638 ( 17%) + # codes of length 06 bits: 3224 ( 10%) + # codes of length 07 bits: 1556 ( 5%) + # codes of length 08 bits: 1170 ( 3%) + # codes of length 09 bits: 277 ( 1%) + # codes of length 10 bits: 14 ( 0%) + # codes of length 11 bits: 111 ( 0%) + # codes of length 12 bits: 34 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[ 97] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 762, 70, -70] RGB=[210,226,237] @ MCU[ 56, 4] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 61 + Next position in scan buffer: Offset 0x0003ED76.3 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0003ED77 + + +*** Searching Compression Signatures *** + + Signature: 01180AF3DE63318828A86409EF4013DD + Signature (Rotated): 01180AF3DE63318828A86409EF4013DD + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 08 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue517-No-EOI-Progressive.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue517-No-EOI-Progressive.jpg.txt new file mode 100644 index 000000000..47e77a4f4 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue517-No-EOI-Progressive.jpg.txt @@ -0,0 +1,406 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue517-No-EOI-Progressive.jpg] + Filesize: [2192567] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 500 x 500 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 248 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0007 + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 500/1 + [YResolution ] = 500/1 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop CS6 (Macintosh)" + [DateTime ] = "2018:01:06 12:59:23" + [ExifOffset ] = @ 0x00A6 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000C4 + Dir Length = 0x0004 + [DateTimeDigitized ] = "2018:01:06 04:40:19" + [ColorSpace ] = sRGB + [ExifImageWidth ] = 0x[000008CA] / 2250 + [ExifImageHeight ] = 0x[000008CA] / 2250 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x0000010E + Length = 4875 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x0000141B + Length = 100 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x002C] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 2 + IPTC [002:062] Digital Creation Date = "20180106" + IPTC [002:063] Digital Creation Time = "044019-0500" + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0x5D 51 F3 F0 D0 DE FC 5F 94 67 16 6F B1 02 A3 89 | ]Q....._.g.o.... + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x00001481 + Frame header length = 17 + Precision = 8 + Number of Lines = 2250 + Samples per Line = 2250 + Image Size = 2250 x 2250 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001494 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (005 total): 02 04 01 05 00 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000014B5 + Huffman table length = 195 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 02 00 03 + Codes of length 04 bits (003 total): 11 04 12 + Codes of length 05 bits (002 total): 21 05 + Codes of length 06 bits (004 total): 31 13 22 10 + Codes of length 07 bits (003 total): 06 41 51 + Codes of length 08 bits (004 total): 32 14 61 71 + Codes of length 09 bits (006 total): 23 07 81 20 91 42 + Codes of length 10 bits (004 total): 15 A1 52 33 + Codes of length 11 bits (007 total): B1 24 62 30 16 C1 72 + Codes of length 12 bits (006 total): D1 43 92 34 82 08 + Codes of length 13 bits (004 total): E1 53 40 25 + Codes of length 14 bits (008 total): 63 17 35 F0 93 73 A2 50 + Codes of length 15 bits (006 total): 44 B2 83 F1 26 54 + Codes of length 16 bits (115 total): 36 64 94 74 C2 60 D2 84 A3 18 70 E2 27 45 37 65 + B3 55 75 A4 95 C3 85 F2 D3 46 76 80 E3 47 56 66 + B4 09 0A 19 1A 28 29 2A 38 39 3A 48 49 4A 57 58 + 59 5A 67 68 69 6A 77 78 79 7A 86 87 88 89 8A 90 + 96 97 98 99 9A A0 A5 A6 A7 A8 A9 AA B0 B5 B6 B7 + B8 B9 BA C0 C4 C5 C6 C7 C8 C9 CA D0 D4 D5 D6 D7 + D8 D9 DA E0 E4 E5 E6 E7 E8 E9 EA F3 F4 F5 F6 F7 + F8 F9 FA + Total number of codes: 176 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000157A + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 01 02 00 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000159B + Huffman table length = 195 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 00 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (003 total): 10 12 21 + Codes of length 06 bits (003 total): 04 20 31 + Codes of length 07 bits (003 total): 41 13 05 + Codes of length 08 bits (002 total): 30 22 + Codes of length 09 bits (003 total): 32 51 14 + Codes of length 10 bits (005 total): 40 06 33 23 61 + Codes of length 11 bits (002 total): 42 15 + Codes of length 12 bits (005 total): 71 52 34 81 50 + Codes of length 13 bits (002 total): 24 91 + Codes of length 14 bits (004 total): A1 43 B1 16 + Codes of length 15 bits (004 total): 07 62 35 53 + Codes of length 16 bits (135 total): F0 D1 25 60 C1 44 E1 72 F1 17 82 63 36 70 26 45 + 54 92 27 A2 D2 08 09 0A 18 19 1A 28 29 2A 37 38 + 39 3A 46 47 48 49 4A 55 56 57 58 59 5A 64 65 66 + 67 68 69 6A 73 74 75 76 77 78 79 7A 80 83 84 85 + 86 87 88 89 8A 90 93 94 95 96 97 98 99 9A A0 A3 + A4 A5 A6 A7 A8 A9 AA B0 B2 B3 B4 B5 B6 B7 B8 B9 + BA C0 C2 C3 C4 C5 C6 C7 C8 C9 CA D0 D3 D4 D5 D6 + D7 D8 D9 DA E0 E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 176 + + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00001660 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 2 + DQT, Row #1: 1 1 1 1 1 1 1 2 + DQT, Row #2: 1 1 1 1 1 1 2 2 + DQT, Row #3: 1 1 1 1 1 2 2 3 + DQT, Row #4: 1 1 1 1 2 2 3 3 + DQT, Row #5: 1 1 1 2 2 3 3 3 + DQT, Row #6: 1 1 2 2 3 3 3 3 + DQT, Row #7: 2 2 2 3 3 3 3 3 + Approx quality factor = 98.11 (scaling=3.79 variance=4.10) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000016A5 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 2 3 3 3 3 + DQT, Row #1: 1 1 1 2 3 3 3 3 + DQT, Row #2: 1 1 2 3 3 3 3 3 + DQT, Row #3: 2 2 3 3 3 3 3 3 + DQT, Row #4: 3 3 3 3 3 3 3 3 + DQT, Row #5: 3 3 3 3 3 3 3 3 + DQT, Row #6: 3 3 3 3 3 3 3 3 + DQT, Row #7: 3 3 3 3 3 3 3 3 + Approx quality factor = 98.36 (scaling=3.29 variance=0.42) + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000016EA + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00023AAF + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0003E82C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0006B107 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0008AA32 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000BA727 + Huffman table length = 51 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 11 00 21 + Codes of length 04 bits (000 total): + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (002 total): 51 61 + Codes of length 07 bits (002 total): 71 81 + Codes of length 08 bits (002 total): 91 A1 + Codes of length 09 bits (002 total): B1 C1 + Codes of length 10 bits (003 total): F0 D1 10 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (002 total): 20 30 + Codes of length 16 bits (011 total): 40 50 60 70 80 90 A0 B0 C0 D0 E0 + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000BA75C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000FE1E7 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x001056B6 + Huffman table length = 51 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 21 31 10 + Codes of length 06 bits (000 total): + Codes of length 07 bits (001 total): 41 + Codes of length 08 bits (002 total): 51 61 + Codes of length 09 bits (005 total): 20 71 F0 91 81 + Codes of length 10 bits (005 total): A1 B1 D1 C1 E1 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (001 total): 30 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): 40 + Codes of length 15 bits (001 total): 50 + Codes of length 16 bits (009 total): 60 70 80 90 A0 B0 C0 D0 E0 + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x001056EB + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0014E060 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x001879C8 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x002174B5 + + +*** Searching Compression Signatures *** + + Signature: 01DADDC4908E9BA57CC067EEAD54E67D + Signature (Rotated): 01DADDC4908E9BA57CC067EEAD54E67D + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop CS6 (Macintosh)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 12 ] + + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue518-Bad-RST-Progressive.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue518-Bad-RST-Progressive.jpg.txt new file mode 100644 index 000000000..1b1027f27 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue518-Bad-RST-Progressive.jpg.txt @@ -0,0 +1,759 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue518-Bad-RST-Progressive.jpg] + Filesize: [3764739] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 14215 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0009 + [Make ] = "OLYMPUS CORPORATION" + [Model ] = "E-1" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 300/1 + [YResolution ] = 300/1 + [ResolutionUnit ] = Inch + [Software ] = "GIMP 2.8.10" + [DateTime ] = "2017:04:18 16:37:56" + [ExifOffset ] = @ 0x00BE + Offset to Next IFD = 0x000001DC + + EXIF IFD1 @ Absolute 0x000001FA + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x023A = @ 0x0258 + [JpegIFByteCount ] = 0x[00003545] / 13637 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000DC + Dir Length = 0x0011 + [ExposureTime ] = 1/4 s + [FNumber ] = F18.0 + [ExposureProgram ] = Manual + [ISOSpeedRatings ] = 100 + [ExifVersion ] = 02.21 + [DateTimeOriginal ] = "2005:07:20 20:08:42" + [ShutterSpeedValue ] = 2/1 + [ApertureValue ] = 833985/100000 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 2972656/1000000 + [MeteringMode ] = CenterWeightedAverage + [Flash ] = Flash did not fire + [FocalLength ] = 14 mm + [FlashPixVersion ] = 01.00 + [ColorSpace ] = Uncalibrated + [ExifImageWidth ] = 0x[00000BB8] / 3000 + [ExifImageHeight ] = 0x[00000BB8] / 3000 + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x0000379D + Comment length = 3 + Comment= + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x000037A2 + Length = 5091 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + | + | + | + | + | 3.1 + | _7201666.ORF + | Custom + | 7450 + | -7 + | -0.75 + | True + | 4 + | True + | 100 + | True + | 0 + | 0 + | 25 + | 0 + | 25 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | Medium Contrast + | ACR 2.4 + | True + | False + | True + | + | + | 0, 0 + | 32, 22 + | 64, 56 + | 128, 128 + | 192, 196 + | 255, 255 + | + | + | 3.1 + | _7201666.ORF + | Custom + | 7450 + | -7 + | -0.75 + | True + | 4 + | True + | 100 + | True + | 0 + | 0 + | 25 + | 0 + | 25 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | 0 + | Medium Contrast + | ACR 2.4 + | True + | False + | True + | + | + | 0, 0 + | 32, 22 + | 64, 56 + | 128, 128 + | 192, 196 + | 255, 255 + | + | + | + | + | 0 + | Adobe Photoshop CS6 (Macintosh) + | 0 + | 2014-06-09T12:43:59-04:00 + | 2005-07-21T18:39:06-06:00 + | 2014-06-09T12:43:59-04:00 + | + | + | xmp.iid:0A801174072068118083C9374AAA53C2 + | uuid:021303F2FBA711D98B5DCD54C315AFD0 + | + | xmp.iid:0A801174072068118083C9374AAA53C2 + | uuid:021303F2FBA711D98B5DCD54C315AFD0 + | + | + | + | + | + | + | + | + | image/jpeg + | + | + | 2005-07-20T20:08:42 + | A8D68AA81537D1C7170A5C69A46C6C94 + | 3 + | Adobe RGB (1998) + | + | + | 100 + | + | + | + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00004B87 + Length = 3160 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 3144 bytes + Preferred CMM Type : 'Lino' (0x4C696E6F) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1998-02-09 06:49:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Microsoft Corporation ('MSFT' (0x4D534654)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'IEC ' (0x49454320) + Device Model : 'sRGB' (0x73524742) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'HP ' (0x48502020) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000057E1 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 8 10 12 + DQT, Row #1: 2 2 3 4 5 12 12 11 + DQT, Row #2: 3 3 3 5 8 11 14 11 + DQT, Row #3: 3 3 4 6 10 17 16 12 + DQT, Row #4: 4 4 7 11 14 22 21 15 + DQT, Row #5: 5 7 11 13 16 21 23 18 + DQT, Row #6: 10 13 16 17 21 24 24 20 + DQT, Row #7: 14 18 19 20 22 20 21 20 + Approx quality factor = 90.06 (scaling=19.88 variance=1.14) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00005826 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 4 5 9 20 20 20 20 + DQT, Row #1: 4 4 5 13 20 20 20 20 + DQT, Row #2: 5 5 11 20 20 20 20 20 + DQT, Row #3: 9 13 20 20 20 20 20 20 + DQT, Row #4: 20 20 20 20 20 20 20 20 + DQT, Row #5: 20 20 20 20 20 20 20 20 + DQT, Row #6: 20 20 20 20 20 20 20 20 + DQT, Row #7: 20 20 20 20 20 20 20 20 + Approx quality factor = 89.93 (scaling=20.14 variance=0.34) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000586B + Frame header length = 17 + Precision = 8 + Number of Lines = 3000 + Samples per Line = 3000 + Image Size = 3000 x 3000 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000587E + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 04 05 + Codes of length 03 bits (002 total): 03 06 + Codes of length 04 bits (003 total): 00 01 02 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000589C + Huffman table length = 27 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 01 02 03 + Codes of length 03 bits (001 total): 00 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x000058B9 + Length = 4 + interval = 375 + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000058BF + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0004A3DA + Huffman table length = 55 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 02 03 + Codes of length 03 bits (003 total): 01 04 05 + Codes of length 04 bits (000 total): + Codes of length 05 bits (001 total): 00 + Codes of length 06 bits (004 total): 06 11 12 13 + Codes of length 07 bits (001 total): 14 + Codes of length 08 bits (003 total): 15 21 22 + Codes of length 09 bits (003 total): 10 23 31 + Codes of length 10 bits (004 total): 07 20 24 41 + Codes of length 11 bits (002 total): 16 32 + Codes of length 12 bits (002 total): 30 33 + Codes of length 13 bits (002 total): 25 40 + Codes of length 14 bits (002 total): 17 42 + Codes of length 15 bits (000 total): + Codes of length 16 bits (007 total): 34 50 60 43 26 35 44 + Total number of codes: 036 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0004A413 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000B0746 + Huffman table length = 62 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (004 total): 03 10 12 31 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (004 total): 13 20 22 51 + Codes of length 08 bits (002 total): 04 32 + Codes of length 09 bits (001 total): 61 + Codes of length 10 bits (003 total): 14 30 71 + Codes of length 11 bits (003 total): 23 40 42 + Codes of length 12 bits (003 total): 33 50 52 + Codes of length 13 bits (003 total): 05 81 91 + Codes of length 14 bits (003 total): 60 A1 B1 + Codes of length 15 bits (000 total): + Codes of length 16 bits (011 total): 15 24 62 43 53 C1 D1 72 F0 F1 E1 + Total number of codes: 043 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000B0786 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000E3DFE + Huffman table length = 69 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (002 total): 03 21 + Codes of length 05 bits (002 total): 12 31 + Codes of length 06 bits (000 total): + Codes of length 07 bits (006 total): 04 10 13 22 41 51 + Codes of length 08 bits (001 total): 32 + Codes of length 09 bits (002 total): 20 61 + Codes of length 10 bits (005 total): 05 14 23 42 71 + Codes of length 11 bits (002 total): 30 52 + Codes of length 12 bits (004 total): 33 40 81 91 + Codes of length 13 bits (005 total): 15 50 60 A1 B1 + Codes of length 14 bits (002 total): 62 F0 + Codes of length 15 bits (000 total): + Codes of length 16 bits (015 total): 24 43 70 C1 D1 06 53 72 E1 F1 25 34 44 63 A2 + Total number of codes: 050 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000E3E45 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0012926F + Huffman table length = 79 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 03 + Codes of length 04 bits (002 total): 11 12 + Codes of length 05 bits (005 total): 04 13 21 31 41 + Codes of length 06 bits (003 total): 22 32 51 + Codes of length 07 bits (003 total): 23 42 61 + Codes of length 08 bits (002 total): 05 14 + Codes of length 09 bits (003 total): 33 52 71 + Codes of length 10 bits (007 total): 10 24 43 62 81 91 A1 + Codes of length 11 bits (001 total): B1 + Codes of length 12 bits (006 total): 15 20 30 53 72 C1 + Codes of length 13 bits (004 total): 34 40 50 82 + Codes of length 14 bits (003 total): 60 63 92 + Codes of length 15 bits (002 total): A2 D1 + Codes of length 16 bits (015 total): 25 44 70 E1 F0 73 83 B2 F1 06 54 16 35 C2 74 + Total number of codes: 060 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x001292C0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x001CCECE + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (003 total): 41 51 61 + Codes of length 06 bits (000 total): + Codes of length 07 bits (002 total): 71 81 + Codes of length 08 bits (002 total): 91 A1 + Codes of length 09 bits (002 total): 10 B1 + Codes of length 10 bits (002 total): C1 D1 + Codes of length 11 bits (003 total): 20 E1 F0 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (001 total): 30 + Codes of length 14 bits (001 total): 40 + Codes of length 15 bits (001 total): 50 + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x001CCEFA + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0024E532 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0025B81A + Huffman table length = 42 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (000 total): + Codes of length 08 bits (002 total): 10 51 + Codes of length 09 bits (002 total): 61 71 + Codes of length 10 bits (001 total): 81 + Codes of length 11 bits (003 total): 20 91 A1 + Codes of length 12 bits (005 total): 30 B1 C1 D1 F0 + Codes of length 13 bits (001 total): E1 + Codes of length 14 bits (001 total): 40 + Codes of length 15 bits (001 total): F1 + Codes of length 16 bits (001 total): 50 + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0025B846 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0029943F + Huffman table length = 43 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (000 total): + Codes of length 07 bits (002 total): 41 51 + Codes of length 08 bits (002 total): 10 61 + Codes of length 09 bits (001 total): 71 + Codes of length 10 bits (003 total): 81 91 A1 + Codes of length 11 bits (005 total): 20 B1 C1 D1 F0 + Codes of length 12 bits (001 total): E1 + Codes of length 13 bits (001 total): 30 + Codes of length 14 bits (001 total): F1 + Codes of length 15 bits (000 total): + Codes of length 16 bits (003 total): 40 50 60 + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0029946C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x002E23F1 + Huffman table length = 41 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (003 total): 41 51 61 + Codes of length 06 bits (001 total): 71 + Codes of length 07 bits (000 total): + Codes of length 08 bits (002 total): 81 91 + Codes of length 09 bits (002 total): A1 B1 + Codes of length 10 bits (002 total): C1 D1 + Codes of length 11 bits (003 total): 10 E1 F0 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (001 total): 20 + Codes of length 14 bits (001 total): 30 + Codes of length 15 bits (001 total): 40 + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x002E241C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00397201 + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000258 + Length: 0x00003545 (13637) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: APP0 + Length = 16 + + * Embedded Thumb Marker: DQT + Length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + + * Embedded Thumb Marker: DQT + Length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 196 + Samples per Line = 196 + Image Size = 196 x 196 + + * Embedded Thumb Marker: DHT + Length = 31 + + * Embedded Thumb Marker: DHT + Length = 181 + + * Embedded Thumb Marker: DHT + Length = 31 + + * Embedded Thumb Marker: DHT + Length = 181 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 13024 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + +*** Searching Compression Signatures *** + + Signature: 013BA18D5561625796E986FDBC09F846 + Signature (Rotated): 01AC57E12793DFA7C46C704625C5AF0F + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: OK [OLYMPUS CORPORATION] [E-1] + EXIF Makernotes: NONE + EXIF Software: OK [GIMP 2.8.10] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[??? ] [Treo 680 ] [ ] No + CAM:[Canon ] [Canon PowerShot Pro1 ] [fine ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E3100 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 9530 ] [Superfine ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W1 ] [ ] No + CAM:[SONY ] [SONY ] [ ] No + SW :[ACDSee ] [ ] + SW :[FixFoto ] [fine ] + SW :[IJG Library ] [090 ] + SW :[ZoomBrowser EX ] [high ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [090 ] + SW :[IrfanView ] [090 ] + SW :[idImager ] [090 ] + SW :[FastStone Image Viewer ] [090 ] + SW :[NeatImage ] [090 ] + SW :[Paint.NET ] [090 ] + SW :[Photomatix ] [090 ] + SW :[XnView ] [090 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 2 - Image has high probability of being processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue520-InvalidCast.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue520-InvalidCast.jpg.txt new file mode 100644 index 000000000..aadf150e6 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue520-InvalidCast.jpg.txt @@ -0,0 +1,364 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue520-InvalidCast.jpg] + Filesize: [7751] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 499 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0011 + [DateTime ] = "2017:09:06 15:13:32" + [Model ] = "SAMSUNG-SM-J320AZ" + [Orientation ] = 1 = Row 0: top, Col 0: left + [WhiteBalance ] = Auto white balance + [DateTime ] = "2017:09:06 15:13:04" + [Make ] = "samsung" + [GPSOffset ] = @ 0x0124 + [ExifOffset ] = @ 0x01CD + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000001EB + Dir Length = 0x0002 + + EXIF GPSIFD @ Absolute 0x00000142 + Dir Length = 0x0008 + [GPSTimeStamp ] = 115:8:12.00 + [GPSLatitudeRef ] = "N" + [GPSLongitude ] = 115 deg 8' 12.000" + [GPSLongitudeRef ] = "W" + [GPSDateStamp ] = "2017:08:08" + [GPSLatitude ] = 36 deg 11' 18.000" + [GPSAltitudeRef ] = Below Sea Level + [GPSAltitude ] = 0.000 m + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000209 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 2 2 1 + DQT, Row #4: 1 1 1 1 1 2 2 2 + DQT, Row #5: 1 1 1 1 2 2 2 2 + DQT, Row #6: 1 1 2 2 2 2 2 2 + DQT, Row #7: 1 2 2 2 2 2 2 2 + Approx quality factor = 98.32 (scaling=3.35 variance=5.00) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000024E + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 1 2 2 2 2 + DQT, Row #1: 1 1 1 1 2 2 2 2 + DQT, Row #2: 1 1 1 2 2 2 2 2 + DQT, Row #3: 1 1 2 2 2 2 2 2 + DQT, Row #4: 2 2 2 2 2 2 2 2 + DQT, Row #5: 2 2 2 2 2 2 2 2 + DQT, Row #6: 2 2 2 2 2 2 2 2 + DQT, Row #7: 2 2 2 2 2 2 2 2 + Approx quality factor = 98.83 (scaling=2.34 variance=0.89) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00000293 + Frame header length = 17 + Precision = 8 + Number of Lines = 100 + Samples per Line = 100 + Image Size = 100 x 100 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000002A6 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 0A + Codes of length 03 bits (001 total): 09 + Codes of length 04 bits (004 total): 06 07 08 0B + Codes of length 05 bits (003 total): 03 04 05 + Codes of length 06 bits (001 total): 01 + Codes of length 07 bits (001 total): 02 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000002C7 + Huffman table length = 60 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (004 total): 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (003 total): 00 07 11 + Codes of length 06 bits (003 total): 08 12 13 + Codes of length 07 bits (002 total): 14 21 + Codes of length 08 bits (003 total): 09 22 31 + Codes of length 09 bits (005 total): 0A 15 41 51 61 + Codes of length 10 bits (006 total): 16 23 24 32 33 71 + Codes of length 11 bits (003 total): 17 52 62 + Codes of length 12 bits (009 total): 18 42 54 73 91 93 A3 B1 B2 + Codes of length 13 bits (001 total): D2 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 041 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000305 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 03 04 05 06 07 + Codes of length 04 bits (001 total): 08 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 01 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000323 + Huffman table length = 50 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 04 05 11 + Codes of length 05 bits (003 total): 00 12 21 + Codes of length 06 bits (003 total): 06 22 31 + Codes of length 07 bits (003 total): 13 41 51 + Codes of length 08 bits (002 total): 61 71 + Codes of length 09 bits (004 total): 07 14 32 91 + Codes of length 10 bits (005 total): 15 23 42 81 D1 + Codes of length 11 bits (005 total): 16 62 92 A1 B1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 031 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000357 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00000365 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00001E45.0 + + Compression stats: + Compression Ratio: 4.36:1 + Bits per pixel: 5.50:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 97 ( 49%) + # codes of length 03 bits: 25 ( 13%) + # codes of length 04 bits: 51 ( 26%) + # codes of length 05 bits: 18 ( 9%) + # codes of length 06 bits: 3 ( 2%) + # codes of length 07 bits: 2 ( 1%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 26 ( 27%) + # codes of length 03 bits: 62 ( 63%) + # codes of length 04 bits: 5 ( 5%) + # codes of length 05 bits: 3 ( 3%) + # codes of length 06 bits: 2 ( 2%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 971 ( 16%) + # codes of length 03 bits: 3435 ( 57%) + # codes of length 04 bits: 456 ( 8%) + # codes of length 05 bits: 579 ( 10%) + # codes of length 06 bits: 285 ( 5%) + # codes of length 07 bits: 96 ( 2%) + # codes of length 08 bits: 74 ( 1%) + # codes of length 09 bits: 59 ( 1%) + # codes of length 10 bits: 30 ( 0%) + # codes of length 11 bits: 7 ( 0%) + # codes of length 12 bits: 9 ( 0%) + # codes of length 13 bits: 1 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 1143 ( 50%) + # codes of length 03 bits: 254 ( 11%) + # codes of length 04 bits: 445 ( 19%) + # codes of length 05 bits: 228 ( 10%) + # codes of length 06 bits: 111 ( 5%) + # codes of length 07 bits: 48 ( 2%) + # codes of length 08 bits: 20 ( 1%) + # codes of length 09 bits: 22 ( 1%) + # codes of length 10 bits: 13 ( 1%) + # codes of length 11 bits: 5 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[193] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1001, -7, 97] RGB=[255,244,251] @ MCU[ 5, 3] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00001E44.1 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00001E45 + + +*** Searching Compression Signatures *** + + Signature: 01C7F83908166C226C06A44017421732 + Signature (Rotated): 01D3EFDD3855C42AE3E0E6289F1A6726 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: OK [samsung] [SAMSUNG-SM-J320AZ] + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Canon ] [Canon EOS-1Ds Mark II ] [fine ] No + CAM:[CASIO COMPUTER CO.,LTD. ] [EX-Z1000 ] [ ] Yes + CAM:[NIKON ] [NIKON D2X ] [FINE ] No + CAM:[NIKON ] [NIKON D3 ] [FINE ] No + CAM:[SIGMA ] [SIGMA SD10 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD10 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD14 ] [Qual:12 ] No + CAM:[SIGMA ] [SIGMA SD14 ] [Qual:12 ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-R1 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[Digital Photo Professiona] [09 ] + SW :[IJG Library ] [099 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [099 ] + SW :[IrfanView ] [099 ] + SW :[idImager ] [099 ] + SW :[FastStone Image Viewer ] [099 ] + SW :[NeatImage ] [099 ] + SW :[Paint.NET ] [099 ] + SW :[Photomatix ] [099 ] + SW :[XnView ] [099 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 2 - Image has high probability of being processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue624-DhtHasWrongLength-Progressive-N.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue624-DhtHasWrongLength-Progressive-N.jpg.txt new file mode 100644 index 000000000..0ee1736d3 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue624-DhtHasWrongLength-Progressive-N.jpg.txt @@ -0,0 +1,284 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue624-DhtHasWrongLength-Progressive-N.jpg] + Filesize: [30441] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 6 6 7 10 15 22 34 + DQT, Row #1: 6 7 8 11 14 16 21 30 + DQT, Row #2: 6 8 10 12 17 25 36 54 + DQT, Row #3: 7 11 12 16 21 30 42 62 + DQT, Row #4: 10 14 17 21 28 38 52 76 + DQT, Row #5: 15 16 25 30 38 50 68 95 + DQT, Row #6: 22 21 36 42 52 68 90 124 + DQT, Row #7: 34 30 54 62 76 95 124 167 + Approx quality factor = 71.19 (scaling=57.62 variance=593.35) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 6 6 6 7 10 15 22 34 + DQT, Row #1: 6 7 8 11 14 16 21 30 + DQT, Row #2: 6 8 10 12 17 25 36 54 + DQT, Row #3: 7 11 12 16 21 30 42 62 + DQT, Row #4: 10 14 17 21 28 38 52 76 + DQT, Row #5: 15 16 25 30 38 50 68 95 + DQT, Row #6: 22 21 36 42 52 68 90 124 + DQT, Row #7: 34 30 54 62 76 95 124 167 + Approx quality factor = 80.24 (scaling=39.51 variance=961.47) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009A + Frame header length = 17 + Precision = 8 + Number of Lines = 1080 + Samples per Line = 1080 + Image Size = 1080 x 1080 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000AD + Huffman table length = 51 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 05 06 + Codes of length 04 bits (003 total): 01 03 04 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 02 04 06 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000E2 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000151B + Huffman table length = 2 + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000151F + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000022BA + Huffman table length = 2 + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000022BE + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000309F + Huffman table length = 53 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (003 total): 00 04 20 + Codes of length 05 bits (007 total): 11 31 33 34 50 71 72 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (005 total): 12 21 52 60 61 + Codes of length 08 bits (007 total): 10 13 22 32 41 51 A1 + Codes of length 09 bits (003 total): 23 53 62 + Codes of length 10 bits (005 total): 70 80 81 A0 F1 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 034 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000030D6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003353 + Huffman table length = 54 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 04 + Codes of length 04 bits (002 total): 03 05 + Codes of length 05 bits (008 total): 00 06 20 32 50 63 71 B1 + Codes of length 06 bits (005 total): 11 25 31 35 73 + Codes of length 07 bits (002 total): 12 21 + Codes of length 08 bits (004 total): 10 22 51 60 + Codes of length 09 bits (005 total): 13 23 41 42 52 + Codes of length 10 bits (005 total): 14 33 70 80 A1 + Codes of length 11 bits (001 total): A0 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 035 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000338B + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000378D + Huffman table length = 83 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 02 03 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (003 total): 06 07 11 + Codes of length 06 bits (005 total): 00 21 30 31 B2 + Codes of length 07 bits (009 total): 12 13 32 40 41 50 51 72 74 + Codes of length 08 bits (011 total): 14 16 22 33 35 42 52 61 71 B1 B3 + Codes of length 09 bits (009 total): 15 20 23 24 60 62 81 91 C2 + Codes of length 10 bits (006 total): 10 25 36 43 75 92 + Codes of length 11 bits (004 total): 82 93 A1 A2 + Codes of length 12 bits (006 total): 34 63 64 73 C3 D2 + Codes of length 13 bits (001 total): A3 + Codes of length 14 bits (005 total): 26 45 53 65 83 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 064 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000037E2 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000076E7 + + +*** Searching Compression Signatures *** + + Signature: 014D6128740A2927C9914C433E852F5A + Signature (Rotated): 014D6128740A2927C9914C433E852F5A + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue694-Decode-Exif-OutOfRange.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue694-Decode-Exif-OutOfRange.jpg.txt new file mode 100644 index 000000000..9feef52cc --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue694-Decode-Exif-OutOfRange.jpg.txt @@ -0,0 +1,368 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue694-Decode-Exif-OutOfRange.jpg] + Filesize: [226421] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 194 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0007 + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 96/1 + [YResolution ] = 96/1 + [ResolutionUnit ] = Inch + [Software ] = "PhotoFiltre 7" + [DateTime ] = "2017:08:30 22:45:26" + [ExifOffset ] = @ 0x0094 + Offset to Next IFD = 0xFC5019BC + + EXIF IFD1 @ Absolute 0xFC5019C8 + Dir Length = 0x0000 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000A0 + Dir Length = 0x0003 + [ExifVersion ] = 02.10 + [ExifImageWidth ] = 1400 + [ExifImageHeight ] = 1400 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000000C6 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=2.99 variance=6.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000010B + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=1.54 variance=1.58) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00000150 + Frame header length = 17 + Precision = 8 + Number of Lines = 1400 + Samples per Line = 1400 + Image Size = 1400 x 1400 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000163 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000184 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000023B + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000025C + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000313 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00000321 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00037473.0 + + Compression stats: + Compression Ratio: 26.06:1 + Bits per pixel: 0.92:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 25384 ( 82%) + # codes of length 03 bits: 1101 ( 4%) + # codes of length 04 bits: 566 ( 2%) + # codes of length 05 bits: 758 ( 2%) + # codes of length 06 bits: 429 ( 1%) + # codes of length 07 bits: 616 ( 2%) + # codes of length 08 bits: 933 ( 3%) + # codes of length 09 bits: 1189 ( 4%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 13762 ( 89%) + # codes of length 03 bits: 146 ( 1%) + # codes of length 04 bits: 264 ( 2%) + # codes of length 05 bits: 354 ( 2%) + # codes of length 06 bits: 509 ( 3%) + # codes of length 07 bits: 335 ( 2%) + # codes of length 08 bits: 116 ( 1%) + # codes of length 09 bits: 2 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 48125 ( 26%) + # codes of length 03 bits: 20074 ( 11%) + # codes of length 04 bits: 54692 ( 30%) + # codes of length 05 bits: 21145 ( 12%) + # codes of length 06 bits: 3017 ( 2%) + # codes of length 07 bits: 14358 ( 8%) + # codes of length 08 bits: 8803 ( 5%) + # codes of length 09 bits: 2231 ( 1%) + # codes of length 10 bits: 5065 ( 3%) + # codes of length 11 bits: 1096 ( 1%) + # codes of length 12 bits: 224 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 6 ( 0%) + # codes of length 16 bits: 4924 ( 3%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 25772 ( 49%) + # codes of length 03 bits: 5924 ( 11%) + # codes of length 04 bits: 7056 ( 13%) + # codes of length 05 bits: 6378 ( 12%) + # codes of length 06 bits: 2891 ( 5%) + # codes of length 07 bits: 1200 ( 2%) + # codes of length 08 bits: 1082 ( 2%) + # codes of length 09 bits: 1030 ( 2%) + # codes of length 10 bits: 559 ( 1%) + # codes of length 11 bits: 299 ( 1%) + # codes of length 12 bits: 38 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 73 ( 0%) + # codes of length 15 bits: 67 ( 0%) + # codes of length 16 bits: 260 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[ 57] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1016, 0, 0] RGB=[255,255,255] @ MCU[ 40, 2] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x00037472.4 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00037473 + + +*** Searching Compression Signatures *** + + Signature: 01BBB1709AC9C1F89220D955A31A8F34 + Signature (Rotated): 01BBB1709AC9C1F89220D955A31A8F34 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: OK [PhotoFiltre 7] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[CASIO COMPUTER CO.,LTD ] [EX-Z750 ] [ ] Yes + CAM:[CASIO COMPUTER CO.,LTD. ] [EX-Z1000 ] [ ] Yes + CAM:[PENTAX ] [PENTAX Optio S5i ] [ ] Yes + CAM:[SIGMA ] [SIGMA SD9 ] [ ] Yes + SW :[ACDSee ] [100 ] + SW :[Apple ImageIO.framework ] [100 (Best) ] + SW :[Digital Photo Professiona] [10 ] + SW :[IJG Library ] [100 ] + SW :[MS Office Pic Mgr ] [ ] + SW :[Nikon Scan ] [Excellent Qualit] + SW :[Picasa ] [100 (Maximum) ] + SW :[ZoomBrowser EX ] [highest ] + SW :[EOS Viewer Utility ] [ ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [100 ] + SW :[IrfanView ] [100 ] + SW :[idImager ] [100 ] + SW :[FastStone Image Viewer ] [100 ] + SW :[NeatImage ] [100 ] + SW :[Paint.NET ] [100 ] + SW :[Photomatix ] [100 ] + SW :[XnView ] [100 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue695-Invalid-EOI.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue695-Invalid-EOI.jpg.txt new file mode 100644 index 000000000..8911896af --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue695-Invalid-EOI.jpg.txt @@ -0,0 +1,39 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue695-Invalid-EOI.jpg] + Filesize: [4805575] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 64 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0001 + [ExifOffset ] = @ 0x001A + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x00000038 + Dir Length = 0x0002 + [ExifImageWidth ] = 0x[000003E8] / 1000 + [ExifImageHeight ] = 0x[000003E8] / 1000 + +ERROR: Expected marker 0xFF, got 0x49 @ offset 0x00000056. Consider using [Tools->Img Search Fwd/Rev]. diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue696-Resize-Exif-OutOfRange.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue696-Resize-Exif-OutOfRange.jpg.txt new file mode 100644 index 000000000..566291b47 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue696-Resize-Exif-OutOfRange.jpg.txt @@ -0,0 +1,377 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue696-Resize-Exif-OutOfRange.jpg] + Filesize: [3196058] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 201 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x0007 + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 96/1 + [YResolution ] = 96/1 + [ResolutionUnit ] = Inch + [Software ] = "PhotoFiltre Studio X" + [DateTime ] = "2017:09:12 23:47:30" + [ExifOffset ] = @ 0x009B + Offset to Next IFD = 0xFFFFFFFF + + EXIF IFD1 @ Absolute 0x0000001D + Dir Length = 0x4900 + Excessive # components (117440512). Limiting to first 4000. + Offset to Next IFD = 0x03011200 + + EXIF SubIFD @ Absolute 0x000000B9 + Dir Length = 0x0003 + [ExifVersion ] = 02.10 + [ExifImageWidth ] = 3000 + [ExifImageHeight ] = 3000 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000000DF + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=2.99 variance=6.13) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000124 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 1 1 1 1 1 + DQT, Row #1: 1 1 1 1 1 1 1 1 + DQT, Row #2: 1 1 1 1 1 1 1 1 + DQT, Row #3: 1 1 1 1 1 1 1 1 + DQT, Row #4: 1 1 1 1 1 1 1 1 + DQT, Row #5: 1 1 1 1 1 1 1 1 + DQT, Row #6: 1 1 1 1 1 1 1 1 + DQT, Row #7: 1 1 1 1 1 1 1 1 + Approx quality factor = 100.00 (scaling=1.54 variance=1.58) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00000169 + Frame header length = 17 + Precision = 8 + Number of Lines = 3000 + Samples per Line = 3000 + Image Size = 3000 x 3000 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000017C + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000019D + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000254 + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000275 + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000032C + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x0000033A + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0030C498.0 + + Compression stats: + Compression Ratio: 8.45:1 + Bits per pixel: 2.84:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 35306 ( 25%) + # codes of length 03 bits: 79378 ( 56%) + # codes of length 04 bits: 10642 ( 8%) + # codes of length 05 bits: 5371 ( 4%) + # codes of length 06 bits: 3913 ( 3%) + # codes of length 07 bits: 2829 ( 2%) + # codes of length 08 bits: 2486 ( 2%) + # codes of length 09 bits: 1451 ( 1%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 45165 ( 64%) + # codes of length 03 bits: 10069 ( 14%) + # codes of length 04 bits: 6960 ( 10%) + # codes of length 05 bits: 3541 ( 5%) + # codes of length 06 bits: 2100 ( 3%) + # codes of length 07 bits: 1345 ( 2%) + # codes of length 08 bits: 1100 ( 2%) + # codes of length 09 bits: 324 ( 0%) + # codes of length 10 bits: 84 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 1981662 ( 53%) + # codes of length 03 bits: 213036 ( 6%) + # codes of length 04 bits: 749857 ( 20%) + # codes of length 05 bits: 410362 ( 11%) + # codes of length 06 bits: 173055 ( 5%) + # codes of length 07 bits: 94282 ( 3%) + # codes of length 08 bits: 61648 ( 2%) + # codes of length 09 bits: 36705 ( 1%) + # codes of length 10 bits: 19723 ( 1%) + # codes of length 11 bits: 10118 ( 0%) + # codes of length 12 bits: 2157 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 211 ( 0%) + # codes of length 16 bits: 9772 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 425513 ( 38%) + # codes of length 03 bits: 127308 ( 11%) + # codes of length 04 bits: 204956 ( 18%) + # codes of length 05 bits: 171523 ( 15%) + # codes of length 06 bits: 89715 ( 8%) + # codes of length 07 bits: 30159 ( 3%) + # codes of length 08 bits: 25054 ( 2%) + # codes of length 09 bits: 22104 ( 2%) + # codes of length 10 bits: 10243 ( 1%) + # codes of length 11 bits: 4250 ( 0%) + # codes of length 12 bits: 210 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 1829 ( 0%) + # codes of length 15 bits: 1498 ( 0%) + # codes of length 16 bits: 2262 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[127] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 992, -112, 17] RGB=[254,255,227] @ MCU[ 35, 79] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0030C497.3 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0030C498 + + +*** Searching Compression Signatures *** + + Signature: 01BBB1709AC9C1F89220D955A31A8F34 + Signature (Rotated): 01BBB1709AC9C1F89220D955A31A8F34 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: OK [PhotoFiltre Studio X] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[CASIO COMPUTER CO.,LTD ] [EX-Z750 ] [ ] Yes + CAM:[CASIO COMPUTER CO.,LTD. ] [EX-Z1000 ] [ ] Yes + CAM:[PENTAX ] [PENTAX Optio S5i ] [ ] Yes + CAM:[SIGMA ] [SIGMA SD9 ] [ ] Yes + SW :[ACDSee ] [100 ] + SW :[Apple ImageIO.framework ] [100 (Best) ] + SW :[Digital Photo Professiona] [10 ] + SW :[IJG Library ] [100 ] + SW :[MS Office Pic Mgr ] [ ] + SW :[Nikon Scan ] [Excellent Qualit] + SW :[Picasa ] [100 (Maximum) ] + SW :[ZoomBrowser EX ] [highest ] + SW :[EOS Viewer Utility ] [ ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [100 ] + SW :[IrfanView ] [100 ] + SW :[idImager ] [100 ] + SW :[FastStone Image Viewer ] [100 ] + SW :[NeatImage ] [100 ] + SW :[Paint.NET ] [100 ] + SW :[Photomatix ] [100 ] + SW :[XnView ] [100 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue721-InvalidAPP0.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue721-InvalidAPP0.jpg.txt new file mode 100644 index 000000000..dc283bfcf --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue721-InvalidAPP0.jpg.txt @@ -0,0 +1,446 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue721-InvalidAPP0.jpg] + Filesize: [1225163] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 806 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0007 + [Make ] = "NIKON CORPORATION" + [Model ] = "NIKON D300S" + [Software ] = "Adobe Bridge CS6 (Windows)" + [DateTime ] = "2017:06:07 16:49:51" + [Artist ] = ""Evgeniy Ivahiv Mr.Ivas"" + [Copyright ] = "Evgeniy Ivahiv Erich Krause" + [ExifOffset ] = @ 0x00EC + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000F8 + Dir Length = 0x0022 + [ExposureTime ] = 1/160 s + [FNumber ] = F10.0 + [ExposureProgram ] = Manual + [ISOSpeedRatings ] = 200 + [ExifVersion ] = 02.21 + [DateTimeOriginal ] = "2017:06:06 11:29:53" + [ShutterSpeedValue ] = 7321928/1000000 + [ApertureValue ] = 6643856/1000000 + [ExposureBiasValue ] = -3.00 eV + [MaxApertureValue ] = 50/10 + [MeteringMode ] = CenterWeightedAverage + [LightSource ] = unknown + [Flash ] = Flash did not fire + [FocalLength ] = 48 mm + [SubSecTimeOriginal ] = "24" + [ColorSpace ] = Uncalibrated + [ExifImageWidth ] = 2304 + [ExifImageHeight ] = 2998 + [SensingMethod ] = One-chip color area sensor + [FileSource ] = DSC + [SceneType ] = A directly photographed image + [ExposureMode ] = Manual exposure + [WhiteBalance ] = Manual white balance + [DigitalZoomRatio ] = 1/1 + [FocalLengthIn35mmFilm ] = 72 + [SceneCaptureType ] = Standard + [GainControl ] = 0 + [Contrast ] = 0 + [Saturation ] = 0 + [Sharpness ] = 2 + [SubjectDistanceRange ] = 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x0000032A + Length = 4442 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00001486 + Length = 160 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x0068] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 4 + IPTC [002:055] Date Created = "20170606" + IPTC [002:060] Time Created = "112953" + IPTC [002:080] By-line = "Evgeniy Ivahiv Mr.Ivas" + IPTC [002:116] Copyright Notice = "Evgeniy Ivahiv Erich Krause" + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0x59 13 63 D2 BD 08 14 B4 2B E3 4F 37 D7 52 D2 6F | Y.c.....+.O7.R.o + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00001528 + Length = 3160 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 3144 bytes + Preferred CMM Type : 'Lino' (0x4C696E6F) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1998-02-09 06:49:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Microsoft Corporation ('MSFT' (0x4D534654)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'IEC ' (0x49454320) + Device Model : 'sRGB' (0x73524742) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'HP ' (0x48502020) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00002182 + Length = 12 + Identifier = [Adobe_CM] + Not known APP0 type. Skipping remainder. + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00002190 + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 7 11 14 17 22 17 + DQT, Row #1: 4 5 6 10 14 19 12 12 + DQT, Row #2: 7 6 8 14 19 12 12 12 + DQT, Row #3: 11 10 14 19 12 12 12 12 + DQT, Row #4: 14 14 19 12 12 12 12 12 + DQT, Row #5: 17 19 12 12 12 12 12 12 + DQT, Row #6: 22 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 83.88 (scaling=32.24 variance=430.71) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 9 19 34 20 20 17 17 + DQT, Row #1: 9 12 19 14 14 12 12 12 + DQT, Row #2: 19 19 14 14 12 12 12 12 + DQT, Row #3: 34 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 89.11 (scaling=21.78 variance=377.49) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00002216 + Length = 4 + interval = 288 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x0000221C + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 49152 + APP14Flags1 = 0 + ColorTransform = 1 [YCbCr] + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x0000222C + Frame header length = 17 + Precision = 8 + Number of Lines = 2998 + Samples per Line = 2304 + Image Size = 2304 x 2998 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000223F + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (004 total): 03 04 05 06 + Codes of length 04 bits (003 total): 02 07 08 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (001 total): 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (001 total): 06 + Codes of length 08 bits (000 total): + Codes of length 09 bits (002 total): 07 08 + Codes of length 10 bits (003 total): 09 0A 0B + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 02 03 11 + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (004 total): 04 12 31 41 + Codes of length 06 bits (002 total): 51 61 + Codes of length 07 bits (008 total): 05 13 22 71 81 91 A1 F0 + Codes of length 08 bits (004 total): 06 14 B1 C1 + Codes of length 09 bits (005 total): 23 32 D1 E1 F1 + Codes of length 10 bits (002 total): 07 42 + Codes of length 11 bits (003 total): 15 24 52 + Codes of length 12 bits (002 total): 33 62 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 16 + Codes of length 16 bits (125 total): 34 43 72 82 92 A2 08 17 53 B2 C2 25 D2 E2 44 83 + 84 F2 09 0A 18 19 1A 26 27 28 29 2A 35 36 37 38 + 39 3A 45 46 47 48 49 4A 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 85 + 86 87 88 89 8A 93 94 95 96 97 98 B3 C3 D3 99 9A + A3 A4 A5 A6 A7 A8 A9 AA B4 B5 B6 B7 B8 B9 BA C4 + C5 C6 C7 C8 C9 CA D4 D5 D6 D7 D8 D9 DA E3 E4 E5 + E6 E7 E8 E9 EA F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 02 11 + Codes of length 05 bits (001 total): 03 + Codes of length 06 bits (003 total): 12 21 31 + Codes of length 07 bits (001 total): 41 + Codes of length 08 bits (005 total): 04 13 51 61 71 + Codes of length 09 bits (002 total): 81 F0 + Codes of length 10 bits (006 total): 22 91 A1 B1 C1 D1 + Codes of length 11 bits (003 total): 14 32 E1 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (127 total): 05 06 07 08 09 0A 15 16 17 18 19 1A 23 24 25 26 + 27 28 29 2A 33 34 35 36 37 38 39 3A 42 43 44 45 + 46 47 48 49 4A 52 53 54 55 56 57 58 59 5A 62 63 + 64 65 66 67 68 69 6A 72 73 74 75 76 77 78 79 7A + 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 + 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 + B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 + D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA + Codes of length 15 bits (009 total): F2 F3 F4 F5 F6 F7 F8 F9 FA + Codes of length 16 bits (000 total): + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000023E3 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000023F1 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + +*** ERROR: Overread scan segment (after bitstring)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.6 +*** ERROR: Bad scan data in MCU(272,16): Lum CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(2176,128) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(272,16): Chr(Cb) CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(2176,128) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(272,16): Chr(Cr) CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(2176,128) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(0,17): Lum CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(0,136) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(0,17): Chr(Cb) CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(0,136) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(0,17): Chr(Cr) CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(0,136) +*** ERROR: Overread scan segment (before nCode)! @ Offset: 0x00003EA5.1 +*** ERROR: Bad huffman code @ 0x00003EA5.1 +*** ERROR: Bad scan data in MCU(0,18): Lum CSS(0,0) @ Offset 0x00003EA5.1 + MCU located at pixel=(0,144) + Only reported first 20 instances of this message... + + Compression stats: + Compression Ratio: 3031.33:1 + Bits per pixel: 0.01:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 4841 ( 99%) + # codes of length 03 bits: 33 ( 1%) + # codes of length 04 bits: 6 ( 0%) + # codes of length 05 bits: 1 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 9732 (100%) + # codes of length 02 bits: 23 ( 0%) + # codes of length 03 bits: 5 ( 0%) + # codes of length 04 bits: 0 ( 0%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 274 ( 5%) + # codes of length 03 bits: 297 ( 5%) + # codes of length 04 bits: 4903 ( 85%) + # codes of length 05 bits: 88 ( 2%) + # codes of length 06 bits: 26 ( 0%) + # codes of length 07 bits: 98 ( 2%) + # codes of length 08 bits: 25 ( 0%) + # codes of length 09 bits: 4 ( 0%) + # codes of length 10 bits: 14 ( 0%) + # codes of length 11 bits: 1 ( 0%) + # codes of length 12 bits: 2 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 17 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 9760 (100%) + # codes of length 02 bits: 5 ( 0%) + # codes of length 03 bits: 0 ( 0%) + # codes of length 04 bits: 14 ( 0%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 2 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[128] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1014, 0, 0] RGB=[254,254,254] @ MCU[ 0, 0] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 17 + Next position in scan buffer: Offset 0x00003EA5.1 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0012B1C9 + + +*** Searching Compression Signatures *** + + Signature: 01A20F69263117021CD16AEF44D6E650 + Signature (Rotated): 01A20F69263117021CD16AEF44D6E650 + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: OK [NIKON] [NIKON D300S] + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Bridge CS6 (Windows)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[Adobe Photoshop ] [Save As 08 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 2 - Image has high probability of being processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-A.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-A.jpg.txt new file mode 100644 index 000000000..92adfb315 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-A.jpg.txt @@ -0,0 +1,519 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue723-Ordered-Interleaved-Progressive-A.jpg] + Filesize: [42798] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 2 1 1 2 2 4 5 6 + DQT, Row #1: 1 1 1 2 3 6 6 6 + DQT, Row #2: 1 1 2 2 4 6 7 6 + DQT, Row #3: 1 2 2 3 5 9 8 6 + DQT, Row #4: 2 2 4 6 7 11 10 8 + DQT, Row #5: 2 4 6 6 8 10 11 9 + DQT, Row #6: 5 6 8 9 10 12 12 10 + DQT, Row #7: 7 9 10 10 11 10 10 10 + Approx quality factor = 95.04 (scaling=9.93 variance=1.25) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 2 2 2 5 10 10 10 10 + DQT, Row #1: 2 2 3 7 10 10 10 10 + DQT, Row #2: 2 3 6 10 10 10 10 10 + DQT, Row #3: 5 7 10 10 10 10 10 10 + DQT, Row #4: 10 10 10 10 10 10 10 10 + DQT, Row #5: 10 10 10 10 10 10 10 10 + DQT, Row #6: 10 10 10 10 10 10 10 10 + DQT, Row #7: 10 10 10 10 10 10 10 10 + Approx quality factor = 94.91 (scaling=10.18 variance=0.26) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 600 + Samples per Line = 600 + Image Size = 600 x 600 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 29 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 01 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (005 total): 04 05 06 07 08 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000D0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000A58 + Huffman table length = 27 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 01 02 + Codes of length 04 bits (003 total): 03 04 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000A75 + Scan header length = 10 + Number of img components = 2 + Component[1]: selector=0x02, table=1(DC),0(AC) + Component[2]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000E55 + Huffman table length = 37 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (005 total): 02 04 05 11 12 + Codes of length 04 bits (004 total): 00 01 03 06 + Codes of length 05 bits (001 total): 30 + Codes of length 06 bits (005 total): 10 13 14 15 16 + Codes of length 07 bits (001 total): 40 + Codes of length 08 bits (001 total): 20 + Codes of length 09 bits (001 total): A0 + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 018 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000E7C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 2 + Successive approximation = 0x03 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000015BD + Huffman table length = 82 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (004 total): 00 04 05 11 + Codes of length 05 bits (002 total): 12 21 + Codes of length 06 bits (002 total): 13 31 + Codes of length 07 bits (011 total): 06 10 14 22 30 32 40 41 51 61 92 + Codes of length 08 bits (012 total): 15 23 25 52 53 54 71 73 91 A1 B1 C1 + Codes of length 09 bits (007 total): 20 24 33 42 72 81 93 + Codes of length 10 bits (006 total): 43 44 55 62 63 A2 + Codes of length 11 bits (003 total): 82 83 D1 + Codes of length 12 bits (006 total): 16 26 34 50 A0 B2 + Codes of length 13 bits (007 total): 35 45 64 84 A3 C2 E1 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 063 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001611 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 3 .. 63 + Successive approximation = 0x03 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002E3F + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 11 + Codes of length 03 bits (001 total): 00 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (004 total): 10 41 51 61 + Codes of length 06 bits (005 total): 20 71 81 91 F0 + Codes of length 07 bits (005 total): 30 A1 B1 C1 D1 + Codes of length 08 bits (001 total): F1 + Codes of length 09 bits (001 total): E1 + Codes of length 10 bits (001 total): 40 + Codes of length 11 bits (001 total): A0 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002E6B + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x32 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003F38 + Huffman table length = 43 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (001 total): 61 + Codes of length 07 bits (004 total): 10 71 81 91 + Codes of length 08 bits (001 total): A1 + Codes of length 09 bits (005 total): 30 B1 C1 D1 F0 + Codes of length 10 bits (001 total): E1 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (003 total): 20 40 A0 + Codes of length 14 bits (001 total): 50 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003F65 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00005B9B + Huffman table length = 58 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 03 + Codes of length 04 bits (003 total): 04 11 12 + Codes of length 05 bits (001 total): 21 + Codes of length 06 bits (005 total): 05 13 14 31 51 + Codes of length 07 bits (005 total): 10 15 20 30 41 + Codes of length 08 bits (005 total): 22 23 32 33 71 + Codes of length 09 bits (005 total): 24 34 61 81 F0 + Codes of length 10 bits (008 total): 80 91 A1 B1 C1 D1 E1 F1 + Codes of length 11 bits (003 total): 42 52 62 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 039 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00005BD7 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00006270 + Huffman table length = 57 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (004 total): 00 02 03 11 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (002 total): 05 30 + Codes of length 07 bits (004 total): 10 13 14 20 + Codes of length 08 bits (003 total): 32 41 51 + Codes of length 09 bits (007 total): 15 22 23 61 71 81 F0 + Codes of length 10 bits (002 total): 91 A1 + Codes of length 11 bits (004 total): 24 25 33 80 + Codes of length 12 bits (007 total): 42 62 B1 C1 D1 E1 F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 038 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000062AB + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00006827 + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (002 total): 51 61 + Codes of length 07 bits (001 total): 71 + Codes of length 08 bits (004 total): 81 91 A1 B1 + Codes of length 09 bits (003 total): 30 C1 D1 + Codes of length 10 bits (001 total): F0 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (001 total): 10 + Codes of length 13 bits (000 total): + Codes of length 14 bits (003 total): 40 A0 F1 + Codes of length 15 bits (001 total): 20 + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00006853 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000099AB + Huffman table length = 41 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (003 total): 31 41 61 + Codes of length 06 bits (003 total): 10 51 91 + Codes of length 07 bits (004 total): 20 71 81 B1 + Codes of length 08 bits (002 total): 30 A1 + Codes of length 09 bits (002 total): C1 F0 + Codes of length 10 bits (003 total): 80 E1 F1 + Codes of length 11 bits (001 total): D1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000099D6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000A0BC + Huffman table length = 41 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (001 total): 41 + Codes of length 06 bits (004 total): 10 51 61 71 + Codes of length 07 bits (002 total): 30 91 + Codes of length 08 bits (002 total): 20 81 + Codes of length 09 bits (002 total): A1 B1 + Codes of length 10 bits (002 total): C1 D1 + Codes of length 11 bits (003 total): 40 80 E1 + Codes of length 12 bits (001 total): F1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000A0E7 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000A72C + + +*** Searching Compression Signatures *** + + Signature: 01E764F3ECB6C14A51FF83F1FF6D546B + Signature (Rotated): 01E6610D026E8E6FE4BECEA9B3328A63 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Minolta Co., Ltd. ] [DiMAGE F100 ] [ ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5400 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E8700 ] [FINE ] No + CAM:[OLYMPUS CORPORATION ] [C8080WZ ] [ ] No + CAM:[PENTAX ] [PENTAX K10D ] [ ] No + CAM:[SAMSUNG TECHWIN ] [Pro 815 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV 7, NV 7 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV10, NV10 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-F828 ] [ ] No + CAM:[SONY ] [DSC-H1 ] [ ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-H5 ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-L1 ] [ ] No + CAM:[SONY ] [DSC-N1 ] [ ] No + CAM:[SONY ] [DSC-P150 ] [ ] No + CAM:[SONY ] [DSC-P200 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-V3 ] [ ] No + CAM:[SONY ] [DSC-W55 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[Apple ImageIO.framework ] [084 ] + SW :[IJG Library ] [095 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [095 ] + SW :[IrfanView ] [095 ] + SW :[idImager ] [095 ] + SW :[FastStone Image Viewer ] [095 ] + SW :[NeatImage ] [095 ] + SW :[Paint.NET ] [095 ] + SW :[Photomatix ] [095 ] + SW :[XnView ] [095 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-B.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-B.jpg.txt new file mode 100644 index 000000000..bcbe9f7f1 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-B.jpg.txt @@ -0,0 +1,477 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue723-Ordered-Interleaved-Progressive-B.jpg] + Filesize: [36937] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 8 10 12 + DQT, Row #1: 2 2 3 4 5 12 12 11 + DQT, Row #2: 3 3 3 5 8 11 14 11 + DQT, Row #3: 3 3 4 6 10 17 16 12 + DQT, Row #4: 4 4 7 11 14 22 21 15 + DQT, Row #5: 5 7 11 13 16 21 23 18 + DQT, Row #6: 10 13 16 17 21 24 24 20 + DQT, Row #7: 14 18 19 20 22 20 21 20 + Approx quality factor = 90.06 (scaling=19.88 variance=1.14) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 4 5 9 20 20 20 20 + DQT, Row #1: 4 4 5 13 20 20 20 20 + DQT, Row #2: 5 5 11 20 20 20 20 20 + DQT, Row #3: 9 13 20 20 20 20 20 20 + DQT, Row #4: 20 20 20 20 20 20 20 20 + DQT, Row #5: 20 20 20 20 20 20 20 20 + DQT, Row #6: 20 20 20 20 20 20 20 20 + DQT, Row #7: 20 20 20 20 20 20 20 20 + Approx quality factor = 89.93 (scaling=20.14 variance=0.34) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 600 + Samples per Line = 600 + Image Size = 600 x 600 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 30 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (000 total): + Codes of length 04 bits (007 total): 02 03 04 05 06 07 08 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000D1 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000A95 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 04 05 + Codes of length 04 bits (003 total): 01 03 06 + Codes of length 05 bits (001 total): 02 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (001 total): 08 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000AB3 + Scan header length = 10 + Number of img components = 2 + Component[1]: selector=0x02, table=1(DC),0(AC) + Component[2]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000E60 + Huffman table length = 54 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (006 total): 00 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (003 total): 11 12 13 + Codes of length 06 bits (002 total): 21 50 + Codes of length 07 bits (004 total): 07 10 14 15 + Codes of length 08 bits (004 total): 20 22 23 31 + Codes of length 09 bits (005 total): 16 24 30 32 36 + Codes of length 10 bits (003 total): 25 40 41 + Codes of length 11 bits (004 total): 17 42 43 80 + Codes of length 12 bits (003 total): 26 33 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 035 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000E98 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001E73 + Huffman table length = 75 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (002 total): 00 11 + Codes of length 05 bits (002 total): 04 12 + Codes of length 06 bits (005 total): 13 21 31 41 51 + Codes of length 07 bits (006 total): 10 22 52 61 71 81 + Codes of length 08 bits (010 total): 05 14 20 32 42 50 91 A1 B1 C1 + Codes of length 09 bits (005 total): 23 33 62 72 D1 + Codes of length 10 bits (010 total): 24 30 40 53 63 73 82 92 E1 F0 + Codes of length 11 bits (005 total): 15 34 35 43 A2 + Codes of length 12 bits (004 total): 64 74 80 B2 + Codes of length 13 bits (003 total): 60 93 F1 + Codes of length 14 bits (001 total): A3 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 056 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001EC0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003A1E + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (005 total): 10 51 61 71 81 + Codes of length 07 bits (004 total): 50 91 A1 B1 + Codes of length 08 bits (002 total): C1 F0 + Codes of length 09 bits (003 total): 20 D1 E1 + Codes of length 10 bits (001 total): F1 + Codes of length 11 bits (001 total): 40 + Codes of length 12 bits (001 total): 80 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003A4A + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00005386 + Huffman table length = 43 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (001 total): 51 + Codes of length 07 bits (003 total): 61 71 81 + Codes of length 08 bits (004 total): 50 91 A1 B1 + Codes of length 09 bits (002 total): 10 C1 + Codes of length 10 bits (003 total): D1 E1 F0 + Codes of length 11 bits (000 total): + Codes of length 12 bits (003 total): 20 80 F1 + Codes of length 13 bits (001 total): 30 + Codes of length 14 bits (001 total): 40 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000053B3 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007B5B + Huffman table length = 50 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (003 total): 13 31 40 + Codes of length 07 bits (003 total): 06 22 41 + Codes of length 08 bits (002 total): 14 32 + Codes of length 09 bits (004 total): 10 16 23 33 + Codes of length 10 bits (005 total): 15 20 42 60 61 + Codes of length 11 bits (005 total): 24 34 50 51 52 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 031 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007B8F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 12 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000081EE + Huffman table length = 49 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (004 total): 21 31 41 51 + Codes of length 05 bits (003 total): 02 61 71 + Codes of length 06 bits (007 total): 10 40 81 91 A1 B1 C1 + Codes of length 07 bits (003 total): D1 E1 F0 + Codes of length 08 bits (003 total): 03 50 F1 + Codes of length 09 bits (004 total): 12 22 30 60 + Codes of length 10 bits (003 total): 20 32 70 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 030 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008221 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 13 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000084F2 + Huffman table length = 48 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (002 total): 03 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (003 total): 00 11 12 + Codes of length 06 bits (003 total): 06 21 31 + Codes of length 07 bits (003 total): 13 22 40 + Codes of length 08 bits (002 total): 14 41 + Codes of length 09 bits (005 total): 07 10 15 32 50 + Codes of length 10 bits (003 total): 42 60 61 + Codes of length 11 bits (005 total): 20 23 33 43 51 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 029 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008524 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 12 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00008C10 + Huffman table length = 51 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (004 total): 02 31 41 51 + Codes of length 06 bits (002 total): 61 71 + Codes of length 07 bits (009 total): 03 12 40 81 91 A1 B1 C1 D1 + Codes of length 08 bits (003 total): 10 E1 F0 + Codes of length 09 bits (003 total): 22 32 F1 + Codes of length 10 bits (004 total): 04 50 52 70 + Codes of length 11 bits (003 total): 20 42 60 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008C45 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 13 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00009047 + + +*** Searching Compression Signatures *** + + Signature: 013BA18D5561625796E986FDBC09F846 + Signature (Rotated): 01AC57E12793DFA7C46C704625C5AF0F + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[??? ] [Treo 680 ] [ ] Yes + CAM:[Canon ] [Canon PowerShot Pro1 ] [fine ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E3100 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 9530 ] [Superfine ] Yes + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W1 ] [ ] No + CAM:[SONY ] [SONY ] [ ] No + SW :[ACDSee ] [ ] + SW :[FixFoto ] [fine ] + SW :[IJG Library ] [090 ] + SW :[ZoomBrowser EX ] [high ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [090 ] + SW :[IrfanView ] [090 ] + SW :[idImager ] [090 ] + SW :[FastStone Image Viewer ] [090 ] + SW :[NeatImage ] [090 ] + SW :[Paint.NET ] [090 ] + SW :[Photomatix ] [090 ] + SW :[XnView ] [090 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-C.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-C.jpg.txt new file mode 100644 index 000000000..c76b74431 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/Issue723-Ordered-Interleaved-Progressive-C.jpg.txt @@ -0,0 +1,484 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Issue723-Ordered-Interleaved-Progressive-C.jpg] + Filesize: [46799] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 38 x 38 DPcm (dots per cm) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 2 1 1 2 2 4 5 6 + DQT, Row #1: 1 1 1 2 3 6 6 6 + DQT, Row #2: 1 1 2 2 4 6 7 6 + DQT, Row #3: 1 2 2 3 5 9 8 6 + DQT, Row #4: 2 2 4 6 7 11 10 8 + DQT, Row #5: 2 4 6 6 8 10 11 9 + DQT, Row #6: 5 6 8 9 10 12 12 10 + DQT, Row #7: 7 9 10 10 11 10 10 10 + Approx quality factor = 95.04 (scaling=9.93 variance=1.25) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 2 2 2 5 10 10 10 10 + DQT, Row #1: 2 2 3 7 10 10 10 10 + DQT, Row #2: 2 3 6 10 10 10 10 10 + DQT, Row #3: 5 7 10 10 10 10 10 10 + DQT, Row #4: 10 10 10 10 10 10 10 10 + DQT, Row #5: 10 10 10 10 10 10 10 10 + DQT, Row #6: 10 10 10 10 10 10 10 10 + DQT, Row #7: 10 10 10 10 10 10 10 10 + Approx quality factor = 94.91 (scaling=10.18 variance=0.26) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 517 + Samples per Line = 502 + Image Size = 502 x 517 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 30 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 06 + Codes of length 04 bits (004 total): 04 05 07 08 + Codes of length 05 bits (003 total): 02 03 09 + Codes of length 06 bits (001 total): 01 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000D1 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000858 + Huffman table length = 29 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (001 total): 05 + Codes of length 04 bits (005 total): 02 03 04 06 07 + Codes of length 05 bits (001 total): 01 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000877 + Scan header length = 10 + Number of img components = 2 + Component[1]: selector=0x02, table=1(DC),0(AC) + Component[2]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000012C2 + Huffman table length = 67 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (004 total): 01 02 04 05 + Codes of length 04 bits (002 total): 00 06 + Codes of length 05 bits (001 total): 11 + Codes of length 06 bits (002 total): 07 12 + Codes of length 07 bits (004 total): 13 14 21 50 + Codes of length 08 bits (004 total): 08 15 22 31 + Codes of length 09 bits (002 total): 17 23 + Codes of length 10 bits (006 total): 10 16 20 24 32 41 + Codes of length 11 bits (008 total): 25 33 34 42 51 52 54 62 + Codes of length 12 bits (004 total): 26 30 35 40 + Codes of length 13 bits (005 total): 18 27 37 55 56 + Codes of length 14 bits (005 total): 44 53 61 70 80 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 048 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001307 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 12 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002FBE + Huffman table length = 80 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (005 total): 13 22 41 51 61 + Codes of length 07 bits (011 total): 05 10 14 32 50 71 81 91 A1 B1 C1 + Codes of length 08 bits (007 total): 20 23 42 52 62 82 D1 + Codes of length 09 bits (009 total): 15 30 33 53 72 92 A2 B2 E1 + Codes of length 10 bits (006 total): 24 40 43 73 C2 E2 + Codes of length 11 bits (004 total): 06 63 D2 F0 + Codes of length 12 bits (005 total): 25 54 75 A3 B3 + Codes of length 13 bits (005 total): 44 64 70 80 83 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 061 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003010 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 13 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000048A9 + Huffman table length = 43 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (001 total): 41 + Codes of length 06 bits (003 total): 51 61 71 + Codes of length 07 bits (003 total): 10 81 A1 + Codes of length 08 bits (004 total): 50 91 B1 C1 + Codes of length 09 bits (003 total): 20 D1 F0 + Codes of length 10 bits (001 total): F1 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (001 total): 30 + Codes of length 13 bits (001 total): 70 + Codes of length 14 bits (001 total): 80 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000048D6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000060D3 + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (002 total): 51 61 + Codes of length 07 bits (001 total): 71 + Codes of length 08 bits (004 total): 50 81 91 A1 + Codes of length 09 bits (002 total): 10 B1 + Codes of length 10 bits (002 total): C1 F0 + Codes of length 11 bits (002 total): D1 F1 + Codes of length 12 bits (003 total): 30 70 E1 + Codes of length 13 bits (001 total): 20 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000060FF + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007FD1 + Huffman table length = 54 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (004 total): 01 02 04 05 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (002 total): 06 11 + Codes of length 06 bits (006 total): 07 12 13 21 31 50 + Codes of length 07 bits (001 total): 14 + Codes of length 08 bits (002 total): 15 22 + Codes of length 09 bits (005 total): 10 23 32 33 41 + Codes of length 10 bits (003 total): 16 17 20 + Codes of length 11 bits (002 total): 24 34 + Codes of length 12 bits (007 total): 25 26 30 40 42 51 70 + Codes of length 13 bits (001 total): 80 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 035 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008009 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 8 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00008F76 + Huffman table length = 59 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (004 total): 03 12 41 51 + Codes of length 06 bits (003 total): 61 71 81 + Codes of length 07 bits (005 total): 10 22 50 91 A1 + Codes of length 08 bits (007 total): 32 52 B1 C1 D1 F0 F1 + Codes of length 09 bits (002 total): 04 13 + Codes of length 10 bits (004 total): 20 23 42 72 + Codes of length 11 bits (006 total): 62 70 80 82 92 E1 + Codes of length 12 bits (003 total): 30 60 A2 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 040 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008FB3 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 9 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00009B28 + Huffman table length = 51 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 03 + Codes of length 03 bits (004 total): 01 02 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (003 total): 00 07 11 + Codes of length 06 bits (003 total): 12 13 31 + Codes of length 07 bits (003 total): 08 21 50 + Codes of length 08 bits (003 total): 10 14 15 + Codes of length 09 bits (004 total): 20 23 32 41 + Codes of length 10 bits (001 total): 16 + Codes of length 11 bits (003 total): 22 24 40 + Codes of length 12 bits (005 total): 17 18 33 34 70 + Codes of length 13 bits (001 total): 80 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00009B5D + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 8 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000AB99 + Huffman table length = 62 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 11 + Codes of length 04 bits (002 total): 03 21 + Codes of length 05 bits (004 total): 12 31 41 51 + Codes of length 06 bits (003 total): 04 61 71 + Codes of length 07 bits (005 total): 10 22 32 50 81 + Codes of length 08 bits (004 total): 13 91 A1 B1 + Codes of length 09 bits (008 total): 20 23 42 52 62 72 C1 D1 + Codes of length 10 bits (005 total): 05 14 92 E1 F0 + Codes of length 11 bits (003 total): 30 33 F1 + Codes of length 12 bits (005 total): 70 80 82 90 A2 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 043 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000ABD9 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 9 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000B6CD + + +*** Searching Compression Signatures *** + + Signature: 01E764F3ECB6C14A51FF83F1FF6D546B + Signature (Rotated): 01E6610D026E8E6FE4BECEA9B3328A63 + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Minolta Co., Ltd. ] [DiMAGE F100 ] [ ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5400 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E8700 ] [FINE ] No + CAM:[OLYMPUS CORPORATION ] [C8080WZ ] [ ] No + CAM:[PENTAX ] [PENTAX K10D ] [ ] No + CAM:[SAMSUNG TECHWIN ] [Pro 815 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV 7, NV 7 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV10, NV10 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-F828 ] [ ] No + CAM:[SONY ] [DSC-H1 ] [ ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-H5 ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-L1 ] [ ] No + CAM:[SONY ] [DSC-N1 ] [ ] No + CAM:[SONY ] [DSC-P150 ] [ ] No + CAM:[SONY ] [DSC-P200 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-V3 ] [ ] No + CAM:[SONY ] [DSC-W55 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + SW :[Apple ImageIO.framework ] [084 ] + SW :[IJG Library ] [095 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [095 ] + SW :[IrfanView ] [095 ] + SW :[idImager ] [095 ] + SW :[FastStone Image Viewer ] [095 ] + SW :[NeatImage ] [095 ] + SW :[Paint.NET ] [095 ] + SW :[Photomatix ] [095 ] + SW :[XnView ] [095 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-load.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-load.jpg.txt new file mode 100644 index 000000000..6070e1cda --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-load.jpg.txt @@ -0,0 +1,772 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\issue750-exif-load.jpg] + Filesize: [36885] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000002 + Length = 3656 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 08000000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000014 + Dir Length = 0x0010 + [Make ] = "Canon" + [Model ] = "Canon EOS 70D" + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 720000/10000 + [YResolution ] = 720000/10000 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop CS6 (Windows)" + [DateTime ] = "2018:02:28 17:51:59" + [YCbCrPositioning ] = Centered + [ExifOffset ] = @ 0x012C + [GPSOffset ] = @ 0x04C8 + Offset to Next IFD = 0x000004DC + + EXIF IFD1 @ Absolute 0x000004E8 + Dir Length = 0x0006 + [Compression ] = JPEG + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [JpegIFOffset ] = @ +0x053A = @ 0x0546 + [JpegIFByteCount ] = 0x[00000906] / 2310 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x00000138 + Dir Length = 0x0025 + [ExposureTime ] = 1/60 s + [FNumber ] = F11.0 + [ExposureProgram ] = Manual + [ISOSpeedRatings ] = 100 + [ExifVersion ] = 02.30 + [DateTimeOriginal ] = "2017:09:14 14:41:54" + [DateTimeDigitized ] = "2017:09:14 14:41:54" + [ComponentsConfiguration ] = [Y Cb Cr .] + [ShutterSpeedValue ] = 393216/65536 + [ApertureValue ] = 458752/65536 + [ExposureBiasValue ] = 0.00 eV + [MeteringMode ] = Pattern + [Flash ] = Flash did not fire + [FocalLength ] = 50 mm + [UserComment ] = "" + [SubSecTime ] = "277" + [SubSecTimeOriginal ] = "00" + [SubSecTimeDigitized ] = "00" + [FlashPixVersion ] = 01.00 + [ColorSpace ] = sRGB + [ExifImageWidth ] = 0x[000001D3] / 467 + [ExifImageHeight ] = 0x[000002BC] / 700 + [ExifInteroperabilityOffset ] = @ 0x04A8 + [FocalPlaneXResolution ] = 5472000/899 + [FocalPlaneYResolution ] = 3648000/599 + [FocalPlaneResolutionUnit ] = Inch + [CustomRendered ] = Normal process + [ExposureMode ] = Manual exposure + [WhiteBalance ] = Auto white balance + [SceneCaptureType ] = Standard + + EXIF GPSIFD @ Absolute 0x000004D4 + Dir Length = 0x0001 + [GPSVersionID ] = 2.3.0.0 + + EXIF InteropIFD @ Absolute 0x000004B4 + Dir Length = 0x0002 + [InteroperabilityIndex ] = "R98" + [InteroperabilityVersion ] = 01.00 + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00000E4C + Length = 4648 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x002C] DefinedName="IPTC-NAA record" + IPTC [001:090] Coded Character Set = "%G" + IPTC [002:000] Record Version = 51658 + IPTC [002:055] Date Created = "20170914" + IPTC [002:060] Time Created = "144154+0000" + 8BIM: [0x0425] Name="" Len=[0x0010] DefinedName="Caption digest" + Caption digest = | 0x8B 58 80 D1 16 85 C7 6D 47 04 59 0B 61 59 FA 69 | .X.....mG.Y.aY.i + 8BIM: [0x043A] Name="" Len=[0x00E5] DefinedName="Print Information" + Print Information = + | 0x00 00 00 10 00 00 00 01 00 00 00 00 00 0B 70 72 | ..............pr + | 0x69 6E 74 4F 75 74 70 75 74 00 00 00 05 00 00 00 | intOutput....... + | 0x00 50 73 74 53 62 6F 6F 6C 01 00 00 00 00 49 6E | .PstSbool.....In + | 0x74 65 65 6E 75 6D 00 00 00 00 49 6E 74 65 00 00 | teenum....Inte.. + | 0x00 00 43 6C 72 6D 00 00 00 0F 70 72 69 6E 74 53 | ..Clrm....printS + | 0x69 78 74 65 65 6E 42 69 74 62 6F 6F 6C 00 00 00 | ixteenBitbool... + | 0x00 0B 70 72 69 6E 74 65 72 4E 61 6D 65 54 45 58 | ..printerNameTEX + | 0x54 00 00 00 01 00 00 00 00 00 0F 70 72 69 6E 74 | T..........print + | ... + 8BIM: [0x043B] Name="" Len=[0x022D] DefinedName="Print Style" + Print Style = + | 0x00 00 00 10 00 00 00 01 00 00 00 00 00 12 70 72 | ..............pr + | 0x69 6E 74 4F 75 74 70 75 74 4F 70 74 69 6F 6E 73 | intOutputOptions + | 0x00 00 00 17 00 00 00 00 43 70 74 6E 62 6F 6F 6C | ........Cptnbool + | 0x00 00 00 00 00 43 6C 62 72 62 6F 6F 6C 00 00 00 | .....Clbrbool... + | 0x00 00 52 67 73 4D 62 6F 6F 6C 00 00 00 00 00 43 | ..RgsMbool.....C + | 0x72 6E 43 62 6F 6F 6C 00 00 00 00 00 43 6E 74 43 | rnCbool.....CntC + | 0x62 6F 6F 6C 00 00 00 00 00 4C 62 6C 73 62 6F 6F | bool.....Lblsboo + | 0x6C 00 00 00 00 00 4E 67 74 76 62 6F 6F 6C 00 00 | l.....Ngtvbool.. + | ... + 8BIM: [0x03ED] Name="" Len=[0x0010] DefinedName="ResolutionInfo structure" + Horizontal resolution = 72 pixels per inch + Width unit = cm + Vertical resolution = 72 pixels per inch + Height unit = cm + 8BIM: [0x0426] Name="" Len=[0x000E] DefinedName="Print scale" + Style = centered + X location = 0.00000 + Y location = 0.00000 + Scale = 1.00000 + 8BIM: [0x040D] Name="" Len=[0x0004] DefinedName="Global Angle" + Global Angle = 30 degrees + 8BIM: [0x0419] Name="" Len=[0x0004] DefinedName="Global Altitude" + Global Altitude = 30 + 8BIM: [0x03F3] Name="" Len=[0x0009] DefinedName="Print flags" + Labels = false + Crop marks = false + Color bars = false + Registration marks = false + Negative = false + Flip = false + Interpolate = false + Caption = false + Print flags = true + 8BIM: [0x2710] Name="" Len=[0x000A] DefinedName="Print flags information" + Version = 1 + Center crop marks = 0 + Reserved = 0 + Bleed width value = 0 + Bleed width scale = 2 + 8BIM: [0x03F5] Name="" Len=[0x0048] DefinedName="Color halftoning information" + Color halftoning information = + | 0x00 2F 66 66 00 01 00 6C 66 66 00 06 00 00 00 00 | ./ff...lff...... + | 0x00 01 00 2F 66 66 00 01 00 A1 99 9A 00 06 00 00 | .../ff.......... + | 0x00 00 00 01 00 32 00 00 00 01 00 5A 00 00 00 06 | .....2.....Z.... + | 0x00 00 00 00 00 01 00 35 00 00 00 01 00 2D 00 00 | .......5.....-.. + | 0x00 06 00 00 00 00 00 01 | ........ + 8BIM: [0x03F8] Name="" Len=[0x0070] DefinedName="Color transfer functions" + Color transfer functions = + | 0x00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF 03 E8 00 00 00 00 FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF 03 E8 00 00 00 00 FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................ + | 0x03 E8 00 00 00 00 FF FF FF FF FF FF FF FF FF FF | ................ + | 0xFF FF FF FF FF FF FF FF FF FF FF FF 03 E8 00 00 | ................ + 8BIM: [0x0408] Name="" Len=[0x0010] DefinedName="Grid and guides information" + Version = 1 + Grid Horizontal = 576 + Grid Vertical = 576 + Number of Guide Resources = 0 + 8BIM: [0x041E] Name="" Len=[0x0004] DefinedName="URL List" + URL List = | 0x00 00 00 00 | .... + 8BIM: [0x041A] Name="" Len=[0x0341] DefinedName="Slices" + Slice Header: + Version = 6 + Bound Rect (top) = 0 + Bound Rect (left) = 0 + Bound Rect (bottom) = 700 + Bound Rect (right) = 467 + Name of group of slices = "513566" + Number of slices = 1 + ----- + Slice #0: + Slice Resource: + ID = 0 + Group ID = 0 + Origin = 0 + Name = "" + Type = 1 + Position (top) = 0 + Position (left) = 0 + Position (bottom) = 467 + Position (right) = 700 + URL = "" + Target = "" + Message = "" + Alt Tag = "" + Cell text is HTML = true + Cell text = "" + Horizontal alignment = 0 + Vertical alignment = 0 + Alpha color = 0 + Red = 0 + Green = 0 + Blue = 0 + Descriptor version = 16 + Descriptor: + Name from classID = "" + classID = "null" + Num items in descriptor = 2 + ----- + Descriptor item #0: + Key = "bounds" + OSType key = "Objc" + Descriptor: + Name from classID = "" + classID = "Rct1" + Num items in descriptor = 4 + ----- + Descriptor item #0: + Key = "Top " + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "Left" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "Btom" + OSType key = "long" + Value = 700 + Descriptor item #3: + Key = "Rght" + OSType key = "long" + Value = 467 + ----- + Descriptor item #1: + Key = "slices" + OSType key = "VlLs" + Num items in list = 1 + ----- + Item #0: + OSType key = "" + Descriptor: + Name from classID = "" + classID = "slice" + Num items in descriptor = 18 + ----- + Descriptor item #0: + Key = "sliceID" + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "groupID" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "origin" + OSType key = "enum" + Type = "ESliceOrigin" + Enum = "autoGenerated" + Descriptor item #3: + Key = "Type" + OSType key = "enum" + Type = "ESliceType" + Enum = "Img " + Descriptor item #4: + Key = "bounds" + OSType key = "Objc" + Descriptor: + Name from classID = "" + classID = "Rct1" + Num items in descriptor = 4 + ----- + Descriptor item #0: + Key = "Top " + OSType key = "long" + Value = 0 + Descriptor item #1: + Key = "Left" + OSType key = "long" + Value = 0 + Descriptor item #2: + Key = "Btom" + OSType key = "long" + Value = 700 + Descriptor item #3: + Key = "Rght" + OSType key = "long" + Value = 467 + ----- + Descriptor item #5: + Key = "url" + OSType key = "TEXT" + String = "" + Descriptor item #6: + Key = "null" + OSType key = "TEXT" + String = "" + Descriptor item #7: + Key = "Msge" + OSType key = "TEXT" + String = "" + Descriptor item #8: + Key = "altTag" + OSType key = "TEXT" + String = "" + Descriptor item #9: + Key = "cellTextIsHTML" + OSType key = "bool" + Value = true + Descriptor item #10: + Key = "cellText" + OSType key = "TEXT" + String = "" + Descriptor item #11: + Key = "horzAlign" + OSType key = "enum" + Type = "ESliceHorzAlign" + Enum = "default" + Descriptor item #12: + Key = "vertAlign" + OSType key = "enum" + Type = "ESliceVertAlign" + Enum = "default" + Descriptor item #13: + Key = "bgColorType" + OSType key = "enum" + Type = "ESliceBGColorType" + Enum = "None" + Descriptor item #14: + Key = "topOutset" + OSType key = "long" + Value = 0 + Descriptor item #15: + Key = "leftOutset" + OSType key = "long" + Value = 0 + Descriptor item #16: + Key = "bottomOutset" + OSType key = "long" + Value = 0 + Descriptor item #17: + Key = "rightOutset" + OSType key = "long" + Value = 0 + ----- + ----- + ----- + ----- + 8BIM: [0x0428] Name="" Len=[0x000C] DefinedName="Pixel Aspect Ratio" + Version = 2 + X/Y Ratio = 1.00000 + 8BIM: [0x0414] Name="" Len=[0x0004] DefinedName="Document-specific IDs seed number" + Base value = 1 + 8BIM: [0x040C] Name="" Len=[0x0922] DefinedName="Thumbnail resources" + Format = 1 + Width of thumbnail = 107 pixels + Height of thumbnail = 160 pixels + Widthbytes = 324 bytes + Total size = 51840 bytes + Size after compression = 2310 bytes + Bits per pixel = 24 bits + Number of planes = 1 + JFIF data @ 0x000016FA + 8BIM: [0x0421] Name="" Len=[0x0055] DefinedName="Version Info" + Version = 1 + hasRealMergedData = 1 + Writer name = "Adobe Photoshop" + Reader name = "Adobe Photoshop CS6" + File version = 1 + 8BIM: [0x0406] Name="" Len=[0x0007] DefinedName="JPEG quality" + Photoshop Save As Quality = 7 + Photoshop Save Format = "Standard" + Photoshop Save Progressive Scans = "3 Scans" + ??? = 1 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00002076 + Length = 3752 + Identifier = [http://ns.adobe.com/xap/1.0/] + XMP = + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00002F20 + Length = 3160 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 3144 bytes + Preferred CMM Type : 'Lino' (0x4C696E6F) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 1998-02-09 06:49:00 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Microsoft Corporation ('MSFT' (0x4D534654)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : 'IEC ' (0x49454320) + Device Model : 'sRGB' (0x73524742) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'HP ' (0x48502020) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: APP14 (xFFEE) *** + OFFSET: 0x00003B7A + Length = 14 + DCTEncodeVersion = 100 + APP14Flags0 = 0 + APP14Flags1 = 0 + ColorTransform = 1 [YCbCr] + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00003B8A + Table length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 10 7 7 10 15 18 20 17 + DQT, Row #1: 7 8 8 10 13 16 12 12 + DQT, Row #2: 7 8 8 10 16 12 12 12 + DQT, Row #3: 10 10 10 18 12 12 12 12 + DQT, Row #4: 15 13 16 12 12 12 12 12 + DQT, Row #5: 18 16 12 12 12 12 12 12 + DQT, Row #6: 20 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 83.48 (scaling=33.04 variance=462.13) + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 11 12 21 34 20 20 17 17 + DQT, Row #1: 12 19 24 14 14 12 12 12 + DQT, Row #2: 21 24 14 14 12 12 12 12 + DQT, Row #3: 34 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + Approx quality factor = 87.98 (scaling=24.05 variance=592.80) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x00003C10 + Frame header length = 17 + Precision = 8 + Number of Lines = 700 + Samples per Line = 467 + Image Size = 467 x 700 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DRI (Restart Interval) (xFFDD) *** + OFFSET: 0x00003C23 + Length = 4 + interval = 59 + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003C29 + Huffman table length = 418 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (007 total): 04 05 03 02 06 01 00 + Codes of length 04 bits (001 total): 07 + Codes of length 05 bits (001 total): 08 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (001 total): 0A + Codes of length 08 bits (001 total): 0B + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 00 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (003 total): 04 05 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 11 04 00 + Codes of length 05 bits (003 total): 05 21 12 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 51 06 13 61 + Codes of length 08 bits (002 total): 22 71 + Codes of length 09 bits (006 total): 81 14 32 91 A1 07 + Codes of length 10 bits (007 total): 15 B1 42 23 C1 52 D1 + Codes of length 11 bits (003 total): E1 33 16 + Codes of length 12 bits (004 total): 62 F0 24 72 + Codes of length 13 bits (002 total): 82 F1 + Codes of length 14 bits (006 total): 25 43 34 53 92 A2 + Codes of length 15 bits (002 total): B2 63 + Codes of length 16 bits (115 total): 73 C2 35 44 27 93 A3 B3 36 17 54 64 74 C3 D2 E2 + 08 26 83 09 0A 18 19 84 94 45 46 A4 B4 56 D3 55 + 28 1A F2 E3 F3 C4 D4 E4 F4 65 75 85 95 A5 B5 C5 + D5 E5 F5 66 76 86 96 A6 B6 C6 D6 E6 F6 37 47 57 + 67 77 87 97 A7 B7 C7 D7 E7 F7 38 48 58 68 78 88 + 98 A8 B8 C8 D8 E8 F8 29 39 49 59 69 79 89 99 A9 + B9 C9 D9 E9 F9 2A 3A 4A 5A 6A 7A 8A 9A AA BA CA + DA EA FA + Total number of codes: 162 + + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 00 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (002 total): 04 21 + Codes of length 06 bits (003 total): 12 31 41 + Codes of length 07 bits (005 total): 05 51 13 61 22 + Codes of length 08 bits (005 total): 06 71 81 91 32 + Codes of length 09 bits (004 total): A1 B1 F0 14 + Codes of length 10 bits (005 total): C1 D1 E1 23 42 + Codes of length 11 bits (006 total): 15 52 62 72 F1 33 + Codes of length 12 bits (004 total): 24 34 43 82 + Codes of length 13 bits (008 total): 16 92 53 25 A2 63 B2 C2 + Codes of length 14 bits (003 total): 07 73 D2 + Codes of length 15 bits (003 total): 35 E2 44 + Codes of length 16 bits (109 total): 83 17 54 93 08 09 0A 18 19 26 36 45 1A 27 64 74 + 55 37 F2 A3 B3 C3 28 29 D3 E3 F3 84 94 A4 B4 C4 + D4 E4 F4 65 75 85 95 A5 B5 C5 D5 E5 F5 46 56 66 + 76 86 96 A6 B6 C6 D6 E6 F6 47 57 67 77 87 97 A7 + B7 C7 D7 E7 F7 38 48 58 68 78 88 98 A8 B8 C8 D8 + E8 F8 39 49 59 69 79 89 99 A9 B9 C9 D9 E9 F9 2A + 3A 4A 5A 6A 7A 8A 9A AA BA CA DA EA FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003DCD + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x00003DDB + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x00009013.0 + + Compression stats: + Compression Ratio: 46.60:1 + Bits per pixel: 0.52:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 0 ( 0%) + # codes of length 03 bits: 4910 ( 95%) + # codes of length 04 bits: 280 ( 5%) + # codes of length 05 bits: 2 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 9997 ( 96%) + # codes of length 03 bits: 335 ( 3%) + # codes of length 04 bits: 52 ( 1%) + # codes of length 05 bits: 0 ( 0%) + # codes of length 06 bits: 0 ( 0%) + # codes of length 07 bits: 0 ( 0%) + # codes of length 08 bits: 0 ( 0%) + # codes of length 09 bits: 0 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 5649 ( 33%) + # codes of length 03 bits: 1560 ( 9%) + # codes of length 04 bits: 6758 ( 39%) + # codes of length 05 bits: 1189 ( 7%) + # codes of length 06 bits: 349 ( 2%) + # codes of length 07 bits: 488 ( 3%) + # codes of length 08 bits: 255 ( 1%) + # codes of length 09 bits: 351 ( 2%) + # codes of length 10 bits: 254 ( 1%) + # codes of length 11 bits: 70 ( 0%) + # codes of length 12 bits: 76 ( 0%) + # codes of length 13 bits: 14 ( 0%) + # codes of length 14 bits: 115 ( 1%) + # codes of length 15 bits: 41 ( 0%) + # codes of length 16 bits: 88 ( 1%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 10917 ( 93%) + # codes of length 03 bits: 435 ( 4%) + # codes of length 04 bits: 77 ( 1%) + # codes of length 05 bits: 75 ( 1%) + # codes of length 06 bits: 121 ( 1%) + # codes of length 07 bits: 47 ( 0%) + # codes of length 08 bits: 36 ( 0%) + # codes of length 09 bits: 5 ( 0%) + # codes of length 10 bits: 15 ( 0%) + # codes of length 11 bits: 39 ( 0%) + # codes of length 12 bits: 11 ( 0%) + # codes of length 13 bits: 3 ( 0%) + # codes of length 14 bits: 2 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 1 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[222] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1020, 0, 0] RGB=[255,255,255] @ MCU[ 0, 0] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 87 + Next position in scan buffer: Offset 0x00009012.5 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00009013 + + +*** Embedded JPEG Thumbnail *** + Offset: 0x00000546 + Length: 0x00000906 (2310) + + * Embedded Thumb Marker: SOI + + * Embedded Thumb Marker: APP13 + Length = 12 + + * Embedded Thumb Marker: APP14 + Length = 14 + + * Embedded Thumb Marker: DQT + Length = 132 + ---- + Precision=8 bits + Destination ID=0 (Luminance, typically) + DQT, Row #0: 12 8 8 12 17 21 24 17 + DQT, Row #1: 8 9 9 11 15 19 12 12 + DQT, Row #2: 8 9 10 12 19 12 12 12 + DQT, Row #3: 12 11 12 21 12 12 12 12 + DQT, Row #4: 17 15 19 12 12 12 12 12 + DQT, Row #5: 21 19 12 12 12 12 12 12 + DQT, Row #6: 24 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + ---- + Precision=8 bits + Destination ID=1 (Chrominance, typically) + DQT, Row #0: 13 11 13 16 20 20 17 17 + DQT, Row #1: 11 14 14 14 14 12 12 12 + DQT, Row #2: 13 14 14 14 12 12 12 12 + DQT, Row #3: 16 14 14 12 12 12 12 12 + DQT, Row #4: 20 14 12 12 12 12 12 12 + DQT, Row #5: 20 12 12 12 12 12 12 12 + DQT, Row #6: 17 12 12 12 12 12 12 12 + DQT, Row #7: 17 12 12 12 12 12 12 12 + + * Embedded Thumb Marker: SOF + Frame header length = 17 + Precision = 8 + Number of Lines = 160 + Samples per Line = 107 + Image Size = 107 x 160 + + * Embedded Thumb Marker: DRI + Length = 4 + + * Embedded Thumb Marker: DHT + Length = 319 + + * Embedded Thumb Marker: SOS + Skipping scan data + Skipped 1785 bytes + + * Embedded Thumb Marker: EOI + + * Embedded Thumb Signature: 01C2DDA29A1B5DCCD5E217CF9C558A62 + +*** Searching Compression Signatures *** + + Signature: 0165B3F1B409A4D8D5F2ADFFA970D3A5 + Signature (Rotated): 0165B3F1B409A4D8D5F2ADFFA970D3A5 + File Offset: 0 bytes + Chroma subsampling: 1x1 + EXIF Make/Model: OK [Canon] [Canon EOS 70D] + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop CS6 (Windows)] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E885 ] [FINE ] Yes + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C700UZ ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + + NOTE: Photoshop IRB detected + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + diff --git a/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-tranform.jpg.txt b/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-tranform.jpg.txt new file mode 100644 index 000000000..48760626b --- /dev/null +++ b/tests/Images/Input/Jpg/issues/JpegSnoopReports/issue750-exif-tranform.jpg.txt @@ -0,0 +1,435 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\issue750-exif-tranform.jpg] + Filesize: [5587341] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 300 x 300 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 8272 + Identifier = [Exif] + Identifier TIFF = 0x[4D4D002A 00000008] + Endian = Motorola (big) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x00000026 + Dir Length = 0x000A + [Make ] = "Canon" + [Model ] = "Canon EOS 500D" + [Orientation ] = 1 = Row 0: top, Col 0: left + [DateTime ] = "2017:12:06 15:48:51" + [Artist ] = "" + [YCbCrPositioning ] = Co-sited + [Copyright ] = "" + [ExifOffset ] = @ 0x00B0 + [GPSOffset ] = @ 0x2034 + [XPAuthor ] = "??" + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x000000CE + Dir Length = 0x0020 + [ExposureTime ] = 1/160 s + [FNumber ] = F9.0 + [ExposureProgram ] = Normal program + [ISOSpeedRatings ] = 3200 + [ExifVersion ] = 02.21 + [DateTimeOriginal ] = "2017:12:06 15:48:51" + [DateTimeDigitized ] = "2017:12:06 15:48:51" + [ComponentsConfiguration ] = [Y Cb Cr .] + [ShutterSpeedValue ] = 483328/65536 + [ApertureValue ] = 417792/65536 + [ExposureBiasValue ] = 1.00 eV + [MeteringMode ] = Pattern + [Flash ] = Flash did not fire + [FocalLength ] = 24 mm + [MakerNote ] = @ 0x028E + [UserComment ] = "" + [SubSecTime ] = "80" + [SubSecTimeOriginal ] = "80" + [SubSecTimeDigitized ] = "80" + [FlashPixVersion ] = 01.00 + [ColorSpace ] = sRGB + [ExifImageWidth ] = 4752 + [ExifImageHeight ] = 3168 + [ExifInteroperabilityOffset ] = @ 0x2010 + [FocalPlaneXResolution ] = 4752000/894 + [FocalPlaneYResolution ] = 3168000/593 + [FocalPlaneResolutionUnit ] = Inch + [CustomRendered ] = Normal process + [ExposureMode ] = Auto exposure + [WhiteBalance ] = Auto white balance + [SceneCaptureType ] = Standard + + EXIF MakerIFD @ Absolute 0x000002AC + Makernote decode option not enabled. + + EXIF GPSIFD @ Absolute 0x00002052 + Dir Length = 0x0001 + [GPSVersionID ] = 2.2.0.0 + + EXIF InteropIFD @ Absolute 0x0000202E + Dir Length = 0x0001 + [InteroperabilityVersion ] = 01.00 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00002066 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 1 1 1 1 1 2 3 4 + DQT, Row #1: 1 1 1 1 2 3 4 3 + DQT, Row #2: 1 1 1 1 2 3 4 3 + DQT, Row #3: 1 1 1 2 3 5 5 4 + DQT, Row #4: 1 1 2 3 4 7 6 5 + DQT, Row #5: 1 2 3 4 5 6 7 6 + DQT, Row #6: 3 4 5 5 6 7 7 6 + DQT, Row #7: 4 6 6 6 7 6 6 6 + Approx quality factor = 96.95 (scaling=6.11 variance=1.09) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000020AB + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 1 1 1 3 6 6 6 6 + DQT, Row #1: 1 1 2 4 6 6 6 6 + DQT, Row #2: 1 2 3 6 6 6 6 6 + DQT, Row #3: 3 4 6 6 6 6 6 6 + DQT, Row #4: 6 6 6 6 6 6 6 6 + DQT, Row #5: 6 6 6 6 6 6 6 6 + DQT, Row #6: 6 6 6 6 6 6 6 6 + DQT, Row #7: 6 6 6 6 6 6 6 6 + Approx quality factor = 96.99 (scaling=6.01 variance=0.24) + +*** Marker: SOF0 (Baseline DCT) (xFFC0) *** + OFFSET: 0x000020F0 + Frame header length = 17 + Precision = 8 + Number of Lines = 3168 + Samples per Line = 4752 + Image Size = 4752 x 3168 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002103 + Huffman table length = 31 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (005 total): 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 09 + Codes of length 08 bits (001 total): 0A + Codes of length 09 bits (001 total): 0B + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002124 + Huffman table length = 181 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (003 total): 00 04 11 + Codes of length 05 bits (003 total): 05 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 06 13 51 61 + Codes of length 08 bits (003 total): 07 22 71 + Codes of length 09 bits (005 total): 14 32 81 91 A1 + Codes of length 10 bits (005 total): 08 23 42 B1 C1 + Codes of length 11 bits (004 total): 15 52 D1 F0 + Codes of length 12 bits (004 total): 24 33 62 72 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (001 total): 82 + Codes of length 16 bits (125 total): 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 + 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 + 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 + 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 + 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 + B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA + D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 + E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000021DB + Huffman table length = 31 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 02 + Codes of length 03 bits (001 total): 03 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (001 total): 05 + Codes of length 06 bits (001 total): 06 + Codes of length 07 bits (001 total): 07 + Codes of length 08 bits (001 total): 08 + Codes of length 09 bits (001 total): 09 + Codes of length 10 bits (001 total): 0A + Codes of length 11 bits (001 total): 0B + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 012 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000021FC + Huffman table length = 181 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (002 total): 03 11 + Codes of length 05 bits (004 total): 04 05 21 31 + Codes of length 06 bits (004 total): 06 12 41 51 + Codes of length 07 bits (003 total): 07 61 71 + Codes of length 08 bits (004 total): 13 22 32 81 + Codes of length 09 bits (007 total): 08 14 42 91 A1 B1 C1 + Codes of length 10 bits (005 total): 09 23 33 52 F0 + Codes of length 11 bits (004 total): 15 62 72 D1 + Codes of length 12 bits (004 total): 0A 16 24 34 + Codes of length 13 bits (000 total): + Codes of length 14 bits (001 total): E1 + Codes of length 15 bits (002 total): 25 F1 + Codes of length 16 bits (119 total): 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 + 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 + 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 + 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 + 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 + B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 + D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 + F4 F5 F6 F7 F8 F9 FA + Total number of codes: 162 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000022B3 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),1(AC) + Component[3]: selector=0x03, table=1(DC),1(AC) + Spectral selection = 0 .. 63 + Successive approximation = 0x00 + + +*** Decoding SCAN Data *** + OFFSET: 0x000022C1 + Scan Decode Mode: No IDCT (DC only) + NOTE: Low-resolution DC component shown. Can decode full-res with [Options->Scan Segment->Full IDCT] + + Scan Data encountered marker 0xFFD9 @ 0x0055418B.0 + + Compression stats: + Compression Ratio: 8.10:1 + Bits per pixel: 2.96:1 + + Huffman code histogram stats: + Huffman Table: (Dest ID: 0, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 7852 ( 3%) + # codes of length 03 bits: 194801 ( 83%) + # codes of length 04 bits: 18114 ( 8%) + # codes of length 05 bits: 9703 ( 4%) + # codes of length 06 bits: 3623 ( 2%) + # codes of length 07 bits: 941 ( 0%) + # codes of length 08 bits: 188 ( 0%) + # codes of length 09 bits: 2 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 1, Class: DC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 53609 ( 46%) + # codes of length 03 bits: 36337 ( 31%) + # codes of length 04 bits: 20089 ( 17%) + # codes of length 05 bits: 4404 ( 4%) + # codes of length 06 bits: 2062 ( 2%) + # codes of length 07 bits: 903 ( 1%) + # codes of length 08 bits: 206 ( 0%) + # codes of length 09 bits: 2 ( 0%) + # codes of length 10 bits: 0 ( 0%) + # codes of length 11 bits: 0 ( 0%) + # codes of length 12 bits: 0 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 0 ( 0%) + # codes of length 16 bits: 0 ( 0%) + + Huffman Table: (Dest ID: 0, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 3801677 ( 49%) + # codes of length 03 bits: 1263986 ( 16%) + # codes of length 04 bits: 1288745 ( 17%) + # codes of length 05 bits: 606891 ( 8%) + # codes of length 06 bits: 282047 ( 4%) + # codes of length 07 bits: 273734 ( 4%) + # codes of length 08 bits: 85749 ( 1%) + # codes of length 09 bits: 90483 ( 1%) + # codes of length 10 bits: 39213 ( 1%) + # codes of length 11 bits: 19089 ( 0%) + # codes of length 12 bits: 6439 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 0 ( 0%) + # codes of length 15 bits: 136 ( 0%) + # codes of length 16 bits: 7545 ( 0%) + + Huffman Table: (Dest ID: 1, Class: AC) + # codes of length 01 bits: 0 ( 0%) + # codes of length 02 bits: 309037 ( 51%) + # codes of length 03 bits: 124353 ( 21%) + # codes of length 04 bits: 87742 ( 14%) + # codes of length 05 bits: 43060 ( 7%) + # codes of length 06 bits: 28928 ( 5%) + # codes of length 07 bits: 2442 ( 0%) + # codes of length 08 bits: 8544 ( 1%) + # codes of length 09 bits: 1150 ( 0%) + # codes of length 10 bits: 376 ( 0%) + # codes of length 11 bits: 126 ( 0%) + # codes of length 12 bits: 30 ( 0%) + # codes of length 13 bits: 0 ( 0%) + # codes of length 14 bits: 50 ( 0%) + # codes of length 15 bits: 24 ( 0%) + # codes of length 16 bits: 4 ( 0%) + + YCC clipping in DC: + Y component: [<0= 0] [>255= 0] + Cb component: [<0= 0] [>255= 0] + Cr component: [<0= 0] [>255= 0] + + RGB clipping in DC: + R component: [<0= 0] [>255= 0] + G component: [<0= 0] [>255= 0] + B component: [<0= 0] [>255= 0] + + Average Pixel Luminance (Y): + Y=[215] (range: 0..255) + + Brightest Pixel Search: + YCC=[ 1016, -3, 3] RGB=[255,255,253] @ MCU[ 92, 26] + + Finished Decoding SCAN Data + Number of RESTART markers decoded: 0 + Next position in scan buffer: Offset 0x0055418A.7 + + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0055418B + + +*** Searching Compression Signatures *** + + Signature: 010564D93F295ADB889B91604DC82EE1 + Signature (Rotated): 014302FE54745F4DBB58A0D51CDC66BD + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: OK [Canon] [Canon EOS 500D] + EXIF Makernotes: OK + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[Leica Camera AG ] [M8 Digital Camera ] [ ] No + CAM:[Leica Camera AG ] [M8 Digital Camera ] [ ] No + CAM:[Leica Camera AG ] [M8 Digital Camera ] [ ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5400 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[OLYMPUS CORPORATION ] [C8080WZ ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C40Z,D40Z ] [ ] No + CAM:[Samsung Techwin ] [Digimax V50/a5 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [Pro 815 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV 7, NV 7 ] [ ] No + CAM:[SAMSUNG TECHWIN ] [VLUU NV10, NV10 ] [ ] No + CAM:[SONY ] [CYBERSHOT ] [ ] No + CAM:[SONY ] [DSC-H1 ] [ ] No + CAM:[SONY ] [DSC-H2 ] [ ] No + CAM:[SONY ] [DSC-H5 ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-L1 ] [ ] No + CAM:[SONY ] [DSC-N2 ] [ ] No + CAM:[SONY ] [DSC-P150 ] [ ] No + CAM:[SONY ] [DSC-P200 ] [ ] No + CAM:[SONY ] [DSC-R1 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-V1 ] [ ] No + CAM:[SONY ] [DSC-V3 ] [ ] No + CAM:[SONY ] [DSC-W35 ] [ ] No + CAM:[SONY ] [DSC-W7 ] [ ] No + CAM:[SONY ] [SONY ] [ ] No + SW :[IJG Library ] [097 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [097 ] + SW :[IrfanView ] [097 ] + SW :[idImager ] [097 ] + SW :[FastStone Image Viewer ] [097 ] + SW :[NeatImage ] [097 ] + SW :[Paint.NET ] [097 ] + SW :[Photomatix ] [097 ] + SW :[XnView ] [097 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 4 - Uncertain if processed or original + While the EXIF fields indicate original, no compression signatures + in the current database were found matching this make/model + + Appears to be new signature for known camera. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/progressive/JpegSnoopReports/BadEofProgressive.jpg.txt b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/BadEofProgressive.jpg.txt new file mode 100644 index 000000000..b6a1fe809 --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/BadEofProgressive.jpg.txt @@ -0,0 +1,452 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\BadEofProgressive.jpg] + Filesize: [67503] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.2] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: APP13 (xFFED) *** + OFFSET: 0x00000014 + Length = 124 + Identifier = [Photoshop 3.0] + 8BIM: [0x0404] Name="" Len=[0x005F] DefinedName="IPTC-NAA record" + IPTC [002:040] Special Instructions = "FBMD2300098903000068210000c735000008450000e88e0000fab00000c6cd000002f80000191a0100653f0100" + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x00000092 + Length = 540 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 524 bytes + Preferred CMM Type : 'lcms' (0x6C636D73) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 2012-01-25 03:41:57 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : '....' (0x00000000) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'lcms' (0x6C636D73) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000002B0 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 6 4 4 6 10 16 20 24 + DQT, Row #1: 5 5 6 8 10 23 24 22 + DQT, Row #2: 6 5 6 10 16 23 28 22 + DQT, Row #3: 6 7 9 12 20 35 32 25 + DQT, Row #4: 7 9 15 22 27 44 41 31 + DQT, Row #5: 10 14 22 26 32 42 45 37 + DQT, Row #6: 20 26 31 35 41 48 48 40 + DQT, Row #7: 29 37 38 39 45 40 41 40 + Approx quality factor = 79.94 (scaling=40.12 variance=1.43) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x000002F5 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 7 7 10 19 40 40 40 40 + DQT, Row #1: 7 8 10 26 40 40 40 40 + DQT, Row #2: 10 10 22 40 40 40 40 40 + DQT, Row #3: 19 26 40 40 40 40 40 40 + DQT, Row #4: 40 40 40 40 40 40 40 40 + DQT, Row #5: 40 40 40 40 40 40 40 40 + DQT, Row #6: 40 40 40 40 40 40 40 40 + DQT, Row #7: 40 40 40 40 40 40 40 40 + Approx quality factor = 79.87 (scaling=40.26 variance=0.36) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000033A + Frame header length = 17 + Precision = 8 + Number of Lines = 640 + Samples per Line = 640 + Image Size = 640 x 640 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000034D + Huffman table length = 29 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (007 total): 01 02 03 04 05 06 07 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (001 total): 08 + Codes of length 06 bits (001 total): 09 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000036C + Huffman table length = 27 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (003 total): 00 03 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 07 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000389 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),0(AC) + Component[3]: selector=0x02, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002127 + Huffman table length = 63 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (004 total): 00 02 03 11 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (002 total): 05 41 + Codes of length 07 bits (003 total): 13 22 51 + Codes of length 08 bits (004 total): 10 32 61 A1 + Codes of length 09 bits (007 total): 14 20 71 81 91 B1 F0 + Codes of length 10 bits (007 total): 06 23 42 52 C1 D1 E1 + Codes of length 11 bits (002 total): 15 30 + Codes of length 12 bits (005 total): 16 24 33 34 62 + Codes of length 13 bits (005 total): 25 40 50 72 F1 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 044 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002168 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003588 + Huffman table length = 61 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (003 total): 04 12 21 + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (004 total): 05 10 13 51 + Codes of length 08 bits (003 total): 14 20 22 + Codes of length 09 bits (005 total): 32 42 61 71 91 + Codes of length 10 bits (007 total): 15 23 33 81 A1 B1 C1 + Codes of length 11 bits (003 total): 06 30 D1 + Codes of length 12 bits (002 total): E1 F0 + Codes of length 13 bits (007 total): 16 24 34 40 43 50 52 + Codes of length 14 bits (001 total): 62 + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 042 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000035C7 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x00 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000044BF + Huffman table length = 71 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (003 total): 12 21 31 + Codes of length 06 bits (004 total): 13 22 41 51 + Codes of length 07 bits (007 total): 05 10 20 32 61 71 81 + Codes of length 08 bits (005 total): 14 23 42 52 91 + Codes of length 09 bits (005 total): 30 33 62 72 A1 + Codes of length 10 bits (007 total): 15 34 43 53 82 92 B1 + Codes of length 11 bits (003 total): 06 24 40 + Codes of length 12 bits (004 total): 44 A2 C1 D1 + Codes of length 13 bits (001 total): E1 + Codes of length 14 bits (004 total): 25 35 50 F0 + Codes of length 15 bits (003 total): 54 63 73 + Codes of length 16 bits (000 total): + Total number of codes: 052 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00004508 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00008EC5 + Huffman table length = 33 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 10 21 31 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (001 total): 51 + Codes of length 08 bits (001 total): 20 + Codes of length 09 bits (001 total): 61 + Codes of length 10 bits (001 total): 71 + Codes of length 11 bits (001 total): 30 + Codes of length 12 bits (001 total): 81 + Codes of length 13 bits (001 total): 40 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 014 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00008EE8 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 10 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000B0CE + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (006 total): 10 41 51 61 71 91 + Codes of length 06 bits (002 total): 20 81 + Codes of length 07 bits (001 total): 30 + Codes of length 08 bits (005 total): 40 A1 B1 C1 F0 + Codes of length 09 bits (001 total): D1 + Codes of length 10 bits (001 total): F1 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (001 total): 50 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000B0FA + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 11 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000CDA4 + Huffman table length = 32 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (001 total): 10 + Codes of length 07 bits (001 total): 41 + Codes of length 08 bits (001 total): 51 + Codes of length 09 bits (001 total): 20 + Codes of length 10 bits (001 total): 61 + Codes of length 11 bits (001 total): 71 + Codes of length 12 bits (001 total): 81 + Codes of length 13 bits (001 total): 91 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 013 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000CDC6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 10 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000F7DF + Huffman table length = 33 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 10 41 + Codes of length 06 bits (003 total): 51 61 71 + Codes of length 07 bits (001 total): 20 + Codes of length 08 bits (001 total): 81 + Codes of length 09 bits (001 total): 30 + Codes of length 10 bits (001 total): 40 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 014 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000F802 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 11 .. 19 + Successive approximation = 0x10 +ERROR: Ran out of buffer before EOI during phase 1 of Scan decode @ 0x000107B0 + + NOTE: Scan parsing doesn't support this SOF mode. + +ERROR: Early EOF - file may be missing EOI + +*** Searching Compression Signatures *** + + Signature: 01DC499064BA9264D591FDE9071DFD89 + Signature (Rotated): 0175BAF3251040E0EFB2930B73328E7F + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C40Z,D40Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C700UZ ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + SW :[Apple ImageIO.framework ] [050 (Normal) ] + SW :[IJG Library ] [080 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [080 ] + SW :[IrfanView ] [080 ] + SW :[idImager ] [080 ] + SW :[FastStone Image Viewer ] [080 ] + SW :[NeatImage ] [080 ] + SW :[Paint.NET ] [080 ] + SW :[Photomatix ] [080 ] + SW :[XnView ] [080 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/progressive/JpegSnoopReports/ExifUndefType.jpg.txt b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/ExifUndefType.jpg.txt new file mode 100644 index 000000000..397343c5e --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/ExifUndefType.jpg.txt @@ -0,0 +1,535 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\ExifUndefType.jpg] + Filesize: [6582] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 72 x 72 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: APP1 (xFFE1) *** + OFFSET: 0x00000014 + Length = 804 + Identifier = [Exif] + Identifier TIFF = 0x[49492A00 86020000] + Endian = Intel (little) + TAG Mark x002A = 0x002A + + EXIF IFD0 @ Absolute 0x000002A4 + Dir Length = 0x000C + [Orientation ] = 1 = Row 0: top, Col 0: left + [XResolution ] = 72/1 + [YResolution ] = 72/1 + [ResolutionUnit ] = Inch + [Software ] = "Adobe Photoshop CS4 Windows" + [DateTime ] = "2014:03:28 16:44:10" + [WhitePoint ] = 0/1000000, 0/1000000 + [PrimChromaticities ] = 0/1000000, 0/1000000, 0/1000000, 0/1000000, 0/1000000, 0/1000000 + [YCbCrCoefficients ] = 0/1000000, 0/1000000, 0/1000000 + [YCbCrPositioning ] = 0 + [ReferenceBlackWhite ] = 0/1000000, 0/1000000, 0/1000000, 0/1000000, 0/1000000, 0/1000000 + [ExifOffset ] = @ 0x0138 + Offset to Next IFD = 0x00000000 + + EXIF SubIFD @ Absolute 0x00000156 + Dir Length = 0x001B + [ExposureTime ] = 0/1000000 s + [FNumber ] = F0.0 + [ExposureProgram ] = Not defined + [ISOSpeedRatings ] = 0, 0 + [ExifVersion ] = 12.20 + [CompressedBitsPerPixel ] = 0/1000000 + [ShutterSpeedValue ] = 0/1000000 + [ApertureValue ] = 0/1000000 + [BrightnessValue ] = 0/1000000 + [ExposureBiasValue ] = 0.00 eV + [MaxApertureValue ] = 0/1000000 + [SubjectDistance ] = 0/1000000 + [MeteringMode ] = Unknown + [LightSource ] = unknown + [Flash ] = Flash did not fire + [FocalLength ] = 0 mm + [FlashPixVersion ] = + [ColorSpace ] = sRGB + [ExifImageWidth ] = 850 + [ExifImageHeight ] = 638 + [FocalPlaneXResolution ] = 0/1000000 + [FocalPlaneYResolution ] = 0/1000000 + [FocalPlaneResolutionUnit ] = 0 + [ExposureIndex ] = 0/1000000 + [SensingMethod ] = 0 + [FileSource ] = 0 + [SceneType ] = 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000033A + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 3 2 2 3 5 8 10 12 + DQT, Row #1: 2 2 3 4 5 12 12 11 + DQT, Row #2: 3 3 3 5 8 11 14 11 + DQT, Row #3: 3 3 4 6 10 17 16 12 + DQT, Row #4: 4 4 7 11 14 22 21 15 + DQT, Row #5: 5 7 11 13 16 21 23 18 + DQT, Row #6: 10 13 16 17 21 24 24 20 + DQT, Row #7: 14 18 19 20 22 20 21 20 + Approx quality factor = 90.06 (scaling=19.88 variance=1.14) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000037F + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 3 4 5 9 20 20 20 20 + DQT, Row #1: 4 4 5 13 20 20 20 20 + DQT, Row #2: 5 5 11 20 20 20 20 20 + DQT, Row #3: 9 13 20 20 20 20 20 20 + DQT, Row #4: 20 20 20 20 20 20 20 20 + DQT, Row #5: 20 20 20 20 20 20 20 20 + DQT, Row #6: 20 20 20 20 20 20 20 20 + DQT, Row #7: 20 20 20 20 20 20 20 20 + Approx quality factor = 89.93 (scaling=20.14 variance=0.34) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x000003C4 + Frame header length = 17 + Precision = 8 + Number of Lines = 165 + Samples per Line = 220 + Image Size = 220 x 165 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000003D7 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 03 07 + Codes of length 04 bits (003 total): 02 04 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (001 total): 01 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000003F5 + Huffman table length = 22 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (000 total): + Codes of length 05 bits (000 total): + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 003 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000040D + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000581 + Huffman table length = 41 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (006 total): 00 01 02 03 04 05 + Codes of length 04 bits (001 total): 06 + Codes of length 05 bits (003 total): 11 15 16 + Codes of length 06 bits (004 total): 12 13 14 21 + Codes of length 07 bits (002 total): 07 10 + Codes of length 08 bits (002 total): 22 40 + Codes of length 09 bits (003 total): 17 30 60 + Codes of length 10 bits (001 total): 24 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000005AC + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000883 + Huffman table length = 27 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 11 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 01 10 + Codes of length 05 bits (003 total): 20 30 40 + Codes of length 06 bits (001 total): 50 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000008A0 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000008BF + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (001 total): 01 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 10 21 30 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 20 40 50 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000008DD + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000905 + Huffman table length = 65 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (000 total): + Codes of length 03 bits (004 total): 00 01 02 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (004 total): 12 21 31 34 + Codes of length 06 bits (008 total): 13 32 33 35 91 92 93 D2 + Codes of length 07 bits (009 total): 05 10 14 22 41 51 71 A1 D1 + Codes of length 08 bits (010 total): 20 23 40 42 52 61 81 A2 A3 B1 + Codes of length 09 bits (007 total): 15 24 60 62 72 E1 E2 + Codes of length 10 bits (001 total): 30 + Codes of length 11 bits (001 total): B2 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 046 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000948 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000E49 + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (004 total): 51 61 71 D1 + Codes of length 07 bits (006 total): 81 91 A1 C1 F0 F1 + Codes of length 08 bits (002 total): 40 B1 + Codes of length 09 bits (003 total): 10 20 60 + Codes of length 10 bits (001 total): 30 + Codes of length 11 bits (001 total): E1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000E75 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001266 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000012E8 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (001 total): 10 + Codes of length 04 bits (000 total): + Codes of length 05 bits (002 total): 30 51 + Codes of length 06 bits (003 total): 21 40 50 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001306 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000133E + Huffman table length = 30 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (003 total): 10 30 51 + Codes of length 05 bits (000 total): + Codes of length 06 bits (002 total): 20 61 + Codes of length 07 bits (003 total): 21 40 50 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000135E + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000139C + Huffman table length = 42 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (003 total): 41 51 61 + Codes of length 07 bits (003 total): 71 81 B1 + Codes of length 08 bits (003 total): 91 A1 D1 + Codes of length 09 bits (004 total): 10 40 E1 F0 + Codes of length 10 bits (003 total): 20 C1 F1 + Codes of length 11 bits (001 total): 60 + Codes of length 12 bits (001 total): 30 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 023 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000013C8 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x000019B4 + + +*** Searching Compression Signatures *** + + Signature: 013BA18D5561625796E986FDBC09F846 + Signature (Rotated): 01AC57E12793DFA7C46C704625C5AF0F + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: OK [Adobe Photoshop CS4 Windows] + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[??? ] [Treo 680 ] [ ] Yes + CAM:[Canon ] [Canon PowerShot Pro1 ] [fine ] No + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[NIKON ] [E3100 ] [FINE ] No + CAM:[NIKON ] [E4500 ] [FINE ] No + CAM:[NIKON ] [E5000 ] [FINE ] No + CAM:[NIKON ] [E5700 ] [FINE ] No + CAM:[NIKON ] [E775 ] [FINE ] No + CAM:[NIKON ] [E885 ] [FINE ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 9530 ] [Superfine ] Yes + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + CAM:[SONY ] [DSC-H7 ] [ ] No + CAM:[SONY ] [DSC-H9 ] [ ] No + CAM:[SONY ] [DSC-S90 ] [ ] No + CAM:[SONY ] [DSC-W1 ] [ ] No + CAM:[SONY ] [SONY ] [ ] No + SW :[ACDSee ] [ ] + SW :[FixFoto ] [fine ] + SW :[IJG Library ] [090 ] + SW :[ZoomBrowser EX ] [high ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [090 ] + SW :[IrfanView ] [090 ] + SW :[idImager ] [090 ] + SW :[FastStone Image Viewer ] [090 ] + SW :[NeatImage ] [090 ] + SW :[Paint.NET ] [090 ] + SW :[Photomatix ] [090 ] + SW :[XnView ] [090 ] + + NOTE: EXIF Software field recognized as from editor + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + Appears to be new signature for known software. + If the camera/software doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/progressive/JpegSnoopReports/Festzug.jpg.txt b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/Festzug.jpg.txt new file mode 100644 index 000000000..445e80a7e --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/Festzug.jpg.txt @@ -0,0 +1,459 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\Festzug.jpg] + Filesize: [49977] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 229 x 229 DPI (dots per inch) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 131 + ---- + Precision=16 bits + Destination ID=0 (Luminance) + DQT, Row #0: 53 37 33 53 80 133 170 203 + DQT, Row #1: 40 40 47 63 87 193 200 183 + DQT, Row #2: 47 43 53 80 133 190 230 186 + DQT, Row #3: 47 57 73 97 170 290 266 206 + DQT, Row #4: 60 73 123 186 226 363 343 256 + DQT, Row #5: 80 117 183 213 270 346 376 306 + DQT, Row #6: 163 213 260 290 343 403 400 336 + DQT, Row #7: 240 306 316 326 373 333 343 330 + Approx quality factor = 15.01 (scaling=333.00 variance=1.25) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000099 + Table length = 131 + ---- + Precision=16 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 57 60 80 157 330 330 330 330 + DQT, Row #1: 60 70 87 220 330 330 330 330 + DQT, Row #2: 80 87 186 330 330 330 330 330 + DQT, Row #3: 157 220 330 330 330 330 330 330 + DQT, Row #4: 330 330 330 330 330 330 330 330 + DQT, Row #5: 330 330 330 330 330 330 330 330 + DQT, Row #6: 330 330 330 330 330 330 330 330 + DQT, Row #7: 330 330 330 330 330 330 330 330 + Approx quality factor = 15.00 (scaling=333.41 variance=0.14) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000011E + Frame header length = 17 + Precision = 8 + Number of Lines = 1071 + Samples per Line = 1443 + Image Size = 1443 x 1071 + Raw Image Orientation = Landscape + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000131 + Huffman table length = 25 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 03 + Codes of length 05 bits (001 total): 04 + Codes of length 06 bits (001 total): 05 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 006 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000014C + Huffman table length = 22 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (001 total): 00 + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (000 total): + Codes of length 05 bits (000 total): + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 003 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000164 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000028E0 + Huffman table length = 38 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (004 total): 02 10 20 30 + Codes of length 05 bits (003 total): 12 31 40 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 21 41 50 + Codes of length 08 bits (001 total): 60 + Codes of length 09 bits (001 total): 03 + Codes of length 10 bits (000 total): + Codes of length 11 bits (003 total): 22 32 42 + Codes of length 12 bits (001 total): 13 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 019 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002908 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003D97 + Huffman table length = 29 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (003 total): 00 10 11 + Codes of length 04 bits (001 total): 20 + Codes of length 05 bits (000 total): + Codes of length 06 bits (002 total): 30 60 + Codes of length 07 bits (003 total): 80 90 C0 + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 010 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003DB6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003DE1 + Huffman table length = 28 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 10 11 + Codes of length 04 bits (003 total): 00 20 60 + Codes of length 05 bits (000 total): + Codes of length 06 bits (003 total): 80 90 C0 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003DFF + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003E21 + Huffman table length = 23 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 21 + Codes of length 02 bits (001 total): D0 + Codes of length 03 bits (001 total): A0 + Codes of length 04 bits (001 total): B0 + Codes of length 05 bits (000 total): + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 004 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003E3A + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003E4C + Huffman table length = 36 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 10 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (003 total): 20 30 41 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 40 50 51 + Codes of length 08 bits (001 total): 61 + Codes of length 09 bits (001 total): 60 + Codes of length 10 bits (001 total): 71 + Codes of length 11 bits (001 total): 81 + Codes of length 12 bits (001 total): B1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 017 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00003E72 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00006325 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007512 + Huffman table length = 30 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (003 total): 10 21 60 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 20 41 80 + Codes of length 08 bits (001 total): C0 + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00007532 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000075CE + Huffman table length = 30 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 11 + Codes of length 03 bits (001 total): 10 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 21 31 60 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (000 total): + Codes of length 08 bits (003 total): 20 80 C0 + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 011 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000075EE + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00007676 + Huffman table length = 43 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (000 total): + Codes of length 05 bits (002 total): 21 31 + Codes of length 06 bits (002 total): 10 41 + Codes of length 07 bits (002 total): 20 51 + Codes of length 08 bits (002 total): 30 61 + Codes of length 09 bits (003 total): 40 50 71 + Codes of length 10 bits (000 total): + Codes of length 11 bits (003 total): 60 81 91 + Codes of length 12 bits (001 total): A1 + Codes of length 13 bits (001 total): B1 + Codes of length 14 bits (000 total): + Codes of length 15 bits (002 total): C1 D1 + Codes of length 16 bits (003 total): E1 F0 F1 + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000076A3 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000C337 + + +*** Searching Compression Signatures *** + + Signature: 0105A3D95D2D36DE9351313E30D8E945 + Signature (Rotated): 013C3A43642D2E8325A76C3818B3C324 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + SW :[IJG Library ] [015 ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [015 ] + SW :[IrfanView ] [015 ] + SW :[idImager ] [015 ] + SW :[FastStone Image Viewer ] [015 ] + SW :[NeatImage ] [015 ] + SW :[Paint.NET ] [015 ] + SW :[Photomatix ] [015 ] + SW :[XnView ] [015 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/progressive/JpegSnoopReports/fb.jpg.txt b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/fb.jpg.txt new file mode 100644 index 000000000..6f20fc1ee --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/fb.jpg.txt @@ -0,0 +1,525 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\fb.jpg] + Filesize: [15787] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.2] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: COM (Comment) (xFFFE) *** + OFFSET: 0x00000014 + Comment length = 4 + Comment=*. + +*** Marker: APP2 (xFFE2) *** + OFFSET: 0x0000001A + Length = 540 + Identifier = [ICC_PROFILE] + ICC Profile: + Marker Number = 1 of 1 + Profile Size : 524 bytes + Preferred CMM Type : 'lcms' (0x6C636D73) + Profile Version : 0.2.1.0 (0x02100000) + Profile Device/Class : Display Device profile ('mntr' (0x6D6E7472)) + Data Colour Space : rgbData ('RGB ' (0x52474220)) + Profile connection space (PCS) : 'XYZ ' (0x58595A20) + Profile creation date : 2012-01-25 03:41:57 + Profile file signature : 'acsp' (0x61637370) + Primary platform : Apple Computer, Inc. ('APPL' (0x4150504C)) + Profile flags : 0x00000000 + Profile flags > Profile not embedded + Profile flags > Profile can't be used independently of embedded + Device Manufacturer : '....' (0x00000000) + Device Model : '....' (0x00000000) + Device attributes : 0x00000000_00000000 + Device attributes > Reflective + Device attributes > Glossy + Device attributes > Media polarity = negative + Device attributes > Black & white media + Rendering intent : Perceptual + Profile creator : 'lcms' (0x6C636D73) + Profile ID : 0x00000000_00000000_00000000_00000000 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000238 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 8 6 5 8 12 20 26 31 + DQT, Row #1: 6 6 7 10 13 29 30 28 + DQT, Row #2: 7 7 8 12 20 29 35 28 + DQT, Row #3: 7 9 11 15 26 44 40 31 + DQT, Row #4: 9 11 19 28 34 55 52 39 + DQT, Row #5: 12 18 28 32 41 52 57 46 + DQT, Row #6: 25 32 39 44 52 61 60 51 + DQT, Row #7: 36 46 48 49 56 50 52 50 + Approx quality factor = 74.75 (scaling=50.51 variance=0.81) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x0000027D + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 9 9 12 24 50 50 50 50 + DQT, Row #1: 9 11 13 33 50 50 50 50 + DQT, Row #2: 12 13 28 50 50 50 50 50 + DQT, Row #3: 24 33 50 50 50 50 50 50 + DQT, Row #4: 50 50 50 50 50 50 50 50 + DQT, Row #5: 50 50 50 50 50 50 50 50 + DQT, Row #6: 50 50 50 50 50 50 50 50 + DQT, Row #7: 50 50 50 50 50 50 50 50 + Approx quality factor = 74.74 (scaling=50.52 variance=0.19) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x000002C2 + Frame header length = 17 + Precision = 8 + Number of Lines = 336 + Samples per Line = 276 + Image Size = 276 x 336 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x00, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x01, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000002D5 + Huffman table length = 27 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 04 + Codes of length 03 bits (005 total): 00 02 03 05 06 + Codes of length 04 bits (001 total): 01 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 008 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000002F2 + Huffman table length = 24 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 03 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (000 total): + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 005 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000030C + Huffman table length = 24 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (003 total): 00 01 03 + Codes of length 03 bits (001 total): 02 + Codes of length 04 bits (001 total): 04 + Codes of length 05 bits (000 total): + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 005 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000326 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000935 + Huffman table length = 43 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 02 03 + Codes of length 03 bits (002 total): 01 04 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (002 total): 11 12 + Codes of length 06 bits (006 total): 05 10 13 20 31 32 + Codes of length 07 bits (002 total): 21 33 + Codes of length 08 bits (002 total): 14 22 + Codes of length 09 bits (002 total): 34 41 + Codes of length 10 bits (003 total): 15 23 30 + Codes of length 11 bits (001 total): 24 + Codes of length 12 bits (001 total): 42 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 024 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000962 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000012EE + Huffman table length = 39 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 10 + Codes of length 05 bits (004 total): 03 20 21 31 + Codes of length 06 bits (001 total): 12 + Codes of length 07 bits (004 total): 13 30 41 51 + Codes of length 08 bits (001 total): 22 + Codes of length 09 bits (005 total): 32 40 42 50 61 + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 020 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001317 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000142A + Huffman table length = 36 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (001 total): 10 + Codes of length 05 bits (004 total): 03 20 21 31 + Codes of length 06 bits (002 total): 12 30 + Codes of length 07 bits (002 total): 13 41 + Codes of length 08 bits (003 total): 22 40 51 + Codes of length 09 bits (001 total): 50 + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 017 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001450 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x0000155A + Huffman table length = 51 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (002 total): 00 02 + Codes of length 04 bits (003 total): 03 10 11 + Codes of length 05 bits (006 total): 12 20 21 31 41 51 + Codes of length 06 bits (005 total): 22 32 61 71 81 + Codes of length 07 bits (002 total): 13 30 + Codes of length 08 bits (005 total): 04 33 42 72 91 + Codes of length 09 bits (004 total): 14 52 62 A1 + Codes of length 10 bits (003 total): 23 82 B1 + Codes of length 11 bits (001 total): 43 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 032 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000158F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00001D3E + Huffman table length = 40 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 11 21 + Codes of length 04 bits (001 total): 31 + Codes of length 05 bits (003 total): 10 41 51 + Codes of length 06 bits (004 total): 20 61 71 A1 + Codes of length 07 bits (002 total): 81 91 + Codes of length 08 bits (002 total): B1 F0 + Codes of length 09 bits (003 total): 30 C1 D1 + Codes of length 10 bits (001 total): E1 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 021 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00001D68 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000028B9 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x00, table=0(DC),0(AC) + Component[2]: selector=0x01, table=1(DC),1(AC) + Component[3]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000029E4 + Huffman table length = 32 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (000 total): + Codes of length 05 bits (003 total): 10 21 31 + Codes of length 06 bits (000 total): + Codes of length 07 bits (003 total): 20 41 51 + Codes of length 08 bits (001 total): 30 + Codes of length 09 bits (001 total): 61 + Codes of length 10 bits (001 total): 40 + Codes of length 11 bits (001 total): 50 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 013 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002A06 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002B55 + Huffman table length = 32 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (003 total): 10 21 31 + Codes of length 05 bits (001 total): 20 + Codes of length 06 bits (001 total): 41 + Codes of length 07 bits (000 total): + Codes of length 08 bits (003 total): 30 51 61 + Codes of length 09 bits (001 total): 71 + Codes of length 10 bits (001 total): 40 + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 013 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002B77 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=1(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002CEA + Huffman table length = 40 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (003 total): 31 41 51 + Codes of length 06 bits (003 total): 10 61 71 + Codes of length 07 bits (004 total): 81 91 A1 B1 + Codes of length 08 bits (003 total): 20 C1 F0 + Codes of length 09 bits (001 total): D1 + Codes of length 10 bits (001 total): E1 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (001 total): 30 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 021 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00002D14 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x00, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x00003DA9 + + +*** Searching Compression Signatures *** + + Signature: 0182408A81A4ABF04D4A34A8A5E98C58 + Signature (Rotated): 012D821C6AB210E2A753BE053B8F55D0 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[SONY ] [CYBERSHOT U ] [ ] Yes + SW :[Adobe Photoshop 7.0 ] [Save As 07 ] + SW :[Apple Quicktime ] [0466-0467 ] + SW :[Digital Photo Professiona] [05 ] + SW :[IJG Library ] [075 ] + SW :[MS Paint ] [ ] + SW :[MS Visio ] [ ] + SW :[ZoomBrowser EX ] [low ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [075 ] + SW :[IrfanView ] [075 ] + SW :[idImager ] [075 ] + SW :[FastStone Image Viewer ] [075 ] + SW :[NeatImage ] [075 ] + SW :[Paint.NET ] [075 ] + SW :[Photomatix ] [075 ] + SW :[XnView ] [075 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + diff --git a/tests/Images/Input/Jpg/progressive/JpegSnoopReports/progress.jpg.txt b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/progress.jpg.txt new file mode 100644 index 000000000..f38a11532 --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/JpegSnoopReports/progress.jpg.txt @@ -0,0 +1,468 @@ + +JPEGsnoop 1.8.0 by Calvin Hass + http://www.impulseadventure.com/photo/ + ------------------------------------- + + Filename: [.\progress.jpg] + Filesize: [44884] Bytes + +Start Offset: 0x00000000 +*** Marker: SOI (xFFD8) *** + OFFSET: 0x00000000 + +*** Marker: APP0 (xFFE0) *** + OFFSET: 0x00000002 + Length = 16 + Identifier = [JFIF] + version = [1.1] + density = 1 x 1 (aspect ratio) + thumbnail = 0 x 0 + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000014 + Table length = 67 + ---- + Precision=8 bits + Destination ID=0 (Luminance) + DQT, Row #0: 5 3 3 5 7 12 15 18 + DQT, Row #1: 4 4 4 6 8 17 18 17 + DQT, Row #2: 4 4 5 7 12 17 21 17 + DQT, Row #3: 4 5 7 9 15 26 24 19 + DQT, Row #4: 5 7 11 17 20 33 31 23 + DQT, Row #5: 7 11 17 19 24 31 34 28 + DQT, Row #6: 15 19 23 26 31 36 36 30 + DQT, Row #7: 22 28 29 29 34 30 31 30 + Approx quality factor = 84.93 (scaling=30.13 variance=1.05) + +*** Marker: DQT (xFFDB) *** + Define a Quantization Table. + OFFSET: 0x00000059 + Table length = 67 + ---- + Precision=8 bits + Destination ID=1 (Chrominance) + DQT, Row #0: 5 5 7 14 30 30 30 30 + DQT, Row #1: 5 6 8 20 30 30 30 30 + DQT, Row #2: 7 8 17 30 30 30 30 30 + DQT, Row #3: 14 20 30 30 30 30 30 30 + DQT, Row #4: 30 30 30 30 30 30 30 30 + DQT, Row #5: 30 30 30 30 30 30 30 30 + DQT, Row #6: 30 30 30 30 30 30 30 30 + DQT, Row #7: 30 30 30 30 30 30 30 30 + Approx quality factor = 84.93 (scaling=30.15 variance=0.29) + +*** Marker: SOF2 (Progressive DCT, Huffman) (xFFC2) *** + OFFSET: 0x0000009E + Frame header length = 17 + Precision = 8 + Number of Lines = 486 + Samples per Line = 341 + Image Size = 341 x 486 + Raw Image Orientation = Portrait + Number of Img components = 3 + Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y) + Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb) + Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr) + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000B1 + Huffman table length = 28 + ---- + Destination ID = 0 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 04 + Codes of length 03 bits (005 total): 01 02 03 05 06 + Codes of length 04 bits (001 total): 00 + Codes of length 05 bits (001 total): 07 + Codes of length 06 bits (001 total): 08 + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 009 + + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000000CF + Huffman table length = 26 + ---- + Destination ID = 1 + Class = 0 (DC / Lossless Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 02 03 + Codes of length 03 bits (003 total): 00 01 04 + Codes of length 04 bits (001 total): 05 + Codes of length 05 bits (001 total): 06 + Codes of length 06 bits (000 total): + Codes of length 07 bits (000 total): + Codes of length 08 bits (000 total): + Codes of length 09 bits (000 total): + Codes of length 10 bits (000 total): + Codes of length 11 bits (000 total): + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 007 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000000EB + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=1(DC),0(AC) + Component[3]: selector=0x03, table=1(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00000CCC + Huffman table length = 45 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 01 02 + Codes of length 03 bits (002 total): 00 03 + Codes of length 04 bits (002 total): 04 11 + Codes of length 05 bits (001 total): 12 + Codes of length 06 bits (003 total): 05 13 21 + Codes of length 07 bits (003 total): 10 22 31 + Codes of length 08 bits (004 total): 14 20 32 41 + Codes of length 09 bits (002 total): 06 23 + Codes of length 10 bits (002 total): 30 33 + Codes of length 11 bits (003 total): 15 24 42 + Codes of length 12 bits (001 total): 34 + Codes of length 13 bits (001 total): 43 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 026 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00000CFB + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 5 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000020DC + Huffman table length = 46 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 03 + Codes of length 04 bits (001 total): 11 + Codes of length 05 bits (004 total): 04 10 21 31 + Codes of length 06 bits (001 total): 12 + Codes of length 07 bits (003 total): 13 20 41 + Codes of length 08 bits (003 total): 05 22 51 + Codes of length 09 bits (003 total): 23 32 61 + Codes of length 10 bits (005 total): 14 30 33 42 71 + Codes of length 11 bits (000 total): + Codes of length 12 bits (003 total): 15 52 91 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 027 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000210C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00002604 + Huffman table length = 41 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (002 total): 00 01 + Codes of length 03 bits (002 total): 02 11 + Codes of length 04 bits (002 total): 03 10 + Codes of length 05 bits (002 total): 21 31 + Codes of length 06 bits (002 total): 12 20 + Codes of length 07 bits (001 total): 13 + Codes of length 08 bits (004 total): 04 22 41 61 + Codes of length 09 bits (002 total): 42 51 + Codes of length 10 bits (002 total): 14 32 + Codes of length 11 bits (003 total): 33 71 F0 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 022 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000262F + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x01 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000029A7 + Huffman table length = 61 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (000 total): + Codes of length 02 bits (001 total): 01 + Codes of length 03 bits (003 total): 00 02 11 + Codes of length 04 bits (003 total): 03 12 21 + Codes of length 05 bits (001 total): 31 + Codes of length 06 bits (005 total): 10 22 41 51 61 + Codes of length 07 bits (006 total): 04 13 20 32 71 81 + Codes of length 08 bits (005 total): 23 30 42 52 91 + Codes of length 09 bits (002 total): A1 B1 + Codes of length 10 bits (004 total): 62 72 C1 F0 + Codes of length 11 bits (006 total): 14 33 40 82 D1 E1 + Codes of length 12 bits (001 total): 24 + Codes of length 13 bits (005 total): 05 43 53 73 F1 + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 042 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000029E6 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 6 .. 63 + Successive approximation = 0x02 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00003FF3 + Huffman table length = 39 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (002 total): 21 31 + Codes of length 05 bits (002 total): 41 51 + Codes of length 06 bits (001 total): 61 + Codes of length 07 bits (003 total): 71 81 91 + Codes of length 08 bits (004 total): 10 A1 B1 C1 + Codes of length 09 bits (003 total): D1 E1 F0 + Codes of length 10 bits (001 total): 20 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 020 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x0000401C + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x21 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00006299 + Scan header length = 12 + Number of img components = 3 + Component[1]: selector=0x01, table=0(DC),0(AC) + Component[2]: selector=0x02, table=0(DC),0(AC) + Component[3]: selector=0x03, table=0(DC),0(AC) + Spectral selection = 0 .. 0 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x000064A9 + Huffman table length = 39 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (000 total): + Codes of length 03 bits (002 total): 00 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (003 total): 31 41 51 + Codes of length 06 bits (003 total): 10 61 71 + Codes of length 07 bits (004 total): 81 91 D1 F0 + Codes of length 08 bits (003 total): A1 B1 E1 + Codes of length 09 bits (001 total): C1 + Codes of length 10 bits (001 total): F1 + Codes of length 11 bits (001 total): 20 + Codes of length 12 bits (000 total): + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 020 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x000064D2 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x03, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00006ACB + Huffman table length = 38 + ---- + Destination ID = 1 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 00 + Codes of length 03 bits (001 total): 11 + Codes of length 04 bits (001 total): 21 + Codes of length 05 bits (000 total): + Codes of length 06 bits (002 total): 31 41 + Codes of length 07 bits (002 total): 10 51 + Codes of length 08 bits (001 total): 61 + Codes of length 09 bits (003 total): 91 D1 F0 + Codes of length 10 bits (005 total): 71 81 A1 B1 C1 + Codes of length 11 bits (001 total): 20 + Codes of length 12 bits (001 total): E1 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 019 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00006AF3 + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x02, table=0(DC),1(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: DHT (Define Huffman Table) (xFFC4) *** + OFFSET: 0x00006F95 + Huffman table length = 38 + ---- + Destination ID = 0 + Class = 1 (AC Table) + Codes of length 01 bits (001 total): 01 + Codes of length 02 bits (001 total): 11 + Codes of length 03 bits (000 total): + Codes of length 04 bits (002 total): 00 21 + Codes of length 05 bits (002 total): 31 41 + Codes of length 06 bits (002 total): 51 61 + Codes of length 07 bits (002 total): 71 81 + Codes of length 08 bits (002 total): 91 A1 + Codes of length 09 bits (002 total): B1 F0 + Codes of length 10 bits (003 total): C1 D1 E1 + Codes of length 11 bits (001 total): F1 + Codes of length 12 bits (001 total): 10 + Codes of length 13 bits (000 total): + Codes of length 14 bits (000 total): + Codes of length 15 bits (000 total): + Codes of length 16 bits (000 total): + Total number of codes: 019 + + +*** Marker: SOS (Start of Scan) (xFFDA) *** + OFFSET: 0x00006FBD + Scan header length = 8 + Number of img components = 1 + Component[1]: selector=0x01, table=0(DC),0(AC) + Spectral selection = 1 .. 63 + Successive approximation = 0x10 + + NOTE: Scan parsing doesn't support this SOF mode. + +*** Marker: EOI (End of Image) (xFFD9) *** + OFFSET: 0x0000AF52 + + +*** Searching Compression Signatures *** + + Signature: 0155D875C95B74D0F3C5835A62516F48 + Signature (Rotated): 01D38A25358EB7649A254E19F1D46600 + File Offset: 0 bytes + Chroma subsampling: 2x2 + EXIF Make/Model: NONE + EXIF Makernotes: NONE + EXIF Software: NONE + + Searching Compression Signatures: (3347 built-in, 0 user(*) ) + + EXIF.Make / Software EXIF.Model Quality Subsamp Match? + ------------------------- ----------------------------------- ---------------- -------------- + CAM:[NIKON ] [E2500 ] [FINE ] No + CAM:[Nokia ] [N73 ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C2000Z ] [ ] No + CAM:[OLYMPUS OPTICAL CO.,LTD ] [C3040Z ] [ ] No + CAM:[PENTAX ] [PENTAX Optio 550 ] [ ] No + CAM:[Research In Motion ] [BlackBerry 8100 ] [ ] No + CAM:[SEIKO EPSON CORP. ] [PhotoPC 3000Z ] [ ] No + SW :[IJG Library ] [085 ] + SW :[Picasa ] [085 (Normal) ] + SW :[ZoomBrowser EX ] [medium ] + + The following IJG-based editors also match this signature: + SW :[GIMP ] [085 ] + SW :[IrfanView ] [085 ] + SW :[idImager ] [085 ] + SW :[FastStone Image Viewer ] [085 ] + SW :[NeatImage ] [085 ] + SW :[Paint.NET ] [085 ] + SW :[Photomatix ] [085 ] + SW :[XnView ] [085 ] + + Based on the analysis of compression characteristics and EXIF metadata: + + ASSESSMENT: Class 1 - Image is processed/edited + + This may be a new software editor for the database. + If this file is processed, and editor doesn't appear in list above, + PLEASE ADD TO DATABASE with [Tools->Add Camera to DB] + From 83eeca9246bfa0f5360c8aa321cb31a4297a7b06 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Sat, 3 Nov 2018 19:24:30 -0500 Subject: [PATCH 141/238] 762: added AoT method to pre-seed dithering engine --- src/ImageSharp/Formats/Gif/ImageExtensions.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index b22620108..2c5496f52 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -5,6 +5,8 @@ using System.IO; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Primitives; +using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp @@ -54,5 +56,17 @@ namespace SixLabors.ImageSharp var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); test.AotGetPalette(); } + + /// + /// This method pre-seeds the default FloydSteinbergDiffuser in the AoT compiler for iOS. + /// + /// The pixel format. + public static void AotCompileDithering() + where TPixel : struct, IPixel + { + var test = new FloydSteinbergDiffuser(); + TPixel pixel = default; + test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); + } } } From 9c14fc5b372db657f2946b0a11c920564f7857c8 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Sat, 3 Nov 2018 19:36:47 -0500 Subject: [PATCH 142/238] 762: added AoT method to pre-seed WuQuantizer --- src/ImageSharp/Formats/Gif/ImageExtensions.cs | 14 +++++++++++++- .../Quantization/WuFrameQuantizer{TPixel}.cs | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index 2c5496f52..f1c2ae5fb 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -58,7 +58,19 @@ namespace SixLabors.ImageSharp } /// - /// This method pre-seeds the default FloydSteinbergDiffuser in the AoT compiler for iOS. + /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS. + /// + /// The pixel format. + public static void AotCompileWuQuantizer() + where TPixel : struct, IPixel + { + var test = new WuFrameQuantizer(new WuQuantizer(false)); + test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1)); + test.AotGetPalette(); + } + + /// + /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. /// /// The pixel format. public static void AotCompileDithering() diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index 43d22597d..44df226cf 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -173,6 +173,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } + internal TPixel[] AotGetPalette() => this.GetPalette(); + /// protected override TPixel[] GetPalette() { From 5404eb6bb150c34f8ef92c84b316d7ad8a2db60b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 01:53:21 +0100 Subject: [PATCH 143/238] improved benchmarks + more benchmark results --- .../Common/Helpers/InliningOptions.cs | 2 +- .../Codecs/Jpeg/DecodeJpeg.cs | 89 ------------- .../Codecs/Jpeg/DecodeJpegMultiple.cs | 18 ++- .../Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs | 125 ++++++++++++++++++ .../Codecs/Jpeg/LoadResizeSave.cs | 2 +- .../Codecs/Jpeg/LoadResizeSave_MultiImage.cs | 88 ++++++++++++ .../Codecs/MultiImageBenchmarkBase.cs | 30 ++++- .../ProfilingBenchmarks/JpegBenchmarks.cs | 56 ++++---- tests/ImageSharp.Tests/TestImages.cs | 13 ++ 9 files changed, 294 insertions(+), 129 deletions(-) delete mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index ad85c4fc8..069a426d7 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -// Uncomment this for verbose profiler results: +// Uncomment this for verbose profiler results. DO NOT PUSH TO MAIN! // #define PROFILING using System.Runtime.CompilerServices; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs deleted file mode 100644 index 57dcede88..000000000 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Drawing; -using System.IO; -using BenchmarkDotNet.Attributes; - -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests; -using CoreSize = SixLabors.Primitives.Size; -using SDImage = System.Drawing.Image; - -namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg -{ - [Config(typeof(Config.ShortClr))] - public class DecodeJpeg - { - private byte[] jpegBytes; - - private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - - [Params(TestImages.Jpeg.Baseline.Jpeg420Exif - //, TestImages.Jpeg.Baseline.Calliphora - )] - public string TestImage { get; set; } - - [GlobalSetup] - public void ReadImages() - { - if (this.jpegBytes == null) - { - this.jpegBytes = File.ReadAllBytes(this.TestImageFullPath); - } - } - - [Benchmark(Baseline = true, Description = "Decode Jpeg - System.Drawing")] - public Size JpegSystemDrawing() - { - using (var memoryStream = new MemoryStream(this.jpegBytes)) - { - using (var image = SDImage.FromStream(memoryStream)) - { - return image.Size; - } - } - } - - [Benchmark(Description = "Decode Jpeg - ImageSharp")] - public CoreSize JpegImageSharp() - { - using (var memoryStream = new MemoryStream(this.jpegBytes)) - { - using (var image = Image.Load(memoryStream, new JpegDecoder())) - { - return new CoreSize(image.Width, image.Height); - } - } - } - - // RESULTS (2018 October): - // - // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 - // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores - // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC - // .NET Core SDK=2.1.403 - // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // - // - // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| - // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | - // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | - // | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | - - // RESULTS (2018 November 1): - // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| - // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.59 ms | 4.611 ms | 0.2605 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | - // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 55.33 ms | 2.133 ms | 0.1205 ms | 3.15 | 0.04 | 125.0000 | 566.01 KB | - // | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.83 ms | 24.326 ms | 1.3745 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 44.93 ms | 3.088 ms | 0.1745 ms | 2.53 | 0.15 | 125.0000 | 529.96 KB | - } -} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs index be0fe76b8..53459e3c4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs @@ -2,23 +2,27 @@ // Licensed under the Apache License, Version 2.0. using System.Collections.Generic; + using BenchmarkDotNet.Attributes; + using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + using SDImage = System.Drawing.Image; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { - [Config(typeof(Config.ShortClr))] + /// + /// An expensive Jpeg benchmark, running on a wide range of input images, showing aggregate results. + /// + [Config(typeof(MultiImageBenchmarkBase.Config))] public class DecodeJpegMultiple : MultiImageBenchmarkBase { - protected override IEnumerable InputImageSubfoldersOrFiles => new[] - { - "Jpg/baseline", - "Jpg/progressive", - }; + protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; - protected override IEnumerable SearchPatterns => new[] { "*.jpg" }; + [Params(InputImageCategory.AllImages)] + public override InputImageCategory InputCategory { get; set; } [Benchmark(Description = "DecodeJpegMultiple - ImageSharp")] public void DecodeJpegImageSharp() diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs new file mode 100644 index 000000000..e161bca05 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -0,0 +1,125 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Drawing; +using System.IO; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; + +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; +using CoreSize = SixLabors.Primitives.Size; +using SDImage = System.Drawing.Image; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + /// + /// Image-specific Jpeg benchmarks + /// + [Config(typeof(Config.ShortClr))] + public class DecodeJpeg_ImageSpecific + { + public class Config : ManualConfig + { + public Config() + { + // Uncomment if you want to use any of the diagnoser + this.Add(new BenchmarkDotNet.Diagnosers.MemoryDiagnoser()); + } + + public class ShortClr : Benchmarks.Config + { + public ShortClr() + { + this.Add( + //Job.Clr.WithLaunchCount(1).WithWarmupCount(2).WithTargetCount(3), + Job.Core.WithLaunchCount(1).WithWarmupCount(2).WithTargetCount(3) + ); + } + } + } + + private byte[] jpegBytes; + + private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [Params( + TestImages.Jpeg.Baseline.Lake, + TestImages.Jpeg.Issues.BadRstProgressive518, + TestImages.Jpeg.Issues.ExifGetString750Transform, + + TestImages.Jpeg.Baseline.Jpeg420Exif + )] + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.jpegBytes == null) + { + this.jpegBytes = File.ReadAllBytes(this.TestImageFullPath); + } + } + + [Benchmark(Baseline = true, Description = "Decode Jpeg - System.Drawing")] + public Size JpegSystemDrawing() + { + using (var memoryStream = new MemoryStream(this.jpegBytes)) + { + using (var image = SDImage.FromStream(memoryStream)) + { + return image.Size; + } + } + } + + [Benchmark(Description = "Decode Jpeg - ImageSharp")] + public CoreSize JpegImageSharp() + { + using (var memoryStream = new MemoryStream(this.jpegBytes)) + { + using (var image = Image.Load(memoryStream, new JpegDecoder(){ IgnoreMetadata = true})) + { + return new CoreSize(image.Width, image.Height); + } + } + } + + // RESULTS (2018 October 31): + // + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // + // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| + // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | + // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | + // | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | + + // RESULTS (2018 November 4): + // Method | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Gen 2 | Allocated | + // ------------------------------- |-------------------------------------------- |-----------:|-----------:|----------:|-------:|---------:|----------:|---------:|---------:|------------:| + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/Lake.jpg | 6.291 ms | 1.200 ms | 0.0678 ms | 1.00 | 0.00 | 62.5000 | - | - | 205.83 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/Lake.jpg | 18.493 ms | 3.025 ms | 0.1709 ms | 2.94 | 0.03 | - | - | - | 19.97 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/jpeg420exif.jpg | 16.962 ms | 1.446 ms | 0.0817 ms | 1.00 | 0.00 | 218.7500 | - | - | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/jpeg420exif.jpg | 42.105 ms | 4.496 ms | 0.2540 ms | 2.48 | 0.02 | - | - | - | 21.94 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 432.344 ms | 89.746 ms | 5.0708 ms | 1.00 | 0.00 | 2375.0000 | - | - | 7403.76 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 421.292 ms | 128.587 ms | 7.2654 ms | 0.97 | 0.02 | 125.0000 | 125.0000 | 125.0000 | 35186.98 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/issue750-exif-tranform.jpg | 94.723 ms | 4.663 ms | 0.2635 ms | 1.00 | 0.00 | 1750.0000 | - | - | 5492.63 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/issue750-exif-tranform.jpg | 234.071 ms | 37.979 ms | 2.1459 ms | 2.47 | 0.02 | 312.5000 | 312.5000 | 312.5000 | 58834.45 KB | + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs index 72062fc7d..b6a4711c4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - // RESULTS (2018 October): + // RESULTS (2018 October 31): // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs new file mode 100644 index 000000000..111c509cf --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs @@ -0,0 +1,88 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Tests; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(MultiImageBenchmarkBase.Config))] + public class LoadResizeSave_MultiImage : MultiImageBenchmarkBase + { + protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; + + [Params(InputImageCategory.AllImages)] + public override InputImageCategory InputCategory { get; set; } + + private readonly Configuration configuration = new Configuration(new JpegConfigurationModule()); + + private byte[] destBytes; + + public override void Setup() + { + base.Setup(); + + this.configuration.MaxDegreeOfParallelism = 1; + const int MaxOutputSizeInBytes = 2 * 1024 * 1024; // ~2 MB + this.destBytes = new byte[MaxOutputSizeInBytes]; + } + + [Benchmark(Baseline = true)] + public void SystemDrawing() + { + this.ForEachStream( + sourceStream => + { + using (var destStream = new MemoryStream(this.destBytes)) + using (var source = System.Drawing.Image.FromStream(sourceStream)) + using (var destination = new Bitmap(source.Width / 4, source.Height / 4)) + { + using (var g = Graphics.FromImage(destination)) + { + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.CompositingQuality = CompositingQuality.HighQuality; + g.DrawImage(source, 0, 0, 400, 400); + } + + destination.Save(destStream, ImageFormat.Jpeg); + } + + return null; + }); + } + + [Benchmark] + public void ImageSharp() + { + this.ForEachStream( + sourceStream => + { + using (var source = Image.Load( + this.configuration, + sourceStream, + new JpegDecoder { IgnoreMetadata = true })) + { + using (var destStream = new MemoryStream(this.destBytes)) + { + source.Mutate(c => c.Resize(source.Width / 4, source.Height / 4)); + source.SaveAsJpeg(destStream); + } + } + + return null; + }); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs index 608d3604f..446c03859 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs @@ -3,6 +3,9 @@ // Licensed under the Apache License, Version 2.0. // +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; + using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.Codecs @@ -22,6 +25,25 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public abstract class MultiImageBenchmarkBase { + public class Config : ManualConfig + { + public Config() + { + // Uncomment if you want to use any of the diagnoser + this.Add(new BenchmarkDotNet.Diagnosers.MemoryDiagnoser()); + } + + public class ShortClr : Benchmarks.Config + { + public ShortClr() + { + this.Add( + Job.Core.WithLaunchCount(1).WithWarmupCount(1).WithTargetCount(2) + ); + } + } + } + protected Dictionary FileNamesToBytes = new Dictionary(); protected Dictionary> FileNamesToImageSharpImages = new Dictionary>(); @@ -49,7 +71,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs /// /// Gets the file names containing these strings are substrings are not processed by the benchmark. /// - protected IEnumerable ExcludeSubstringsInFileNames => new[] { "badeof", "BadEof", "CriticalEOF" }; + protected virtual IEnumerable ExcludeSubstringsInFileNames => new[] { "badeof", "BadEof", "CriticalEOF" }; /// /// Enumerates folders containing files OR files to be processed by the benchmark. @@ -87,7 +109,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs protected abstract IEnumerable InputImageSubfoldersOrFiles { get; } [GlobalSetup] - public void ReadImages() + public virtual void Setup() { if (!Vector.IsHardwareAccelerated) { @@ -107,11 +129,13 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs continue; } + string[] excludeStrings = this.ExcludeSubstringsInFileNames.Select(s => s.ToLower()).ToArray(); + string[] allFiles = this.SearchPatterns.SelectMany( f => Directory.EnumerateFiles(path, f, SearchOption.AllDirectories) - .Where(fn => !this.ExcludeSubstringsInFileNames.Any(w => fn.ToLower().Contains(w)))).ToArray(); + .Where(fn => !excludeStrings.Any(excludeStr => fn.ToLower().Contains(excludeStr)))).ToArray(); foreach (string fn in allFiles) { diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index 3d439c5ce..a7f848e3a 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -22,15 +22,19 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { } - public static readonly TheoryData DecodeJpegData = new TheoryData() - { - //TestImages.Jpeg.Baseline.Cmyk, - //TestImages.Jpeg.Baseline.Ycck, - TestImages.Jpeg.Baseline.Calliphora, - TestImages.Jpeg.Baseline.Jpeg400, - TestImages.Jpeg.Baseline.Jpeg420Exif, - TestImages.Jpeg.Baseline.Jpeg444, - }; + public static readonly TheoryData DecodeJpegData = new TheoryData + { + // Except "Jpeg400", all images are YCbCr + + TestImages.Jpeg.Baseline.Jpeg400, + TestImages.Jpeg.Baseline.Jpeg420Exif, + TestImages.Jpeg.Baseline.Lake, // 444 + + // Using images from the "issues" set, because they are LARGE + TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159, // 420 + TestImages.Jpeg.Issues.BadRstProgressive518, // 444 + TestImages.Jpeg.Issues.ExifGetString750Transform, // 420 + }; [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [MemberData(nameof(DecodeJpegData))] @@ -38,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { this.DecodeJpegBenchmarkImpl(fileName, new JpegDecoder()); } - + private void DecodeJpegBenchmarkImpl(string fileName, IImageDecoder decoder) { // do not run this on CI even by accident @@ -47,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks return; } - const int ExecutionCount = 30; + const int ExecutionCount = 10; if (!Vector.IsHardwareAccelerated) { @@ -83,29 +87,26 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks } string[] testFiles = TestImages.Bmp.All - .Concat(new[] { TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk }) - .ToArray(); + .Concat(new[] { TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk }).ToArray(); - Image[] testImages = - testFiles.Select( - tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.Rgba32).GetImage()) - .ToArray(); + Image[] testImages = testFiles.Select( + tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.Rgba32).GetImage()).ToArray(); using (var ms = new MemoryStream()) { - this.Measure(executionCount, + this.Measure( + executionCount, () => - { - foreach (Image img in testImages) { - var options = new JpegEncoder { Quality = quality, Subsample = subsample }; - img.Save(ms, options); - ms.Seek(0, SeekOrigin.Begin); - } - }, + foreach (Image img in testImages) + { + var options = new JpegEncoder { Quality = quality, Subsample = subsample }; + img.Save(ms, options); + ms.Seek(0, SeekOrigin.Begin); + } + }, // ReSharper disable once ExplicitCallerInfoArgument - $@"Encode {testFiles.Length} images" - ); + $@"Encode {testFiles.Length} images"); } foreach (Image image in testImages) @@ -113,6 +114,5 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks image.Dispose(); } } - } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 03f875485..caffe81ab 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -165,6 +165,19 @@ namespace SixLabors.ImageSharp.Tests } public static readonly string[] All = Baseline.All.Concat(Progressive.All).ToArray(); + + public static readonly string[] BenchmarkSuite = + { + // Except "Jpeg400", all images are YCbCr + Baseline.Jpeg400, + Baseline.Jpeg420Exif, + Baseline.Lake, // 444 + + // Using images from the "issues" set, because they are LARGE + Issues.MissingFF00ProgressiveBedroom159, // 420 + Issues.BadRstProgressive518, // 444 + Issues.ExifGetString750Transform, // 420 + }; } public static class Bmp From f1f0bc04f9048ad83f78092ee2ae5180f2b0d546 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 02:54:21 +0100 Subject: [PATCH 144/238] Drop all GetBlockDataReference() usages --- .../Decoder/JpegComponentExtensions.cs | 39 ------------- .../Jpeg/Components/Decoder/ScanDecoder.cs | 58 +++++++++++-------- .../Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs | 22 ++++--- .../Jpg/Utils/LibJpegTools.ComponentData.cs | 3 +- 4 files changed, 48 insertions(+), 74 deletions(-) delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs deleted file mode 100644 index d7fb52a79..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentExtensions.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Runtime.CompilerServices; - -using SixLabors.ImageSharp.Memory; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder -{ - /// - /// Extension methods for - /// - internal static class JpegComponentExtensions - { - /// - /// Gets a reference to the at the given row and column index from - /// - /// The - /// The column - /// The row - /// The - [MethodImpl(InliningOptions.ShortMethod)] - public static ref Block8x8 GetBlockReference(this IJpegComponent component, int column, int row) - { - return ref component.SpectralBlocks.GetRowSpan(row)[column]; - } - - /// - /// Gets a reference to the first item in a block - /// at the given row and column index from - /// - [MethodImpl(InliningOptions.ShortMethod)] - public static ref short GetBlockDataReference(this IJpegComponent component, int column, int row) - { - ref Block8x8 blockRef = ref component.GetBlockReference(column, row); - return ref Unsafe.As(ref blockRef); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs index 39b9792ac..ec9805309 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs @@ -1,8 +1,10 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { @@ -179,10 +181,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int h = component.HorizontalSamplingFactor; int v = component.VerticalSamplingFactor; + int mcuRow = mcu / mcusPerLine; + // Scan out an mcu's worth of this component; that's just determined // by the basic H and V specified for the component for (int y = 0; y < v; y++) { + int blockRow = (mcuRow * v) + y; + Span blockSpan = component.SpectralBlocks.GetRowSpan(blockRow); for (int x = 0; x < h; x++) { if (this.eof) @@ -190,15 +196,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder return; } - int mcuRow = mcu / mcusPerLine; int mcuCol = mcu % mcusPerLine; - int blockRow = (mcuRow * v) + y; int blockCol = (mcuCol * h) + x; this.DecodeBlockBaseline( component, - blockRow, - blockCol, + ref blockSpan[blockCol], ref dcHuffmanTable, ref acHuffmanTable, ref fastACRef); @@ -236,6 +239,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int mcu = 0; for (int j = 0; j < h; j++) { + // TODO: Isn't blockRow == j actually? + int blockRow = mcu / w; + Span blockSpan = component.SpectralBlocks.GetRowSpan(blockRow); + for (int i = 0; i < w; i++) { if (this.eof) @@ -243,13 +250,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder return; } - int blockRow = mcu / w; + // TODO: Isn't blockCol == i actually? int blockCol = mcu % w; this.DecodeBlockBaseline( component, - blockRow, - blockCol, + ref blockSpan[blockCol], ref dcHuffmanTable, ref acHuffmanTable, ref fastACRef); @@ -299,6 +305,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder // by the basic H and V specified for the component for (int y = 0; y < v; y++) { + int mcuRow = mcu / mcusPerLine; + int blockRow = (mcuRow * v) + y; + Span blockSpan = component.SpectralBlocks.GetRowSpan(blockRow); + for (int x = 0; x < h; x++) { if (this.eof) @@ -306,15 +316,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder return; } - int mcuRow = mcu / mcusPerLine; int mcuCol = mcu % mcusPerLine; - int blockRow = (mcuRow * v) + y; int blockCol = (mcuCol * h) + x; this.DecodeBlockProgressiveDC( component, - blockRow, - blockCol, + ref blockSpan[blockCol], ref dcHuffmanTable); } } @@ -351,6 +358,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int mcu = 0; for (int j = 0; j < h; j++) { + // TODO: isn't blockRow == j actually? + int blockRow = mcu / w; + Span blockSpan = component.SpectralBlocks.GetRowSpan(blockRow); + for (int i = 0; i < w; i++) { if (this.eof) @@ -358,23 +369,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder return; } - int blockRow = mcu / w; + // TODO: isn't blockCol == i actually? int blockCol = mcu % w; + ref Block8x8 block = ref blockSpan[blockCol]; + if (this.spectralStart == 0) { this.DecodeBlockProgressiveDC( component, - blockRow, - blockCol, + ref block, ref dcHuffmanTable); } else { this.DecodeBlockProgressiveAC( component, - blockRow, - blockCol, + ref block, ref acHuffmanTable, ref fastACRef); } @@ -391,8 +402,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder private void DecodeBlockBaseline( JpegComponent component, - int row, - int col, + ref Block8x8 block, ref HuffmanTable dcTable, ref HuffmanTable acTable, ref short fastACRef) @@ -405,7 +415,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder JpegThrowHelper.ThrowBadHuffmanCode(); } - ref short blockDataRef = ref component.GetBlockDataReference(col, row); + ref short blockDataRef = ref Unsafe.As(ref block); int diff = t != 0 ? this.ExtendReceive(t) : 0; int dc = component.DcPredictor + diff; @@ -470,8 +480,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder private void DecodeBlockProgressiveDC( JpegComponent component, - int row, - int col, + ref Block8x8 block, ref HuffmanTable dcTable) { if (this.spectralEnd != 0) @@ -481,7 +490,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder this.CheckBits(); - ref short blockDataRef = ref component.GetBlockDataReference(col, row); + ref short blockDataRef = ref Unsafe.As(ref block); if (this.successiveHigh == 0) { @@ -506,8 +515,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder private void DecodeBlockProgressiveAC( JpegComponent component, - int row, - int col, + ref Block8x8 block, ref HuffmanTable acTable, ref short fastACRef) { @@ -516,7 +524,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder JpegThrowHelper.ThrowImageFormatException("Can't merge DC and AC."); } - ref short blockDataRef = ref component.GetBlockDataReference(col, row); + ref short blockDataRef = ref Unsafe.As(ref block); if (this.successiveHigh == 0) { diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs index e161bca05..9292d5f7d 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -46,15 +46,19 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + // NOTE: + // The scaled result for very large image "TestImages.Jpeg.Issues.ExifGetString750Transform" + // is almost the same as the result for Jpeg420Exif, + // which proves that the execution time for the most common YCbCr 420 path scales linearly [Params( TestImages.Jpeg.Baseline.Lake, TestImages.Jpeg.Issues.BadRstProgressive518, - TestImages.Jpeg.Issues.ExifGetString750Transform, TestImages.Jpeg.Baseline.Jpeg420Exif )] public string TestImage { get; set; } + [GlobalSetup] public void ReadImages() { @@ -110,16 +114,16 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg // RESULTS (2018 November 4): // Method | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Gen 2 | Allocated | // ------------------------------- |-------------------------------------------- |-----------:|-----------:|----------:|-------:|---------:|----------:|---------:|---------:|------------:| - // 'Decode Jpeg - System.Drawing' | Jpg/baseline/Lake.jpg | 6.291 ms | 1.200 ms | 0.0678 ms | 1.00 | 0.00 | 62.5000 | - | - | 205.83 KB | - // 'Decode Jpeg - ImageSharp' | Jpg/baseline/Lake.jpg | 18.493 ms | 3.025 ms | 0.1709 ms | 2.94 | 0.03 | - | - | - | 19.97 KB | + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/Lake.jpg | 6.117 ms | 0.3923 ms | 0.0222 ms | 1.00 | 0.00 | 62.5000 | - | - | 205.83 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/Lake.jpg | 18.126 ms | 0.6023 ms | 0.0340 ms | 2.96 | 0.01 | - | - | - | 19.97 KB | // | | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Jpg/baseline/jpeg420exif.jpg | 16.962 ms | 1.446 ms | 0.0817 ms | 1.00 | 0.00 | 218.7500 | - | - | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Jpg/baseline/jpeg420exif.jpg | 42.105 ms | 4.496 ms | 0.2540 ms | 2.48 | 0.02 | - | - | - | 21.94 KB | + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/jpeg420exif.jpg | 17.063 ms | 2.6096 ms | 0.1474 ms | 1.00 | 0.00 | 218.7500 | - | - | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/jpeg420exif.jpg | 41.366 ms | 1.0115 ms | 0.0572 ms | 2.42 | 0.02 | - | - | - | 21.94 KB | // | | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 432.344 ms | 89.746 ms | 5.0708 ms | 1.00 | 0.00 | 2375.0000 | - | - | 7403.76 KB | - // 'Decode Jpeg - ImageSharp' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 421.292 ms | 128.587 ms | 7.2654 ms | 0.97 | 0.02 | 125.0000 | 125.0000 | 125.0000 | 35186.98 KB | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 428.282 ms | 94.9163 ms | 5.3629 ms | 1.00 | 0.00 | 2375.0000 | - | - | 7403.76 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 386.698 ms | 33.0065 ms | 1.8649 ms | 0.90 | 0.01 | 125.0000 | 125.0000 | 125.0000 | 35186.97 KB | // | | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Jpg/issues/issue750-exif-tranform.jpg | 94.723 ms | 4.663 ms | 0.2635 ms | 1.00 | 0.00 | 1750.0000 | - | - | 5492.63 KB | - // 'Decode Jpeg - ImageSharp' | Jpg/issues/issue750-exif-tranform.jpg | 234.071 ms | 37.979 ms | 2.1459 ms | 2.47 | 0.02 | 312.5000 | 312.5000 | 312.5000 | 58834.45 KB | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/issue750-exif-tranform.jpg | 95.192 ms | 3.1762 ms | 0.1795 ms | 1.00 | 0.00 | 1750.0000 | - | - | 5492.63 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/issue750-exif-tranform.jpg | 230.158 ms | 48.8128 ms | 2.7580 ms | 2.42 | 0.02 | 312.5000 | 312.5000 | 312.5000 | 58834.66 KB | } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs index 7acce84ce..e4fcd10c5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs @@ -67,9 +67,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils for (int y = 0; y < result.HeightInBlocks; y++) { + Span blockRow = c.SpectralBlocks.GetRowSpan(y); for (int x = 0; x < result.WidthInBlocks; x++) { - short[] data = c.GetBlockReference(x, y).ToArray(); + short[] data = blockRow[x].ToArray(); result.MakeBlock(data, y, x); } } From 3ceb7423ec7592d910af3de02ff11368598b022d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 03:32:43 +0100 Subject: [PATCH 145/238] simplify benchmark suite --- tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs | 2 +- tests/ImageSharp.Tests/TestImages.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index a7f848e3a..06eb203d5 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks // Using images from the "issues" set, because they are LARGE TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159, // 420 - TestImages.Jpeg.Issues.BadRstProgressive518, // 444 + // TestImages.Jpeg.Issues.BadRstProgressive518, // 444 TestImages.Jpeg.Issues.ExifGetString750Transform, // 420 }; diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index caffe81ab..35de87228 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -175,7 +175,7 @@ namespace SixLabors.ImageSharp.Tests // Using images from the "issues" set, because they are LARGE Issues.MissingFF00ProgressiveBedroom159, // 420 - Issues.BadRstProgressive518, // 444 + // Issues.BadRstProgressive518, // 444 Issues.ExifGetString750Transform, // 420 }; } From 29fb1e26ccc516567a679d3e8dca4c121ffef79e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 03:35:04 +0100 Subject: [PATCH 146/238] drop old benchmark results --- .../Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs index 9292d5f7d..206a33729 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -92,26 +92,14 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - // RESULTS (2018 October 31): + // RESULTS (2018 November 4): // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC // .NET Core SDK=2.1.403 // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // // - // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| - // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | - // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | - // | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | - - // RESULTS (2018 November 4): // Method | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Gen 2 | Allocated | // ------------------------------- |-------------------------------------------- |-----------:|-----------:|----------:|-------:|---------:|----------:|---------:|---------:|------------:| // 'Decode Jpeg - System.Drawing' | Jpg/baseline/Lake.jpg | 6.117 ms | 0.3923 ms | 0.0222 ms | 1.00 | 0.00 | 62.5000 | - | - | 205.83 KB | From 0c32fe7d19a0ef9ad41765369617cf3915a9f192 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 14:24:17 +0100 Subject: [PATCH 147/238] fix Block8x8FTests.Copy1x1Scale, reorganize TestImages.Jpeg.BenchmarkSuite as a static class --- ...pegMultiple.cs => DecodeJpeg_Aggregate.cs} | 21 +++++++++++++------ .../Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs | 18 +++++++++------- ...tiImage.cs => LoadResizeSave_Aggregate.cs} | 12 +++++++++-- ...ave.cs => LoadResizeSave_ImageSpecific.cs} | 9 +++++--- .../Jpg/Block8x8FTests.CopyToBufferArea.cs | 2 +- .../ProfilingBenchmarks/JpegBenchmarks.cs | 19 +++++++---------- tests/ImageSharp.Tests/TestImages.cs | 21 +++++++++---------- 7 files changed, 59 insertions(+), 43 deletions(-) rename tests/ImageSharp.Benchmarks/Codecs/Jpeg/{DecodeJpegMultiple.cs => DecodeJpeg_Aggregate.cs} (56%) rename tests/ImageSharp.Benchmarks/Codecs/Jpeg/{LoadResizeSave_MultiImage.cs => LoadResizeSave_Aggregate.cs} (84%) rename tests/ImageSharp.Benchmarks/Codecs/Jpeg/{LoadResizeSave.cs => LoadResizeSave_ImageSpecific.cs} (94%) diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_Aggregate.cs similarity index 56% rename from tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_Aggregate.cs index 53459e3c4..f8a7556ca 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_Aggregate.cs @@ -10,6 +10,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests; using SDImage = System.Drawing.Image; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { @@ -17,21 +18,29 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg /// An expensive Jpeg benchmark, running on a wide range of input images, showing aggregate results. /// [Config(typeof(MultiImageBenchmarkBase.Config))] - public class DecodeJpegMultiple : MultiImageBenchmarkBase + public class DecodeJpeg_Aggregate : MultiImageBenchmarkBase { - protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; + protected override IEnumerable InputImageSubfoldersOrFiles => + new[] + { + TestImages.Jpeg.BenchmarkSuite.Jpeg400_SmallMonochrome, + TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr, + TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, + TestImages.Jpeg.BenchmarkSuite.MissingFF00ProgressiveBedroom159_MidSize420YCbCr, + TestImages.Jpeg.BenchmarkSuite.ExifGetString750Transform_Huge420YCbCr, + }; [Params(InputImageCategory.AllImages)] public override InputImageCategory InputCategory { get; set; } - [Benchmark(Description = "DecodeJpegMultiple - ImageSharp")] - public void DecodeJpegImageSharp() + [Benchmark] + public void ImageSharp() { this.ForEachStream(ms => Image.Load(ms, new JpegDecoder())); } - [Benchmark(Baseline = true, Description = "DecodeJpegMultiple - System.Drawing")] - public void DecodeJpegSystemDrawing() + [Benchmark(Baseline = true)] + public void SystemDrawing() { this.ForEachStream(SDImage.FromStream); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs index 206a33729..fe112042e 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -45,16 +45,18 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg private byte[] jpegBytes; private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - - // NOTE: - // The scaled result for very large image "TestImages.Jpeg.Issues.ExifGetString750Transform" - // is almost the same as the result for Jpeg420Exif, - // which proves that the execution time for the most common YCbCr 420 path scales linearly + [Params( - TestImages.Jpeg.Baseline.Lake, - TestImages.Jpeg.Issues.BadRstProgressive518, + TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, + TestImages.Jpeg.BenchmarkSuite.BadRstProgressive518_Large444YCbCr, + + // The scaled result for the large image "ExifGetString750Transform_Huge420YCbCr" + // is almost the same as the result for Jpeg420Exif, + // which proves that the execution time for the most common YCbCr 420 path scales linearly. + // + // TestImages.Jpeg.BenchmarkSuite.ExifGetString750Transform_Huge420YCbCr, - TestImages.Jpeg.Baseline.Jpeg420Exif + TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr )] public string TestImage { get; set; } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_Aggregate.cs similarity index 84% rename from tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_Aggregate.cs index 111c509cf..e39cfa6ba 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_Aggregate.cs @@ -18,9 +18,17 @@ using SixLabors.ImageSharp.Tests; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { [Config(typeof(MultiImageBenchmarkBase.Config))] - public class LoadResizeSave_MultiImage : MultiImageBenchmarkBase + public class LoadResizeSave_Aggregate : MultiImageBenchmarkBase { - protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; + protected override IEnumerable InputImageSubfoldersOrFiles => + new[] + { + TestImages.Jpeg.BenchmarkSuite.Jpeg400_SmallMonochrome, + TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr, + TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, + TestImages.Jpeg.BenchmarkSuite.MissingFF00ProgressiveBedroom159_MidSize420YCbCr, + TestImages.Jpeg.BenchmarkSuite.ExifGetString750Transform_Huge420YCbCr, + }; [Params(InputImageCategory.AllImages)] public override InputImageCategory InputCategory { get; set; } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_ImageSpecific.cs similarity index 94% rename from tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs rename to tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_ImageSpecific.cs index b6a4711c4..1834f77ea 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_ImageSpecific.cs @@ -11,11 +11,12 @@ using System.Drawing.Imaging; using SixLabors.ImageSharp.Processing; using SDImage = System.Drawing.Image; using SixLabors.ImageSharp.Formats.Jpeg; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { [Config(typeof(Config.ShortClr))] - public class LoadResizeSave + public class LoadResizeSave_ImageSpecific { private readonly Configuration configuration = new Configuration(new JpegConfigurationModule()); @@ -26,8 +27,10 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); [Params( - TestImages.Jpeg.Baseline.Jpeg420Exif - //, TestImages.Jpeg.Baseline.Calliphora + TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, + TestImages.Jpeg.BenchmarkSuite.BadRstProgressive518_Large444YCbCr, + + TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr )] public string TestImage { get; set; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs index d5eaaa294..4b1abf909 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.CopyToBufferArea.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { Block8x8F block = CreateRandomFloatBlock(0, 100); - using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(20, 20)) + using (Buffer2D buffer = Configuration.Default.MemoryAllocator.Allocate2D(20, 20, AllocationOptions.Clean)) { BufferArea area = buffer.GetArea(5, 10, 8, 8); block.Copy1x1Scale(area); diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index 06eb203d5..5bc1693bc 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -23,18 +23,13 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks } public static readonly TheoryData DecodeJpegData = new TheoryData - { - // Except "Jpeg400", all images are YCbCr - - TestImages.Jpeg.Baseline.Jpeg400, - TestImages.Jpeg.Baseline.Jpeg420Exif, - TestImages.Jpeg.Baseline.Lake, // 444 - - // Using images from the "issues" set, because they are LARGE - TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159, // 420 - // TestImages.Jpeg.Issues.BadRstProgressive518, // 444 - TestImages.Jpeg.Issues.ExifGetString750Transform, // 420 - }; + { + TestImages.Jpeg.BenchmarkSuite.Jpeg400_SmallMonochrome, + TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr, + TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, + TestImages.Jpeg.BenchmarkSuite.MissingFF00ProgressiveBedroom159_MidSize420YCbCr, + TestImages.Jpeg.BenchmarkSuite.ExifGetString750Transform_Huge420YCbCr, + }; [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [MemberData(nameof(DecodeJpegData))] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 35de87228..8da458e52 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -166,18 +166,17 @@ namespace SixLabors.ImageSharp.Tests public static readonly string[] All = Baseline.All.Concat(Progressive.All).ToArray(); - public static readonly string[] BenchmarkSuite = + public static class BenchmarkSuite { - // Except "Jpeg400", all images are YCbCr - Baseline.Jpeg400, - Baseline.Jpeg420Exif, - Baseline.Lake, // 444 - - // Using images from the "issues" set, because they are LARGE - Issues.MissingFF00ProgressiveBedroom159, // 420 - // Issues.BadRstProgressive518, // 444 - Issues.ExifGetString750Transform, // 420 - }; + public const string Jpeg400_SmallMonochrome = Baseline.Jpeg400; + public const string Jpeg420Exif_MidSizeYCbCr = Baseline.Jpeg420Exif; + public const string Lake_Small444YCbCr = Baseline.Lake; + + // A few large images from the "issues" set are actually very useful for benchmarking: + public const string MissingFF00ProgressiveBedroom159_MidSize420YCbCr = Issues.MissingFF00ProgressiveBedroom159; + public const string BadRstProgressive518_Large444YCbCr = Issues.BadRstProgressive518; + public const string ExifGetString750Transform_Huge420YCbCr = Issues.ExifGetString750Transform; + } } public static class Bmp From 633eca516f8d7926376e0b7d8983b2fa1c224e92 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 14:49:03 +0100 Subject: [PATCH 148/238] oops --- tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs index 267c70219..f9a68d4e7 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/ProfilingSetup.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. // Uncomment to enable local profiling benchmarks. DO NOT PUSH TO MAIN! -#define PROFILING +// #define PROFILING namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { From 903601ecbfb7a98f82e2a0b6ac2e0090bdc3f686 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 16:11:45 +0100 Subject: [PATCH 149/238] move ResizeProfilingBenchmarks, use the ***ProfilingBenchmarks naming convention everywhere --- tests/ImageSharp.Sandbox46/Program.cs | 4 ++-- .../{JpegBenchmarks.cs => JpegProfilingBenchmarks.cs} | 4 ++-- ...hmarks.cs => LoadResizeSaveProfilingBenchmarks.cs} | 4 ++-- .../ResizeProfilingBenchmarks.cs | 11 ++--------- 4 files changed, 8 insertions(+), 15 deletions(-) rename tests/ImageSharp.Tests/ProfilingBenchmarks/{JpegBenchmarks.cs => JpegProfilingBenchmarks.cs} (96%) rename tests/ImageSharp.Tests/ProfilingBenchmarks/{LoadResizeSaveBenchmarks.cs => LoadResizeSaveProfilingBenchmarks.cs} (89%) rename tests/ImageSharp.Tests/{Processing/Processors/Transforms => ProfilingBenchmarks}/ResizeProfilingBenchmarks.cs (82%) diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index c0bb25a1b..02d4f80c5 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -63,8 +63,8 @@ namespace SixLabors.ImageSharp.Sandbox46 private static void RunDecodeJpegProfilingTests() { Console.WriteLine("RunDecodeJpegProfilingTests..."); - var benchmarks = new JpegBenchmarks(new ConsoleOutput()); - foreach (object[] data in JpegBenchmarks.DecodeJpegData) + var benchmarks = new JpegProfilingBenchmarks(new ConsoleOutput()); + foreach (object[] data in JpegProfilingBenchmarks.DecodeJpegData) { string fileName = (string)data[0]; benchmarks.DecodeJpeg(fileName); diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs similarity index 96% rename from tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs rename to tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs index 5bc1693bc..609aa43b7 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs @@ -15,9 +15,9 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { - public class JpegBenchmarks : MeasureFixture + public class JpegProfilingBenchmarks : MeasureFixture { - public JpegBenchmarks(ITestOutputHelper output) + public JpegProfilingBenchmarks(ITestOutputHelper output) : base(output) { } diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs similarity index 89% rename from tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs rename to tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs index 306072276..95fe4e48f 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs @@ -10,9 +10,9 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { - public class LoadResizeSaveBenchmarks : MeasureFixture + public class LoadResizeSaveProfilingBenchmarks : MeasureFixture { - public LoadResizeSaveBenchmarks(ITestOutputHelper output) + public LoadResizeSaveProfilingBenchmarks(ITestOutputHelper output) : base(output) { } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs similarity index 82% rename from tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs rename to tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs index e24458d38..8b9355938 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs @@ -7,17 +7,10 @@ using SixLabors.ImageSharp.Processing; using Xunit; using Xunit.Abstractions; -namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms +namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { public class ResizeProfilingBenchmarks : MeasureFixture { - public const string SkipText = -#if false - null; -#else - "Benchmark, enable manually!"; -#endif - private readonly Configuration configuration = Configuration.CreateDefaultInstance(); public ResizeProfilingBenchmarks(ITestOutputHelper output) @@ -28,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public int ExecutionCount { get; set; } = 50; - [Theory(Skip = SkipText)] + [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [InlineData(100, 100)] [InlineData(2000, 2000)] public void ResizeBicubic(int width, int height) From 537a2210c8af868a1b76028b7d0f5ba7db67086d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 16:59:15 +0100 Subject: [PATCH 150/238] simplify ResizeKernel.Convolve(...) --- .../Processing/Processors/Transforms/ResizeKernel.cs | 4 ++-- .../Processors/Transforms/ResizeProcessor.cs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs index cc3c20453..be4b7a741 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs @@ -73,11 +73,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The source row position. /// The weighted sum [MethodImpl(InliningOptions.ShortMethod)] - public Vector4 Convolve(Span rowSpan, int sourceX) + public Vector4 Convolve(Span rowSpan) { ref float horizontalValues = ref this.GetStartReference(); int left = this.Left; - ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left + sourceX); + ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left); // Destination color components Vector4 result = Vector4.Zero; diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index 4d4ed06ce..d0d225d9b 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -254,8 +254,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { for (int y = rows.Min; y < rows.Max; y++) { - Span sourceRow = source.GetPixelRowSpan(y); - Span tempRowSpan = tempRowBuffer.Span; + Span sourceRow = source.GetPixelRowSpan(y).Slice(sourceX); + Span tempRowSpan = tempRowBuffer.Span.Slice(sourceX); PixelOperations.Instance.ToVector4(configuration, sourceRow, tempRowSpan); Vector4Utils.Premultiply(tempRowSpan); @@ -271,7 +271,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX]; Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = - window.Convolve(tempRowSpan, sourceX); + window.Convolve(tempRowSpan); } } }); @@ -295,10 +295,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int x = 0; x < width; x++) { - Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x); + Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY); // Destination color components - Unsafe.Add(ref tempRowBase, x) = window.Convolve(firstPassColumn, sourceY); + Unsafe.Add(ref tempRowBase, x) = window.Convolve(firstPassColumn); } Vector4Utils.UnPremultiply(tempRowSpan); From 8666ce32d2a1aafc72775b6d6af37103640c5b1c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 19:59:06 +0100 Subject: [PATCH 151/238] minor refactor on ResizeKernel --- .../Processors/Transforms/KernelMap.cs | 3 ++- .../Processors/Transforms/ResizeKernel.cs | 22 ++++--------------- .../Processors/Transforms/KernelMapTests.cs | 14 +++++++----- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index 277be53ff..f7a3a6f6d 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using SixLabors.Memory; @@ -89,7 +90,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms ResizeKernel ws = result.CreateKernel(i, left, right); result.Kernels[i] = ws; - ref float weightsBaseRef = ref ws.GetStartReference(); + ref float weightsBaseRef = ref MemoryMarshal.GetReference(ws.GetValues()); for (int j = left; j <= right; j++) { diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs index be4b7a741..707f1467b 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs @@ -2,13 +2,11 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; -using SixLabors.Memory; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { @@ -18,12 +16,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms internal struct ResizeKernel { /// - /// The local left index position + /// The left index for the destination row /// public int Left; /// - /// The length of the weights window + /// The length of the kernel /// public int Length; @@ -48,34 +46,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.Length = length; } - /// - /// Gets a reference to the first item of the window. - /// - /// The reference to the first item of the window - [MethodImpl(InliningOptions.ShortMethod)] - public ref float GetStartReference() - { - Span span = this.buffer.Span; - return ref span[0]; - } - /// /// Gets the span representing the portion of the that this window covers /// /// The [MethodImpl(InliningOptions.ShortMethod)] - public Span GetSpan() => this.buffer.Span; + public Span GetValues() => this.buffer.Span; /// /// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this instance. /// /// The input span of vectors - /// The source row position. /// The weighted sum [MethodImpl(InliningOptions.ShortMethod)] public Vector4 Convolve(Span rowSpan) { - ref float horizontalValues = ref this.GetStartReference(); + ref float horizontalValues = ref MemoryMarshal.GetReference(this.GetValues()); int left = this.Left; ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 1b4b3cf6a..a7d93ad1d 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -21,10 +21,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms this.Output = output; } - [Theory(Skip = "TODO: Add asserionts")] + [Theory] [InlineData(500, 200, nameof(KnownResamplers.Bicubic))] [InlineData(50, 40, nameof(KnownResamplers.Bicubic))] [InlineData(40, 30, nameof(KnownResamplers.Bicubic))] + [InlineData(15, 10, nameof(KnownResamplers.Bicubic))] [InlineData(500, 200, nameof(KnownResamplers.Lanczos8))] [InlineData(100, 80, nameof(KnownResamplers.Lanczos8))] [InlineData(100, 10, nameof(KnownResamplers.Lanczos8))] @@ -37,14 +38,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var bld = new StringBuilder(); - foreach (ResizeKernel window in kernelMap.Kernels) + foreach (ResizeKernel kernel in kernelMap.Kernels) { - Span span = window.GetSpan(); - for (int i = 0; i < window.Length; i++) + bld.Append($"({kernel.Left:D3}) || "); + Span span = kernel.GetValues(); + for (int i = 0; i < kernel.Length; i++) { float value = span[i]; - bld.Append($"{value,7:F4}"); - bld.Append("| "); + bld.Append($"{value,7:F5}"); + bld.Append(" | "); } bld.AppendLine(); From d8cb11c077716205d01e613bf6c211138d257bd9 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 20:44:22 +0100 Subject: [PATCH 152/238] drop unused parameter --- src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs | 2 -- tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs index ec9805309..5d232b571 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs @@ -384,7 +384,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder else { this.DecodeBlockProgressiveAC( - component, ref block, ref acHuffmanTable, ref fastACRef); @@ -514,7 +513,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } private void DecodeBlockProgressiveAC( - JpegComponent component, ref Block8x8 block, ref HuffmanTable acTable, ref short fastACRef) diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index 5bc1693bc..e06d2da91 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -28,6 +28,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks TestImages.Jpeg.BenchmarkSuite.Jpeg420Exif_MidSizeYCbCr, TestImages.Jpeg.BenchmarkSuite.Lake_Small444YCbCr, TestImages.Jpeg.BenchmarkSuite.MissingFF00ProgressiveBedroom159_MidSize420YCbCr, + TestImages.Jpeg.BenchmarkSuite.BadRstProgressive518_Large444YCbCr, TestImages.Jpeg.BenchmarkSuite.ExifGetString750Transform_Huge420YCbCr, }; @@ -46,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks return; } - const int ExecutionCount = 10; + const int ExecutionCount = 20; if (!Vector.IsHardwareAccelerated) { From f152d459de89c6ad88eac6613936d68047dee166 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 21:59:18 +0100 Subject: [PATCH 153/238] Cover KernelMap with tests --- .../Processors/Transforms/KernelMap.cs | 18 ++-- .../Processors/Transforms/ResizeProcessor.cs | 8 +- .../KernelMapTests.ReferenceKernelMap.cs | 99 +++++++++++++++++++ .../Processors/Transforms/KernelMapTests.cs | 42 +++++--- 4 files changed, 145 insertions(+), 22 deletions(-) create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index f7a3a6f6d..b0fd0e2cd 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { private readonly Buffer2D data; + private readonly ResizeKernel[] kernels; + /// /// Initializes a new instance of the class. /// @@ -25,15 +27,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The radius of the kernel public KernelMap(MemoryAllocator memoryAllocator, int destinationSize, float kernelRadius) { + this.DestinationSize = destinationSize; int width = (int)Math.Ceiling(kernelRadius * 2); this.data = memoryAllocator.Allocate2D(width, destinationSize, AllocationOptions.Clean); - this.Kernels = new ResizeKernel[destinationSize]; + this.kernels = new ResizeKernel[destinationSize]; } - /// - /// Gets the calculated values. - /// - public ResizeKernel[] Kernels { get; } + public int DestinationSize { get; } /// /// Disposes instance releasing it's backing buffer. @@ -43,6 +43,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.data.Dispose(); } + /// + /// Returns a for an index value between 0 and destinationSize - 1. + /// + [MethodImpl(InliningOptions.ShortMethod)] + public ref ResizeKernel GetKernel(int destIdx) => ref this.kernels[destIdx]; + /// /// Computes the weights to apply at each pixel when resizing. /// @@ -88,7 +94,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float sum = 0; ResizeKernel ws = result.CreateKernel(i, left, right); - result.Kernels[i] = ws; + result.kernels[i] = ws; ref float weightsBaseRef = ref MemoryMarshal.GetReference(ws.GetValues()); diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index d0d225d9b..7c9d39fc5 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -269,9 +269,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int x = minX; x < maxX; x++) { - ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX]; + ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX); Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = - window.Convolve(tempRowSpan); + kernel.Convolve(tempRowSpan); } } }); @@ -289,7 +289,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int y = rows.Min; y < rows.Max; y++) { // Ensure offsets are normalized for cropping and padding. - ResizeKernel window = this.verticalKernelMap.Kernels[y - startY]; + ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY); ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan); @@ -298,7 +298,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY); // Destination color components - Unsafe.Add(ref tempRowBase, x) = window.Convolve(firstPassColumn); + Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn); } Vector4Utils.UnPremultiply(tempRowSpan); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs new file mode 100644 index 000000000..932ea5494 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; + +using SixLabors.ImageSharp.Processing.Processors.Transforms; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms +{ + public partial class KernelMapTests + { + /// + /// Simplified reference implementation for functionality. + /// + public class ReferenceKernelMap + { + private readonly ReferenceKernel[] kernels; + + public ReferenceKernelMap(ReferenceKernel[] kernels) + { + this.kernels = kernels; + } + + public int DestinationSize => this.kernels.Length; + + public ReferenceKernel GetKernel(int destinationIndex) => this.kernels[destinationIndex]; + + public static ReferenceKernelMap Calculate(IResampler sampler, int destinationSize, int sourceSize) + { + float ratio = (float)sourceSize / destinationSize; + float scale = ratio; + + if (scale < 1F) + { + scale = 1F; + } + + float radius = MathF.Ceiling(scale * sampler.Radius); + + var result = new List(); + + for (int i = 0; i < destinationSize; i++) + { + float center = ((i + .5F) * ratio) - .5F; + + // Keep inside bounds. + int left = (int)MathF.Ceiling(center - radius); + if (left < 0) + { + left = 0; + } + + int right = (int)MathF.Floor(center + radius); + if (right > sourceSize - 1) + { + right = sourceSize - 1; + } + + float sum = 0; + + float[] values = new float[right - left + 1]; + + for (int j = left; j <= right; j++) + { + float weight = sampler.GetValue((j - center) / scale); + sum += weight; + + values[j - left] = weight; + } + + result.Add(new ReferenceKernel(left, values)); + + if (sum > 0) + { + for (int w = 0; w < values.Length; w++) + { + values[w] /= sum; + } + } + } + + return new ReferenceKernelMap(result.ToArray()); + } + } + + public struct ReferenceKernel + { + public ReferenceKernel(int left, float[] values) + { + this.Left = left; + this.Values = values; + } + + public int Left { get; } + + public float[] Values { get; } + + public int Length => this.Values.Length; + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index a7d93ad1d..9f4d53b96 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -12,7 +12,7 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { - public class KernelMapTests + public partial class KernelMapTests { private ITestOutputHelper Output { get; } @@ -30,34 +30,52 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms [InlineData(100, 80, nameof(KnownResamplers.Lanczos8))] [InlineData(100, 10, nameof(KnownResamplers.Lanczos8))] [InlineData(10, 100, nameof(KnownResamplers.Lanczos8))] - public void PrintKernelMap(int srcSize, int destSize, string resamplerName) + public void KernelMapContentIsCorrect(int srcSize, int destSize, string resamplerName) { var resampler = (IResampler)typeof(KnownResamplers).GetProperty(resamplerName).GetValue(null); var kernelMap = KernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); + var referenceMap = ReferenceKernelMap.Calculate(resampler, destSize, srcSize); + +#if DEBUG + string text = PrintKernelMap(kernelMap); + this.Output.WriteLine(text); +#endif + + for (int i = 0; i < kernelMap.DestinationSize; i++) + { + ResizeKernel kernel = kernelMap.GetKernel(i); + + ReferenceKernel referenceKernel = referenceMap.GetKernel(i); + + Assert.Equal(referenceKernel.Length, kernel.Length); + Assert.Equal(referenceKernel.Left, kernel.Left); + Assert.True(kernel.GetValues().SequenceEqual(referenceKernel.Values)); + } + } + + private static string PrintKernelMap(KernelMap kernelMap) + { var bld = new StringBuilder(); - foreach (ResizeKernel kernel in kernelMap.Kernels) + for (int i = 0; i < kernelMap.DestinationSize; i++) { + ResizeKernel kernel = kernelMap.GetKernel(i); bld.Append($"({kernel.Left:D3}) || "); Span span = kernel.GetValues(); - for (int i = 0; i < kernel.Length; i++) + + for (int j = 0; j < kernel.Length; j++) { - float value = span[i]; - bld.Append($"{value,7:F5}"); + float value = span[j]; + bld.Append($"{value,8:F5}"); bld.Append(" | "); } bld.AppendLine(); } - string outDir = TestEnvironment.CreateOutputDirectory("." + nameof(this.PrintKernelMap)); - string fileName = $@"{outDir}\{resamplerName}_{srcSize}_{destSize}.MD"; - - File.WriteAllText(fileName, bld.ToString()); - - this.Output.WriteLine(bld.ToString()); + return bld.ToString(); } } } \ No newline at end of file From 3dd28364c32d177072e60288a552ee707b27a929 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 22:17:46 +0100 Subject: [PATCH 154/238] refactor ResizeKernel creation --- .../Processors/Transforms/KernelMap.cs | 13 ++++--- .../Processors/Transforms/ResizeKernel.cs | 34 ++++++++----------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index b0fd0e2cd..278fd93d8 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The to use for allocations. /// The size of the destination window /// The radius of the kernel - public KernelMap(MemoryAllocator memoryAllocator, int destinationSize, float kernelRadius) + private KernelMap(MemoryAllocator memoryAllocator, int destinationSize, float kernelRadius) { this.DestinationSize = destinationSize; int width = (int)Math.Ceiling(kernelRadius * 2); @@ -125,13 +125,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Slices a weights value at the given positions. /// - /// The index in destination buffer - /// The local left index value - /// The local right index value - /// The weights - private ResizeKernel CreateKernel(int destIdx, int leftIdx, int rightIdx) + private ResizeKernel CreateKernel(int destIdx, int left, int rightIdx) { - return new ResizeKernel(destIdx, leftIdx, this.data, rightIdx - leftIdx + 1); + int flatStartIndex = destIdx * this.data.Width; + int length = rightIdx - left + 1; + Memory bufferSlice = this.data.Memory.Slice(flatStartIndex, length); + return new ResizeKernel(left, bufferSlice); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs index 707f1467b..1ce9c9c91 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs @@ -16,42 +16,36 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms internal struct ResizeKernel { /// - /// The left index for the destination row + /// Initializes a new instance of the struct. /// - public int Left; + [MethodImpl(InliningOptions.ShortMethod)] + internal ResizeKernel(int left, Memory bufferSlice) + { + this.Left = left; + this.BufferSlice = bufferSlice; + } /// - /// The length of the kernel + /// Gets the left index for the destination row /// - public int Length; + public int Left { get; } /// - /// The buffer containing the weights values. + /// Gets the slice of the buffer containing the weights values. /// - private readonly Memory buffer; + public Memory BufferSlice { get; } /// - /// Initializes a new instance of the struct. + /// Gets the the length of the kernel /// - /// The destination index in the buffer - /// The local left index - /// The span - /// The length of the window - [MethodImpl(InliningOptions.ShortMethod)] - internal ResizeKernel(int index, int left, Buffer2D buffer, int length) - { - int flatStartIndex = index * buffer.Width; - this.Left = left; - this.buffer = buffer.MemorySource.Memory.Slice(flatStartIndex, length); - this.Length = length; - } + public int Length => this.BufferSlice.Length; /// /// Gets the span representing the portion of the that this window covers /// /// The [MethodImpl(InliningOptions.ShortMethod)] - public Span GetValues() => this.buffer.Span; + public Span GetValues() => this.BufferSlice.Span; /// /// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this instance. From f04fad180e4e55f1242e4d7f834868a0b47f15d7 Mon Sep 17 00:00:00 2001 From: Anton Firsov Date: Mon, 5 Nov 2018 01:33:06 +0100 Subject: [PATCH 155/238] Fix EnumHelper.IsDefined --- src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index c6a5b7d23..100649c0f 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -567,8 +567,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif [MethodImpl(InliningOptions.ShortMethod)] public static bool IsDefined(int value) { - return Array.BinarySearch(Values, 0, Values.Length, value) > 0; + return Array.BinarySearch(Values, value) >= 0; } } } -} \ No newline at end of file +} From ba589d3121b38a402c481cb54725e91091351412 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 5 Nov 2018 01:34:03 +0100 Subject: [PATCH 156/238] KernelMap refactor WIP --- .../ImageSharp.Drawing.csproj | 3 +- src/ImageSharp/ImageSharp.csproj | 3 +- .../Processors/Transforms/KernelMap.cs | 34 ++++++++++----- .../ImageSharp.Benchmarks.csproj | 3 +- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +- .../Processors/Transforms/KernelMapTests.cs | 42 ++++++++++++++----- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index 1cb3f444f..6341e1771 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -5,7 +5,8 @@ $(packageversion) 0.0.1 SixLabors and contributors - netstandard1.3;netstandard2.0 + + netcoreapp2.1 7.3 true true diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 29d29d50d..e2f55e3c6 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,7 +5,8 @@ $(packageversion) 0.0.1 Six Labors and contributors - netstandard1.3;netstandard2.0;netcoreapp2.1;net472 + + netcoreapp2.1 true true SixLabors.ImageSharp diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index 278fd93d8..3f984fef0 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -19,16 +19,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private readonly ResizeKernel[] kernels; - /// - /// Initializes a new instance of the class. - /// - /// The to use for allocations. - /// The size of the destination window - /// The radius of the kernel - private KernelMap(MemoryAllocator memoryAllocator, int destinationSize, float kernelRadius) + private int period; + + private int radius; + + private int periodicRegionMin; + + private int periodicRegionMax; + + private KernelMap(MemoryAllocator memoryAllocator, int destinationSize, int radius, int period) { this.DestinationSize = destinationSize; - int width = (int)Math.Ceiling(kernelRadius * 2); + this.period = period; + this.radius = radius; + this.periodicRegionMin = period + radius; + this.periodicRegionMax = destinationSize - radius; + + int width = radius * 2; this.data = memoryAllocator.Allocate2D(width, destinationSize, AllocationOptions.Clean); this.kernels = new ResizeKernel[destinationSize]; } @@ -71,8 +78,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms scale = 1F; } - float radius = MathF.Ceiling(scale * sampler.Radius); - var result = new KernelMap(memoryAllocator, destinationSize, radius); + int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; + + int radius = (int)MathF.Ceiling(scale * sampler.Radius); + var result = new KernelMap(memoryAllocator, destinationSize, radius, period); for (int i = 0; i < destinationSize; i++) { @@ -122,6 +131,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return result; } + private int ReduceIndex(int destIndex) + { + return destIndex; + } + /// /// Slices a weights value at the given positions. /// diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index a705c9bac..04a4541b2 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -1,6 +1,7 @@  - netcoreapp2.1;net461 + + netcoreapp2.1 Exe True SixLabors.ImageSharp.Benchmarks diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 86c1a7a25..75ac7450c 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,6 +1,7 @@  - net462;net472;netcoreapp2.1 + + netcoreapp2.1 True latest full diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 9f4d53b96..7abc1c312 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -20,17 +20,39 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { this.Output = output; } - + + /// + /// resamplerName, srcSize, destSize + /// + public static readonly TheoryData KernelMapData = new TheoryData + { + { nameof(KnownResamplers.Bicubic), 15, 10 }, + { nameof(KnownResamplers.Bicubic), 10, 15 }, + { nameof(KnownResamplers.Bicubic), 20, 20 }, + { nameof(KnownResamplers.Bicubic), 50, 40 }, + { nameof(KnownResamplers.Bicubic), 40, 50 }, + { nameof(KnownResamplers.Bicubic), 500, 200 }, + { nameof(KnownResamplers.Bicubic), 200, 500 }, + + { nameof(KnownResamplers.Lanczos3), 16, 12 }, + { nameof(KnownResamplers.Lanczos3), 12, 16 }, + { nameof(KnownResamplers.Lanczos3), 12, 9 }, + { nameof(KnownResamplers.Lanczos3), 9, 12 }, + { nameof(KnownResamplers.Lanczos3), 6, 8 }, + { nameof(KnownResamplers.Lanczos3), 8, 6 }, + + // TODO: What's wrong here: + // { nameof(KnownResamplers.Lanczos3), 20, 12 }, + + {nameof(KnownResamplers.Lanczos8), 500, 200 }, + {nameof(KnownResamplers.Lanczos8), 100, 10 }, + {nameof(KnownResamplers.Lanczos8), 100, 80 }, + {nameof(KnownResamplers.Lanczos8), 10, 100 }, + }; + [Theory] - [InlineData(500, 200, nameof(KnownResamplers.Bicubic))] - [InlineData(50, 40, nameof(KnownResamplers.Bicubic))] - [InlineData(40, 30, nameof(KnownResamplers.Bicubic))] - [InlineData(15, 10, nameof(KnownResamplers.Bicubic))] - [InlineData(500, 200, nameof(KnownResamplers.Lanczos8))] - [InlineData(100, 80, nameof(KnownResamplers.Lanczos8))] - [InlineData(100, 10, nameof(KnownResamplers.Lanczos8))] - [InlineData(10, 100, nameof(KnownResamplers.Lanczos8))] - public void KernelMapContentIsCorrect(int srcSize, int destSize, string resamplerName) + [MemberData(nameof(KernelMapData))] + public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { var resampler = (IResampler)typeof(KnownResamplers).GetProperty(resamplerName).GetValue(null); From fa5c0403c25e1392e2119f34d129e8ecb25afbac Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 5 Nov 2018 10:55:22 +0000 Subject: [PATCH 157/238] Add base becnhmark --- .../InterpolatedTransformProcessorBase.cs | 5 +-- .../ImageSharp.Benchmarks/Samplers/Rotate.cs | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Samplers/Rotate.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs b/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs index c1abb4a5e..4737a4102 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int i = 0; i < length; i++) { ref float wRef = ref Unsafe.Add(ref weightsRef, i); - wRef = wRef / sum; + wRef /= sum; } } } @@ -90,8 +90,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { for (int x = 0, i = sourceMin; i <= sourceMax; i++, x++) { - float weight = sampler.GetValue(i - point); - Unsafe.Add(ref weightsRef, x) = weight; + Unsafe.Add(ref weightsRef, x) = sampler.GetValue(i - point); } } diff --git a/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs b/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs new file mode 100644 index 000000000..c1456f9d7 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs @@ -0,0 +1,39 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Benchmarks.Samplers +{ + [Config(typeof(Config.ShortClr))] + public class Rotate + { + [Benchmark] + public Size DoRotate() + { + using (var image = new Image(Configuration.Default, 400, 400, Rgba32.BlanchedAlmond)) + { + image.Mutate(x => x.Rotate(37.5F)); + + return image.Size(); + } + } + } +} + +// Nov 4 2018 +//BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17763 +//Intel Core i7-6600U CPU 2.60GHz(Skylake), 1 CPU, 4 logical and 2 physical cores +//.NET Core SDK = 2.1.403 + +// [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT +// Job-KKDIMW : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 +// Job-IUZRFA : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + +//LaunchCount=1 TargetCount=3 WarmupCount=3 + +// #### BEFORE ####: +// Method | Runtime | Mean | Error | StdDev | Allocated | +//--------- |-------- |---------:|----------:|----------:|----------:| +// DoRotate | Clr | 85.19 ms | 13.379 ms | 0.7560 ms | 6 KB | +// DoRotate | Core | 53.51 ms | 9.512 ms | 0.5375 ms | 4.29 KB | \ No newline at end of file From 5e729854ec86b0c25791d0989534270d625e95f8 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 5 Nov 2018 10:57:55 +0000 Subject: [PATCH 158/238] Remove unused declaration. --- .../Processors/Quantization/PaletteQuantizer{TPixel}.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs index e2f302f1e..ac143a767 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs @@ -61,8 +61,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } TPixel[] paletteRef = this.palette; - TPixel1[] castPalette = Unsafe.As(ref paletteRef); - return new PaletteFrameQuantizer(this, Unsafe.As(ref paletteRef)); } From 8f55046917d204cbd32c93246b692ee899b3635f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 5 Nov 2018 13:49:14 +0000 Subject: [PATCH 159/238] Mask the PaletteQuantizer.CreateFrameQuantizer() methods. --- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 2 +- .../Quantization/PaletteQuantizer{TPixel}.cs | 36 ++++++--- .../Quantization/OctreeQuantizerTests.cs | 58 ++++++++++++++ .../Quantization/PaletteQuantizerTests.cs | 79 +++++++++++++++++++ .../Quantization/WuQuantizerTests.cs | 58 ++++++++++++++ 5 files changed, 223 insertions(+), 10 deletions(-) create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index de68cd46e..17ee61607 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.Formats.Gif } else { - using (QuantizedFrame paletteQuantized = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(frame)) + using (QuantizedFrame paletteQuantized = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs index ac143a767..a350adfc0 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs @@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public class PaletteQuantizer : IQuantizer where TPixel : struct, IPixel { - private readonly TPixel[] palette; - /// /// Initializes a new instance of the class. /// @@ -44,36 +42,56 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public PaletteQuantizer(TPixel[] palette, IErrorDiffuser diffuser) { Guard.MustBeBetweenOrEqualTo(palette.Length, QuantizerConstants.MinColors, QuantizerConstants.MaxColors, nameof(palette)); - this.palette = palette; + this.Palette = palette; this.Diffuser = diffuser; } /// public IErrorDiffuser Diffuser { get; } + /// + /// Gets the palette. + /// + public TPixel[] Palette { get; } + + /// + /// Creates the generic frame quantizer. + /// + /// The to configure internal operations. + /// The . + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) + => ((IQuantizer)this).CreateFrameQuantizer(configuration); + + /// + /// Creates the generic frame quantizer. + /// + /// The to configure internal operations. + /// The maximum number of colors to hold in the color palette. + /// The . + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) + => ((IQuantizer)this).CreateFrameQuantizer(configuration, maxColors); + /// - public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) - where TPixel1 : struct, IPixel + IFrameQuantizer IQuantizer.CreateFrameQuantizer(Configuration configuration) { if (!typeof(TPixel).Equals(typeof(TPixel1))) { throw new InvalidOperationException("Generic method type must be the same as class type."); } - TPixel[] paletteRef = this.palette; + TPixel[] paletteRef = this.Palette; return new PaletteFrameQuantizer(this, Unsafe.As(ref paletteRef)); } /// - public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) - where TPixel1 : struct, IPixel + IFrameQuantizer IQuantizer.CreateFrameQuantizer(Configuration configuration, int maxColors) { if (!typeof(TPixel).Equals(typeof(TPixel1))) { throw new InvalidOperationException("Generic method type must be the same as class type."); } - TPixel[] paletteRef = this.palette; + TPixel[] paletteRef = this.Palette; TPixel1[] castPalette = Unsafe.As(ref paletteRef); maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs new file mode 100644 index 000000000..b3900325d --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class OctreeQuantizerTests + { + [Fact] + public void OctreeQuantizerConstructor() + { + var quantizer = new OctreeQuantizer(128); + + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new OctreeQuantizer(false); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Null(quantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson, 128); + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void OctreeQuantizerCanCreateFrameQuantizer() + { + var quantizer = new OctreeQuantizer(); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new OctreeQuantizer(false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + } +} diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs new file mode 100644 index 000000000..a4e6edd53 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs @@ -0,0 +1,79 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class PaletteQuantizerTests + { + private static readonly Rgba32[] Rgb = new Rgba32[] { Rgba32.Red, Rgba32.Green, Rgba32.Blue }; + + [Fact] + public void PaletteQuantizerConstructor() + { + var quantizer = new PaletteQuantizer(Rgb); + + Assert.Equal(Rgb, quantizer.Palette); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, false); + Assert.Equal(Rgb, quantizer.Palette); + Assert.Null(quantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, KnownDiffusers.Atkinson); + Assert.Equal(Rgb, quantizer.Palette); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void PaletteQuantizerCanCreateFrameQuantizer() + { + var quantizer = new PaletteQuantizer(Rgb); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + + [Fact] + public void PaletteQuantizerThrowsOnInvalidGenericMethodCall() + { + var quantizer = new PaletteQuantizer(Rgb); + + Assert.Throws(() => ((IQuantizer)quantizer).CreateFrameQuantizer(Configuration.Default)); + } + + [Fact] + public void KnownQuantizersWebSafeTests() + { + IQuantizer quantizer = KnownQuantizers.WebSafe; + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + } + + [Fact] + public void KnownQuantizersWernerTests() + { + IQuantizer quantizer = KnownQuantizers.Werner; + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + } + } +} diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs new file mode 100644 index 000000000..625043c7f --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class WuQuantizerTests + { + [Fact] + public void WuQuantizerConstructor() + { + var quantizer = new WuQuantizer(128); + + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new WuQuantizer(false); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Null(quantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson, 128); + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void WuQuantizerCanCreateFrameQuantizer() + { + var quantizer = new WuQuantizer(); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new WuQuantizer(false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + } +} From 23142318827e9f949d0018179495ed9c024bf172 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Mon, 5 Nov 2018 13:27:08 -0600 Subject: [PATCH 160/238] ImageSharp-762_Aot-compiling: moved AoT methods to AotCompiler static class --- src/ImageSharp/Advanced/AotCompiler.cs | 103 ++++++++++++++++++ src/ImageSharp/Formats/Gif/ImageExtensions.cs | 42 ------- 2 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 src/ImageSharp/Advanced/AotCompiler.cs diff --git a/src/ImageSharp/Advanced/AotCompiler.cs b/src/ImageSharp/Advanced/AotCompiler.cs new file mode 100644 index 000000000..1c7f12ef7 --- /dev/null +++ b/src/ImageSharp/Advanced/AotCompiler.cs @@ -0,0 +1,103 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Dithering; +using SixLabors.ImageSharp.Processing.Processors.Quantization; + +namespace SixLabors.ImageSharp.Advanced +{ + /// + /// Unlike traditional Mono/.NET, code on the iPhone is statically compiled ahead of time instead of being + /// compiled on demand by a JIT compiler. This means there are a few limitations with respect to generics, + /// these are caused because not every possible generic instantiation can be determined up front at compile time. + /// The Aot Compiler is designed to overcome the limitations of this compiler. + /// + public static class AotCompiler + { + /// + /// Seeds the compiler using the given pixel format. + /// + /// The pixel format. + public static void Seed() + where TPixel : struct, IPixel + { + // This is we actually call all the individual methods you need to seed. + AotCompileOctreeQuantizer(); + AotCompileWuQuantizer(); + AotCompileDithering(); + + // TODO: Do the discovery work to figure out what works and what doesn't. + } + + /// + /// Seeds the compiler using the given pixel formats. + /// + /// The first pixel format. + /// The second pixel format. + public static void Seed() + where TPixel : struct, IPixel + where TPixel2 : struct, IPixel + { + Seed(); + Seed(); + } + + /// + /// Seeds the compiler using the given pixel formats. + /// + /// The first pixel format. + /// The second pixel format. + /// The third pixel format. + public static void Seed() + where TPixel : struct, IPixel + where TPixel2 : struct, IPixel + where TPixel3 : struct, IPixel + { + Seed(); + Seed(); + } + + /// + /// This method doesn't actually do anything but serves an important purpose... + /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: + /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." + /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT + /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on + /// iOS so it bombs out. + /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the + /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! + /// + /// The pixel format. + private static void AotCompileOctreeQuantizer() + where TPixel : struct, IPixel + { + var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); + test.AotGetPalette(); + } + + /// + /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS. + /// + /// The pixel format. + private static void AotCompileWuQuantizer() + where TPixel : struct, IPixel + { + var test = new WuFrameQuantizer(new WuQuantizer(false)); + test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1)); + test.AotGetPalette(); + } + + /// + /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. + /// + /// The pixel format. + private static void AotCompileDithering() + where TPixel : struct, IPixel + { + var test = new FloydSteinbergDiffuser(); + TPixel pixel = default; + test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index f1c2ae5fb..3939299e9 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -38,47 +38,5 @@ namespace SixLabors.ImageSharp public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) where TPixel : struct, IPixel => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); - - /// - /// This method doesn't actually do anything but serves an important purpose... - /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: - /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." - /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT - /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on - /// iOS so it bombs out. - /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the - /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! - /// - /// The pixel format. - public static void AotCompileOctreeQuantizer() - where TPixel : struct, IPixel - { - var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); - test.AotGetPalette(); - } - - /// - /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS. - /// - /// The pixel format. - public static void AotCompileWuQuantizer() - where TPixel : struct, IPixel - { - var test = new WuFrameQuantizer(new WuQuantizer(false)); - test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1)); - test.AotGetPalette(); - } - - /// - /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. - /// - /// The pixel format. - public static void AotCompileDithering() - where TPixel : struct, IPixel - { - var test = new FloydSteinbergDiffuser(); - TPixel pixel = default; - test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); - } } } From c80d8f604bb9d54e72cb8ccc5fdb3e4735a4ea1b Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Mon, 5 Nov 2018 13:28:17 -0600 Subject: [PATCH 161/238] ImageSharp-762_Aot-compiling: namespace cleanup --- src/ImageSharp/Formats/Gif/ImageExtensions.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index 3939299e9..8ddd4247e 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -5,9 +5,6 @@ using System.IO; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Primitives; -using SixLabors.ImageSharp.Processing.Processors.Dithering; -using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp { From 54b279983a2b0cd6088fcd02836533b99a3c3bc5 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 11:12:25 +0100 Subject: [PATCH 162/238] fix typos in comments --- .../Processors/Drawing/FillRegionProcessor.cs | 6 +-- .../Processors/Text/DrawTextProcessor.cs | 4 +- .../Processing/SolidBrush{TPixel}.cs | 2 +- .../Advanced/AdvancedImageExtensions.cs | 6 +-- src/ImageSharp/Common/Helpers/ImageMaths.cs | 2 +- .../Helpers/SimdUtils.BasicIntrinsics256.cs | 2 +- src/ImageSharp/Common/Helpers/SimdUtils.cs | 4 +- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 2 +- .../Formats/Bmp/IBmpDecoderOptions.cs | 2 +- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 2 +- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 4 +- src/ImageSharp/Formats/Gif/LzwEncoder.cs | 4 +- src/ImageSharp/Formats/IImageFormat.cs | 4 +- .../Formats/Jpeg/Components/Block8x8.cs | 6 +-- .../Formats/Jpeg/Components/Block8x8F.cs | 4 +- .../JpegColorConverter.FromYCbCrSimd.cs | 4 +- .../JpegColorConverter.FromYCbCrSimdAvx2.cs | 2 +- .../ColorConverters/JpegColorConverter.cs | 2 +- .../Jpeg/Components/Decoder/HuffmanTable.cs | 2 +- .../Jpeg/Components/Decoder/IRawJpegData.cs | 2 +- .../Jpeg/Components/Decoder/JFifMarker.cs | 2 +- .../Decoder/JpegBlockPostProcessor.cs | 2 +- .../Decoder/JpegComponentPostProcessor.cs | 2 +- .../Jpeg/Components/Decoder/ScanDecoder.cs | 4 +- .../Components/Encoder/RgbToYCbCrTables.cs | 2 +- .../Jpeg/Components/GenericBlock8x8.cs | 2 +- .../Formats/Jpeg/JpegDecoderCore.cs | 4 +- .../Formats/Png/Chunks/PhysicalChunkData.cs | 2 +- .../Formats/Png/IPngDecoderOptions.cs | 2 +- src/ImageSharp/IImageInfo.cs | 2 +- src/ImageSharp/Image.WrapMemory.cs | 24 +++++------ src/ImageSharp/ImageExtensions.cs | 4 +- src/ImageSharp/Image{TPixel}.cs | 2 +- .../Profiles/ICC/Enums/IccProfileClass.cs | 10 ++--- .../Profiles/ICC/Enums/IccProfileFlag.cs | 4 +- .../Profiles/ICC/Enums/IccProfileTag.cs | 42 +++++++++---------- .../Profiles/ICC/Enums/IccRenderingIntent.cs | 10 ++--- .../Profiles/ICC/Enums/IccTypeSignature.cs | 28 ++++++------- .../PixelFormats/ColorBuilder{TPixel}.cs | 2 +- .../PixelFormats/PixelOperations{TPixel}.cs | 2 +- .../PixelFormats/Utils/PixelConverter.cs | 2 +- .../Utils/Vector4Converters.RgbaCompatible.cs | 2 +- 42 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs index 514249a2d..1dc63efa2 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs @@ -82,11 +82,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing // we need to offset the pixel grid to account for when we outline a path. // basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5] // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the# - // region to alline with the pixel grid. + // region to align with the pixel grid. float offset = 0.5f; if (this.Options.Antialias) { - offset = 0f; // we are antialising skip offsetting as real antalising should take care of offset. + offset = 0f; // we are antialiasing skip offsetting as real antialiasing should take care of offset. subpixelCount = this.Options.AntialiasSubpixelDepth; if (subpixelCount < 4) { @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing int pointsFound = region.Scan(subPixel + offset, buffer, configuration); if (pointsFound == 0) { - // nothing on this line skip + // nothing on this line, skip continue; } diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index f9a1d8739..487c88064 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text /// The font we want to render with /// The brush to source pixel colors from. /// The pen to outline text with. - /// The location on the image to start drawign the text from. + /// The location on the image to start drawing the text from. public DrawTextProcessor(TextGraphicsOptions options, string text, Font font, IBrush brush, IPen pen, PointF location) { Guard.NotNull(text, nameof(text)); @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text { base.BeforeImageApply(source, sourceRectangle); - // do everythign at the image level as we are deligating the processing down to other processors + // do everything at the image level as we are delegating the processing down to other processors var style = new RendererOptions(this.Font, this.Options.DpiX, this.Options.DpiY, this.Location) { ApplyKerning = this.Options.ApplyKerning, diff --git a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs index 6a8028770..20a6833c4 100644 --- a/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/SolidBrush{TPixel}.cs @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Processing { Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x); - // constrain the spans to eachother + // constrain the spans to each other if (destinationRow.Length > scanline.Length) { destinationRow = destinationRow.Slice(0, scanline.Length); diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 328d57596..63ccea4e6 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Advanced /// /// The type of the pixel. /// The source. - /// The span retuned from Pixel source + /// The span returned from Pixel source private static Span GetSpan(IPixelSource source) where TPixel : struct, IPixel => source.PixelBuffer.GetSpan(); @@ -172,7 +172,7 @@ namespace SixLabors.ImageSharp.Advanced /// The source. /// The row. /// - /// The span retuned from Pixel source + /// The span returned from Pixel source /// private static Span GetSpan(IPixelSource source, int row) where TPixel : struct, IPixel @@ -185,7 +185,7 @@ namespace SixLabors.ImageSharp.Advanced /// The source. /// The row. /// - /// The span retuned from Pixel source + /// The span returned from Pixel source /// private static Span GetSpan(Buffer2D source, int row) where TPixel : struct, IPixel diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 402aa79b5..f07ccb03b 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp /// /// Scales a value from an 8 bit to it's 16 bit equivalent. /// - /// The 8 bit compoonent value. + /// The 8 bit component value. /// The [MethodImpl(InliningOptions.ShortMethod)] public static ushort UpscaleFrom8BitTo16Bit(byte component) => (ushort)(component * 257); diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs index 0f1ce2ab6..85c9f0074 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp var bVec = new Vector(256.0f / 255.0f); var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + var magicInt = new Vector(1191182336); // reinterpreted value of 32768.0f var mask = new Vector(255); ref Octet.OfByte sourceBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source)); diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index a989cc875..867e7b9de 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp DebugGuard.IsTrue( ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0, nameof(source), - $"length should be divisable by {shouldBeDivisibleBy}!"); + $"length should be divisible by {shouldBeDivisibleBy}!"); } [Conditional("DEBUG")] @@ -179,7 +179,7 @@ namespace SixLabors.ImageSharp DebugGuard.IsTrue( ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0, nameof(source), - $"length should be divisable by {shouldBeDivisibleBy}!"); + $"length should be divisible by {shouldBeDivisibleBy}!"); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index cea90cb45..eb519f421 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// Looks up color values and builds the image from de-compressed RLE8 data. - /// Compresssed RLE8 stream is uncompressed by + /// Compressed RLE8 stream is uncompressed by /// /// The pixel format. /// The to assign the palette to. diff --git a/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs index c44ca73f2..219d37ca6 100644 --- a/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs +++ b/src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs @@ -8,6 +8,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// internal interface IBmpDecoderOptions { - // added this for consistancy so we can add stuff as required, no options currently availible + // added this for consistency so we can add stuff as required, no options currently available } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index db512a078..b8a270b3f 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Formats.Gif private GifGraphicControlExtension graphicsControlExtension; /// - /// The image desciptor. + /// The image descriptor. /// private GifImageDescriptor imageDescriptor; diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 17ee61607..a922f3011 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Gif internal sealed class GifEncoderCore { /// - /// Used for allocating memory during procesing operations. + /// Used for allocating memory during processing operations. /// private readonly MemoryAllocator memoryAllocator; @@ -421,7 +421,7 @@ namespace SixLabors.ImageSharp.Formats.Gif private void WriteColorTable(QuantizedFrame image, Stream stream) where TPixel : struct, IPixel { - // The maximium number of colors for the bit depth + // The maximum number of colors for the bit depth int colorTableLength = ImageMaths.GetColorCountForBitDepth(this.bitDepth) * 3; int pixelCount = image.Palette.Length; diff --git a/src/ImageSharp/Formats/Gif/LzwEncoder.cs b/src/ImageSharp/Formats/Gif/LzwEncoder.cs index e390dfd54..34c353ec9 100644 --- a/src/ImageSharp/Formats/Gif/LzwEncoder.cs +++ b/src/ImageSharp/Formats/Gif/LzwEncoder.cs @@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Formats.Gif }; /// - /// The maximium number of bits/code. + /// The maximum number of bits/code. /// private const int MaxBits = 12; @@ -210,7 +210,7 @@ namespace SixLabors.ImageSharp.Formats.Gif /// flush the packet to disk. /// /// The character to add. - /// The reference to the storage for packat accumulators + /// The reference to the storage for packet accumulators /// The stream to write to. [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AddCharacter(byte c, ref byte accumulatorsRef, Stream stream) diff --git a/src/ImageSharp/Formats/IImageFormat.cs b/src/ImageSharp/Formats/IImageFormat.cs index 94191c149..3cd289df7 100644 --- a/src/ImageSharp/Formats/IImageFormat.cs +++ b/src/ImageSharp/Formats/IImageFormat.cs @@ -16,12 +16,12 @@ namespace SixLabors.ImageSharp.Formats string Name { get; } /// - /// Gets the default mimetype that the image foramt uses + /// Gets the default mimetype that the image format uses /// string DefaultMimeType { get; } /// - /// Gets all the mimetypes that have been used by this image foramt. + /// Gets all the mimetypes that have been used by this image format. /// IEnumerable MimeTypes { get; } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index 5601a9436..60fec25d2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -10,7 +10,7 @@ using System.Text; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { /// - /// Represents a Jpeg block with coefficiens. + /// Represents a Jpeg block with coefficients. /// // ReSharper disable once InconsistentNaming internal unsafe struct Block8x8 : IEquatable @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } /// - /// Gets or sets a value in a row+coulumn of the 8x8 block + /// Gets or sets a value in a row+column of the 8x8 block /// /// The x position index in the row /// The column index @@ -283,7 +283,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } /// - /// Calculate the total sum of absoulute differences of elements in 'a' and 'b'. + /// Calculate the total sum of absolute differences of elements in 'a' and 'b'. /// public static long TotalDifference(ref Block8x8 a, ref Block8x8 b) { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 137a8029d..2be5addc2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -395,7 +395,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } /// - /// Scales the 16x16 region represented by the 4 source blocks to the 8x8 DST block. + /// Scales the 16x16 region represented by the 4 source blocks to the 8x8 DST block. /// /// The destination block. /// The source block. @@ -571,7 +571,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // sign(dividend) = max(min(dividend, 1), -1) var sign = Vector4.Clamp(dividend, NegativeOne, Vector4.One); - // AlmostRound(dividend/divisor) = dividend/divisior + 0.5*sign(dividend) + // AlmostRound(dividend/divisor) = dividend/divisor + 0.5*sign(dividend) return (dividend / divisor) + (sign * Offset); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs index 1dc72aaf5..23aa1acbe 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs @@ -32,11 +32,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } /// - /// SIMD convert using buffers of sizes divisable by 8. + /// SIMD convert using buffers of sizes divisible by 8. /// internal static void ConvertCore(in ComponentValues values, Span result) { - DebugGuard.IsTrue(result.Length % 8 == 0, nameof(result), "result.Length should be divisable by 8!"); + DebugGuard.IsTrue(result.Length % 8 == 0, nameof(result), "result.Length should be divisible by 8!"); ref Vector4Pair yBase = ref Unsafe.As(ref MemoryMarshal.GetReference(values.Component0)); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs index 46644258b..f0a70a6f3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters } /// - /// SIMD convert using buffers of sizes divisable by 8. + /// SIMD convert using buffers of sizes divisible by 8. /// internal static void ConvertCore(in ComponentValues values, Span result) { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs index 456636dc3..a44ebf89d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters internal abstract partial class JpegColorConverter { /// - /// The avalilable converters + /// The available converters /// private static readonly JpegColorConverter[] Converters = { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs index 24d570bf1..9e134746b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } // Figure F.15: generate decoding tables for bit-sequential decoding. - // Compute largest code + 1 for this size. preshifted as we needit later. + // Compute largest code + 1 for this size. preshifted as we need it later. Unsafe.Add(ref maxcodeRef, k) = code << (16 - k); code <<= 1; } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs index dace78b33..1454bb5b1 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder Size ImageSizeInPixels { get; } /// - /// Gets the number of coponents. + /// Gets the number of components. /// int ComponentCount { get; } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs index f153ce062..4bff49248 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// The minor version /// The units for the density values /// The horizontal pixel density - /// The veritcal pixel density + /// The vertical pixel density private JFifMarker(byte majorVersion, byte minorVersion, byte densityUnits, short xDensity, short yDensity) { Guard.MustBeGreaterThan(xDensity, 0, nameof(xDensity)); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs index 0108e3081..da4b2847b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// - Dequantize /// - Applying IDCT /// - Level shift by +128, clip to [0, 255] - /// - Copy the resultin color values into 'destArea' scaling up the block by amount defined in + /// - Copy the resulting color values into 'destArea' scaling up the block by amount defined in /// /// The source block. /// The destination buffer area. diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs index 57a53549f..94ec600dd 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder private int currentComponentRowInBlocks; /// - /// The size of the area in corrsponding to one 8x8 Jpeg block + /// The size of the area in corresponding to one 8x8 Jpeg block /// private readonly Size blockAreaSize; diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs index 5d232b571..48abca2a4 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ScanDecoder.cs @@ -755,7 +755,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder [MethodImpl(InliningOptions.ColdPath)] private void FillBuffer() { - // Attempt to load at least the minimum nbumber of required bits into the buffer. + // Attempt to load at least the minimum number of required bits into the buffer. // We fail to do so only if we hit a marker or reach the end of the input stream. do { @@ -912,7 +912,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } // If it's NOT a restart, then just bail, so we get corrupt data rather than no data. - // Reset the stream to before any bad markers to ensure we can read sucessive segments. + // Reset the stream to before any bad markers to ensure we can read successive segments. if (this.badMarker) { this.stream.Position = this.markerPosition; diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs index a0cc9ee8e..cb0810985 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// /// Initializes the YCbCr tables /// - /// The intialized + /// The initialized public static RgbToYCbCrTables Create() { RgbToYCbCrTables tables = default; diff --git a/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs index 2e20da266..c795ccc8b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// FOR TESTING ONLY! - /// Gets or sets a value in a row+coulumn of the 8x8 block + /// Gets or sets a value in a row+column of the 8x8 block /// /// The x position index in the row /// The column index diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index ef73aab38..67f665576 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -51,12 +51,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg private readonly byte[] markerBuffer = new byte[2]; /// - /// The DC HUffman tables + /// The DC Huffman tables /// private HuffmanTables dcHuffmanTables; /// - /// The AC HUffman tables + /// The AC Huffman tables /// private HuffmanTables acHuffmanTables; diff --git a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs index 07fc688d5..6ab0dd657 100644 --- a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs +++ b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks /// /// Constructs the PngPhysicalChunkData from the provided metadata. - /// If the resolution units are not in meters, they are automatically convereted. + /// If the resolution units are not in meters, they are automatically converted. /// /// The metadata. /// The constructed PngPhysicalChunkData instance. diff --git a/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs b/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs index bd0b93205..5b650ac2a 100644 --- a/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs +++ b/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs @@ -6,7 +6,7 @@ using System.Text; namespace SixLabors.ImageSharp.Formats.Png { /// - /// The optioas for decoding png images + /// The options for decoding png images /// internal interface IPngDecoderOptions { diff --git a/src/ImageSharp/IImageInfo.cs b/src/ImageSharp/IImageInfo.cs index 25d5ec7ca..6e64aa679 100644 --- a/src/ImageSharp/IImageInfo.cs +++ b/src/ImageSharp/IImageInfo.cs @@ -7,7 +7,7 @@ using SixLabors.ImageSharp.MetaData; namespace SixLabors.ImageSharp { /// - /// Encapsulates properties that descibe basic image information including dimensions, pixel type information + /// Encapsulates properties that describe basic image information including dimensions, pixel type information /// and additional metadata /// public interface IImageInfo diff --git a/src/ImageSharp/Image.WrapMemory.cs b/src/ImageSharp/Image.WrapMemory.cs index e8d9ab754..c2935bed9 100644 --- a/src/ImageSharp/Image.WrapMemory.cs +++ b/src/ImageSharp/Image.WrapMemory.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp public static partial class Image { /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. /// /// The pixel type @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp } /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. /// /// The pixel type @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp } /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. /// The memory is being observed, the caller remains responsible for managing it's lifecycle. /// @@ -79,15 +79,15 @@ namespace SixLabors.ImageSharp } /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. - /// The ownership of the is being transfered to the new instance, + /// The ownership of the is being transferred to the new instance, /// meaning that the caller is not allowed to dispose . /// It will be disposed together with the result image. /// /// The pixel type /// The - /// The that is being transfered to the image + /// The that is being transferred to the image /// The width of the memory image /// The height of the memory image /// The @@ -105,15 +105,15 @@ namespace SixLabors.ImageSharp } /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. - /// The ownership of the is being transfered to the new instance, + /// The ownership of the is being transferred to the new instance, /// meaning that the caller is not allowed to dispose . /// It will be disposed together with the result image. /// /// The pixel type /// The - /// The that is being transfered to the image + /// The that is being transferred to the image /// The width of the memory image /// The height of the memory image /// An instance @@ -128,14 +128,14 @@ namespace SixLabors.ImageSharp } /// - /// Wraps an existing contigous memory area of 'width'x'height' pixels, + /// Wraps an existing contiguous memory area of 'width' x 'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. - /// The ownership of the is being transfered to the new instance, + /// The ownership of the is being transferred to the new instance, /// meaning that the caller is not allowed to dispose . /// It will be disposed together with the result image. /// /// The pixel type - /// The that is being transfered to the image + /// The that is being transferred to the image /// The width of the memory image /// The height of the memory image /// An instance diff --git a/src/ImageSharp/ImageExtensions.cs b/src/ImageSharp/ImageExtensions.cs index e579bec1a..cbf93275c 100644 --- a/src/ImageSharp/ImageExtensions.cs +++ b/src/ImageSharp/ImageExtensions.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp if (format is null) { var sb = new StringBuilder(); - sb.AppendLine($"Can't find a format that is associated with the file extention '{ext}'. Registered formats with there extensions include:"); + sb.AppendLine($"Can't find a format that is associated with the file extension '{ext}'. Registered formats with there extensions include:"); foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats) { sb.AppendLine($" - {fmt.Name} : {string.Join(", ", fmt.FileExtensions)}"); @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp if (encoder is null) { var sb = new StringBuilder(); - sb.AppendLine($"Can't find encoder for file extention '{ext}' using image format '{format.Name}'. Registered encoders include:"); + sb.AppendLine($"Can't find encoder for file extension '{ext}' using image format '{format.Name}'. Registered encoders include:"); foreach (KeyValuePair enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { sb.AppendLine($" - {enc.Key} : {enc.Value.GetType().Name}"); diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 9d4c1ef0b..178194b21 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -186,7 +186,7 @@ namespace SixLabors.ImageSharp public Image Clone() => this.Clone(this.configuration); /// - /// Clones the current image with the given configueation. + /// Clones the current image with the given configuration. /// /// The configuration providing initialization code which allows extending the library. /// Returns a new with all the same pixel data as the original. diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileClass.cs b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileClass.cs index 71c27ca61..8f0427db2 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileClass.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileClass.cs @@ -39,15 +39,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// This profile provides the relevant information to perform a transformation - /// between colour encodings and the PCS. This type of profile is based on - /// modelling rather than device measurement or characterization data. + /// between color encodings and the PCS. This type of profile is based on + /// modeling rather than device measurement or characterization data. /// ColorSpace profiles may be embedded in images. /// ColorSpace = 0x73706163, // spac /// /// This profile represents abstract transforms and does not represent any - /// device model. Colour transformations using Abstract profiles are performed + /// device model. Color transformations using Abstract profiles are performed /// from PCS to PCS. Abstract profiles cannot be embedded in images. /// Abstract = 0x61627374, // abst @@ -55,8 +55,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// NamedColor profiles can be thought of as sibling profiles to device profiles. /// For a given device there would be one or more device profiles to handle - /// process colour conversions and one or more named colour profiles to handle - /// named colours. + /// process color conversions and one or more named color profiles to handle + /// named colors. /// NamedColor = 0x6E6D636C, // nmcl } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileFlag.cs b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileFlag.cs index 3758be34b..1e9ec18e8 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileFlag.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileFlag.cs @@ -29,12 +29,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc NotEmbedded = 0, /// - /// Profile cannot be used independently of the embedded colour data + /// Profile cannot be used independently of the embedded color data /// NotIndependent = 1 << 1, /// - /// Profile can be used independently of the embedded colour data + /// Profile can be used independently of the embedded color data /// Independent = 0, } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileTag.cs b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileTag.cs index 82b296900..61d34dca1 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileTag.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccProfileTag.cs @@ -19,18 +19,18 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc Unknown, /// - /// A2B0 - This tag defines a colour transform from Device, Colour Encoding or PCS, to PCS, or a colour transform + /// A2B0 - This tag defines a color transform from Device, Color Encoding or PCS, to PCS, or a color transform /// from Device 1 to Device 2, using lookup table tag element structures /// AToB0 = 0x41324230, /// - /// A2B2 - This tag describes the colour transform from Device or Colour Encoding to PCS using lookup table tag element structures + /// A2B2 - This tag describes the color transform from Device or Color Encoding to PCS using lookup table tag element structures /// AToB1 = 0x41324231, /// - /// A2B2 - This tag describes the colour transform from Device or Colour Encoding to PCS using lookup table tag element structures + /// A2B2 - This tag describes the color transform from Device or Color Encoding to PCS using lookup table tag element structures /// AToB2 = 0x41324232, @@ -46,40 +46,40 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc BlueTrc = 0x62545243, /// - /// B2A0 - This tag defines a colour transform from PCS to Device or Colour Encoding using the lookup table tag element structures + /// B2A0 - This tag defines a color transform from PCS to Device or Color Encoding using the lookup table tag element structures /// BToA0 = 0x42324130, /// - /// B2A1 - This tag defines a colour transform from PCS to Device or Colour Encoding using the lookup table tag element structures. + /// B2A1 - This tag defines a color transform from PCS to Device or Color Encoding using the lookup table tag element structures. /// BToA1 = 0x42324131, /// - /// B2A2 - This tag defines a colour transform from PCS to Device or Colour Encoding using the lookup table tag element structures. + /// B2A2 - This tag defines a color transform from PCS to Device or Color Encoding using the lookup table tag element structures. /// BToA2 = 0x42324132, /// - /// B2D0 - This tag defines a colour transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and + /// B2D0 - This tag defines a color transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and /// provides a means to override the BToA0 tag. /// BToD0 = 0x42324430, /// - /// B2D1 - This tag defines a colour transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and + /// B2D1 - This tag defines a color transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and /// provides a means to override the BToA1 tag. /// BToD1 = 0x42324431, /// - /// B2D2 - This tag defines a colour transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and + /// B2D2 - This tag defines a color transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and /// provides a means to override the BToA2 tag. /// BToD2 = 0x42324432, /// - /// B2D3 - This tag defines a colour transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and + /// B2D3 - This tag defines a color transform from PCS to Device. It supports float32Number-encoded input range, output range and transform, and /// provides a means to override the BToA1 tag. /// BToD3 = 0x42324433, @@ -97,8 +97,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc CharTarget = 0x74617267, /// - /// chad - This tag contains a matrix, which shall be invertible, and which converts an nCIEXYZ colour, measured using the actual illumination - /// conditions and relative to the actual adopted white, to an nCIEXYZ colour relative to the PCS adopted white + /// chad - This tag contains a matrix, which shall be invertible, and which converts an nCIEXYZ color, measured using the actual illumination + /// conditions and relative to the actual adopted white, to an nCIEXYZ color relative to the PCS adopted white /// ChromaticAdaptation = 0x63686164, @@ -166,33 +166,33 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc DeviceSettings = 0x64657673, /// - /// D2B0 - This tag defines a colour transform from Device to PCS. It supports float32Number-encoded + /// D2B0 - This tag defines a color transform from Device to PCS. It supports float32Number-encoded /// input range, output range and transform, and provides a means to override the AToB0 tag /// DToB0 = 0x44324230, /// - /// D2B1 - This tag defines a colour transform from Device to PCS. It supports float32Number-encoded + /// D2B1 - This tag defines a color transform from Device to PCS. It supports float32Number-encoded /// input range, output range and transform, and provides a means to override the AToB1 tag /// DToB1 = 0x44324230, /// - /// D2B2 - This tag defines a colour transform from Device to PCS. It supports float32Number-encoded + /// D2B2 - This tag defines a color transform from Device to PCS. It supports float32Number-encoded /// input range, output range and transform, and provides a means to override the AToB1 tag /// DToB2 = 0x44324230, /// - /// D2B3 - This tag defines a colour transform from Device to PCS. It supports float32Number-encoded + /// D2B3 - This tag defines a color transform from Device to PCS. It supports float32Number-encoded /// input range, output range and transform, and provides a means to override the AToB1 tag /// DToB3 = 0x44324230, /// /// gamt - This tag provides a table in which PCS values are the input and a single - /// output value for each input value is the output. If the output value is 0, the PCS colour is in-gamut. - /// If the output is non-zero, the PCS colour is out-of-gamut + /// output value for each input value is the output. If the output value is 0, the PCS color is in-gamut. + /// If the output is non-zero, the PCS color is out-of-gamut /// Gamut = 0x67616D74, @@ -214,7 +214,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc GreenTrc = 0x67545243, /// - /// lumi - This tag contains the absolute luminance of emissive devices in candelas per square metre as described by the Y channel. + /// lumi - This tag contains the absolute luminance of emissive devices in candelas per square meter as described by the Y channel. /// Luminance = 0x6C756d69, @@ -240,8 +240,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc NamedColor = 0x6E636f6C, /// - /// ncl2 - This tag contains the named colour information providing a PCS and optional device representation - /// for a list of named colours. + /// ncl2 - This tag contains the named color information providing a PCS and optional device representation + /// for a list of named colors. /// NamedColor2 = 0x6E636C32, diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccRenderingIntent.cs b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccRenderingIntent.cs index e0504b24c..7cb9c00f3 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccRenderingIntent.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccRenderingIntent.cs @@ -10,11 +10,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { /// /// In perceptual transforms the PCS values represent hypothetical - /// measurements of a colour reproduction on the reference reflective + /// measurements of a color reproduction on the reference reflective /// medium. By extension, for the perceptual intent, the PCS represents /// the appearance of that reproduction as viewed in the reference viewing /// environment by a human observer adapted to that environment. The exact - /// colour rendering of the perceptual intent is vendor specific. + /// color rendering of the perceptual intent is vendor specific. /// Perceptual = 0, @@ -27,15 +27,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc MediaRelativeColorimetric = 1, /// - /// The exact colour rendering of the saturation intent is vendor + /// The exact color rendering of the saturation intent is vendor /// specific and involves compromises such as trading off - /// preservation of hue in order to preserve the vividness of pure colours. + /// preservation of hue in order to preserve the vividness of pure colors. /// Saturation = 2, /// /// Transformations for this intent shall leave the chromatically - /// adapted nCIEXYZ tristimulus values of the in-gamut colours unchanged. + /// adapted nCIEXYZ tristimulus values of the in-gamut colors unchanged. /// AbsoluteColorimetric = 3, } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccTypeSignature.cs b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccTypeSignature.cs index 1493ecc6b..ad0db4df9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccTypeSignature.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Enums/IccTypeSignature.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// This is an optional tag which specifies the laydown order in which colorants /// will be printed on an n-colorant device. The laydown order may be the same /// as the channel generation order listed in the colorantTableTag or the channel - /// order of a colour encoding type such as CMYK, in which case this tag is not + /// order of a color encoding type such as CMYK, in which case this tag is not /// needed. When this is not the case (for example, ink-towers sometimes use /// the order KCMY), this tag may be used to specify the laydown order of the /// colorants @@ -59,25 +59,25 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc DateTime = 0x6474696D, /// - /// This structure represents a colour transform using tables with 16-bit + /// This structure represents a color transform using tables with 16-bit /// precision. This type contains four processing elements: a 3 × 3 matrix - /// (which shall be the identity matrix unless the input colour space is + /// (which shall be the identity matrix unless the input color space is /// PCSXYZ), a set of one-dimensional input tables, a multi-dimensional /// lookup table, and a set of one-dimensional output tables /// Lut16 = 0x6D667432, /// - /// This structure represents a colour transform using tables of 8-bit + /// This structure represents a color transform using tables of 8-bit /// precision. This type contains four processing elements: a 3 × 3 matrix - /// (which shall be the identity matrix unless the input colour space is + /// (which shall be the identity matrix unless the input color space is /// PCSXYZ), a set of one-dimensional input tables, a multi-dimensional /// lookup table, and a set of one-dimensional output tables. /// Lut8 = 0x6D667431, /// - /// This structure represents a colour transform. The type contains up + /// This structure represents a color transform. The type contains up /// to five processing elements which are stored in the AToBTag tag /// in the following order: a set of one-dimensional curves, a 3 × 3 /// matrix with offset terms, a set of one-dimensional curves, a @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc LutAToB = 0x6D414220, /// - /// This structure represents a colour transform. The type contains + /// This structure represents a color transform. The type contains /// up to five processing elements which are stored in the BToATag /// in the following order: a set of one-dimensional curves, a 3 × 3 /// matrix with offset terms, a set of one-dimensional curves, a @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc MultiLocalizedUnicode = 0x6D6C7563, /// - /// This structure represents a colour transform, containing a sequence + /// This structure represents a color transform, containing a sequence /// of processing elements. The processing elements contained in the /// structure are defined in the structure itself, allowing for a flexible /// structure. Currently supported processing elements are: a set of one @@ -123,15 +123,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc MultiProcessElements = 0x6D706574, /// - /// This type is a count value and array of structures that provide colour - /// coordinates for colour names. For each named colour, a PCS and optional - /// device representation of the colour are given. Both representations are + /// This type is a count value and array of structures that provide color + /// coordinates for color names. For each named color, a PCS and optional + /// device representation of the color are given. Both representations are /// 16-bit values and PCS values shall be relative colorimetric. The device - /// representation corresponds to the header’s "data colour space" field. + /// representation corresponds to the header’s "data color space" field. /// This representation should be consistent with the "number of device /// coordinates" field in the namedColor2Type. If this field is 0, device /// coordinates are not provided. The PCS representation corresponds to the - /// header's PCS field. The PCS representation is always provided. Colour + /// header's PCS field. The PCS representation is always provided. Color /// names are fixed-length, 32-byte fields including null termination. In /// order to maintain maximum portability, it is strongly recommended that /// special characters of the 7-bit ASCII set not be used. @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// so that corrections can be made for variation in the device without /// having to produce a new profile. The mechanism can be used by applications /// to allow users with relatively inexpensive and readily available - /// instrumentation to apply corrections to individual output colour + /// instrumentation to apply corrections to individual output color /// channels in order to achieve consistent results. /// ResponseCurveSet16 = 0x72637332, diff --git a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs index 2ed316409..2572b3293 100644 --- a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The hexadecimal representation of the combined color components arranged /// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax. /// - /// Returns a that represents the color defined by the provided RGBA heax string. + /// Returns a that represents the color defined by the provided RGBA hex string. public static TPixel FromHex(string hex) { Guard.NotNullOrWhiteSpace(hex, nameof(hex)); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index f4eb19be3..115dd7a43 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.PixelFormats ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); // Gray8 and Gray16 are special implementations of IPixel in that they do not conform to the - // standard RGBA colorspace format and must be converted from RGBA using the special ITU BT709 alogrithm. + // standard RGBA colorspace format and must be converted from RGBA using the special ITU BT709 algorithm. // One of the requirements of FromScaledVector4/ToScaledVector4 is that it unaware of this and // packs/unpacks the pixel without and conversion so we employ custom methods do do this. if (typeof(TDestinationPixel) == typeof(Gray16)) diff --git a/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs index 55a94fc81..12ec389b0 100644 --- a/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs +++ b/src/ImageSharp/PixelFormats/Utils/PixelConverter.cs @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // packedRgba = [aa bb gg rr] // tmp1 = [aa 00 gg 00] // tmp2 = [00 bb 00 rr] - // tmp3=ROTL(16, tmp2) = [00 rr 00 bb] + // tmp3=ROTL(16, tmp2) = [00 rr 00 bb] // tmp1 + tmp3 = [aa rr gg bb] uint tmp1 = packedRgba & 0xFF00FF00; uint tmp2 = packedRgba & 0x00FF00FF; diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index 7c57fe4fb..5609e606d 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils Span lastQuarterOfDestBuffer = MemoryMarshal.Cast(destVectors).Slice((3 * count) + 1, countWithoutLastItem); pixelOperations.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer); - // 'destVectors' and 'lastQuarterOfDestBuffer' are ovelapping buffers, + // 'destVectors' and 'lastQuarterOfDestBuffer' are overlapping buffers, // but we are always reading/writing at different positions: SimdUtils.BulkConvertByteToNormalizedFloat( MemoryMarshal.Cast(lastQuarterOfDestBuffer), From b78d08065aa139ad3db80aa5f961235667095fdb Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:07:06 +0100 Subject: [PATCH 163/238] fix typo in comment --- src/ImageSharp/Formats/Png/Filters/PaethFilter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs index 4ffc39bdb..4cd61e043 100644 --- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline); // Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp)) - int offset = bytesPerPixel + 1; // Add one bcause x starts at one. + int offset = bytesPerPixel + 1; // Add one because x starts at one. int x = 1; for (; x < offset; x++) { From e80ba75efd51c09943cf1558b29e3b623ac4ba3e Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Mon, 5 Nov 2018 16:55:48 -0600 Subject: [PATCH 164/238] ImageSharp-762_Aot-compiling: whitespace cleanup --- src/ImageSharp/Advanced/AotCompiler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Advanced/AotCompiler.cs b/src/ImageSharp/Advanced/AotCompiler.cs index 1c7f12ef7..406c162ad 100644 --- a/src/ImageSharp/Advanced/AotCompiler.cs +++ b/src/ImageSharp/Advanced/AotCompiler.cs @@ -63,9 +63,9 @@ namespace SixLabors.ImageSharp.Advanced /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT - /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on - /// iOS so it bombs out. - /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the + /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on + /// iOS so it bombs out. + /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! /// /// The pixel format. From 0337b1ac5193c95d9f4275e72594123dc9e55201 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Mon, 5 Nov 2018 19:21:16 -0800 Subject: [PATCH 165/238] Fix infinate loop when a GIF prematurely terminates in Skip --- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index b8a270b3f..bfa91416a 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -142,8 +142,7 @@ namespace SixLabors.ImageSharp.Formats.Gif this.ReadApplicationExtension(); break; case GifConstants.PlainTextLabel: - int plainLength = stream.ReadByte(); - this.Skip(plainLength); // Not supported by any known decoder. + this.SkipBlock(); // Not supported by any known decoder. break; } } @@ -190,9 +189,7 @@ namespace SixLabors.ImageSharp.Formats.Gif switch (stream.ReadByte()) { case GifConstants.GraphicControlLabel: - - // Skip graphic control extension block - this.Skip(0); + this.SkipBlock(); // Skip graphic control extension block break; case GifConstants.CommentLabel: this.ReadComments(); @@ -201,8 +198,7 @@ namespace SixLabors.ImageSharp.Formats.Gif this.ReadApplicationExtension(); break; case GifConstants.PlainTextLabel: - int plainLength = stream.ReadByte(); - this.Skip(plainLength); // Not supported by any known decoder. + this.SkipBlock(); // Not supported by any known decoder. break; } } @@ -288,24 +284,27 @@ namespace SixLabors.ImageSharp.Formats.Gif // Could be XMP or something else not supported yet. // Back up and skip. this.stream.Position -= appLength + 1; - this.Skip(appLength); + this.SkipBlock(appLength); return; } - this.Skip(appLength); // Not supported by any known decoder. + this.SkipBlock(appLength); // Not supported by any known decoder. } /// - /// Skips the designated number of bytes in the stream. + /// Skips over a block or reads its terminator. + /// The length of the block to skip. /// - /// The number of bytes to skip. - private void Skip(int length) + private void SkipBlock(int blockSize = 0) { - this.stream.Skip(length); + if (blockSize > 0) + { + this.stream.Skip(blockSize); + } int flag; - while ((flag = this.stream.ReadByte()) != 0) + while ((flag = this.stream.ReadByte()) > 0) { this.stream.Skip(flag); } @@ -370,7 +369,7 @@ namespace SixLabors.ImageSharp.Formats.Gif this.ReadFrameColors(ref image, ref previousFrame, indices.GetSpan(), colorTable, this.imageDescriptor); // Skip any remaining blocks - this.Skip(0); + this.SkipBlock(); } finally { From 71285affda077b6a68a2c0f5711ba710aaf61280 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Tue, 6 Nov 2018 09:46:14 -0600 Subject: [PATCH 166/238] ImageSharp-762_Aot-compiling: clean up AotGetPalette method --- .../Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 8f688e838..dd56375f6 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } - internal TPixel[] AotGetPalette() => this.octree.Palletize(this.colors); + internal TPixel[] AotGetPalette() => this.GetPalette(); /// protected override TPixel[] GetPalette() => this.octree.Palletize(this.colors); From 0ee2a8ac4bd95489ec00f03c6ea39916a5186bad Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 6 Nov 2018 08:40:08 -0800 Subject: [PATCH 167/238] Add test coverage for #770 --- .../ImageSharp.Sandbox46.csproj | 2 +- .../Formats/Gif/GifDecoderTests.cs | 33 +++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index bb559b70d..4d7b7de75 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -11,7 +11,7 @@ James Jackson-South and contributors James Jackson-South SixLabors.ImageSharp.Sandbox46 - 7.2 + 7.3 diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index 6d2a74c03..5bfbb058b 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -1,20 +1,20 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; +using System.Collections.Generic; +using System.IO; using System.Text; +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; -using System.IO; -using SixLabors.ImageSharp.Advanced; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Gif { - using System.Collections.Generic; - using SixLabors.ImageSharp.MetaData; - using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; - public class GifDecoderTests { private const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.RgbaVector | PixelTypes.Argb32; @@ -70,6 +70,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif } } + [Fact] + public unsafe void Decode_NonTerminatedFinalFrame() + { + var testFile = TestFile.Create(TestImages.Gif.Rings); + + int length = testFile.Bytes.Length - 2; + + fixed (byte* data = testFile.Bytes.AsSpan(0, length)) + { + using (var stream = new UnmanagedMemoryStream(data, length)) + { + var decoder = new GifDecoder(); + + using (Image image = decoder.Decode(Configuration.Default, stream)) + { + Assert.Equal((200, 200), (image.Width, image.Height)); + } + } + } + } + [Theory] [MemberData(nameof(RatioFiles))] public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) From 6c0fb45cc68b3cad15ba85dd8303b1e580551c72 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 6 Nov 2018 17:27:21 +0000 Subject: [PATCH 168/238] Better Rotate --- .../Transforms/AffineTransformProcessor.cs | 204 ++++----------- .../Transforms/AffineTransformProcessorOld.cs | 239 ++++++++++++++++++ .../CenteredAffineTransformProcessor.cs | 2 +- .../Processors/Transforms/RotateProcessor.cs | 16 +- .../Transforms/TransformKernelMap.cs | 188 ++++++++++++++ .../Processors/Transforms/TransformUtils.cs | 121 +++++++++ .../Processing/TransformExtensions.cs | 6 +- 7 files changed, 611 insertions(+), 165 deletions(-) create mode 100644 src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs create mode 100644 src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs create mode 100644 src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index e12b91eab..edddab181 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -5,13 +5,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Memory; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -20,29 +16,42 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Provides the base methods to perform affine transforms on an image. /// /// The pixel format. - internal class AffineTransformProcessor : InterpolatedTransformProcessorBase + internal class AffineTransformProcessor : TransformProcessorBase where TPixel : struct, IPixel { + private readonly Rectangle transformedRectangle; + /// /// Initializes a new instance of the class. /// /// The transform matrix /// The sampler to perform the transform operation. - /// The target dimensions to constrain the transformed image to. - public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions) - : base(sampler) + /// The source image size + public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size sourceSize) { + Guard.NotNull(sampler, nameof(sampler)); + this.Sampler = sampler; this.TransformMatrix = matrix; - this.TargetDimensions = targetDimensions; + this.transformedRectangle = TransformUtils.GetTransformedRectangle( + new Rectangle(Point.Empty, sourceSize), + matrix); + + // We want to resize the canvas here taking into account any translations. + this.TargetDimensions = new Size(this.transformedRectangle.Right, this.transformedRectangle.Bottom); } /// - /// Gets the matrix used to supply the affine transform + /// Gets the sampler to perform interpolation of the transform operation. + /// + public IResampler Sampler { get; } + + /// + /// Gets the matrix used to supply the affine transform. /// public Matrix3x2 TransformMatrix { get; } /// - /// Gets the target dimensions to constrain the transformed image to + /// Gets the target dimensions to constrain the transformed image to. /// public Size TargetDimensions { get; } @@ -68,13 +77,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int width = this.TargetDimensions.Width; Rectangle sourceBounds = source.Bounds(); - var targetBounds = new Rectangle(0, 0, width, height); - - // Since could potentially be resizing the canvas we might need to re-calculate the matrix - Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); + var targetBounds = new Rectangle(Point.Empty, this.TargetDimensions); // Convert from screen to world space. - Matrix3x2.Invert(matrix, out matrix); + Matrix3x2.Invert(this.TransformMatrix, out Matrix3x2 matrix); if (this.Sampler is NearestNeighborResampler) { @@ -82,158 +88,52 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms targetBounds, configuration, rows => + { + for (int y = rows.Min; y < rows.Max; y++) { - for (int y = rows.Min; y < rows.Max; y++) - { - Span destRow = destination.GetPixelRowSpan(y); + Span destRow = destination.GetPixelRowSpan(y); - for (int x = 0; x < width; x++) + for (int x = 0; x < width; x++) + { + var point = Point.Transform(new Point(x, y), matrix); + if (sourceBounds.Contains(point.X, point.Y)) { - var point = Point.Transform(new Point(x, y), matrix); - if (sourceBounds.Contains(point.X, point.Y)) - { - destRow[x] = source[point.X, point.Y]; - } + destRow[x] = source[point.X, point.Y]; } } - }); + } + }); return; } - int maxSourceX = source.Width - 1; - int maxSourceY = source.Height - 1; - (float radius, float scale, float ratio) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); - (float radius, float scale, float ratio) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); - float xScale = xRadiusScale.scale; - float yScale = yRadiusScale.scale; - var radius = new Vector2(xRadiusScale.radius, yRadiusScale.radius); - IResampler sampler = this.Sampler; - var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); - int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); - int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); - - MemoryAllocator memoryAllocator = configuration.MemoryAllocator; - - using (Buffer2D yBuffer = memoryAllocator.Allocate2D(yLength, height)) - using (Buffer2D xBuffer = memoryAllocator.Allocate2D(xLength, height)) + using (var kernel = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.Sampler)) { - ParallelHelper.IterateRows( + ParallelHelper.IterateRowsWithTempBuffer( targetBounds, configuration, - rows => + (rows, vectorBuffer) => + { + Span vectorSpan = vectorBuffer.Span; + for (int y = rows.Min; y < rows.Max; y++) { - for (int y = rows.Min; y < rows.Max; y++) - { - ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); - ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); - ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y)); + Span targetRowSpan = destination.GetPixelRowSpan(y); + PixelOperations.Instance.ToVector4(configuration, targetRowSpan, vectorSpan); + ref float ySpanRef = ref kernel.GetYStartReference(y); + ref float xSpanRef = ref kernel.GetXStartReference(y); - for (int x = 0; x < width; x++) - { - // Use the single precision position to calculate correct bounding pixels - // otherwise we get rogue pixels outside of the bounds. - var point = Vector2.Transform(new Vector2(x, y), matrix); - - // Clamp sampling pixel radial extents to the source image edges - Vector2 maxXY = point + radius; - Vector2 minXY = point - radius; - - // max, maxY, minX, minY - var extents = new Vector4( - MathF.Floor(maxXY.X + .5F), - MathF.Floor(maxXY.Y + .5F), - MathF.Ceiling(minXY.X - .5F), - MathF.Ceiling(minXY.Y - .5F)); - - int right = (int)extents.X; - int bottom = (int)extents.Y; - int left = (int)extents.Z; - int top = (int)extents.W; - - extents = Vector4.Clamp(extents, Vector4.Zero, maxSource); - - int maxX = (int)extents.X; - int maxY = (int)extents.Y; - int minX = (int)extents.Z; - int minY = (int)extents.W; - - if (minX == maxX || minY == maxY) - { - continue; - } - - // It appears these have to be calculated on-the-fly. - // Precalculating transformed weights would require prior knowledge of every transformed pixel location - // since they can be at sub-pixel positions on both axis. - // I've optimized where I can but am always open to suggestions. - if (yScale > 1 && xScale > 1) - { - CalculateWeightsDown( - top, - bottom, - minY, - maxY, - point.Y, - sampler, - yScale, - ref ySpanRef, - yLength); - - CalculateWeightsDown( - left, - right, - minX, - maxX, - point.X, - sampler, - xScale, - ref xSpanRef, - xLength); - } - else - { - CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ref ySpanRef); - CalculateWeightsScaleUp(minX, maxX, point.X, sampler, ref xSpanRef); - } - - // Now multiply the results against the offsets - Vector4 sum = Vector4.Zero; - for (int yy = 0, j = minY; j <= maxY; j++, yy++) - { - float yWeight = Unsafe.Add(ref ySpanRef, yy); - - for (int xx = 0, i = minX; i <= maxX; i++, xx++) - { - float xWeight = Unsafe.Add(ref xSpanRef, xx); - - // Values are first premultiplied to prevent darkening of edge pixels - var current = source[i, j].ToVector4(); - Vector4Utils.Premultiply(ref current); - sum += current * xWeight * yWeight; - } - } - - ref TPixel dest = ref Unsafe.Add(ref destRowRef, x); - - // Reverse the premultiplication - Vector4Utils.UnPremultiply(ref sum); - dest.FromVector4(sum); - } + for (int x = 0; x < width; x++) + { + // Use the single precision position to calculate correct bounding pixels + // otherwise we get rogue pixels outside of the bounds. + var point = Vector2.Transform(new Vector2(x, y), matrix); + kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); } - }); + + PixelOperations.Instance.FromVector4(configuration, vectorSpan, targetRowSpan); + } + }); } } - - /// - /// Gets a transform matrix adjusted for final processing based upon the target image bounds. - /// - /// The source image bounds. - /// The destination image bounds. - /// - /// The . - /// - protected virtual Matrix3x2 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) - => this.TransformMatrix; } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs new file mode 100644 index 000000000..5891afd9a --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs @@ -0,0 +1,239 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.ParallelUtils; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Memory; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Provides the base methods to perform affine transforms on an image. + /// + /// The pixel format. + internal class AffineTransformProcessorOld : InterpolatedTransformProcessorBase + where TPixel : struct, IPixel + { + /// + /// Initializes a new instance of the class. + /// + /// The transform matrix + /// The sampler to perform the transform operation. + /// The target dimensions to constrain the transformed image to. + public AffineTransformProcessorOld(Matrix3x2 matrix, IResampler sampler, Size targetDimensions) + : base(sampler) + { + this.TransformMatrix = matrix; + this.TargetDimensions = targetDimensions; + } + + /// + /// Gets the matrix used to supply the affine transform + /// + public Matrix3x2 TransformMatrix { get; } + + /// + /// Gets the target dimensions to constrain the transformed image to + /// + public Size TargetDimensions { get; } + + /// + protected override Image CreateDestination(Image source, Rectangle sourceRectangle) + { + // We will always be creating the clone even for mutate because we may need to resize the canvas + IEnumerable> frames = + source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions, x.MetaData.DeepClone())); + + // Use the overload to prevent an extra frame being added + return new Image(source.GetConfiguration(), source.MetaData.DeepClone(), frames); + } + + /// + protected override void OnFrameApply( + ImageFrame source, + ImageFrame destination, + Rectangle sourceRectangle, + Configuration configuration) + { + int height = this.TargetDimensions.Height; + int width = this.TargetDimensions.Width; + + Rectangle sourceBounds = source.Bounds(); + var targetBounds = new Rectangle(0, 0, width, height); + + // Since could potentially be resizing the canvas we might need to re-calculate the matrix + Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); + + // Convert from screen to world space. + Matrix3x2.Invert(matrix, out matrix); + + if (this.Sampler is NearestNeighborResampler) + { + ParallelHelper.IterateRows( + targetBounds, + configuration, + rows => + { + for (int y = rows.Min; y < rows.Max; y++) + { + Span destRow = destination.GetPixelRowSpan(y); + + for (int x = 0; x < width; x++) + { + var point = Point.Transform(new Point(x, y), matrix); + if (sourceBounds.Contains(point.X, point.Y)) + { + destRow[x] = source[point.X, point.Y]; + } + } + } + }); + + return; + } + + int maxSourceX = source.Width - 1; + int maxSourceY = source.Height - 1; + (float radius, float scale, float ratio) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); + (float radius, float scale, float ratio) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); + float xScale = xRadiusScale.scale; + float yScale = yRadiusScale.scale; + var radius = new Vector2(xRadiusScale.radius, yRadiusScale.radius); + IResampler sampler = this.Sampler; + var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); + int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); + int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); + + MemoryAllocator memoryAllocator = configuration.MemoryAllocator; + + using (Buffer2D yBuffer = memoryAllocator.Allocate2D(yLength, height)) + using (Buffer2D xBuffer = memoryAllocator.Allocate2D(xLength, height)) + { + ParallelHelper.IterateRows( + targetBounds, + configuration, + rows => + { + for (int y = rows.Min; y < rows.Max; y++) + { + ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); + ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); + ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y)); + + for (int x = 0; x < width; x++) + { + // Use the single precision position to calculate correct bounding pixels + // otherwise we get rogue pixels outside of the bounds. + var point = Vector2.Transform(new Vector2(x, y), matrix); + + // Clamp sampling pixel radial extents to the source image edges + Vector2 maxXY = point + radius; + Vector2 minXY = point - radius; + + // max, maxY, minX, minY + var extents = new Vector4( + MathF.Floor(maxXY.X + .5F), + MathF.Floor(maxXY.Y + .5F), + MathF.Ceiling(minXY.X - .5F), + MathF.Ceiling(minXY.Y - .5F)); + + int right = (int)extents.X; + int bottom = (int)extents.Y; + int left = (int)extents.Z; + int top = (int)extents.W; + + extents = Vector4.Clamp(extents, Vector4.Zero, maxSource); + + int maxX = (int)extents.X; + int maxY = (int)extents.Y; + int minX = (int)extents.Z; + int minY = (int)extents.W; + + if (minX == maxX || minY == maxY) + { + continue; + } + + // It appears these have to be calculated on-the-fly. + // Precalculating transformed weights would require prior knowledge of every transformed pixel location + // since they can be at sub-pixel positions on both axis. + // I've optimized where I can but am always open to suggestions. + if (yScale > 1 && xScale > 1) + { + CalculateWeightsDown( + top, + bottom, + minY, + maxY, + point.Y, + sampler, + yScale, + ref ySpanRef, + yLength); + + CalculateWeightsDown( + left, + right, + minX, + maxX, + point.X, + sampler, + xScale, + ref xSpanRef, + xLength); + } + else + { + CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ref ySpanRef); + CalculateWeightsScaleUp(minX, maxX, point.X, sampler, ref xSpanRef); + } + + // Now multiply the results against the offsets + Vector4 sum = Vector4.Zero; + for (int yy = 0, j = minY; j <= maxY; j++, yy++) + { + float yWeight = Unsafe.Add(ref ySpanRef, yy); + + for (int xx = 0, i = minX; i <= maxX; i++, xx++) + { + float xWeight = Unsafe.Add(ref xSpanRef, xx); + + // Values are first premultiplied to prevent darkening of edge pixels + var current = source[i, j].ToVector4(); + Vector4Utils.Premultiply(ref current); + sum += current * xWeight * yWeight; + } + } + + ref TPixel dest = ref Unsafe.Add(ref destRowRef, x); + + // Reverse the premultiplication + Vector4Utils.UnPremultiply(ref sum); + dest.FromVector4(sum); + } + } + }); + } + } + + /// + /// Gets a transform matrix adjusted for final processing based upon the target image bounds. + /// + /// The source image bounds. + /// The destination image bounds. + /// + /// The . + /// + protected virtual Matrix3x2 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) + => this.TransformMatrix; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs index adaee1766..82614dc8c 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// A base class that provides methods to allow the automatic centering of affine transforms /// /// The pixel format. - internal abstract class CenteredAffineTransformProcessor : AffineTransformProcessor + internal abstract class CenteredAffineTransformProcessor : AffineTransformProcessorOld where TPixel : struct, IPixel { /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs index 2ad626755..cbf82cc9b 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs @@ -2,12 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -16,7 +14,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Provides methods that allow the rotating of images. /// /// The pixel format. - internal class RotateProcessor : CenteredAffineTransformProcessor + internal class RotateProcessor : AffineTransformProcessor where TPixel : struct, IPixel { /// @@ -36,10 +34,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The sampler to perform the rotating operation. /// The source image size public RotateProcessor(float degrees, IResampler sampler, Size sourceSize) - : base(Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty), sampler, sourceSize) - { - this.Degrees = degrees; - } + : base( + TransformUtils.CreateCenteredRotationMatrixDegrees(degrees, sourceSize), + sampler, + sourceSize) + => this.Degrees = degrees; /// /// Gets the angle of rotation in degrees. @@ -84,7 +83,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The private static float WrapDegrees(float degrees) { - degrees = degrees % 360; + degrees %= 360; while (degrees < 0) { @@ -223,7 +222,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int newX = height - y - 1; for (int x = 0; x < width; x++) { - // TODO: Optimize this: if (destinationBounds.Contains(newX, x)) { destination[newX, x] = sourceRow[x]; diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs new file mode 100644 index 000000000..5acc7213c --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs @@ -0,0 +1,188 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; + +// TODO: It would be great if we could somehow optimize this to calculate the weights once. +// currently we cannot do that as we are calulating the weight of the transformed point dimension +// not the point in the original image. +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Contains the methods required to calculate kernel sampling weights on-the-fly. + /// + internal class TransformKernelMap : IDisposable + { + private readonly Buffer2D yBuffer; + private readonly Buffer2D xBuffer; + private readonly float yScale; + private readonly float xScale; + private readonly int yLength; + private readonly int xLength; + private readonly Vector2 extents; + private Vector4 maxSourceExtents; + private readonly IResampler sampler; + + /// + /// Initializes a new instance of the class. + /// + /// The configuration. + /// The source size. + /// The destination size. + /// The sampler. + public TransformKernelMap(Configuration configuration, Size source, Size destination, IResampler sampler) + { + this.sampler = sampler; + (float radius, float scale) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); + (float radius, float scale) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); + + this.yScale = yRadiusScale.scale; + this.xScale = xRadiusScale.scale; + this.extents = new Vector2(xRadiusScale.radius, yRadiusScale.radius); + this.xLength = (int)MathF.Ceiling((this.extents.X * 2) + 2); + this.yLength = (int)MathF.Ceiling((this.extents.Y * 2) + 2); + + // We use 2D buffers so that we can access the weight spans in parallel. + this.yBuffer = configuration.MemoryAllocator.Allocate2D(this.yLength, destination.Height); + this.xBuffer = configuration.MemoryAllocator.Allocate2D(this.xLength, destination.Height); + + int maxX = source.Width - 1; + int maxY = source.Height - 1; + this.maxSourceExtents = new Vector4(maxX, maxY, maxX, maxY); + } + + /// + /// Gets a reference to the first item of the y window. + /// + /// The reference to the first item of the window. + [MethodImpl(InliningOptions.ShortMethod)] + public ref float GetYStartReference(int y) + => ref MemoryMarshal.GetReference(this.yBuffer.GetRowSpan(y)); + + /// + /// Gets a reference to the first item of the x window. + /// + /// The reference to the first item of the window. + [MethodImpl(InliningOptions.ShortMethod)] + public ref float GetXStartReference(int y) + => ref MemoryMarshal.GetReference(this.xBuffer.GetRowSpan(y)); + + public void Convolve( + Vector2 transformedPoint, + int column, + ref float ySpanRef, + ref float xSpanRef, + Buffer2D sourcePixels, + Span targetRow) + where TPixel : struct, IPixel + { + // Clamp sampling pixel radial extents to the source image edges + Vector2 minXY = transformedPoint - this.extents; + Vector2 maxXY = transformedPoint + this.extents; + + // minX, minY, maxX, maxY + var extents = new Vector4( + MathF.Ceiling(minXY.X - .5F), + MathF.Ceiling(minXY.Y - .5F), + MathF.Floor(maxXY.X + .5F), + MathF.Floor(maxXY.Y + .5F)); + + int left = (int)extents.X; + int top = (int)extents.Y; + int right = (int)extents.Z; + int bottom = (int)extents.W; + + extents = Vector4.Clamp(extents, Vector4.Zero, this.maxSourceExtents); + + int minX = (int)extents.X; + int minY = (int)extents.Y; + int maxX = (int)extents.Z; + int maxY = (int)extents.W; + + if (minX == maxX || minY == maxY) + { + return; + } + + // TODO: Get Anton to use his superior brain on this one. + // It looks to me like we're calculating the same weights over and over again + // since min(X+Y) and max(X+Y) are the same distance apart. + this.CalculateWeights(minY, maxY, maxY - minY, transformedPoint.Y, ref ySpanRef); + this.CalculateWeights(minX, maxX, maxX - minX, transformedPoint.X, ref xSpanRef); + + Vector4 sum = Vector4.Zero; + for (int kernelY = 0, y = minY; y <= maxY; y++, kernelY++) + { + float yWeight = Unsafe.Add(ref ySpanRef, kernelY); + + for (int kernelX = 0, x = minX; x <= maxX; x++, kernelX++) + { + float xWeight = Unsafe.Add(ref xSpanRef, kernelX); + + // Values are first premultiplied to prevent darkening of edge pixels. + var current = sourcePixels[x, y].ToVector4(); + Vector4Utils.Premultiply(ref current); + sum += current * xWeight * yWeight; + } + } + + // Reverse the premultiplication + Vector4Utils.UnPremultiply(ref sum); + targetRow[column] = sum; + } + + /// + /// Calculated the normalized weights for the given point. + /// + /// The minimum sampling offset + /// The maximum sampling offset + /// The length of the weights collection + /// The transformed point dimension + /// The reference to the collection of weights + [MethodImpl(InliningOptions.ShortMethod)] + private void CalculateWeights(int min, int max, int length, float point, ref float weightsRef) + { + float sum = 0; + for (int x = 0, i = min; i <= max; i++, x++) + { + float weight = this.sampler.GetValue(i - point); + sum += weight; + Unsafe.Add(ref weightsRef, x) = this.sampler.GetValue(i - point); + } + + // TODO: Do we need this? Check what happens when we scale an image down. + // if (sum > 0) + // { + // for (int i = 0; i < length; i++) + // { + // ref float wRef = ref Unsafe.Add(ref weightsRef, i); + // wRef /= sum; + // } + // } + } + + private (float radius, float scale) GetSamplingRadius(int sourceSize, int destinationSize) + { + float scale = (float)sourceSize / destinationSize; + + if (scale < 1F) + { + scale = 1F; + } + + return (MathF.Ceiling(scale * this.sampler.Radius), scale); + } + + public void Dispose() + { + this.yBuffer?.Dispose(); + this.xBuffer?.Dispose(); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs new file mode 100644 index 000000000..7d0350249 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -0,0 +1,121 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Contains utility methods for working with transforms. + /// + public static class TransformUtils + { + /// + /// Creates a centered rotation matrix using the given rotation in degrees and the source size. + /// + /// The amount of rotation, in degrees. + /// The source image size. + /// The . + public static Matrix3x2 CreateCenteredRotationMatrixDegrees(float degrees, Size size) + => CreateCenteredTransformMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty)); + + /// + /// Gets the centered transform matrix based upon the source and destination rectangles. + /// + /// The source image bounds. + /// The transformation matrix. + /// The + public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, Matrix3x2 matrix) + { + Rectangle destinationRectangle = GetTransformedBoundingRectangle(sourceRectangle, matrix); + + // We invert the matrix to handle the transformation from screen to world space. + // This ensures scaling matrices are correct. + Matrix3x2.Invert(matrix, out Matrix3x2 inverted); + + var translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-destinationRectangle.Width, -destinationRectangle.Height) * .5F); + var translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width, sourceRectangle.Height) * .5F); + + // Translate back to world space. + Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); + + return centered; + } + + /// + /// Gets the centered transform matrix based upon the source and destination rectangles. + /// + /// The source image bounds. + /// The destination image bounds. + /// The transformation matrix. + /// The + public static Matrix3x2 GetCenteredTransformMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle, Matrix3x2 matrix) + { + // We invert the matrix to handle the transformation from screen to world space. + // This ensures scaling matrices are correct. + Matrix3x2.Invert(matrix, out Matrix3x2 inverted); + + var translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-destinationRectangle.Width, -destinationRectangle.Height) * .5F); + var translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width, sourceRectangle.Height) * .5F); + + // Translate back to world space. + Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); + + return centered; + } + + /// + /// Returns the rectangle bounds relative to the source for the given transformation matrix. + /// + /// The source rectangle. + /// The transformation matrix. + /// + /// The . + /// + public static Rectangle GetTransformedBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix) + { + Rectangle transformed = GetTransformedRectangle(rectangle, matrix); + + // TODO: Check this. + return new Rectangle(0, 0, transformed.Width, transformed.Height); + } + + /// + /// Returns the rectangle relative to the source for the given transformation matrix. + /// + /// The source rectangle. + /// The transformation matrix. + /// + /// The . + /// + public static Rectangle GetTransformedRectangle(Rectangle rectangle, Matrix3x2 matrix) + { + if (rectangle.Equals(default) || Matrix3x2.Identity.Equals(matrix)) + { + return rectangle; + } + + var tl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Top), matrix); + var tr = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Top), matrix); + var bl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Bottom), matrix); + var br = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Bottom), matrix); + + return GetBoundingRectangle(tl, tr, bl, br); + } + + private static Rectangle GetBoundingRectangle(Vector2 tl, Vector2 tr, Vector2 bl, Vector2 br) + { + // Find the minimum and maximum "corners" based on the given vectors + float left = MathF.Min(tl.X, MathF.Min(tr.X, MathF.Min(bl.X, br.X))); + float top = MathF.Min(tl.Y, MathF.Min(tr.Y, MathF.Min(bl.Y, br.Y))); + float right = MathF.Max(tl.X, MathF.Max(tr.X, MathF.Max(bl.X, br.X))); + float bottom = MathF.Max(tl.Y, MathF.Max(tr.Y, MathF.Max(bl.Y, br.Y))); + + return Rectangle.Round(RectangleF.FromLTRB(left, top, right, bottom)); + } + } +} diff --git a/src/ImageSharp/Processing/TransformExtensions.cs b/src/ImageSharp/Processing/TransformExtensions.cs index 0ec1e295d..3f24969a3 100644 --- a/src/ImageSharp/Processing/TransformExtensions.cs +++ b/src/ImageSharp/Processing/TransformExtensions.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing /// The public static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix3x2 matrix, IResampler sampler) where TPixel : struct, IPixel - => source.ApplyProcessor(new AffineTransformProcessor(matrix, sampler, source.GetCurrentSize())); + => source.ApplyProcessor(new AffineTransformProcessorOld(matrix, sampler, source.GetCurrentSize())); /// /// Transforms an image by the given matrix using the specified sampling algorithm @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing { var t = Matrix3x2.CreateTranslation(-rectangle.Location); Matrix3x2 combinedMatrix = t * matrix; - return source.ApplyProcessor(new AffineTransformProcessor(combinedMatrix, sampler, rectangle.Size)); + return source.ApplyProcessor(new AffineTransformProcessorOld(combinedMatrix, sampler, rectangle.Size)); } /// @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Processing IResampler sampler, Size destinationSize) where TPixel : struct, IPixel - => source.ApplyProcessor(new AffineTransformProcessor(matrix, sampler, destinationSize)); + => source.ApplyProcessor(new AffineTransformProcessorOld(matrix, sampler, destinationSize)); /// /// Transforms an image by the given matrix. From 5651c5cd03b34081ab13e1fb378c4a63df7c70d7 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 6 Nov 2018 21:04:30 +0100 Subject: [PATCH 169/238] simplify calculations by using intermediate results instead of calculating the same stuff multiple times --- .../Converters/CieXyzToHunterLabConverter.cs | 8 +++++--- .../Converters/HunterLabToCieXyzConverter.cs | 9 ++++++--- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 4 ++-- .../Quantization/FrameQuantizerBase{TPixel}.cs | 6 ++++-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs index c27c61608..f21235d06 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs @@ -45,9 +45,11 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation float ka = ComputeKa(this.HunterLabWhitePoint); float kb = ComputeKb(this.HunterLabWhitePoint); - float l = 100 * MathF.Sqrt(y / yn); - float a = ka * (((x / xn) - (y / yn)) / MathF.Sqrt(y / yn)); - float b = kb * (((y / yn) - (z / zn)) / MathF.Sqrt(y / yn)); + float yByYn = y / yn; + float sqrtYbyYn = MathF.Sqrt(yByYn); + float l = 100 * sqrtYbyYn; + float a = ka * (((x / xn) - yByYn) / sqrtYbyYn); + float b = kb * ((yByYn - (z / zn)) / sqrtYbyYn); if (float.IsNaN(a)) { diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs index 783d29a55..4d6808e6c 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs @@ -26,9 +26,12 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation float ka = ComputeKa(input.WhitePoint); float kb = ComputeKb(input.WhitePoint); - float y = ImageMaths.Pow2(l / 100F) * yn; - float x = (((a / ka) * MathF.Sqrt(y / yn)) + (y / yn)) * xn; - float z = (((b / kb) * MathF.Sqrt(y / yn)) - (y / yn)) * (-zn); + float pow = ImageMaths.Pow2(l / 100F); + float sqrtPow = MathF.Sqrt(pow); + float y = pow * yn; + + float x = (((a / ka) * sqrtPow) + pow) * xn; + float z = (((b / kb) * sqrtPow) - pow) * (-zn); return new CieXyz(x, y, z); } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 7ae716aa0..468f619b9 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -896,9 +896,9 @@ namespace SixLabors.ImageSharp.Formats.Png ref byte sourceRef = ref MemoryMarshal.GetReference(source); ref byte resultRef = ref MemoryMarshal.GetReference(result); - byte mask = (byte)(0xFF >> (8 - bits)); - byte shift0 = (byte)(8 - bits); int shift = 8 - bits; + byte mask = (byte)(0xFF >> shift); + byte shift0 = (byte)shift; int v = 0; int resultOffset = 0; diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index a8c6c5d7e..3b9b046a0 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -139,8 +139,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization protected byte GetTransparentIndex() { // Transparent pixels are much more likely to be found at the end of a palette. - int index = this.paletteVector.Length - 1; - for (int i = this.paletteVector.Length - 1; i >= 0; i--) + int paletteVectorLengthMinus1 = this.paletteVector.Length - 1; + + int index = paletteVectorLengthMinus1; + for (int i = paletteVectorLengthMinus1; i >= 0; i--) { ref Vector4 candidate = ref this.paletteVector[i]; if (candidate.Equals(default)) From 6576040c59699c4dd9919991687f8a638e72f8e3 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 14:01:41 +0100 Subject: [PATCH 170/238] inline division as it's only used in some cases (and done at most once) --- src/ImageSharp/Processing/ResizeHelper.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Processing/ResizeHelper.cs b/src/ImageSharp/Processing/ResizeHelper.cs index b9233937b..92af89d9e 100644 --- a/src/ImageSharp/Processing/ResizeHelper.cs +++ b/src/ImageSharp/Processing/ResizeHelper.cs @@ -337,21 +337,19 @@ namespace SixLabors.ImageSharp.Processing float percentHeight = MathF.Abs(height / (float)sourceHeight); float percentWidth = MathF.Abs(width / (float)sourceWidth); - float sourceRatio = (float)sourceHeight / sourceWidth; - // Find the shortest distance to go. int widthDiff = sourceWidth - width; int heightDiff = sourceHeight - height; if (widthDiff < heightDiff) { - destinationHeight = (int)MathF.Round(width * sourceRatio); + destinationHeight = (int)MathF.Round(width * ((float)sourceHeight / sourceWidth)); height = destinationHeight; destinationWidth = width; } else if (widthDiff > heightDiff) { - destinationWidth = (int)MathF.Round(height / sourceRatio); + destinationWidth = (int)MathF.Round(height * ((float)sourceWidth / sourceHeight)); destinationHeight = height; width = destinationWidth; } From b732fae2405075c15200dfed60b2481b8dbc0a67 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:02:50 +0100 Subject: [PATCH 171/238] inline variable --- .../Processing/Processors/Text/DrawTextProcessor.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 487c88064..266d842bf 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -139,10 +139,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text fistRow = -startY; } - int end = operation.Map.Height; - int maxHeight = source.Height - startY; - end = Math.Min(end, maxHeight); + int end = Math.Min(operation.Map.Height, maxHeight); for (int row = fistRow; row < end; row++) { From a8812d7aa50ab751c7473340f5ae02ba660228ca Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:04:42 +0100 Subject: [PATCH 172/238] unwrap for-loop to avoid conditional check inside it is known beforehand when the if condition inside the loop will not match: only in the last iteration. Thus we can loop once less and append the last element afterwards. --- src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 2be5addc2..81393342d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -543,15 +543,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components { var sb = new StringBuilder(); sb.Append('['); - for (int i = 0; i < Size; i++) + for (int i = 0; i < Size - 1; i++) { sb.Append(this[i]); - if (i < Size - 1) - { - sb.Append(','); - } + sb.Append(','); } + sb.Append(this[Size - 1]); + sb.Append(']'); return sb.ToString(); } From 6cd15cdf5544d1809f833b920637d20d4105dd0c Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:05:56 +0100 Subject: [PATCH 173/238] inline variable initialization --- src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 67f665576..f6da9cb2e 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -856,10 +856,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg private void ProcessStartOfScanMarker() { int selectorsCount = this.InputStream.ReadByte(); - int componentIndex = -1; for (int i = 0; i < selectorsCount; i++) { - componentIndex = -1; + int componentIndex = -1; int selector = this.InputStream.ReadByte(); for (int j = 0; j < this.Frame.ComponentIds.Length; j++) From 1bb7af2144f6ba315e6a83538a256b09cb890678 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:48:19 +0100 Subject: [PATCH 174/238] invert condition: always assign literal 1, substract only on special case --- src/ImageSharp/Formats/Gif/LzwEncoder.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Gif/LzwEncoder.cs b/src/ImageSharp/Formats/Gif/LzwEncoder.cs index 34c353ec9..2d32fd23a 100644 --- a/src/ImageSharp/Formats/Gif/LzwEncoder.cs +++ b/src/ImageSharp/Formats/Gif/LzwEncoder.cs @@ -309,10 +309,10 @@ namespace SixLabors.ImageSharp.Formats.Gif // Non-empty slot if (Unsafe.Add(ref hashTableRef, i) >= 0) { - int disp = hsizeReg - i; - if (i == 0) + int disp = 1; + if (i != 0) { - disp = 1; + disp = hsizeReg - i; } do From 8c14ec87de5434c58f3ca6b8a2e52aa2a9fb20cb Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:56:38 +0100 Subject: [PATCH 175/238] multiply once and reuse --- src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs index a4677ba2b..0dcbd8fef 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs @@ -822,11 +822,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { for (int i = 0; i < componentCount; i++) { - this.buffer[(3 * i) + 6] = (byte)(i + 1); + int i3 = 3 * i; + this.buffer[i3 + 6] = (byte)(i + 1); // We use 4:2:0 chroma subsampling by default. - this.buffer[(3 * i) + 7] = subsamples[i]; - this.buffer[(3 * i) + 8] = chroma[i]; + this.buffer[i3 + 7] = subsamples[i]; + this.buffer[i3 + 8] = chroma[i]; } } From 052c9818a8594d6f2f6396a47ce69badf0c6f818 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 16:02:54 +0100 Subject: [PATCH 176/238] avoid local variable copy when the original is never changed --- src/ImageSharp/Formats/Png/PngScanlineProcessor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 3fe590ee2..420775eca 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -190,12 +190,11 @@ namespace SixLabors.ImageSharp.Formats.Png else { Rgba32 rgba32 = default; - int bps = bytesPerSample; for (int x = 0; x < header.Width; x++) { int offset = x * bytesPerPixel; byte luminance = Unsafe.Add(ref scanlineSpanRef, offset); - byte alpha = Unsafe.Add(ref scanlineSpanRef, offset + bps); + byte alpha = Unsafe.Add(ref scanlineSpanRef, offset + bytesPerSample); rgba32.R = luminance; rgba32.G = luminance; From 33aea03adbfc35f7c9391f587b5122c06e76a9b8 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 16:03:49 +0100 Subject: [PATCH 177/238] return first matching ImageFormat when iterating over FormatDetectors --- src/ImageSharp/Image.FromBytes.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs index 07adc03ff..34927e6e2 100644 --- a/src/ImageSharp/Image.FromBytes.cs +++ b/src/ImageSharp/Image.FromBytes.cs @@ -198,18 +198,17 @@ namespace SixLabors.ImageSharp return null; } - IImageFormat format = default; foreach (IImageFormatDetector detector in config.ImageFormatsManager.FormatDetectors) { IImageFormat f = detector.DetectFormat(data); if (f != null) { - format = f; + return f; } } - return format; + return default; } /// From 7ff074fca6466fe86b350ea4aaaa3f032f874477 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 23:33:22 +0100 Subject: [PATCH 178/238] avoid doubled increment in for loop and multiple array indexer access --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index eb519f421..5a6cc1260 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -310,9 +310,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp } else { - for (int i = 0; i < cmd[0]; i++) + int max = cmd[0] + count; + byte cmd1 = cmd[1]; + + for (; count < max; count++) { - buffer[count++] = cmd[1]; + buffer[count] = cmd1; } } } From c2409c6fe57955fe6a3b1c4051202e45e361bce7 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 14:47:17 +0100 Subject: [PATCH 179/238] simplify BoxBlurProcessor kernel initialization old code seemed to be a relict from the GaussianBlurProcessor where this pattern made sense. Here each value of the matrix is just 1.0/size as a result, and we can leverage DenseMatrix.Fill() for that. --- .../Convolution/BoxBlurProcessor.cs | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs index 0ec62ac3d..38dc638b9 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs @@ -66,36 +66,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution ? new DenseMatrix(size, 1) : new DenseMatrix(1, size); - float sum = 0F; - for (int i = 0; i < size; i++) - { - float x = 1; - sum += x; - if (horizontal) - { - kernel[0, i] = x; - } - else - { - kernel[i, 0] = x; - } - } - - // Normalize kernel so that the sum of all weights equals 1 - if (horizontal) - { - for (int i = 0; i < size; i++) - { - kernel[0, i] = kernel[0, i] / sum; - } - } - else - { - for (int i = 0; i < size; i++) - { - kernel[i, 0] = kernel[i, 0] / sum; - } - } + kernel.Fill(1.0F / size); return kernel; } From f3d79643cf35629c5fc5e6d434bbebc564413d5d Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 7 Nov 2018 00:00:41 +0000 Subject: [PATCH 180/238] Cleanup TransformKernel and handle negative transform dimensions --- .../Transforms/AffineTransformProcessor.cs | 6 ++++++ .../Processors/Transforms/TransformKernelMap.cs | 15 ++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index edddab181..f63baa95c 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -38,6 +38,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // We want to resize the canvas here taking into account any translations. this.TargetDimensions = new Size(this.transformedRectangle.Right, this.transformedRectangle.Bottom); + + // Handle a negative translation that exceeds the original with of the image. + if (this.TargetDimensions.Width <= 0 || this.TargetDimensions.Height <= 0) + { + this.TargetDimensions = sourceSize; + } } /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs index 5acc7213c..531edbc45 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs @@ -21,8 +21,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { private readonly Buffer2D yBuffer; private readonly Buffer2D xBuffer; - private readonly float yScale; - private readonly float xScale; private readonly int yLength; private readonly int xLength; private readonly Vector2 extents; @@ -39,12 +37,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public TransformKernelMap(Configuration configuration, Size source, Size destination, IResampler sampler) { this.sampler = sampler; - (float radius, float scale) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); - (float radius, float scale) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); + float yRadius = this.GetSamplingRadius(source.Height, destination.Height); + float xRadius = this.GetSamplingRadius(source.Width, destination.Width); - this.yScale = yRadiusScale.scale; - this.xScale = xRadiusScale.scale; - this.extents = new Vector2(xRadiusScale.radius, yRadiusScale.radius); + this.extents = new Vector2(xRadius, yRadius); this.xLength = (int)MathF.Ceiling((this.extents.X * 2) + 2); this.yLength = (int)MathF.Ceiling((this.extents.Y * 2) + 2); @@ -167,7 +163,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // } } - private (float radius, float scale) GetSamplingRadius(int sourceSize, int destinationSize) + [MethodImpl(InliningOptions.ShortMethod)] + private float GetSamplingRadius(int sourceSize, int destinationSize) { float scale = (float)sourceSize / destinationSize; @@ -176,7 +173,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms scale = 1F; } - return (MathF.Ceiling(scale * this.sampler.Radius), scale); + return MathF.Ceiling(scale * this.sampler.Radius); } public void Dispose() From 5ab0d95433c16634b8eb8cbbac40c07e9e3fb26f Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 7 Nov 2018 18:47:08 +0100 Subject: [PATCH 181/238] #771: change order of addition as proposed by @dlemstra added comments as explanation --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 5a6cc1260..ef3ca24ee 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -310,8 +310,8 @@ namespace SixLabors.ImageSharp.Formats.Bmp } else { - int max = cmd[0] + count; - byte cmd1 = cmd[1]; + int max = count + cmd[0]; // as we start at the current count in the following loop, max is count + cmd[0] + byte cmd1 = cmd[1]; // store the value to avoid the repeated indexer access inside the loop for (; count < max; count++) { From 1089a323514fd8cd06a673346bc1046ca5e94b0b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 10 Nov 2018 14:20:52 +0000 Subject: [PATCH 182/238] Introduce AffineTransformBuilder --- .../Processing/AffineTransformBuilder.cs | 177 +++++++++++++ .../Transforms/AffineTransformProcessor.cs | 33 ++- .../Transforms/AffineTransformProcessorOld.cs | 239 ------------------ .../CenteredAffineTransformProcessor.cs | 38 --- .../Processors/Transforms/RotateProcessor.cs | 2 +- .../Processors/Transforms/SkewProcessor.cs | 8 +- .../Processors/Transforms/TransformHelpers.cs | 20 -- .../Transforms/TransformKernelMap.cs | 56 ++-- .../Processors/Transforms/TransformUtils.cs | 78 ++++-- .../Processing/TransformExtensions.cs | 54 +--- .../ImageSharp.Benchmarks/Samplers/Rotate.cs | 10 +- tests/ImageSharp.Benchmarks/Samplers/Skew.cs | 45 ++++ .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 22 +- .../Transforms/AffineTransformTests.cs | 54 ++-- 14 files changed, 360 insertions(+), 476 deletions(-) create mode 100644 src/ImageSharp/Processing/AffineTransformBuilder.cs delete mode 100644 src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs delete mode 100644 src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs create mode 100644 tests/ImageSharp.Benchmarks/Samplers/Skew.cs diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs new file mode 100644 index 000000000..e5ce1450f --- /dev/null +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; +using System.Numerics; +using SixLabors.ImageSharp.Processing.Processors.Transforms; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// A helper class for constructing instances for use in affine transforms. + /// + public class AffineTransformBuilder + { + private readonly List matrices = new List(); + private Rectangle rectangle; + + /// + /// Initializes a new instance of the class. + /// + /// The source image size. + public AffineTransformBuilder(Size sourceSize) => this.Size = sourceSize; + + /// + /// Initializes a new instance of the class. + /// + /// The source rectangle. + public AffineTransformBuilder(Rectangle sourceRectangle) + : this(sourceRectangle.Size) + => this.rectangle = sourceRectangle; + + /// + /// Prepends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public AffineTransformBuilder PrependRotateMatrixDegrees(float degrees) + { + this.matrices.Insert(0, TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + return this; + } + + /// + /// Gets the source image size. + /// + internal Size Size { get; } + + /// + /// Appends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public AffineTransformBuilder AppendRotateMatrixDegrees(float degrees) + { + this.matrices.Add(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + return this; + } + + /// + /// Prepends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public AffineTransformBuilder PrependScaleMatrix(SizeF scales) + { + this.matrices.Insert(0, Matrix3x2Extensions.CreateScale(scales)); + return this; + } + + /// + /// Appends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public AffineTransformBuilder AppendScaleMatrix(SizeF scales) + { + this.matrices.Add(Matrix3x2Extensions.CreateScale(scales)); + return this; + } + + /// + /// Prepends a centered skew matrix from the give angles in degrees. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The . + public AffineTransformBuilder PrependSkewMatrixDegrees(float degreesX, float degreesY) + { + this.matrices.Insert(0, TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + return this; + } + + /// + /// Appends a centered skew matrix from the give angles in degrees. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The . + public AffineTransformBuilder AppendSkewMatrixDegrees(float degreesX, float degreesY) + { + this.matrices.Add(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + return this; + } + + /// + /// Prepends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public AffineTransformBuilder PrependTranslationMatrix(PointF position) + { + this.matrices.Insert(0, Matrix3x2Extensions.CreateTranslation(position)); + return this; + } + + /// + /// Appends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public AffineTransformBuilder AppendTranslationMatrix(PointF position) + { + this.matrices.Add(Matrix3x2Extensions.CreateTranslation(position)); + return this; + } + + /// + /// Prepends a raw matrix. + /// + /// The matrix to prepend. + /// The . + public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) + { + this.matrices.Insert(0, matrix); + return this; + } + + /// + /// Appends a raw matrix. + /// + /// The matrix to append. + /// The . + public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) + { + this.matrices.Add(matrix); + return this; + } + + /// + /// Returns the combined matrix. + /// + /// The . + public Matrix3x2 BuildMatrix() + { + Matrix3x2 matrix = Matrix3x2.Identity; + + // Translate the origin matrix to cater for source rectangle offsets. + if (!this.rectangle.Equals(default)) + { + matrix *= Matrix3x2.CreateTranslation(-this.rectangle.Location); + } + + foreach (Matrix3x2 m in this.matrices) + { + matrix *= m; + } + + return matrix; + } + + /// + /// Removes all matrices from the builder. + /// + public void Clear() => this.matrices.Clear(); + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index f63baa95c..fb42b8334 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -19,8 +19,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms internal class AffineTransformProcessor : TransformProcessorBase where TPixel : struct, IPixel { - private readonly Rectangle transformedRectangle; - /// /// Initializes a new instance of the class. /// @@ -32,18 +30,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Guard.NotNull(sampler, nameof(sampler)); this.Sampler = sampler; this.TransformMatrix = matrix; - this.transformedRectangle = TransformUtils.GetTransformedRectangle( - new Rectangle(Point.Empty, sourceSize), - matrix); - - // We want to resize the canvas here taking into account any translations. - this.TargetDimensions = new Size(this.transformedRectangle.Right, this.transformedRectangle.Bottom); - - // Handle a negative translation that exceeds the original with of the image. - if (this.TargetDimensions.Width <= 0 || this.TargetDimensions.Height <= 0) - { - this.TargetDimensions = sourceSize; - } + this.TargetDimensions = TransformUtils.GetTransformedSize(sourceSize, matrix); } /// @@ -79,10 +66,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Rectangle sourceRectangle, Configuration configuration) { + // Handle tranforms that result in output identical to the original. + if (this.TransformMatrix.Equals(Matrix3x2.Identity)) + { + // The cloned will be blank here copy all the pixel data over + source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); + return; + } + int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; - Rectangle sourceBounds = source.Bounds(); var targetBounds = new Rectangle(Point.Empty, this.TargetDimensions); // Convert from screen to world space. @@ -102,7 +96,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int x = 0; x < width; x++) { var point = Point.Transform(new Point(x, y), matrix); - if (sourceBounds.Contains(point.X, point.Y)) + if (sourceRectangle.Contains(point.X, point.Y)) { destRow[x] = source[point.X, point.Y]; } @@ -113,7 +107,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return; } - using (var kernel = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.Sampler)) + var kernel = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.Sampler); + try { ParallelHelper.IterateRowsWithTempBuffer( targetBounds, @@ -140,6 +135,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } }); } + finally + { + kernel.Dispose(); + } } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs deleted file mode 100644 index 5891afd9a..000000000 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessorOld.cs +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.ParallelUtils; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Memory; -using SixLabors.Primitives; - -namespace SixLabors.ImageSharp.Processing.Processors.Transforms -{ - /// - /// Provides the base methods to perform affine transforms on an image. - /// - /// The pixel format. - internal class AffineTransformProcessorOld : InterpolatedTransformProcessorBase - where TPixel : struct, IPixel - { - /// - /// Initializes a new instance of the class. - /// - /// The transform matrix - /// The sampler to perform the transform operation. - /// The target dimensions to constrain the transformed image to. - public AffineTransformProcessorOld(Matrix3x2 matrix, IResampler sampler, Size targetDimensions) - : base(sampler) - { - this.TransformMatrix = matrix; - this.TargetDimensions = targetDimensions; - } - - /// - /// Gets the matrix used to supply the affine transform - /// - public Matrix3x2 TransformMatrix { get; } - - /// - /// Gets the target dimensions to constrain the transformed image to - /// - public Size TargetDimensions { get; } - - /// - protected override Image CreateDestination(Image source, Rectangle sourceRectangle) - { - // We will always be creating the clone even for mutate because we may need to resize the canvas - IEnumerable> frames = - source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions, x.MetaData.DeepClone())); - - // Use the overload to prevent an extra frame being added - return new Image(source.GetConfiguration(), source.MetaData.DeepClone(), frames); - } - - /// - protected override void OnFrameApply( - ImageFrame source, - ImageFrame destination, - Rectangle sourceRectangle, - Configuration configuration) - { - int height = this.TargetDimensions.Height; - int width = this.TargetDimensions.Width; - - Rectangle sourceBounds = source.Bounds(); - var targetBounds = new Rectangle(0, 0, width, height); - - // Since could potentially be resizing the canvas we might need to re-calculate the matrix - Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); - - // Convert from screen to world space. - Matrix3x2.Invert(matrix, out matrix); - - if (this.Sampler is NearestNeighborResampler) - { - ParallelHelper.IterateRows( - targetBounds, - configuration, - rows => - { - for (int y = rows.Min; y < rows.Max; y++) - { - Span destRow = destination.GetPixelRowSpan(y); - - for (int x = 0; x < width; x++) - { - var point = Point.Transform(new Point(x, y), matrix); - if (sourceBounds.Contains(point.X, point.Y)) - { - destRow[x] = source[point.X, point.Y]; - } - } - } - }); - - return; - } - - int maxSourceX = source.Width - 1; - int maxSourceY = source.Height - 1; - (float radius, float scale, float ratio) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); - (float radius, float scale, float ratio) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); - float xScale = xRadiusScale.scale; - float yScale = yRadiusScale.scale; - var radius = new Vector2(xRadiusScale.radius, yRadiusScale.radius); - IResampler sampler = this.Sampler; - var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); - int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); - int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); - - MemoryAllocator memoryAllocator = configuration.MemoryAllocator; - - using (Buffer2D yBuffer = memoryAllocator.Allocate2D(yLength, height)) - using (Buffer2D xBuffer = memoryAllocator.Allocate2D(xLength, height)) - { - ParallelHelper.IterateRows( - targetBounds, - configuration, - rows => - { - for (int y = rows.Min; y < rows.Max; y++) - { - ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); - ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); - ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y)); - - for (int x = 0; x < width; x++) - { - // Use the single precision position to calculate correct bounding pixels - // otherwise we get rogue pixels outside of the bounds. - var point = Vector2.Transform(new Vector2(x, y), matrix); - - // Clamp sampling pixel radial extents to the source image edges - Vector2 maxXY = point + radius; - Vector2 minXY = point - radius; - - // max, maxY, minX, minY - var extents = new Vector4( - MathF.Floor(maxXY.X + .5F), - MathF.Floor(maxXY.Y + .5F), - MathF.Ceiling(minXY.X - .5F), - MathF.Ceiling(minXY.Y - .5F)); - - int right = (int)extents.X; - int bottom = (int)extents.Y; - int left = (int)extents.Z; - int top = (int)extents.W; - - extents = Vector4.Clamp(extents, Vector4.Zero, maxSource); - - int maxX = (int)extents.X; - int maxY = (int)extents.Y; - int minX = (int)extents.Z; - int minY = (int)extents.W; - - if (minX == maxX || minY == maxY) - { - continue; - } - - // It appears these have to be calculated on-the-fly. - // Precalculating transformed weights would require prior knowledge of every transformed pixel location - // since they can be at sub-pixel positions on both axis. - // I've optimized where I can but am always open to suggestions. - if (yScale > 1 && xScale > 1) - { - CalculateWeightsDown( - top, - bottom, - minY, - maxY, - point.Y, - sampler, - yScale, - ref ySpanRef, - yLength); - - CalculateWeightsDown( - left, - right, - minX, - maxX, - point.X, - sampler, - xScale, - ref xSpanRef, - xLength); - } - else - { - CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ref ySpanRef); - CalculateWeightsScaleUp(minX, maxX, point.X, sampler, ref xSpanRef); - } - - // Now multiply the results against the offsets - Vector4 sum = Vector4.Zero; - for (int yy = 0, j = minY; j <= maxY; j++, yy++) - { - float yWeight = Unsafe.Add(ref ySpanRef, yy); - - for (int xx = 0, i = minX; i <= maxX; i++, xx++) - { - float xWeight = Unsafe.Add(ref xSpanRef, xx); - - // Values are first premultiplied to prevent darkening of edge pixels - var current = source[i, j].ToVector4(); - Vector4Utils.Premultiply(ref current); - sum += current * xWeight * yWeight; - } - } - - ref TPixel dest = ref Unsafe.Add(ref destRowRef, x); - - // Reverse the premultiplication - Vector4Utils.UnPremultiply(ref sum); - dest.FromVector4(sum); - } - } - }); - } - } - - /// - /// Gets a transform matrix adjusted for final processing based upon the target image bounds. - /// - /// The source image bounds. - /// The destination image bounds. - /// - /// The . - /// - protected virtual Matrix3x2 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) - => this.TransformMatrix; - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs deleted file mode 100644 index 82614dc8c..000000000 --- a/src/ImageSharp/Processing/Processors/Transforms/CenteredAffineTransformProcessor.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Primitives; - -namespace SixLabors.ImageSharp.Processing.Processors.Transforms -{ - /// - /// A base class that provides methods to allow the automatic centering of affine transforms - /// - /// The pixel format. - internal abstract class CenteredAffineTransformProcessor : AffineTransformProcessorOld - where TPixel : struct, IPixel - { - /// - /// Initializes a new instance of the class. - /// - /// The transform matrix - /// The sampler to perform the transform operation. - /// The source image size - protected CenteredAffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size sourceSize) - : base(matrix, sampler, GetTransformedDimensions(sourceSize, matrix)) - { - } - - /// - protected override Matrix3x2 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) - => TransformHelpers.GetCenteredTransformMatrix(sourceRectangle, destinationRectangle, this.TransformMatrix); - - private static Size GetTransformedDimensions(Size sourceDimensions, Matrix3x2 matrix) - { - var sourceRectangle = new Rectangle(0, 0, sourceDimensions.Width, sourceDimensions.Height); - return TransformHelpers.GetTransformedBoundingRectangle(sourceRectangle, matrix).Size; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs index cbf82cc9b..57cca4bf9 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The source image size public RotateProcessor(float degrees, IResampler sampler, Size sourceSize) : base( - TransformUtils.CreateCenteredRotationMatrixDegrees(degrees, sourceSize), + TransformUtils.CreateRotationMatrixDegrees(degrees, sourceSize), sampler, sourceSize) => this.Degrees = degrees; diff --git a/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs index a0cfa6379..4a006a9df 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -11,7 +10,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Provides methods that allow the skewing of images. /// /// The pixel format. - internal class SkewProcessor : CenteredAffineTransformProcessor + internal class SkewProcessor : AffineTransformProcessor where TPixel : struct, IPixel { /// @@ -33,7 +32,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The sampler to perform the skew operation. /// The source image size public SkewProcessor(float degreesX, float degreesY, IResampler sampler, Size sourceSize) - : base(Matrix3x2Extensions.CreateSkewDegrees(degreesX, degreesY, PointF.Empty), sampler, sourceSize) + : base( + TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, sourceSize), + sampler, + sourceSize) { this.DegreesX = degreesX; this.DegreesY = degreesY; diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs index b22fa64cf..2e85f6c2c 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs @@ -102,26 +102,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return centered; } - /// - /// Returns the bounding rectangle relative to the source for the given transformation matrix. - /// - /// The source rectangle. - /// The transformation matrix. - /// - /// The . - /// - public static Rectangle GetTransformedBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix) - { - // Calculate the position of the four corners in world space by applying - // The world matrix to the four corners in object space (0, 0, width, height) - var tl = Vector2.Transform(Vector2.Zero, matrix); - var tr = Vector2.Transform(new Vector2(rectangle.Width, 0), matrix); - var bl = Vector2.Transform(new Vector2(0, rectangle.Height), matrix); - var br = Vector2.Transform(new Vector2(rectangle.Width, rectangle.Height), matrix); - - return GetBoundingRectangle(tl, tr, bl, br); - } - /// /// Returns the bounding rectangle relative to the source for the given transformation matrix. /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs index 531edbc45..573120888 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformKernelMap.cs @@ -9,20 +9,15 @@ using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; -// TODO: It would be great if we could somehow optimize this to calculate the weights once. -// currently we cannot do that as we are calulating the weight of the transformed point dimension -// not the point in the original image. namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// - /// Contains the methods required to calculate kernel sampling weights on-the-fly. + /// Contains the methods required to calculate transform kernel convolution. /// internal class TransformKernelMap : IDisposable { private readonly Buffer2D yBuffer; private readonly Buffer2D xBuffer; - private readonly int yLength; - private readonly int xLength; private readonly Vector2 extents; private Vector4 maxSourceExtents; private readonly IResampler sampler; @@ -41,12 +36,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float xRadius = this.GetSamplingRadius(source.Width, destination.Width); this.extents = new Vector2(xRadius, yRadius); - this.xLength = (int)MathF.Ceiling((this.extents.X * 2) + 2); - this.yLength = (int)MathF.Ceiling((this.extents.Y * 2) + 2); + int xLength = (int)MathF.Ceiling((this.extents.X * 2) + 2); + int yLength = (int)MathF.Ceiling((this.extents.Y * 2) + 2); - // We use 2D buffers so that we can access the weight spans in parallel. - this.yBuffer = configuration.MemoryAllocator.Allocate2D(this.yLength, destination.Height); - this.xBuffer = configuration.MemoryAllocator.Allocate2D(this.xLength, destination.Height); + // We use 2D buffers so that we can access the weight spans per row in parallel. + this.yBuffer = configuration.MemoryAllocator.Allocate2D(yLength, destination.Height); + this.xBuffer = configuration.MemoryAllocator.Allocate2D(xLength, destination.Height); int maxX = source.Width - 1; int maxY = source.Height - 1; @@ -82,42 +77,34 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Vector2 minXY = transformedPoint - this.extents; Vector2 maxXY = transformedPoint + this.extents; - // minX, minY, maxX, maxY + // left, top, right, bottom var extents = new Vector4( MathF.Ceiling(minXY.X - .5F), MathF.Ceiling(minXY.Y - .5F), MathF.Floor(maxXY.X + .5F), MathF.Floor(maxXY.Y + .5F)); + extents = Vector4.Clamp(extents, Vector4.Zero, this.maxSourceExtents); + int left = (int)extents.X; int top = (int)extents.Y; int right = (int)extents.Z; int bottom = (int)extents.W; - extents = Vector4.Clamp(extents, Vector4.Zero, this.maxSourceExtents); - - int minX = (int)extents.X; - int minY = (int)extents.Y; - int maxX = (int)extents.Z; - int maxY = (int)extents.W; - - if (minX == maxX || minY == maxY) + if (left == right || top == bottom) { return; } - // TODO: Get Anton to use his superior brain on this one. - // It looks to me like we're calculating the same weights over and over again - // since min(X+Y) and max(X+Y) are the same distance apart. - this.CalculateWeights(minY, maxY, maxY - minY, transformedPoint.Y, ref ySpanRef); - this.CalculateWeights(minX, maxX, maxX - minX, transformedPoint.X, ref xSpanRef); + this.CalculateWeights(top, bottom, transformedPoint.Y, ref ySpanRef); + this.CalculateWeights(left, right, transformedPoint.X, ref xSpanRef); Vector4 sum = Vector4.Zero; - for (int kernelY = 0, y = minY; y <= maxY; y++, kernelY++) + for (int kernelY = 0, y = top; y <= bottom; y++, kernelY++) { float yWeight = Unsafe.Add(ref ySpanRef, kernelY); - for (int kernelX = 0, x = minX; x <= maxX; x++, kernelX++) + for (int kernelX = 0, x = left; x <= right; x++, kernelX++) { float xWeight = Unsafe.Add(ref xSpanRef, kernelX); @@ -138,29 +125,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The minimum sampling offset /// The maximum sampling offset - /// The length of the weights collection /// The transformed point dimension /// The reference to the collection of weights [MethodImpl(InliningOptions.ShortMethod)] - private void CalculateWeights(int min, int max, int length, float point, ref float weightsRef) + private void CalculateWeights(int min, int max, float point, ref float weightsRef) { float sum = 0; for (int x = 0, i = min; i <= max; i++, x++) { float weight = this.sampler.GetValue(i - point); sum += weight; - Unsafe.Add(ref weightsRef, x) = this.sampler.GetValue(i - point); + Unsafe.Add(ref weightsRef, x) = weight; } - - // TODO: Do we need this? Check what happens when we scale an image down. - // if (sum > 0) - // { - // for (int i = 0; i < length; i++) - // { - // ref float wRef = ref Unsafe.Add(ref weightsRef, i); - // wRef /= sum; - // } - // } } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index 7d0350249..10cf49c34 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Contains utility methods for working with transforms. /// - public static class TransformUtils + internal static class TransformUtils { /// /// Creates a centered rotation matrix using the given rotation in degrees and the source size. @@ -18,43 +18,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The amount of rotation, in degrees. /// The source image size. /// The . - public static Matrix3x2 CreateCenteredRotationMatrixDegrees(float degrees, Size size) + public static Matrix3x2 CreateRotationMatrixDegrees(float degrees, Size size) => CreateCenteredTransformMatrix( new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty)); /// - /// Gets the centered transform matrix based upon the source and destination rectangles. + /// Creates a centered skew matrix from the give angles in degrees and the source size. /// - /// The source image bounds. - /// The transformation matrix. - /// The - public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, Matrix3x2 matrix) - { - Rectangle destinationRectangle = GetTransformedBoundingRectangle(sourceRectangle, matrix); - - // We invert the matrix to handle the transformation from screen to world space. - // This ensures scaling matrices are correct. - Matrix3x2.Invert(matrix, out Matrix3x2 inverted); - - var translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-destinationRectangle.Width, -destinationRectangle.Height) * .5F); - var translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width, sourceRectangle.Height) * .5F); - - // Translate back to world space. - Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); - - return centered; - } + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The source image size. + /// The . + public static Matrix3x2 CreateSkewMatrixDegrees(float degreesX, float degreesY, Size size) + => CreateCenteredTransformMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateSkewDegrees(degreesX, degreesY, PointF.Empty)); /// /// Gets the centered transform matrix based upon the source and destination rectangles. /// /// The source image bounds. - /// The destination image bounds. /// The transformation matrix. /// The - public static Matrix3x2 GetCenteredTransformMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle, Matrix3x2 matrix) + public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, Matrix3x2 matrix) { + Rectangle destinationRectangle = GetTransformedBoundingRectangle(sourceRectangle, matrix); + // We invert the matrix to handle the transformation from screen to world space. // This ensures scaling matrices are correct. Matrix3x2.Invert(matrix, out Matrix3x2 inverted); @@ -79,8 +69,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public static Rectangle GetTransformedBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix) { Rectangle transformed = GetTransformedRectangle(rectangle, matrix); - - // TODO: Check this. return new Rectangle(0, 0, transformed.Width, transformed.Height); } @@ -107,6 +95,44 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return GetBoundingRectangle(tl, tr, bl, br); } + /// + /// Returns the size relative to the source for the given transformation matrix. + /// + /// The source size. + /// The transformation matrix. + /// + /// The . + /// + public static Size GetTransformedSize(Size size, Matrix3x2 matrix) + { + Guard.IsTrue(size.Width > 0 && size.Height > 0, nameof(size), "Source size dimensions cannot be 0!"); + + if (matrix.Equals(default) || matrix.Equals(Matrix3x2.Identity)) + { + return size; + } + + Rectangle rectangle = GetTransformedRectangle(new Rectangle(Point.Empty, size), matrix); + + // We want to resize the canvas here taking into account any translations. + int height = rectangle.Top < 0 ? rectangle.Bottom : Math.Max(rectangle.Height, rectangle.Bottom); + int width = rectangle.Left < 0 ? rectangle.Right : Math.Max(rectangle.Width, rectangle.Right); + + // If location in either direction is translated to a negative value equal to or exceeding the + // dimensions in eith direction we need to reassign the dimension. + if (height <= 0) + { + height = rectangle.Height; + } + + if (width <= 0) + { + width = rectangle.Width; + } + + return new Size(width, height); + } + private static Rectangle GetBoundingRectangle(Vector2 tl, Vector2 tr, Vector2 bl, Vector2 br) { // Find the minimum and maximum "corners" based on the given vectors diff --git a/src/ImageSharp/Processing/TransformExtensions.cs b/src/ImageSharp/Processing/TransformExtensions.cs index 3f24969a3..4cbd1b041 100644 --- a/src/ImageSharp/Processing/TransformExtensions.cs +++ b/src/ImageSharp/Processing/TransformExtensions.cs @@ -18,65 +18,23 @@ namespace SixLabors.ImageSharp.Processing /// /// The pixel format. /// The image to transform. - /// The transformation matrix. + /// The affine transform builder. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix3x2 matrix) + public static IImageProcessingContext Transform(this IImageProcessingContext source, AffineTransformBuilder builder) where TPixel : struct, IPixel - => Transform(source, matrix, KnownResamplers.Bicubic); + => Transform(source, builder, KnownResamplers.Bicubic); /// /// Transforms an image by the given matrix using the specified sampling algorithm. /// /// The pixel format. /// The image to transform. - /// The transformation matrix. - /// The to perform the resampling. - /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix3x2 matrix, IResampler sampler) - where TPixel : struct, IPixel - => source.ApplyProcessor(new AffineTransformProcessorOld(matrix, sampler, source.GetCurrentSize())); - - /// - /// Transforms an image by the given matrix using the specified sampling algorithm - /// and a rectangle defining the transform origin in the source image and the size of the result image. - /// - /// The pixel format. - /// The image to transform. - /// The transformation matrix. - /// The to perform the resampling. - /// - /// The rectangle defining the transform origin in the source image, and the size of the result image. - /// - /// The - public static IImageProcessingContext Transform( - this IImageProcessingContext source, - Matrix3x2 matrix, - IResampler sampler, - Rectangle rectangle) - where TPixel : struct, IPixel - { - var t = Matrix3x2.CreateTranslation(-rectangle.Location); - Matrix3x2 combinedMatrix = t * matrix; - return source.ApplyProcessor(new AffineTransformProcessorOld(combinedMatrix, sampler, rectangle.Size)); - } - - /// - /// Transforms an image by the given matrix using the specified sampling algorithm, - /// cropping or extending the image according to . - /// - /// The pixel format. - /// The image to transform. - /// The transformation matrix. + /// The affine transform builder. /// The to perform the resampling. - /// The size of the destination image. /// The - public static IImageProcessingContext Transform( - this IImageProcessingContext source, - Matrix3x2 matrix, - IResampler sampler, - Size destinationSize) + public static IImageProcessingContext Transform(this IImageProcessingContext source, AffineTransformBuilder builder, IResampler sampler) where TPixel : struct, IPixel - => source.ApplyProcessor(new AffineTransformProcessorOld(matrix, sampler, destinationSize)); + => source.ApplyProcessor(new AffineTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); /// /// Transforms an image by the given matrix. diff --git a/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs b/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs index c1456f9d7..f898576af 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Rotate.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Samplers } } -// Nov 4 2018 +// Nov 7 2018 //BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17763 //Intel Core i7-6600U CPU 2.60GHz(Skylake), 1 CPU, 4 logical and 2 physical cores //.NET Core SDK = 2.1.403 @@ -36,4 +36,10 @@ namespace SixLabors.ImageSharp.Benchmarks.Samplers // Method | Runtime | Mean | Error | StdDev | Allocated | //--------- |-------- |---------:|----------:|----------:|----------:| // DoRotate | Clr | 85.19 ms | 13.379 ms | 0.7560 ms | 6 KB | -// DoRotate | Core | 53.51 ms | 9.512 ms | 0.5375 ms | 4.29 KB | \ No newline at end of file +// DoRotate | Core | 53.51 ms | 9.512 ms | 0.5375 ms | 4.29 KB | + +// #### AFTER ####: +//Method | Runtime | Mean | Error | StdDev | Allocated | +//--------- |-------- |---------:|---------:|---------:|----------:| +// DoRotate | Clr | 77.08 ms | 23.97 ms | 1.354 ms | 6 KB | +// DoRotate | Core | 40.36 ms | 47.43 ms | 2.680 ms | 4.36 KB | \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Samplers/Skew.cs b/tests/ImageSharp.Benchmarks/Samplers/Skew.cs new file mode 100644 index 000000000..84819750a --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Samplers/Skew.cs @@ -0,0 +1,45 @@ +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Benchmarks.Samplers +{ + [Config(typeof(Config.ShortClr))] + public class Skew + { + [Benchmark] + public Size DoSkew() + { + using (var image = new Image(Configuration.Default, 400, 400, Rgba32.BlanchedAlmond)) + { + image.Mutate(x => x.Skew(20, 10)); + + return image.Size(); + } + } + } +} + +// Nov 7 2018 +//BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17763 +//Intel Core i7-6600U CPU 2.60GHz(Skylake), 1 CPU, 4 logical and 2 physical cores +//.NET Core SDK = 2.1.403 + +// [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT +// Job-KKDIMW : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 +// Job-IUZRFA : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + +//LaunchCount=1 TargetCount=3 WarmupCount=3 + +// #### BEFORE ####: +//Method | Runtime | Mean | Error | StdDev | Allocated | +//------- |-------- |---------:|---------:|----------:|----------:| +// DoSkew | Clr | 78.14 ms | 8.383 ms | 0.4736 ms | 6 KB | +// DoSkew | Core | 44.22 ms | 4.109 ms | 0.2322 ms | 4.28 KB | + +// #### AFTER ####: +//Method | Runtime | Mean | Error | StdDev | Allocated | +//------- |-------- |---------:|----------:|----------:|----------:| +// DoSkew | Clr | 71.63 ms | 25.589 ms | 1.4458 ms | 6 KB | +// DoSkew | Core | 38.99 ms | 8.640 ms | 0.4882 ms | 4.36 KB | \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 496692d96..564318e5e 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -2,10 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Numerics; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; -using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.Primitives; using Xunit; @@ -75,21 +73,15 @@ namespace SixLabors.ImageSharp.Tests using (Image image = provider.GetImage()) using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { - Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(45F); - Matrix3x2 scale = Matrix3x2Extensions.CreateScale(new SizeF(.25F, .25F)); - Matrix3x2 matrix = rotate * scale; + AffineTransformBuilder builder = new AffineTransformBuilder(blend.Size()) + .AppendRotateMatrixDegrees(45F) + .AppendScaleMatrix(new SizeF(.25F, .25F)) + .AppendTranslationMatrix(new PointF(10, 10)); - // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor - Rectangle srcBounds = blend.Bounds(); - Rectangle destBounds = TransformHelpers.GetTransformedBoundingRectangle(srcBounds, matrix); - Matrix3x2 centeredMatrix = TransformHelpers.GetCenteredTransformMatrix(srcBounds, destBounds, matrix); - - // We pass a new rectangle here based on the dest bounds since we've offset the matrix - blend.Mutate(x => x.Transform( - centeredMatrix, - KnownResamplers.Bicubic, - new Rectangle(0, 0, destBounds.Width, destBounds.Height))); + // Apply a background color so we can see the translation. + blend.Mutate(x => x.Transform(builder).BackgroundColor(NamedColors.HotPink)); + // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); image.Mutate(x => x.DrawImage(blend, position, mode, .75F)); image.DebugSave(provider, new[] { "Transformed" }); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index ae572498a..32280d48c 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -78,15 +78,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler resampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - var rotate = Matrix3x2.CreateRotation((float)Math.PI / 4F, new Vector2(5 / 2F, 5 / 2F)); - var translate = Matrix3x2.CreateTranslation((7 - 5) / 2F, (7 - 5) / 2F); + AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + .AppendRotateMatrixDegrees((float)Math.PI / 4F); - Rectangle sourceRectangle = image.Bounds(); - Matrix3x2 matrix = rotate * translate; - - Rectangle destRectangle = TransformHelpers.GetTransformedBoundingRectangle(sourceRectangle, matrix); - - image.Mutate(c => c.Transform(matrix, resampler, destRectangle)); + image.Mutate(c => c.Transform(builder, resampler)); image.DebugSave(provider, resamplerName); VerifyAllPixelsAreWhiteOrTransparent(image); @@ -104,14 +99,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(angleDeg); - var translate = Matrix3x2.CreateTranslation(tx, ty); - var scale = Matrix3x2.CreateScale(sx, sy); - Matrix3x2 m = rotate * scale * translate; + image.DebugSave(provider, $"_original"); + AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + .AppendRotateMatrixDegrees(angleDeg) + .AppendScaleMatrix(new SizeF(sx, sy)) + .AppendTranslationMatrix(new PointF(tx, ty)); - this.PrintMatrix(m); + this.PrintMatrix(builder.BuildMatrix()); - image.Mutate(i => i.Transform(m, KnownResamplers.Bicubic)); + image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); FormattableString testOutputDetails = $"R({angleDeg})_S({sx},{sy})_T({tx},{ty})"; image.DebugSave(provider, testOutputDetails); @@ -126,9 +122,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - Matrix3x2 m = this.MakeManuallyCenteredMatrix(angleDeg, s, image); + AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + .AppendRotateMatrixDegrees(angleDeg) + .AppendScaleMatrix(new SizeF(s, s)); - image.Mutate(i => i.Transform(m, KnownResamplers.Bicubic)); + image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); FormattableString testOutputDetails = $"R({angleDeg})_S({s})"; image.DebugSave(provider, testOutputDetails); @@ -155,13 +153,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void Transform_FromSourceRectangle1(TestImageProvider provider) where TPixel : struct, IPixel { - var rectangle = new Rectangle(48, 0, 96, 36); + var rectangle = new Rectangle(48, 0, 48, 24); using (Image image = provider.GetImage()) { - var m = Matrix3x2.CreateScale(2.0F, 1.5F); + image.DebugSave(provider, $"_original"); + AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) + .AppendScaleMatrix(new SizeF(2, 1.5F)); - image.Mutate(i => i.Transform(m, KnownResamplers.Spline, rectangle)); + image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); image.DebugSave(provider); image.CompareToReferenceOutput(ValidatorComparer, provider); @@ -173,13 +173,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void Transform_FromSourceRectangle2(TestImageProvider provider) where TPixel : struct, IPixel { - var rectangle = new Rectangle(0, 24, 48, 48); + var rectangle = new Rectangle(0, 24, 48, 24); using (Image image = provider.GetImage()) { - var m = Matrix3x2.CreateScale(1.0F, 2.0F); + AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) + .AppendScaleMatrix(new SizeF(1F, 2F)); - image.Mutate(i => i.Transform(m, KnownResamplers.Spline, rectangle)); + image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); image.DebugSave(provider); image.CompareToReferenceOutput(ValidatorComparer, provider); @@ -194,12 +195,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler sampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - Matrix3x2 m = this.MakeManuallyCenteredMatrix(50, 0.6f, image); + AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + .AppendRotateMatrixDegrees(50) + .AppendScaleMatrix(new SizeF(.6F, .6F)); - image.Mutate(i => - { - i.Transform(m, sampler); - }); + image.Mutate(i => i.Transform(builder, sampler)); image.DebugSave(provider, resamplerName); image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName); From 434a5ee4317824696a909182afd21e91e5d53444 Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 14:38:33 +0100 Subject: [PATCH 183/238] fix typo in KirschKernels class name --- .../{KirshKernels.cs => KirschKernels.cs} | 4 ++-- .../Processors/Convolution/KirschProcessor.cs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) rename src/ImageSharp/Processing/Processors/Convolution/{KirshKernels.cs => KirschKernels.cs} (96%) diff --git a/src/ImageSharp/Processing/Processors/Convolution/KirshKernels.cs b/src/ImageSharp/Processing/Processors/Convolution/KirschKernels.cs similarity index 96% rename from src/ImageSharp/Processing/Processors/Convolution/KirshKernels.cs rename to src/ImageSharp/Processing/Processors/Convolution/KirschKernels.cs index d31587508..86232e306 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/KirshKernels.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/KirschKernels.cs @@ -6,9 +6,9 @@ using SixLabors.ImageSharp.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Convolution { /// - /// Contains the eight matrices used for Kirsh edge detection + /// Contains the eight matrices used for Kirsch edge detection /// - internal static class KirshKernels + internal static class KirschKernels { /// /// Gets the North gradient operator diff --git a/src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs index 46cf00c22..c3188676f 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs @@ -23,27 +23,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution } /// - public override DenseMatrix North => KirshKernels.KirschNorth; + public override DenseMatrix North => KirschKernels.KirschNorth; /// - public override DenseMatrix NorthWest => KirshKernels.KirschNorthWest; + public override DenseMatrix NorthWest => KirschKernels.KirschNorthWest; /// - public override DenseMatrix West => KirshKernels.KirschWest; + public override DenseMatrix West => KirschKernels.KirschWest; /// - public override DenseMatrix SouthWest => KirshKernels.KirschSouthWest; + public override DenseMatrix SouthWest => KirschKernels.KirschSouthWest; /// - public override DenseMatrix South => KirshKernels.KirschSouth; + public override DenseMatrix South => KirschKernels.KirschSouth; /// - public override DenseMatrix SouthEast => KirshKernels.KirschSouthEast; + public override DenseMatrix SouthEast => KirschKernels.KirschSouthEast; /// - public override DenseMatrix East => KirshKernels.KirschEast; + public override DenseMatrix East => KirschKernels.KirschEast; /// - public override DenseMatrix NorthEast => KirshKernels.KirschNorthEast; + public override DenseMatrix NorthEast => KirschKernels.KirschNorthEast; } } \ No newline at end of file From cf71cf5c534f2a53b0011da8f4412328c90d4cdf Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 4 Nov 2018 15:13:24 +0100 Subject: [PATCH 184/238] fix typo in local variable name --- .../Profiles/ICC/DataReader/IccDataReader.Curves.cs | 8 ++++---- .../ICC/DataReader/IccDataReader.TagDataEntry.cs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs index ee91ad7a1..b27083dc4 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs @@ -41,10 +41,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc public IccResponseCurve ReadResponseCurve(int channelCount) { var type = (IccCurveMeasurementEncodings)this.ReadUInt32(); - uint[] measurment = new uint[channelCount]; + uint[] measurement = new uint[channelCount]; for (int i = 0; i < channelCount; i++) { - measurment[i] = this.ReadUInt32(); + measurement[i] = this.ReadUInt32(); } Vector3[] xyzValues = new Vector3[channelCount]; @@ -56,8 +56,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc IccResponseNumber[][] response = new IccResponseNumber[channelCount][]; for (int i = 0; i < channelCount; i++) { - response[i] = new IccResponseNumber[measurment[i]]; - for (uint j = 0; j < measurment[i]; j++) + response[i] = new IccResponseNumber[measurement[i]]; + for (uint j = 0; j < measurement[i]; j++) { response[i][j] = this.ReadResponseNumber(); } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs index e41d9b3b8..c572b7f21 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs @@ -628,16 +628,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { int start = this.currentIndex - 8; // 8 is the tag header size ushort channelCount = this.ReadUInt16(); - ushort measurmentCount = this.ReadUInt16(); + ushort measurementCount = this.ReadUInt16(); - uint[] offset = new uint[measurmentCount]; - for (int i = 0; i < measurmentCount; i++) + uint[] offset = new uint[measurementCount]; + for (int i = 0; i < measurementCount; i++) { offset[i] = this.ReadUInt32(); } - var curves = new IccResponseCurve[measurmentCount]; - for (int i = 0; i < measurmentCount; i++) + var curves = new IccResponseCurve[measurementCount]; + for (int i = 0; i < measurementCount; i++) { this.currentIndex = (int)(start + offset[i]); curves[i] = this.ReadResponseCurve(channelCount); From d786c6e53e2c5c6fd7ee7140f942143aed45b9ba Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 10 Nov 2018 21:14:30 +0000 Subject: [PATCH 185/238] Introduce ProjectiveTransformBuilder --- .../Processing/AffineTransformBuilder.cs | 10 +- .../Transforms/AffineTransformProcessor.cs | 6 +- .../CenteredProjectiveTransformProcessor.cs | 40 ---- .../InterpolatedTransformProcessorBase.cs | 116 ----------- .../ProjectiveTransformProcessor.cs | 197 +++++------------- .../Processors/Transforms/TransformHelpers.cs | 138 ------------ .../Transforms/TransformProcessorBase.cs | 2 +- .../Transforms/TransformProcessorHelpers.cs | 58 ++++++ .../Processors/Transforms/TransformUtils.cs | 162 ++++++++++++++ .../Processing/ProjectiveTransformBuilder.cs | 113 ++++++++++ .../Processing/ProjectiveTransformHelper.cs | 166 --------------- src/ImageSharp/Processing/TaperCorner.cs | 26 +++ src/ImageSharp/Processing/TaperSide.cs | 31 +++ .../Processing/TransformExtensions.cs | 40 +--- .../Transforms/AffineTransformTests.cs | 2 +- .../Transforms/ProjectiveTransformTests.cs | 27 +-- .../Transforms/TransformsHelpersTest.cs | 2 +- 17 files changed, 475 insertions(+), 661 deletions(-) delete mode 100644 src/ImageSharp/Processing/Processors/Transforms/CenteredProjectiveTransformProcessor.cs delete mode 100644 src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs delete mode 100644 src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs create mode 100644 src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs create mode 100644 src/ImageSharp/Processing/ProjectiveTransformBuilder.cs delete mode 100644 src/ImageSharp/Processing/ProjectiveTransformHelper.cs create mode 100644 src/ImageSharp/Processing/TaperCorner.cs create mode 100644 src/ImageSharp/Processing/TaperSide.cs diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index e5ce1450f..ff44915b1 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -30,6 +30,11 @@ namespace SixLabors.ImageSharp.Processing : this(sourceRectangle.Size) => this.rectangle = sourceRectangle; + /// + /// Gets the source image size. + /// + internal Size Size { get; } + /// /// Prepends a centered rotation matrix using the given rotation in degrees. /// @@ -41,11 +46,6 @@ namespace SixLabors.ImageSharp.Processing return this; } - /// - /// Gets the source image size. - /// - internal Size Size { get; } - /// /// Appends a centered rotation matrix using the given rotation in degrees. /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index fb42b8334..2370adb86 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -22,9 +22,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Initializes a new instance of the class. /// - /// The transform matrix + /// The transform matrix. /// The sampler to perform the transform operation. - /// The source image size + /// The source image size. public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size sourceSize) { Guard.NotNull(sampler, nameof(sampler)); @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Configuration configuration) { // Handle tranforms that result in output identical to the original. - if (this.TransformMatrix.Equals(Matrix3x2.Identity)) + if (this.TransformMatrix.Equals(default) || this.TransformMatrix.Equals(Matrix3x2.Identity)) { // The cloned will be blank here copy all the pixel data over source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); diff --git a/src/ImageSharp/Processing/Processors/Transforms/CenteredProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CenteredProjectiveTransformProcessor.cs deleted file mode 100644 index 962b9e4c9..000000000 --- a/src/ImageSharp/Processing/Processors/Transforms/CenteredProjectiveTransformProcessor.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Numerics; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Primitives; - -namespace SixLabors.ImageSharp.Processing.Processors.Transforms -{ - /// - /// A base class that provides methods to allow the automatic centering of non-affine transforms - /// - /// The pixel format. - internal abstract class CenteredProjectiveTransformProcessor : ProjectiveTransformProcessor - where TPixel : struct, IPixel - { - /// - /// Initializes a new instance of the class. - /// - /// The transform matrix - /// The sampler to perform the transform operation. - /// The source image size - protected CenteredProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size sourceSize) - : base(matrix, sampler, GetTransformedDimensions(sourceSize, matrix)) - { - } - - /// - protected override Matrix4x4 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) - { - return TransformHelpers.GetCenteredTransformMatrix(sourceRectangle, destinationRectangle, this.TransformMatrix); - } - - private static Size GetTransformedDimensions(Size sourceDimensions, Matrix4x4 matrix) - { - var sourceRectangle = new Rectangle(0, 0, sourceDimensions.Width, sourceDimensions.Height); - return TransformHelpers.GetTransformedBoundingRectangle(sourceRectangle, matrix).Size; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs b/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs deleted file mode 100644 index 4737a4102..000000000 --- a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.PixelFormats; - -namespace SixLabors.ImageSharp.Processing.Processors.Transforms -{ - /// - /// The base class for performing interpolated affine and non-affine transforms. - /// - /// The pixel format. - internal abstract class InterpolatedTransformProcessorBase : TransformProcessorBase - where TPixel : struct, IPixel - { - /// - /// Initializes a new instance of the class. - /// - /// The sampler to perform the transform operation. - protected InterpolatedTransformProcessorBase(IResampler sampler) - { - Guard.NotNull(sampler, nameof(sampler)); - this.Sampler = sampler; - } - - /// - /// Gets the sampler to perform interpolation of the transform operation. - /// - public IResampler Sampler { get; } - - /// - /// Calculated the weights for the given point. - /// This method uses more samples than the upscaled version to ensure edge pixels are correctly rendered. - /// Additionally the weights are normalized. - /// - /// The minimum sampling offset - /// The maximum sampling offset - /// The minimum source bounds - /// The maximum source bounds - /// The transformed point dimension - /// The sampler - /// The transformed image scale relative to the source - /// The reference to the collection of weights - /// The length of the weights collection - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected static void CalculateWeightsDown(int min, int max, int sourceMin, int sourceMax, float point, IResampler sampler, float scale, ref float weightsRef, int length) - { - float sum = 0; - - // Downsampling weights requires more edge sampling plus normalization of the weights - for (int x = 0, i = min; i <= max; i++, x++) - { - int index = i; - if (index < sourceMin) - { - index = sourceMin; - } - - if (index > sourceMax) - { - index = sourceMax; - } - - float weight = sampler.GetValue((index - point) / scale); - sum += weight; - Unsafe.Add(ref weightsRef, x) = weight; - } - - if (sum > 0) - { - for (int i = 0; i < length; i++) - { - ref float wRef = ref Unsafe.Add(ref weightsRef, i); - wRef /= sum; - } - } - } - - /// - /// Calculated the weights for the given point. - /// - /// The minimum source bounds - /// The maximum source bounds - /// The transformed point dimension - /// The sampler - /// The reference to the collection of weights - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected static void CalculateWeightsScaleUp(int sourceMin, int sourceMax, float point, IResampler sampler, ref float weightsRef) - { - for (int x = 0, i = sourceMin; i <= sourceMax; i++, x++) - { - Unsafe.Add(ref weightsRef, x) = sampler.GetValue(i - point); - } - } - - /// - /// Calculates the sampling radius for the current sampler - /// - /// The source dimension size - /// The destination dimension size - /// The radius, and scaling factor - protected (float radius, float scale, float ratio) GetSamplingRadius(int sourceSize, int destinationSize) - { - float ratio = (float)sourceSize / destinationSize; - float scale = ratio; - - if (scale < 1F) - { - scale = 1F; - } - - return (MathF.Ceiling(scale * this.Sampler.Radius), scale, ratio); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index 50af26aeb..bfde1769c 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -5,13 +5,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Memory; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -20,22 +16,28 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Provides the base methods to perform non-affine transforms on an image. /// /// The pixel format. - internal class ProjectiveTransformProcessor : InterpolatedTransformProcessorBase + internal class ProjectiveTransformProcessor : TransformProcessorBase where TPixel : struct, IPixel { /// /// Initializes a new instance of the class. /// - /// The transform matrix + /// The transform matrix. /// The sampler to perform the transform operation. - /// The target dimensions to constrain the transformed image to. - public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size targetDimensions) - : base(sampler) + /// The source image size. + public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size sourceSize) { + Guard.NotNull(sampler, nameof(sampler)); + this.Sampler = sampler; this.TransformMatrix = matrix; - this.TargetDimensions = targetDimensions; + this.TargetDimensions = TransformUtils.GetTransformedSize(sourceSize, matrix); } + /// + /// Gets the sampler to perform interpolation of the transform operation. + /// + public IResampler Sampler { get; } + /// /// Gets the matrix used to supply the projective transform /// @@ -60,17 +62,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// protected override void OnFrameApply(ImageFrame source, ImageFrame destination, Rectangle sourceRectangle, Configuration configuration) { + // Handle tranforms that result in output identical to the original. + if (this.TransformMatrix.Equals(default) || this.TransformMatrix.Equals(Matrix4x4.Identity)) + { + // The cloned will be blank here copy all the pixel data over + source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); + return; + } + int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; - Rectangle sourceBounds = source.Bounds(); - var targetBounds = new Rectangle(0, 0, width, height); - - // Since could potentially be resizing the canvas we might need to re-calculate the matrix - Matrix4x4 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); + var targetBounds = new Rectangle(Point.Empty, this.TargetDimensions); // Convert from screen to world space. - Matrix4x4.Invert(matrix, out matrix); + Matrix4x4.Invert(this.TransformMatrix, out Matrix4x4 matrix); const float Epsilon = 0.0000001F; if (this.Sampler is NearestNeighborResampler) @@ -92,7 +98,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int px = (int)MathF.Round(v3.X / z); int py = (int)MathF.Round(v3.Y / z); - if (sourceBounds.Contains(px, py)) + if (sourceRectangle.Contains(px, py)) { destRow[x] = source[px, py]; } @@ -103,145 +109,40 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return; } - int maxSourceX = source.Width - 1; - int maxSourceY = source.Height - 1; - (float radius, float scale, float ratio) xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width); - (float radius, float scale, float ratio) yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height); - float xScale = xRadiusScale.scale; - float yScale = yRadiusScale.scale; - - // Using Vector4 with dummy 0-s, because Vector2 SIMD implementation is not reliable: - var radius = new Vector4(xRadiusScale.radius, yRadiusScale.radius, 0, 0); - - IResampler sampler = this.Sampler; - var maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY); - int xLength = (int)MathF.Ceiling((radius.X * 2) + 2); - int yLength = (int)MathF.Ceiling((radius.Y * 2) + 2); - - MemoryAllocator memoryAllocator = configuration.MemoryAllocator; - - using (Buffer2D yBuffer = memoryAllocator.Allocate2D(yLength, height)) - using (Buffer2D xBuffer = memoryAllocator.Allocate2D(xLength, height)) + var kernel = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.Sampler); + try { - ParallelHelper.IterateRows( + ParallelHelper.IterateRowsWithTempBuffer( targetBounds, configuration, - rows => + (rows, vectorBuffer) => + { + Span vectorSpan = vectorBuffer.Span; + for (int y = rows.Min; y < rows.Max; y++) { - for (int y = rows.Min; y < rows.Max; y++) - { - ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); - ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); - ref float xSpanRef = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y)); - - for (int x = 0; x < width; x++) - { - // Use the single precision position to calculate correct bounding pixels - // otherwise we get rogue pixels outside of the bounds. - var v3 = Vector3.Transform(new Vector3(x, y, 1), matrix); - float z = MathF.Max(v3.Z, Epsilon); - - // Using Vector4 with dummy 0-s, because Vector2 SIMD implementation is not reliable: - Vector4 point = new Vector4(v3.X, v3.Y, 0, 0) / z; - - // Clamp sampling pixel radial extents to the source image edges - Vector4 maxXY = point + radius; - Vector4 minXY = point - radius; - - // max, maxY, minX, minY - var extents = new Vector4( - MathF.Floor(maxXY.X + .5F), - MathF.Floor(maxXY.Y + .5F), - MathF.Ceiling(minXY.X - .5F), - MathF.Ceiling(minXY.Y - .5F)); - - int right = (int)extents.X; - int bottom = (int)extents.Y; - int left = (int)extents.Z; - int top = (int)extents.W; + Span targetRowSpan = destination.GetPixelRowSpan(y); + PixelOperations.Instance.ToVector4(configuration, targetRowSpan, vectorSpan); + ref float ySpanRef = ref kernel.GetYStartReference(y); + ref float xSpanRef = ref kernel.GetXStartReference(y); - extents = Vector4.Clamp(extents, Vector4.Zero, maxSource); - - int maxX = (int)extents.X; - int maxY = (int)extents.Y; - int minX = (int)extents.Z; - int minY = (int)extents.W; - - if (minX == maxX || minY == maxY) - { - continue; - } - - // It appears these have to be calculated on-the-fly. - // Precalulating transformed weights would require prior knowledge of every transformed pixel location - // since they can be at sub-pixel positions on both axis. - // I've optimized where I can but am always open to suggestions. - if (yScale > 1 && xScale > 1) - { - CalculateWeightsDown( - top, - bottom, - minY, - maxY, - point.Y, - sampler, - yScale, - ref ySpanRef, - yLength); - - CalculateWeightsDown( - left, - right, - minX, - maxX, - point.X, - sampler, - xScale, - ref xSpanRef, - xLength); - } - else - { - CalculateWeightsScaleUp(minY, maxY, point.Y, sampler, ref ySpanRef); - CalculateWeightsScaleUp(minX, maxX, point.X, sampler, ref xSpanRef); - } - - // Now multiply the results against the offsets - Vector4 sum = Vector4.Zero; - for (int yy = 0, j = minY; j <= maxY; j++, yy++) - { - float yWeight = Unsafe.Add(ref ySpanRef, yy); - - for (int xx = 0, i = minX; i <= maxX; i++, xx++) - { - float xWeight = Unsafe.Add(ref xSpanRef, xx); - - // Values are first premultiplied to prevent darkening of edge pixels - var current = source[i, j].ToVector4(); - Vector4Utils.Premultiply(ref current); - sum += current * xWeight * yWeight; - } - } - - ref TPixel dest = ref Unsafe.Add(ref destRowRef, x); + for (int x = 0; x < width; x++) + { + // Use the single precision position to calculate correct bounding pixels + // otherwise we get rogue pixels outside of the bounds. + var v3 = Vector3.Transform(new Vector3(x, y, 1), matrix); + Vector2 point = new Vector2(v3.X, v3.Y) / MathF.Max(v3.Z, Epsilon); - // Reverse the premultiplication - Vector4Utils.UnPremultiply(ref sum); - dest.FromVector4(sum); - } + kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); } - }); + + PixelOperations.Instance.FromVector4(configuration, vectorSpan, targetRowSpan); + } + }); + } + finally + { + kernel.Dispose(); } } - - /// - /// Gets a transform matrix adjusted for final processing based upon the target image bounds. - /// - /// The source image bounds. - /// The destination image bounds. - /// - /// The . - /// - protected virtual Matrix4x4 GetProcessingMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle) => this.TransformMatrix; } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs deleted file mode 100644 index 2e85f6c2c..000000000 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformHelpers.cs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Numerics; -using SixLabors.ImageSharp.MetaData.Profiles.Exif; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Primitives; - -namespace SixLabors.ImageSharp.Processing.Processors.Transforms -{ - /// - /// Contains helper methods for working with affine and non-affine transforms - /// - internal static class TransformHelpers - { - /// - /// Updates the dimensional metadata of a transformed image - /// - /// The pixel format. - /// The image to update - public static void UpdateDimensionalMetData(Image image) - where TPixel : struct, IPixel - { - ExifProfile profile = image.MetaData.ExifProfile; - if (profile is null) - { - return; - } - - // Removing the previously stored value allows us to set a value with our own data tag if required. - if (profile.GetValue(ExifTag.PixelXDimension) != null) - { - profile.RemoveValue(ExifTag.PixelXDimension); - - if (image.Width <= ushort.MaxValue) - { - profile.SetValue(ExifTag.PixelXDimension, (ushort)image.Width); - } - else - { - profile.SetValue(ExifTag.PixelXDimension, (uint)image.Width); - } - } - - if (profile.GetValue(ExifTag.PixelYDimension) != null) - { - profile.RemoveValue(ExifTag.PixelYDimension); - - if (image.Height <= ushort.MaxValue) - { - profile.SetValue(ExifTag.PixelYDimension, (ushort)image.Height); - } - else - { - profile.SetValue(ExifTag.PixelYDimension, (uint)image.Height); - } - } - } - - /// - /// Gets the centered transform matrix based upon the source and destination rectangles - /// - /// The source image bounds. - /// The destination image bounds. - /// The transformation matrix. - /// The - public static Matrix3x2 GetCenteredTransformMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle, Matrix3x2 matrix) - { - // We invert the matrix to handle the transformation from screen to world space. - // This ensures scaling matrices are correct. - Matrix3x2.Invert(matrix, out Matrix3x2 inverted); - - var translationToTargetCenter = Matrix3x2.CreateTranslation(-destinationRectangle.Width * .5F, -destinationRectangle.Height * .5F); - var translateToSourceCenter = Matrix3x2.CreateTranslation(sourceRectangle.Width * .5F, sourceRectangle.Height * .5F); - - Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); - - // Translate back to world to pass to the Transform method. - return centered; - } - - /// - /// Gets the centered transform matrix based upon the source and destination rectangles - /// - /// The source image bounds. - /// The destination image bounds. - /// The transformation matrix. - /// The - public static Matrix4x4 GetCenteredTransformMatrix(Rectangle sourceRectangle, Rectangle destinationRectangle, Matrix4x4 matrix) - { - // We invert the matrix to handle the transformation from screen to world space. - // This ensures scaling matrices are correct. - Matrix4x4.Invert(matrix, out Matrix4x4 inverted); - - var translationToTargetCenter = Matrix4x4.CreateTranslation(-destinationRectangle.Width * .5F, -destinationRectangle.Height * .5F, 0); - var translateToSourceCenter = Matrix4x4.CreateTranslation(sourceRectangle.Width * .5F, sourceRectangle.Height * .5F, 0); - - Matrix4x4.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix4x4 centered); - - // Translate back to world to pass to the Transform method. - return centered; - } - - /// - /// Returns the bounding rectangle relative to the source for the given transformation matrix. - /// - /// The source rectangle. - /// The transformation matrix. - /// - /// The . - /// - public static Rectangle GetTransformedBoundingRectangle(Rectangle rectangle, Matrix4x4 matrix) - { - // Calculate the position of the four corners in world space by applying - // The world matrix to the four corners in object space (0, 0, width, height) - var tl = Vector2.Transform(Vector2.Zero, matrix); - var tr = Vector2.Transform(new Vector2(rectangle.Width, 0), matrix); - var bl = Vector2.Transform(new Vector2(0, rectangle.Height), matrix); - var br = Vector2.Transform(new Vector2(rectangle.Width, rectangle.Height), matrix); - - return GetBoundingRectangle(tl, tr, bl, br); - } - - private static Rectangle GetBoundingRectangle(Vector2 tl, Vector2 tr, Vector2 bl, Vector2 br) - { - // Find the minimum and maximum "corners" based on the given vectors - float minX = MathF.Min(tl.X, MathF.Min(tr.X, MathF.Min(bl.X, br.X))); - float maxX = MathF.Max(tl.X, MathF.Max(tr.X, MathF.Max(bl.X, br.X))); - float minY = MathF.Min(tl.Y, MathF.Min(tr.Y, MathF.Min(bl.Y, br.Y))); - float maxY = MathF.Max(tl.Y, MathF.Max(tr.Y, MathF.Max(bl.Y, br.Y))); - float sizeX = maxX - minX + .5F; - float sizeY = maxY - minY + .5F; - - return new Rectangle((int)(MathF.Ceiling(minX) - .5F), (int)(MathF.Ceiling(minY) - .5F), (int)MathF.Floor(sizeX), (int)MathF.Floor(sizeY)); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs index 13ee90a06..4973b90f4 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs @@ -16,6 +16,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// protected override void AfterImageApply(Image source, Image destination, Rectangle sourceRectangle) - => TransformHelpers.UpdateDimensionalMetData(destination); + => TransformProcessorHelpers.UpdateDimensionalMetData(destination); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs new file mode 100644 index 000000000..f5536d046 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorHelpers.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.MetaData.Profiles.Exif; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Contains helper methods for working with transforms. + /// + internal static class TransformProcessorHelpers + { + /// + /// Updates the dimensional metadata of a transformed image + /// + /// The pixel format. + /// The image to update + public static void UpdateDimensionalMetData(Image image) + where TPixel : struct, IPixel + { + ExifProfile profile = image.MetaData.ExifProfile; + if (profile is null) + { + return; + } + + // Removing the previously stored value allows us to set a value with our own data tag if required. + if (profile.GetValue(ExifTag.PixelXDimension) != null) + { + profile.RemoveValue(ExifTag.PixelXDimension); + + if (image.Width <= ushort.MaxValue) + { + profile.SetValue(ExifTag.PixelXDimension, (ushort)image.Width); + } + else + { + profile.SetValue(ExifTag.PixelXDimension, (uint)image.Width); + } + } + + if (profile.GetValue(ExifTag.PixelYDimension) != null) + { + profile.RemoveValue(ExifTag.PixelYDimension); + + if (image.Height <= ushort.MaxValue) + { + profile.SetValue(ExifTag.PixelYDimension, (ushort)image.Height); + } + else + { + profile.SetValue(ExifTag.PixelYDimension, (uint)image.Height); + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index 10cf49c34..f561d3513 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -58,6 +58,111 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return centered; } + /// + /// Creates a matrix that performs a tapering projective transform. + /// + /// + /// The rectangular size of the image being transformed. + /// An enumeration that indicates the side of the rectangle that tapers. + /// An enumeration that indicates on which corners to taper the rectangle. + /// The amount to taper. + /// The + public static Matrix4x4 CreateTaperMatrix(Size size, TaperSide side, TaperCorner corner, float fraction) + { + Matrix4x4 matrix = Matrix4x4.Identity; + + switch (side) + { + case TaperSide.Left: + matrix.M11 = fraction; + matrix.M22 = fraction; + matrix.M13 = (fraction - 1) / size.Width; + + switch (corner) + { + case TaperCorner.RightOrBottom: + break; + + case TaperCorner.LeftOrTop: + matrix.M12 = size.Height * matrix.M13; + matrix.M32 = size.Height * (1 - fraction); + break; + + case TaperCorner.Both: + matrix.M12 = size.Height * .5F * matrix.M13; + matrix.M32 = size.Height * (1 - fraction) / 2; + break; + } + + break; + + case TaperSide.Top: + matrix.M11 = fraction; + matrix.M22 = fraction; + matrix.M23 = (fraction - 1) / size.Height; + + switch (corner) + { + case TaperCorner.RightOrBottom: + break; + + case TaperCorner.LeftOrTop: + matrix.M21 = size.Width * matrix.M23; + matrix.M31 = size.Width * (1 - fraction); + break; + + case TaperCorner.Both: + matrix.M21 = size.Width * .5F * matrix.M23; + matrix.M31 = size.Width * (1 - fraction) / 2; + break; + } + + break; + + case TaperSide.Right: + matrix.M11 = 1 / fraction; + matrix.M13 = (1 - fraction) / (size.Width * fraction); + + switch (corner) + { + case TaperCorner.RightOrBottom: + break; + + case TaperCorner.LeftOrTop: + matrix.M12 = size.Height * matrix.M13; + break; + + case TaperCorner.Both: + matrix.M12 = size.Height * .5F * matrix.M13; + break; + } + + break; + + case TaperSide.Bottom: + matrix.M22 = 1 / fraction; + matrix.M23 = (1 - fraction) / (size.Height * fraction); + + switch (corner) + { + case TaperCorner.RightOrBottom: + break; + + case TaperCorner.LeftOrTop: + matrix.M21 = size.Width * matrix.M23; + break; + + case TaperCorner.Both: + matrix.M21 = size.Width * .5F * matrix.M23; + break; + } + + break; + } + + return matrix; + } + /// /// Returns the rectangle bounds relative to the source for the given transformation matrix. /// @@ -114,6 +219,63 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Rectangle rectangle = GetTransformedRectangle(new Rectangle(Point.Empty, size), matrix); + return ConstrainSize(rectangle); + } + + /// + /// Returns the rectangle relative to the source for the given transformation matrix. + /// + /// The source rectangle. + /// The transformation matrix. + /// + /// The . + /// + public static Rectangle GetTransformedRectangle(Rectangle rectangle, Matrix4x4 matrix) + { + if (rectangle.Equals(default) || Matrix4x4.Identity.Equals(matrix)) + { + return rectangle; + } + + Vector2 GetVector(float x, float y) + { + const float Epsilon = 0.0000001F; + var v3 = Vector3.Transform(new Vector3(x, y, 1F), matrix); + return new Vector2(v3.X, v3.Y) / MathF.Max(v3.Z, Epsilon); + } + + Vector2 tl = GetVector(rectangle.Left, rectangle.Top); + Vector2 tr = GetVector(rectangle.Right, rectangle.Top); + Vector2 bl = GetVector(rectangle.Left, rectangle.Bottom); + Vector2 br = GetVector(rectangle.Right, rectangle.Bottom); + + return GetBoundingRectangle(tl, tr, bl, br); + } + + /// + /// Returns the size relative to the source for the given transformation matrix. + /// + /// The source size. + /// The transformation matrix. + /// + /// The . + /// + public static Size GetTransformedSize(Size size, Matrix4x4 matrix) + { + Guard.IsTrue(size.Width > 0 && size.Height > 0, nameof(size), "Source size dimensions cannot be 0!"); + + if (matrix.Equals(default) || matrix.Equals(Matrix4x4.Identity)) + { + return size; + } + + Rectangle rectangle = GetTransformedRectangle(new Rectangle(Point.Empty, size), matrix); + + return ConstrainSize(rectangle); + } + + private static Size ConstrainSize(Rectangle rectangle) + { // We want to resize the canvas here taking into account any translations. int height = rectangle.Top < 0 ? rectangle.Bottom : Math.Max(rectangle.Height, rectangle.Bottom); int width = rectangle.Left < 0 ? rectangle.Right : Math.Max(rectangle.Width, rectangle.Right); diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs new file mode 100644 index 000000000..3edc993c4 --- /dev/null +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -0,0 +1,113 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; +using System.Numerics; +using SixLabors.ImageSharp.Processing.Processors.Transforms; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// A helper class for constructing instances for use in projective transforms. + /// + public class ProjectiveTransformBuilder + { + private readonly List matrices = new List(); + private Rectangle rectangle; + + /// + /// Initializes a new instance of the class. + /// + /// The source image size. + public ProjectiveTransformBuilder(Size sourceSize) => this.Size = sourceSize; + + /// + /// Initializes a new instance of the class. + /// + /// The source rectangle. + public ProjectiveTransformBuilder(Rectangle sourceRectangle) + : this(sourceRectangle.Size) + => this.rectangle = sourceRectangle; + + /// + /// Gets the source image size. + /// + internal Size Size { get; } + + /// + /// Prepends a matrix that performs a tapering projective transform. + /// + /// An enumeration that indicates the side of the rectangle that tapers. + /// An enumeration that indicates on which corners to taper the rectangle. + /// The amount to taper. + /// The . + public ProjectiveTransformBuilder PrependTaperMatrix(TaperSide side, TaperCorner corner, float fraction) + { + this.matrices.Insert(0, TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + return this; + } + + /// + /// Appends a matrix that performs a tapering projective transform. + /// + /// An enumeration that indicates the side of the rectangle that tapers. + /// An enumeration that indicates on which corners to taper the rectangle. + /// The amount to taper. + /// The . + public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) + { + this.matrices.Add(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + return this; + } + + /// + /// Prepends a raw matrix. + /// + /// The matrix to prepend. + /// The . + public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) + { + this.matrices.Insert(0, matrix); + return this; + } + + /// + /// Appends a raw matrix. + /// + /// The matrix to append. + /// The . + public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) + { + this.matrices.Add(matrix); + return this; + } + + /// + /// Returns the combined matrix. + /// + /// The . + public Matrix4x4 BuildMatrix() + { + Matrix4x4 matrix = Matrix4x4.Identity; + + // Translate the origin matrix to cater for source rectangle offsets. + if (!this.rectangle.Equals(default)) + { + matrix *= Matrix4x4.CreateTranslation(new Vector3(-this.rectangle.Location, 0)); + } + + foreach (Matrix4x4 m in this.matrices) + { + matrix *= m; + } + + return matrix; + } + + /// + /// Removes all matrices from the builder. + /// + public void Clear() => this.matrices.Clear(); + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/ProjectiveTransformHelper.cs b/src/ImageSharp/Processing/ProjectiveTransformHelper.cs deleted file mode 100644 index 4057ec586..000000000 --- a/src/ImageSharp/Processing/ProjectiveTransformHelper.cs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Numerics; -using SixLabors.Primitives; - -namespace SixLabors.ImageSharp.Processing -{ - /// - /// Enumerates the various options which determine which side to taper - /// - public enum TaperSide - { - /// - /// Taper the left side - /// - Left, - - /// - /// Taper the top side - /// - Top, - - /// - /// Taper the right side - /// - Right, - - /// - /// Taper the bottom side - /// - Bottom - } - - /// - /// Enumerates the various options which determine how to taper corners - /// - public enum TaperCorner - { - /// - /// Taper the left or top corner - /// - LeftOrTop, - - /// - /// Taper the right or bottom corner - /// - RightOrBottom, - - /// - /// Taper the both sets of corners - /// - Both - } - - /// - /// Provides helper methods for working with generalized projective transforms. - /// - public static class ProjectiveTransformHelper - { - /// - /// Creates a matrix that performs a tapering projective transform. - /// - /// - /// The rectangular size of the image being transformed. - /// An enumeration that indicates the side of the rectangle that tapers. - /// An enumeration that indicates on which corners to taper the rectangle. - /// The amount to taper. - /// The - public static Matrix4x4 CreateTaperMatrix(Size size, TaperSide taperSide, TaperCorner taperCorner, float taperFraction) - { - Matrix4x4 matrix = Matrix4x4.Identity; - - switch (taperSide) - { - case TaperSide.Left: - matrix.M11 = taperFraction; - matrix.M22 = taperFraction; - matrix.M13 = (taperFraction - 1) / size.Width; - - switch (taperCorner) - { - case TaperCorner.RightOrBottom: - break; - - case TaperCorner.LeftOrTop: - matrix.M12 = size.Height * matrix.M13; - matrix.M32 = size.Height * (1 - taperFraction); - break; - - case TaperCorner.Both: - matrix.M12 = (size.Height * 0.5f) * matrix.M13; - matrix.M32 = size.Height * (1 - taperFraction) / 2; - break; - } - - break; - - case TaperSide.Top: - matrix.M11 = taperFraction; - matrix.M22 = taperFraction; - matrix.M23 = (taperFraction - 1) / size.Height; - - switch (taperCorner) - { - case TaperCorner.RightOrBottom: - break; - - case TaperCorner.LeftOrTop: - matrix.M21 = size.Width * matrix.M23; - matrix.M31 = size.Width * (1 - taperFraction); - break; - - case TaperCorner.Both: - matrix.M21 = (size.Width * 0.5f) * matrix.M23; - matrix.M31 = size.Width * (1 - taperFraction) / 2; - break; - } - - break; - - case TaperSide.Right: - matrix.M11 = 1 / taperFraction; - matrix.M13 = (1 - taperFraction) / (size.Width * taperFraction); - - switch (taperCorner) - { - case TaperCorner.RightOrBottom: - break; - - case TaperCorner.LeftOrTop: - matrix.M12 = size.Height * matrix.M13; - break; - - case TaperCorner.Both: - matrix.M12 = (size.Height * 0.5f) * matrix.M13; - break; - } - - break; - - case TaperSide.Bottom: - matrix.M22 = 1 / taperFraction; - matrix.M23 = (1 - taperFraction) / (size.Height * taperFraction); - - switch (taperCorner) - { - case TaperCorner.RightOrBottom: - break; - - case TaperCorner.LeftOrTop: - matrix.M21 = size.Width * matrix.M23; - break; - - case TaperCorner.Both: - matrix.M21 = (size.Width * 0.5f) * matrix.M23; - break; - } - - break; - } - - return matrix; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Processing/TaperCorner.cs b/src/ImageSharp/Processing/TaperCorner.cs new file mode 100644 index 000000000..395b17142 --- /dev/null +++ b/src/ImageSharp/Processing/TaperCorner.cs @@ -0,0 +1,26 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// Enumerates the various options which determine how to taper corners + /// + public enum TaperCorner + { + /// + /// Taper the left or top corner + /// + LeftOrTop, + + /// + /// Taper the right or bottom corner + /// + RightOrBottom, + + /// + /// Taper the both sets of corners + /// + Both + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/TaperSide.cs b/src/ImageSharp/Processing/TaperSide.cs new file mode 100644 index 000000000..226d11aed --- /dev/null +++ b/src/ImageSharp/Processing/TaperSide.cs @@ -0,0 +1,31 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// Enumerates the various options which determine which side to taper + /// + public enum TaperSide + { + /// + /// Taper the left side + /// + Left, + + /// + /// Taper the top side + /// + Top, + + /// + /// Taper the right side + /// + Right, + + /// + /// Taper the bottom side + /// + Bottom + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/TransformExtensions.cs b/src/ImageSharp/Processing/TransformExtensions.cs index 4cbd1b041..ea789eb3d 100644 --- a/src/ImageSharp/Processing/TransformExtensions.cs +++ b/src/ImageSharp/Processing/TransformExtensions.cs @@ -1,10 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System.Numerics; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Transforms; -using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing { @@ -14,7 +12,7 @@ namespace SixLabors.ImageSharp.Processing public static class TransformExtensions { /// - /// Transforms an image by the given matrix. + /// Performs an affine transform of an image. /// /// The pixel format. /// The image to transform. @@ -25,7 +23,7 @@ namespace SixLabors.ImageSharp.Processing => Transform(source, builder, KnownResamplers.Bicubic); /// - /// Transforms an image by the given matrix using the specified sampling algorithm. + /// Performs an affine transform of an image using the specified sampling algorithm. /// /// The pixel format. /// The image to transform. @@ -37,44 +35,26 @@ namespace SixLabors.ImageSharp.Processing => source.ApplyProcessor(new AffineTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); /// - /// Transforms an image by the given matrix. + /// Performs a projective transform of an image. /// /// The pixel format. /// The image to transform. - /// The transformation matrix. - /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix4x4 matrix) - where TPixel : struct, IPixel - => Transform(source, matrix, KnownResamplers.Bicubic); - - /// - /// Applies a projective transform to the image by the given matrix using the specified sampling algorithm. - /// - /// The pixel format. - /// The image to transform. - /// The transformation matrix. - /// The to perform the resampling. + /// The affine transform builder. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix4x4 matrix, IResampler sampler) + public static IImageProcessingContext Transform(this IImageProcessingContext source, ProjectiveTransformBuilder builder) where TPixel : struct, IPixel - => source.ApplyProcessor(new ProjectiveTransformProcessor(matrix, sampler, source.GetCurrentSize())); + => Transform(source, builder, KnownResamplers.Bicubic); /// - /// Applies a projective transform to the image by the given matrix using the specified sampling algorithm. - /// TODO: Should we be offsetting the matrix here? + /// Performs a projective transform of an image using the specified sampling algorithm. /// /// The pixel format. /// The image to transform. - /// The transformation matrix. + /// The projective transform builder. /// The to perform the resampling. - /// The rectangle to constrain the transformed image to. /// The - internal static IImageProcessingContext Transform(this IImageProcessingContext source, Matrix4x4 matrix, IResampler sampler, Rectangle rectangle) + public static IImageProcessingContext Transform(this IImageProcessingContext source, ProjectiveTransformBuilder builder, IResampler sampler) where TPixel : struct, IPixel - { - var t = Matrix4x4.CreateTranslation(new Vector3(-rectangle.Location, 0)); - Matrix4x4 combinedMatrix = t * matrix; - return source.ApplyProcessor(new ProjectiveTransformProcessor(combinedMatrix, sampler, rectangle.Size)); - } + => source.ApplyProcessor(new ProjectiveTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index 32280d48c..e05a8e381 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotateMatrixDegrees((float)Math.PI / 4F); + .AppendRotateMatrixDegrees(30); image.Mutate(c => c.Transform(builder, resampler)); image.DebugSave(provider, resamplerName); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs index 5190a71e7..0362d75a0 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms private static readonly ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.5f, 3); private ITestOutputHelper Output { get; } - + public static readonly TheoryData ResamplerNames = new TheoryData { nameof(KnownResamplers.Bicubic), @@ -60,10 +60,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms }; - public ProjectiveTransformTests(ITestOutputHelper output) - { - this.Output = output; - } + public ProjectiveTransformTests(ITestOutputHelper output) => this.Output = output; [Theory] [WithTestPatternImages(nameof(ResamplerNames), 150, 150, PixelTypes.Rgba32)] @@ -73,9 +70,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler sampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - Matrix4x4 m = ProjectiveTransformHelper.CreateTaperMatrix(image.Size(), TaperSide.Right, TaperCorner.Both, .5F); + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + .AppendTaperMatrix(TaperSide.Right, TaperCorner.Both, .5F); - image.Mutate(i => { i.Transform(m, sampler); }); + image.Mutate(i => i.Transform(builder, sampler)); image.DebugSave(provider, resamplerName); image.CompareToReferenceOutput(ValidatorComparer, provider, resamplerName); @@ -89,8 +87,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - Matrix4x4 m = ProjectiveTransformHelper.CreateTaperMatrix(image.Size(), taperSide, taperCorner, .5F); - image.Mutate(i => { i.Transform(m); }); + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + .AppendTaperMatrix(taperSide, taperCorner, .5F); + + image.Mutate(i => i.Transform(builder)); FormattableString testOutputDetails = $"{taperSide}-{taperCorner}"; image.DebugSave(provider, testOutputDetails); @@ -110,10 +110,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms // https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/non-affine using (Image image = provider.GetImage()) { - Matrix4x4 m = Matrix4x4.Identity; - m.M13 = 0.01F; + Matrix4x4 matrix = Matrix4x4.Identity; + matrix.M13 = 0.01F; + + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + .AppendMatrix(matrix); - image.Mutate(i => { i.Transform(m); }); + image.Mutate(i => i.Transform(builder)); image.DebugSave(provider); image.CompareToReferenceOutput(TolerantComparer, provider); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs index 146ed6230..909e50535 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformsHelpersTest.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelXDimension).DataType); Assert.Equal(ExifDataType.Long, profile.GetValue(ExifTag.PixelYDimension).DataType); - TransformHelpers.UpdateDimensionalMetData(img); + TransformProcessorHelpers.UpdateDimensionalMetData(img); Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelXDimension).DataType); Assert.Equal(ExifDataType.Short, profile.GetValue(ExifTag.PixelYDimension).DataType); From 8b98cf2a7de5f8da24d606f35c687cca1c85bf9e Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 10 Nov 2018 21:45:02 +0000 Subject: [PATCH 186/238] Update tests/Images/External --- tests/Images/External | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Images/External b/tests/Images/External index ed8a7b0b6..e7e0f1311 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit ed8a7b0b6fe1b2e2a7c822aa617103ae31192655 +Subproject commit e7e0f1311d1d585ea8e38efb5a69fca98c44e8a4 From f4fbe8d3c1dd0a1ff2f3d1bfe2486b249cd701e6 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Sat, 10 Nov 2018 17:25:39 -0600 Subject: [PATCH 187/238] ImageSharp-762_Aot-compiling: added simple unit test to check no exceptions are thrown by AotCompiler --- .../Advanced/AotCompilerTests.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs diff --git a/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs new file mode 100644 index 000000000..3d6faa27e --- /dev/null +++ b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs @@ -0,0 +1,18 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Advanced +{ + public class AotCompilerTests + { + [Fact] + public void AotCompiler_NoExceptions() + { + AotCompiler.Seed(); + } + } +} From e61b272d22590c072aba4e686547b1eb7edc98e0 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 11 Nov 2018 10:24:32 +0000 Subject: [PATCH 188/238] Change tolerance for 32bit framework builds. --- .../Processing/Transforms/AffineTransformTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index e05a8e381..15b4500bb 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -17,7 +17,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { private readonly ITestOutputHelper Output; - private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.0085f, 3); + // 1 byte difference on one color component. + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.0134F, 3); /// /// angleDeg, sx, sy, tx, ty From 3347ffc4779473092466c7ffa173f2948b15aa8b Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 11 Nov 2018 21:28:53 +0100 Subject: [PATCH 189/238] make code more clear by extracting the ratio to a variable again while keeping it inlined to avoid it in the third case, and while still replacing the division by a multiplication in the second case. --- src/ImageSharp/Processing/ResizeHelper.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Processing/ResizeHelper.cs b/src/ImageSharp/Processing/ResizeHelper.cs index 92af89d9e..aaac7346d 100644 --- a/src/ImageSharp/Processing/ResizeHelper.cs +++ b/src/ImageSharp/Processing/ResizeHelper.cs @@ -343,13 +343,15 @@ namespace SixLabors.ImageSharp.Processing if (widthDiff < heightDiff) { - destinationHeight = (int)MathF.Round(width * ((float)sourceHeight / sourceWidth)); + float sourceRatio = (float)sourceHeight / sourceWidth; + destinationHeight = (int)MathF.Round(width * sourceRatio); height = destinationHeight; destinationWidth = width; } else if (widthDiff > heightDiff) { - destinationWidth = (int)MathF.Round(height * ((float)sourceWidth / sourceHeight)); + float sourceRatioInverse = (float)sourceWidth / sourceHeight; + destinationWidth = (int)MathF.Round(height * sourceRatioInverse); destinationHeight = height; width = destinationWidth; } From 49557515992461e03d25ae08d3c066dd17b0905e Mon Sep 17 00:00:00 2001 From: Peter Amrehn Date: Sun, 11 Nov 2018 21:30:19 +0100 Subject: [PATCH 190/238] inline percentHeiught and percentWidth as they are used only in one case each --- src/ImageSharp/Processing/ResizeHelper.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Processing/ResizeHelper.cs b/src/ImageSharp/Processing/ResizeHelper.cs index aaac7346d..3ae632162 100644 --- a/src/ImageSharp/Processing/ResizeHelper.cs +++ b/src/ImageSharp/Processing/ResizeHelper.cs @@ -333,10 +333,6 @@ namespace SixLabors.ImageSharp.Processing return (new Size(sourceWidth, sourceWidth), new Rectangle(0, 0, sourceWidth, sourceHeight)); } - // Fractional variants for preserving aspect ratio. - float percentHeight = MathF.Abs(height / (float)sourceHeight); - float percentWidth = MathF.Abs(width / (float)sourceWidth); - // Find the shortest distance to go. int widthDiff = sourceWidth - width; int heightDiff = sourceHeight - height; @@ -360,12 +356,14 @@ namespace SixLabors.ImageSharp.Processing if (height > width) { destinationWidth = width; + float percentWidth = MathF.Abs(width / (float)sourceWidth); destinationHeight = (int)MathF.Round(sourceHeight * percentWidth); height = destinationHeight; } else { destinationHeight = height; + float percentHeight = MathF.Abs(height / (float)sourceHeight); destinationWidth = (int)MathF.Round(sourceWidth * percentHeight); width = destinationWidth; } From 2277d5a3e544f9cafc7b8b243ffdf3832b132ea9 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 11 Nov 2018 21:33:39 +0000 Subject: [PATCH 191/238] Improve transform builder coverage --- .../Processing/AffineTransformBuilder.cs | 16 ++++++++-------- .../Processing/ProjectiveTransformBuilder.cs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index ff44915b1..b2b011264 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder PrependRotateMatrixDegrees(float degrees) { - this.matrices.Insert(0, TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); return this; } @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder AppendRotateMatrixDegrees(float degrees) { - this.matrices.Add(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + this.AppendMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); return this; } @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder PrependScaleMatrix(SizeF scales) { - this.matrices.Insert(0, Matrix3x2Extensions.CreateScale(scales)); + this.PrependMatrix(Matrix3x2Extensions.CreateScale(scales)); return this; } @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder AppendScaleMatrix(SizeF scales) { - this.matrices.Add(Matrix3x2Extensions.CreateScale(scales)); + this.AppendMatrix(Matrix3x2Extensions.CreateScale(scales)); return this; } @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder PrependSkewMatrixDegrees(float degreesX, float degreesY) { - this.matrices.Insert(0, TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + this.PrependMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); return this; } @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder AppendSkewMatrixDegrees(float degreesX, float degreesY) { - this.matrices.Add(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + this.AppendMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); return this; } @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder PrependTranslationMatrix(PointF position) { - this.matrices.Insert(0, Matrix3x2Extensions.CreateTranslation(position)); + this.PrependMatrix(Matrix3x2Extensions.CreateTranslation(position)); return this; } @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder AppendTranslationMatrix(PointF position) { - this.matrices.Add(Matrix3x2Extensions.CreateTranslation(position)); + this.AppendMatrix(Matrix3x2Extensions.CreateTranslation(position)); return this; } diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 3edc993c4..529dd56b1 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public ProjectiveTransformBuilder PrependTaperMatrix(TaperSide side, TaperCorner corner, float fraction) { - this.matrices.Insert(0, TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + this.PrependMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); return this; } @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) { - this.matrices.Add(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); return this; } From 5a2a29872a523865e169c12d3deb8b52bf71bf0a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 11 Nov 2018 22:42:05 +0000 Subject: [PATCH 192/238] Cleanup and add dedicated transform builder tests --- .../Processing/AffineTransformBuilder.cs | 48 ++++------- .../Processing/ProjectiveTransformBuilder.cs | 18 ++--- .../Transforms/AffineTransformBuilderTests.cs | 79 +++++++++++++++++++ .../ProjectiveTransformBuilderTests.cs | 78 ++++++++++++++++++ 4 files changed, 181 insertions(+), 42 deletions(-) create mode 100644 tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs create mode 100644 tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index b2b011264..003249d6e 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -20,7 +20,13 @@ namespace SixLabors.ImageSharp.Processing /// Initializes a new instance of the class. /// /// The source image size. - public AffineTransformBuilder(Size sourceSize) => this.Size = sourceSize; + public AffineTransformBuilder(Size sourceSize) + { + Guard.MustBeGreaterThan(sourceSize.Width, 0, nameof(sourceSize)); + Guard.MustBeGreaterThan(sourceSize.Height, 0, nameof(sourceSize)); + + this.Size = sourceSize; + } /// /// Initializes a new instance of the class. @@ -41,10 +47,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder PrependRotateMatrixDegrees(float degrees) - { - this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); - return this; - } + => this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); /// /// Appends a centered rotation matrix using the given rotation in degrees. @@ -52,10 +55,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder AppendRotateMatrixDegrees(float degrees) - { - this.AppendMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); - return this; - } + => this.AppendMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); /// /// Prepends a scale matrix from the given vector scale. @@ -63,10 +63,7 @@ namespace SixLabors.ImageSharp.Processing /// The horizontal and vertical scale. /// The . public AffineTransformBuilder PrependScaleMatrix(SizeF scales) - { - this.PrependMatrix(Matrix3x2Extensions.CreateScale(scales)); - return this; - } + => this.PrependMatrix(Matrix3x2Extensions.CreateScale(scales)); /// /// Appends a scale matrix from the given vector scale. @@ -74,10 +71,7 @@ namespace SixLabors.ImageSharp.Processing /// The horizontal and vertical scale. /// The . public AffineTransformBuilder AppendScaleMatrix(SizeF scales) - { - this.AppendMatrix(Matrix3x2Extensions.CreateScale(scales)); - return this; - } + => this.AppendMatrix(Matrix3x2Extensions.CreateScale(scales)); /// /// Prepends a centered skew matrix from the give angles in degrees. @@ -86,10 +80,7 @@ namespace SixLabors.ImageSharp.Processing /// The Y angle, in degrees. /// The . public AffineTransformBuilder PrependSkewMatrixDegrees(float degreesX, float degreesY) - { - this.PrependMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); - return this; - } + => this.PrependMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); /// /// Appends a centered skew matrix from the give angles in degrees. @@ -98,10 +89,7 @@ namespace SixLabors.ImageSharp.Processing /// The Y angle, in degrees. /// The . public AffineTransformBuilder AppendSkewMatrixDegrees(float degreesX, float degreesY) - { - this.AppendMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); - return this; - } + => this.AppendMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); /// /// Prepends a translation matrix from the given vector. @@ -109,10 +97,7 @@ namespace SixLabors.ImageSharp.Processing /// The translation position. /// The . public AffineTransformBuilder PrependTranslationMatrix(PointF position) - { - this.PrependMatrix(Matrix3x2Extensions.CreateTranslation(position)); - return this; - } + => this.PrependMatrix(Matrix3x2Extensions.CreateTranslation(position)); /// /// Appends a translation matrix from the given vector. @@ -120,10 +105,7 @@ namespace SixLabors.ImageSharp.Processing /// The translation position. /// The . public AffineTransformBuilder AppendTranslationMatrix(PointF position) - { - this.AppendMatrix(Matrix3x2Extensions.CreateTranslation(position)); - return this; - } + => this.AppendMatrix(Matrix3x2Extensions.CreateTranslation(position)); /// /// Prepends a raw matrix. diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 529dd56b1..be4c67518 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -20,7 +20,13 @@ namespace SixLabors.ImageSharp.Processing /// Initializes a new instance of the class. /// /// The source image size. - public ProjectiveTransformBuilder(Size sourceSize) => this.Size = sourceSize; + public ProjectiveTransformBuilder(Size sourceSize) + { + Guard.MustBeGreaterThan(sourceSize.Width, 0, nameof(sourceSize)); + Guard.MustBeGreaterThan(sourceSize.Height, 0, nameof(sourceSize)); + + this.Size = sourceSize; + } /// /// Initializes a new instance of the class. @@ -43,10 +49,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount to taper. /// The . public ProjectiveTransformBuilder PrependTaperMatrix(TaperSide side, TaperCorner corner, float fraction) - { - this.PrependMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); - return this; - } + => this.PrependMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); /// /// Appends a matrix that performs a tapering projective transform. @@ -56,10 +59,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount to taper. /// The . public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) - { - this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); - return this; - } + => this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); /// /// Prepends a raw matrix. diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs new file mode 100644 index 000000000..eaa51b129 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -0,0 +1,79 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using SixLabors.ImageSharp.Processing; +using SixLabors.Primitives; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Transforms +{ + public class AffineTransformBuilderTests + { + [Fact] + public void ConstructorAssignsProperties() + { + var s = new Size(1, 1); + var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); + Assert.Equal(s, builder.Size); + } + + [Fact] + public void ConstructorThrowsInvalid() + { + Assert.Throws(() => + { + var s = new Size(0, 1); + var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); + }); + + Assert.Throws(() => + { + var s = new Size(1, 0); + var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); + }); + } + + [Fact] + public void AppendPrependOpposite() + { + var rectangle = new Rectangle(-1, -1, 3, 3); + var b1 = new AffineTransformBuilder(rectangle); + var b2 = new AffineTransformBuilder(rectangle); + + const float pi = (float)Math.PI; + + // Forwards + b1.AppendRotateMatrixDegrees(pi) + .AppendSkewMatrixDegrees(pi, pi) + .AppendScaleMatrix(new SizeF(pi, pi)) + .AppendTranslationMatrix(new PointF(pi, pi)); + + // Backwards + b2.PrependTranslationMatrix(new PointF(pi, pi)) + .PrependScaleMatrix(new SizeF(pi, pi)) + .PrependSkewMatrixDegrees(pi, pi) + .PrependRotateMatrixDegrees(pi); + + Assert.Equal(b1.BuildMatrix(), b2.BuildMatrix()); + } + + [Fact] + public void BuilderCanClear() + { + var rectangle = new Rectangle(0, 0, 3, 3); + var builder = new AffineTransformBuilder(rectangle); + Matrix3x2 matrix = Matrix3x2.Identity; + matrix.M31 = (float)Math.PI; + + Assert.Equal(Matrix3x2.Identity, builder.BuildMatrix()); + + builder.AppendMatrix(matrix); + Assert.NotEqual(Matrix3x2.Identity, builder.BuildMatrix()); + + builder.Clear(); + Assert.Equal(Matrix3x2.Identity, builder.BuildMatrix()); + } + } +} diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs new file mode 100644 index 000000000..3dfc42d4f --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -0,0 +1,78 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using SixLabors.ImageSharp.Processing; +using SixLabors.Primitives; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Transforms +{ + public class ProjectiveTransformBuilderTests + { + [Fact] + public void ConstructorAssignsProperties() + { + var s = new Size(1, 1); + var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); + Assert.Equal(s, builder.Size); + } + + [Fact] + public void ConstructorThrowsInvalid() + { + Assert.Throws(() => + { + var s = new Size(0, 1); + var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); + }); + + Assert.Throws(() => + { + var s = new Size(1, 0); + var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); + }); + } + + [Fact] + public void AppendPrependOpposite() + { + var rectangle = new Rectangle(-1, -1, 3, 3); + var b1 = new ProjectiveTransformBuilder(rectangle); + var b2 = new ProjectiveTransformBuilder(rectangle); + + const float pi = (float)Math.PI; + + Matrix4x4 m4 = Matrix4x4.Identity; + m4.M31 = pi; + + // Forwards + b1.AppendMatrix(m4) + .AppendTaperMatrix(TaperSide.Left, TaperCorner.LeftOrTop, pi); + + // Backwards + b2.PrependTaperMatrix(TaperSide.Left, TaperCorner.LeftOrTop, pi) + .PrependMatrix(m4); + + Assert.Equal(b1.BuildMatrix(), b2.BuildMatrix()); + } + + [Fact] + public void BuilderCanClear() + { + var rectangle = new Rectangle(0, 0, 3, 3); + var builder = new ProjectiveTransformBuilder(rectangle); + Matrix4x4 matrix = Matrix4x4.Identity; + matrix.M31 = (float)Math.PI; + + Assert.Equal(Matrix4x4.Identity, builder.BuildMatrix()); + + builder.AppendMatrix(matrix); + Assert.NotEqual(Matrix4x4.Identity, builder.BuildMatrix()); + + builder.Clear(); + Assert.Equal(Matrix4x4.Identity, builder.BuildMatrix()); + } + } +} From 3f2953f61118bbdd2b6322ff55c282d57997de61 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Mon, 12 Nov 2018 13:34:17 -0600 Subject: [PATCH 193/238] ImageSharp-762_Aot-compiling: renamed to AotCompilerTools --- src/ImageSharp/Advanced/{AotCompiler.cs => AotCompilerTools.cs} | 2 +- tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/ImageSharp/Advanced/{AotCompiler.cs => AotCompilerTools.cs} (99%) diff --git a/src/ImageSharp/Advanced/AotCompiler.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs similarity index 99% rename from src/ImageSharp/Advanced/AotCompiler.cs rename to src/ImageSharp/Advanced/AotCompilerTools.cs index 406c162ad..9e7624480 100644 --- a/src/ImageSharp/Advanced/AotCompiler.cs +++ b/src/ImageSharp/Advanced/AotCompilerTools.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Advanced /// these are caused because not every possible generic instantiation can be determined up front at compile time. /// The Aot Compiler is designed to overcome the limitations of this compiler. /// - public static class AotCompiler + public static class AotCompilerTools { /// /// Seeds the compiler using the given pixel format. diff --git a/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs index 3d6faa27e..5c1dd4bb0 100644 --- a/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs +++ b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.Advanced [Fact] public void AotCompiler_NoExceptions() { - AotCompiler.Seed(); + AotCompilerTools.Seed(); } } } From 60fe5881e720148bb1b318bb2567c046d1be9bdf Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 12 Nov 2018 20:34:37 +0000 Subject: [PATCH 194/238] Tighten up coverage on new AotCompilerTools --- tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs index 5c1dd4bb0..f6397dbd0 100644 --- a/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs +++ b/tests/ImageSharp.Tests/Advanced/AotCompilerTests.cs @@ -10,9 +10,6 @@ namespace SixLabors.ImageSharp.Tests.Advanced public class AotCompilerTests { [Fact] - public void AotCompiler_NoExceptions() - { - AotCompilerTools.Seed(); - } + public void AotCompiler_NoExceptions() => AotCompilerTools.Seed(); } } From 8e91b7a06b9a30932a952b595fb8a1c7f2f5ffa1 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 13 Nov 2018 09:38:57 +0000 Subject: [PATCH 195/238] Update tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs --- .../Processing/Transforms/AffineTransformTests.cs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index 15b4500bb..3d7fba2c1 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -207,21 +207,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms } } - private Matrix3x2 MakeManuallyCenteredMatrix(float angleDeg, float s, Image image) - where TPixel : struct, IPixel - { - Matrix3x2 rotate = Matrix3x2Extensions.CreateRotationDegrees(angleDeg); - Vector2 toCenter = 0.5f * new Vector2(image.Width, image.Height); - var translate = Matrix3x2.CreateTranslation(-toCenter); - var translateBack = Matrix3x2.CreateTranslation(toCenter); - var scale = Matrix3x2.CreateScale(s); - - Matrix3x2 m = translate * rotate * scale * translateBack; - - this.PrintMatrix(m); - return m; - } - private static IResampler GetResampler(string name) { PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); From b31db43b1156959390ee810164e1a4a3a3510624 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Thu, 1 Nov 2018 16:25:55 -0700 Subject: [PATCH 196/238] Optimize filling a region with a solid brush when antialias is off --- .../Processors/Drawing/FillRegionProcessor.cs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs index 1dc63efa2..170e3d34f 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs @@ -3,7 +3,7 @@ using System; using System.Buffers; - +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Primitives; @@ -168,17 +168,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing { if (!this.Options.Antialias) { + bool hasOnes = false; + bool hasZeros = false; for (int x = 0; x < scanlineWidth; x++) { if (scanline[x] >= 0.5) { scanline[x] = 1; + hasOnes = true; } else { scanline[x] = 0; + hasZeros = true; } } + + if (hasOnes != hasZeros && this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush)) + { + if (hasOnes) + { + source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrush.Color); + } + + continue; + } } applicator.Apply(scanline, minX, y); @@ -187,5 +201,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing } } } + + private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush) + { + solidBrush = this.Brush as SolidBrush; + + if (solidBrush == null) + { + return false; + } + + return this.Options.IsOpaqueColorWithoutBlending(solidBrush.Color); + } } } \ No newline at end of file From 26b2b3d3107a43d361ff50deb79c483331bd910d Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Thu, 15 Nov 2018 08:55:22 -0800 Subject: [PATCH 197/238] Check for solid brush outside of loops --- .../Processing/Processors/Drawing/FillRegionProcessor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs index 170e3d34f..550c021ca 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs @@ -107,6 +107,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing Span buffer = bBuffer.GetSpan(); Span scanline = bScanline.GetSpan(); + bool isSolidBrushWithoutBlending = this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush); + for (int y = minY; y < maxY; y++) { if (scanlineDirty) @@ -184,7 +186,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing } } - if (hasOnes != hasZeros && this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush)) + if (isSolidBrushWithoutBlending && hasOnes != hasZeros) { if (hasOnes) { From 6c2421b21f89485fdf8df80081f94e2a20bd2d73 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 22 Nov 2018 17:09:48 +0000 Subject: [PATCH 198/238] Reduce allocatoins, check bit depth and rename. --- src/ImageSharp/Formats/Png/PngChunkType.cs | 4 +- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 6 +- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 107 ++++++++---------- .../Formats/Png/PngChunkTypeTests.cs | 2 +- .../Formats/Png/PngDecoderTests.Chunks.cs | 2 +- 5 files changed, 56 insertions(+), 65 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngChunkType.cs b/src/ImageSharp/Formats/Png/PngChunkType.cs index 7654c1701..1b251a574 100644 --- a/src/ImageSharp/Formats/Png/PngChunkType.cs +++ b/src/ImageSharp/Formats/Png/PngChunkType.cs @@ -56,10 +56,10 @@ namespace SixLabors.ImageSharp.Formats.Png Text = 0x74455874U, /// - /// This chunk specifies that the image uses simple transparency: + /// The tRNS chunk specifies that the image uses simple transparency: /// either alpha values associated with palette entries (for indexed-color images) /// or a single transparent color (for grayscale and true color images). /// - PaletteAlpha = 0x74524E53U + Transparency = 0x74524E53U } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index c446184d8..9ffac5e62 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Formats.Png Buffer.BlockCopy(chunk.Data.Array, 0, pal, 0, chunk.Length); this.palette = pal; break; - case PngChunkType.PaletteAlpha: + case PngChunkType.Transparency: byte[] alpha = new byte[chunk.Length]; Buffer.BlockCopy(chunk.Data.Array, 0, alpha, 0, chunk.Length); this.paletteAlpha = alpha; @@ -306,9 +306,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] private static byte ReadByteLittleEndian(ReadOnlySpan buffer, int offset) - { - return (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF)); - } + => (byte)(((buffer[offset] & 0xFF) << 16) | (buffer[offset + 1] & 0xFF)); /// /// Attempts to convert a byte array to a new array where each value in the original array is represented by the diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 532e6f747..8a31aaf51 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -292,7 +292,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (pngMetaData.HasTrans) { - this.WriteTransparencyMarkers(stream, pngMetaData); + this.WriteTransparencyChunk(stream, pngMetaData); } this.WritePhysicalChunk(stream, metaData); @@ -305,52 +305,6 @@ namespace SixLabors.ImageSharp.Formats.Png quantized?.Dispose(); } - /// - /// Writes the transparency markers to the stream - /// - /// The containing image data. - /// The image meta data. - private void WriteTransparencyMarkers(Stream stream, PngMetaData pngMetaData) - { - if (pngMetaData.ColorType == PngColorType.Rgb) - { - if (pngMetaData.TransparentRgb48 != null) - { - var r = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.R); - var g = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.R); - var b = BitConverter.GetBytes(pngMetaData.TransparentRgb48.Value.B); - - var alphaArray = r.Concat(g).Concat(b).ToArray(); - - this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); - } - else if (pngMetaData.TransparentRgb24 != null) - { - var alphaArray = new byte[6]; - alphaArray[1] = pngMetaData.TransparentRgb24.Value.R; - alphaArray[3] = pngMetaData.TransparentRgb24.Value.G; - alphaArray[5] = pngMetaData.TransparentRgb24.Value.B; - this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); - } - } - else if (pngMetaData.ColorType == PngColorType.Grayscale) - { - if (pngMetaData.TransparentGray16 != null) - { - var alphaArray = BitConverter.GetBytes(pngMetaData.TransparentGray16.Value.PackedValue); - - this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); - } - else if (pngMetaData.TransparentGray8 != null) - { - var alphaArray = new byte[2]; - alphaArray[1] = pngMetaData.TransparentGray8.Value.PackedValue; - - this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length); - } - } - } - /// public void Dispose() { @@ -377,7 +331,6 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.pngColorType.Equals(PngColorType.Grayscale)) { - // TODO: Research and add support for grayscale plus tRNS if (this.use16Bit) { // 16 bit grayscale @@ -752,7 +705,7 @@ namespace SixLabors.ImageSharp.Formats.Png // Write the transparency data if (anyAlpha) { - this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaTable.Array, 0, paletteLength); + this.WriteChunk(stream, PngChunkType.Transparency, alphaTable.Array, 0, paletteLength); } } } @@ -800,6 +753,52 @@ namespace SixLabors.ImageSharp.Formats.Png } } + /// + /// Writes the transparency chunk to the stream + /// + /// The containing image data. + /// The image meta data. + private void WriteTransparencyChunk(Stream stream, PngMetaData pngMetaData) + { + if (pngMetaData.ColorType.Equals(PngColorType.Rgb)) + { + Span alpha = this.buffer.AsSpan(); + if (pngMetaData.TransparentRgb48.HasValue && this.use16Bit) + { + Rgb48 rgb = pngMetaData.TransparentRgb48.Value; + BinaryPrimitives.WriteUInt16LittleEndian(alpha, rgb.R); + BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(2, 2), rgb.G); + BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(4, 2), rgb.B); + + this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6); + } + else if (pngMetaData.TransparentRgb24.HasValue) + { + alpha.Clear(); + Rgb24 rgb = pngMetaData.TransparentRgb24.Value; + alpha[1] = rgb.R; + alpha[3] = rgb.G; + alpha[5] = rgb.B; + this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6); + } + } + else if (pngMetaData.ColorType.Equals(PngColorType.Grayscale)) + { + Span alpha = this.buffer.AsSpan(); + if (pngMetaData.TransparentGray16.HasValue && this.bitDepth == 16) + { + BinaryPrimitives.WriteUInt16LittleEndian(alpha, pngMetaData.TransparentGray16.Value.PackedValue); + this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2); + } + else if (pngMetaData.TransparentGray8.HasValue) + { + alpha.Clear(); + alpha[1] = pngMetaData.TransparentGray8.Value.PackedValue; + this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2); + } + } + } + /// /// Writes the pixel information to the stream. /// @@ -894,10 +893,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// Writes the chunk end to the stream. /// /// The containing image data. - private void WriteEndChunk(Stream stream) - { - this.WriteChunk(stream, PngChunkType.End, null); - } + private void WriteEndChunk(Stream stream) => this.WriteChunk(stream, PngChunkType.End, null); /// /// Writes a chunk to the stream. @@ -905,10 +901,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// The to write to. /// The type of chunk to write. /// The containing data. - private void WriteChunk(Stream stream, PngChunkType type, byte[] data) - { - this.WriteChunk(stream, type, data, 0, data?.Length ?? 0); - } + private void WriteChunk(Stream stream, PngChunkType type, byte[] data) => this.WriteChunk(stream, type, data, 0, data?.Length ?? 0); /// /// Writes a chunk of a specified length to the stream at the given offset. diff --git a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs index e4cd06ab1..894d902b7 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngChunkTypeTests.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Equal(PngChunkType.Palette, GetType("PLTE")); Assert.Equal(PngChunkType.Data, GetType("IDAT")); Assert.Equal(PngChunkType.End, GetType("IEND")); - Assert.Equal(PngChunkType.PaletteAlpha, GetType("tRNS")); + Assert.Equal(PngChunkType.Transparency, GetType("tRNS")); Assert.Equal(PngChunkType.Text, GetType("tEXt")); Assert.Equal(PngChunkType.Gamma, GetType("gAMA")); Assert.Equal(PngChunkType.Physical, GetType("pHYs")); diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs index 2a7d69616..6a0119f0f 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [Theory] [InlineData((uint)PngChunkType.Gamma)] // gAMA - [InlineData((uint)PngChunkType.PaletteAlpha)] // tRNS + [InlineData((uint)PngChunkType.Transparency)] // tRNS [InlineData((uint)PngChunkType.Physical)] // pHYs: It's ok to test physical as we don't throw for duplicate chunks. //[InlineData(PngChunkTypes.Text)] //TODO: Figure out how to test this public void Decode_IncorrectCRCForNonCriticalChunk_ExceptionIsThrown(uint chunkType) From 9fbc8ed3df4c61a9e248865af3d758e222435c16 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 22 Nov 2018 17:12:43 +0000 Subject: [PATCH 199/238] Use existing field --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 8a31aaf51..bb800c8a4 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -785,7 +785,7 @@ namespace SixLabors.ImageSharp.Formats.Png else if (pngMetaData.ColorType.Equals(PngColorType.Grayscale)) { Span alpha = this.buffer.AsSpan(); - if (pngMetaData.TransparentGray16.HasValue && this.bitDepth == 16) + if (pngMetaData.TransparentGray16.HasValue && this.use16Bit) { BinaryPrimitives.WriteUInt16LittleEndian(alpha, pngMetaData.TransparentGray16.Value.PackedValue); this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2); From 3235ce41b82afba33cc4fabc5675f609b6c2e2fb Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 23 Nov 2018 12:25:05 +0000 Subject: [PATCH 200/238] Fix trns preservation and add tests --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 11 ++- src/ImageSharp/Formats/Png/PngMetaData.cs | 5 ++ .../Formats/Png/PngEncoderTests.cs | 67 +++++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 3 + tests/Images/Input/Png/gray-2-tRNS.png | 3 + tests/Images/Input/Png/gray-4-tRNS.png | 3 + tests/Images/Input/Png/gray-8-tRNS.png | 3 + 7 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 tests/Images/Input/Png/gray-2-tRNS.png create mode 100644 tests/Images/Input/Png/gray-4-tRNS.png create mode 100644 tests/Images/Input/Png/gray-8-tRNS.png diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index bb800c8a4..292de007c 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -760,9 +760,9 @@ namespace SixLabors.ImageSharp.Formats.Png /// The image meta data. private void WriteTransparencyChunk(Stream stream, PngMetaData pngMetaData) { + Span alpha = this.chunkDataBuffer.AsSpan(); if (pngMetaData.ColorType.Equals(PngColorType.Rgb)) { - Span alpha = this.buffer.AsSpan(); if (pngMetaData.TransparentRgb48.HasValue && this.use16Bit) { Rgb48 rgb = pngMetaData.TransparentRgb48.Value; @@ -770,7 +770,7 @@ namespace SixLabors.ImageSharp.Formats.Png BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(2, 2), rgb.G); BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(4, 2), rgb.B); - this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6); + this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6); } else if (pngMetaData.TransparentRgb24.HasValue) { @@ -779,22 +779,21 @@ namespace SixLabors.ImageSharp.Formats.Png alpha[1] = rgb.R; alpha[3] = rgb.G; alpha[5] = rgb.B; - this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6); + this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6); } } else if (pngMetaData.ColorType.Equals(PngColorType.Grayscale)) { - Span alpha = this.buffer.AsSpan(); if (pngMetaData.TransparentGray16.HasValue && this.use16Bit) { BinaryPrimitives.WriteUInt16LittleEndian(alpha, pngMetaData.TransparentGray16.Value.PackedValue); - this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2); + this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2); } else if (pngMetaData.TransparentGray8.HasValue) { alpha.Clear(); alpha[1] = pngMetaData.TransparentGray8.Value.PackedValue; - this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2); + this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2); } } } diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs index 6a293f770..d5ab3d255 100644 --- a/src/ImageSharp/Formats/Png/PngMetaData.cs +++ b/src/ImageSharp/Formats/Png/PngMetaData.cs @@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Formats.Png this.BitDepth = other.BitDepth; this.ColorType = other.ColorType; this.Gamma = other.Gamma; + this.HasTrans = other.HasTrans; + this.TransparentGray8 = other.TransparentGray8; + this.TransparentGray16 = other.TransparentGray16; + this.TransparentRgb24 = other.TransparentRgb24; + this.TransparentRgb48 = other.TransparentRgb48; } /// diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index 5d328db36..9079b15fb 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -25,6 +25,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png { TestImages.Png.Bpp1, PngBitDepth.Bit1 } }; + public static readonly TheoryData PngTrnsFiles = + new TheoryData + { + { TestImages.Png.Gray1BitTrans, PngBitDepth.Bit1, PngColorType.Grayscale }, + { TestImages.Png.Gray2BitTrans, PngBitDepth.Bit2, PngColorType.Grayscale }, + { TestImages.Png.Gray4BitTrans, PngBitDepth.Bit4, PngColorType.Grayscale }, + { TestImages.Png.Gray8BitTrans, PngBitDepth.Bit8, PngColorType.Grayscale }, + { TestImages.Png.GrayTrns16BitInterlaced, PngBitDepth.Bit16, PngColorType.Grayscale }, + { TestImages.Png.Rgb24BppTrans, PngBitDepth.Bit8, PngColorType.Rgb }, + { TestImages.Png.Rgb48BppTrans, PngBitDepth.Bit16, PngColorType.Rgb } + }; + /// /// All types except Palette /// @@ -249,6 +261,61 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } } + [Theory] + [MemberData(nameof(PngTrnsFiles))] + public void Encode_PreserveTrns(string imagePath, PngBitDepth pngBitDepth, PngColorType pngColorType) + { + var options = new PngEncoder(); + + var testFile = TestFile.Create(imagePath); + using (Image input = testFile.CreateImage()) + { + PngMetaData inMeta = input.MetaData.GetFormatMetaData(PngFormat.Instance); + Assert.True(inMeta.HasTrans); + + using (var memStream = new MemoryStream()) + { + input.Save(memStream, options); + memStream.Position = 0; + using (var output = Image.Load(memStream)) + { + PngMetaData outMeta = output.MetaData.GetFormatMetaData(PngFormat.Instance); + Assert.True(outMeta.HasTrans); + + switch (pngColorType) + { + case PngColorType.Grayscale: + if (pngBitDepth.Equals(PngBitDepth.Bit16)) + { + Assert.True(outMeta.TransparentGray16.HasValue); + Assert.Equal(inMeta.TransparentGray16, outMeta.TransparentGray16); + } + else + { + Assert.True(outMeta.TransparentGray8.HasValue); + Assert.Equal(inMeta.TransparentGray8, outMeta.TransparentGray8); + } + + break; + case PngColorType.Rgb: + if (pngBitDepth.Equals(PngBitDepth.Bit16)) + { + Assert.True(outMeta.TransparentRgb48.HasValue); + Assert.Equal(inMeta.TransparentRgb48, outMeta.TransparentRgb48); + } + else + { + Assert.True(outMeta.TransparentRgb24.HasValue); + Assert.Equal(inMeta.TransparentRgb24, outMeta.TransparentRgb24); + } + + break; + } + } + } + } + } + private static void TestPngEncoderCore( TestImageProvider provider, PngColorType pngColorType, diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 8da458e52..1144a3f7c 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -46,6 +46,9 @@ namespace SixLabors.ImageSharp.Tests public const string PDSrc = "Png/pd-source.png"; public const string PDDest = "Png/pd-dest.png"; public const string Gray1BitTrans = "Png/gray-1-trns.png"; + public const string Gray2BitTrans = "Png/gray-2-tRNS.png"; + public const string Gray4BitTrans = "Png/gray-4-tRNS.png"; + public const string Gray8BitTrans = "Png/gray-8-tRNS.png"; // Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html public const string Filter0 = "Png/filter0.png"; diff --git a/tests/Images/Input/Png/gray-2-tRNS.png b/tests/Images/Input/Png/gray-2-tRNS.png new file mode 100644 index 000000000..d5657ac34 --- /dev/null +++ b/tests/Images/Input/Png/gray-2-tRNS.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c36d10c8498bbe148bc44d41e0243137e47b07402dfb8e58978d1a9b5029cabc +size 265 diff --git a/tests/Images/Input/Png/gray-4-tRNS.png b/tests/Images/Input/Png/gray-4-tRNS.png new file mode 100644 index 000000000..01c1b6992 --- /dev/null +++ b/tests/Images/Input/Png/gray-4-tRNS.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:217248c079a0ed7896803a2bf5d9719b6060ef898314a5f6ab898c6c4349f341 +size 267 diff --git a/tests/Images/Input/Png/gray-8-tRNS.png b/tests/Images/Input/Png/gray-8-tRNS.png new file mode 100644 index 000000000..9b0b78ce5 --- /dev/null +++ b/tests/Images/Input/Png/gray-8-tRNS.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e14dce9350fc40f7ee542d1dc788fbf6c1c0178515ea8b76ffa0b18bcf54e8a +size 267 From 9afad9bd7c130e5af3b1f004d45434e90093a8b3 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 25 Nov 2018 22:52:47 +0100 Subject: [PATCH 201/238] add more tests --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 15 +- .../Processing/AffineTransformBuilder.cs | 35 ++-- .../Processors/Transforms/TransformUtils.cs | 11 ++ .../Transforms/AffineTransformBuilderTests.cs | 67 +++----- .../Transforms/TransformBuilderTestBase.cs | 151 ++++++++++++++++++ .../TestUtilities/ApproximateFloatComparer.cs | 13 +- 6 files changed, 234 insertions(+), 58 deletions(-) create mode 100644 tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index f07ccb03b..45556741e 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -22,7 +22,8 @@ namespace SixLabors.ImageSharp /// The blue component. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static byte Get8BitBT709Luminance(byte r, byte g, byte b) => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5f); + public static byte Get8BitBT709Luminance(byte r, byte g, byte b) => + (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5f); /// /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709. @@ -32,7 +33,8 @@ namespace SixLabors.ImageSharp /// The blue component. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F)); + public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) => + (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F)); /// /// Scales a value from a 16 bit to it's 8 bit equivalent. @@ -128,6 +130,15 @@ namespace SixLabors.ImageSharp return x & (m - 1); } + /// + /// Converts degrees to radians + /// + [MethodImpl(InliningOptions.ShortMethod)] + public static float ToRadian(float degrees) + { + return degrees * ((float)Math.PI / 180f); + } + /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. /// diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 003249d6e..4d798f439 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -14,18 +14,15 @@ namespace SixLabors.ImageSharp.Processing public class AffineTransformBuilder { private readonly List matrices = new List(); - private Rectangle rectangle; + private readonly Rectangle rectangle; /// /// Initializes a new instance of the class. /// /// The source image size. public AffineTransformBuilder(Size sourceSize) + : this(new Rectangle(Point.Empty, sourceSize)) { - Guard.MustBeGreaterThan(sourceSize.Width, 0, nameof(sourceSize)); - Guard.MustBeGreaterThan(sourceSize.Height, 0, nameof(sourceSize)); - - this.Size = sourceSize; } /// @@ -33,13 +30,17 @@ namespace SixLabors.ImageSharp.Processing /// /// The source rectangle. public AffineTransformBuilder(Rectangle sourceRectangle) - : this(sourceRectangle.Size) - => this.rectangle = sourceRectangle; + { + Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); + Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); + + this.rectangle = sourceRectangle; + } /// /// Gets the source image size. /// - internal Size Size { get; } + internal Size Size => this.rectangle.Size; /// /// Prepends a centered rotation matrix using the given rotation in degrees. @@ -49,13 +50,29 @@ namespace SixLabors.ImageSharp.Processing public AffineTransformBuilder PrependRotateMatrixDegrees(float degrees) => this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + /// + /// Prepends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The . + public AffineTransformBuilder PrependRotateMatrixRadians(float radians) + => this.PrependMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + /// /// Appends a centered rotation matrix using the given rotation in degrees. /// /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder AppendRotateMatrixDegrees(float degrees) - => this.AppendMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + => this.AppendRotateMatrixRadians(ImageMaths.ToRadian(degrees)); + + /// + /// Appends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The . + public AffineTransformBuilder AppendRotateMatrixRadians(float radians) + => this.AppendMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); /// /// Prepends a scale matrix from the given vector scale. diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index f561d3513..6cef38f8f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -23,6 +23,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty)); + /// + /// Creates a centered rotation matrix using the given rotation in radians and the source size. + /// + /// The amount of rotation, in radians. + /// The source image size. + /// The . + public static Matrix3x2 CreateRotationMatrixRadians(float radians, Size size) + => CreateCenteredTransformMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateRotation(radians, PointF.Empty)); + /// /// Creates a centered skew matrix from the give angles in degrees and the source size. /// diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index eaa51b129..1b4caee14 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -4,12 +4,13 @@ using System; using System.Numerics; using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; using Xunit; namespace SixLabors.ImageSharp.Tests.Processing.Transforms { - public class AffineTransformBuilderTests + public class AffineTransformBuilderTests : TransformBuilderTestBase { [Fact] public void ConstructorAssignsProperties() @@ -23,57 +24,33 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void ConstructorThrowsInvalid() { Assert.Throws(() => - { - var s = new Size(0, 1); - var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); - }); + { + var s = new Size(0, 1); + var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); + }); Assert.Throws(() => - { - var s = new Size(1, 0); - var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); - }); + { + var s = new Size(1, 0); + var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); + }); } - [Fact] - public void AppendPrependOpposite() - { - var rectangle = new Rectangle(-1, -1, 3, 3); - var b1 = new AffineTransformBuilder(rectangle); - var b2 = new AffineTransformBuilder(rectangle); - - const float pi = (float)Math.PI; - - // Forwards - b1.AppendRotateMatrixDegrees(pi) - .AppendSkewMatrixDegrees(pi, pi) - .AppendScaleMatrix(new SizeF(pi, pi)) - .AppendTranslationMatrix(new PointF(pi, pi)); - - // Backwards - b2.PrependTranslationMatrix(new PointF(pi, pi)) - .PrependScaleMatrix(new SizeF(pi, pi)) - .PrependSkewMatrixDegrees(pi, pi) - .PrependRotateMatrixDegrees(pi); + protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslationMatrix(translate); + protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScaleMatrix(scale); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotateMatrixRadians(radians); - Assert.Equal(b1.BuildMatrix(), b2.BuildMatrix()); - } + protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslationMatrix(translate); + protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScaleMatrix(scale); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotateMatrixRadians(radians); - [Fact] - public void BuilderCanClear() + protected override Vector2 Execute( + AffineTransformBuilder builder, + Rectangle rectangle, + Vector2 sourcePoint) { - var rectangle = new Rectangle(0, 0, 3, 3); - var builder = new AffineTransformBuilder(rectangle); - Matrix3x2 matrix = Matrix3x2.Identity; - matrix.M31 = (float)Math.PI; - - Assert.Equal(Matrix3x2.Identity, builder.BuildMatrix()); - - builder.AppendMatrix(matrix); - Assert.NotEqual(Matrix3x2.Identity, builder.BuildMatrix()); - - builder.Clear(); - Assert.Equal(Matrix3x2.Identity, builder.BuildMatrix()); + Matrix3x2 matrix = builder.BuildMatrix(); + return Vector2.Transform(sourcePoint, matrix); } } } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs new file mode 100644 index 000000000..d109387cc --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -0,0 +1,151 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Transforms; +using SixLabors.Primitives; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Transforms +{ + public abstract class TransformBuilderTestBase + { + private static readonly ApproximateFloatComparer Comparer = new ApproximateFloatComparer(1e-6f); + + public static readonly TheoryData ScaleTranslate_Data = + new TheoryData + { + // scale, translate, source, expectedDest + + { Vector2.One, Vector2.Zero, Vector2.Zero, Vector2.Zero }, + { Vector2.One, Vector2.Zero, new Vector2(10, 20), new Vector2(10, 20) }, + { Vector2.One, new Vector2(3, 1), new Vector2(10, 20), new Vector2(13, 21) }, + { new Vector2(2, 0.5f), new Vector2(3, 1), new Vector2(10, 20), new Vector2(23, 11) }, + }; + + [Theory] + [MemberData(nameof(ScaleTranslate_Data))] + public void _1Scale_2Translate(Vector2 scale, Vector2 translate, Vector2 source, Vector2 expectedDest) + { + // These operations should be size-agnostic: + var size = new Size(123, 321); + TBuilder builder = this.CreateBuilder(size); + + this.AppendScale(builder, new SizeF(scale)); + this.AppendTranslation(builder, translate); + + Vector2 actualDest = this.Execute(builder, new Rectangle(Point.Empty, size), source); + Assert.True(Comparer.Equals(expectedDest, actualDest)); + } + + public static readonly TheoryData TranslateScale_Data = + new TheoryData + { + // translate, scale, source, expectedDest + + { Vector2.Zero, Vector2.One, Vector2.Zero, Vector2.Zero }, + { Vector2.Zero, Vector2.One, new Vector2(10, 20), new Vector2(10, 20) }, + { new Vector2(3, 1), new Vector2(2, 0.5f), new Vector2(10, 20), new Vector2(26, 10.5f) }, + }; + + [Theory] + [MemberData(nameof(TranslateScale_Data))] + public void _1Translate_2Scale(Vector2 translate, Vector2 scale, Vector2 source, Vector2 expectedDest) + { + // Translate ans scale are size-agnostic: + var size = new Size(456, 432); + TBuilder builder = this.CreateBuilder(size); + + this.AppendTranslation(builder, translate); + this.AppendScale(builder, new SizeF(scale)); + + Vector2 actualDest = this.Execute(builder, new Rectangle(Point.Empty, size), source); + Assert.Equal(expectedDest, actualDest, Comparer); + } + + [Theory] + [InlineData(10, 20)] + [InlineData(-20, 10)] + public void LocationOffsetIsPrepended(int locationX, int locationY) + { + var rectangle = new Rectangle(locationX, locationY, 10, 10); + TBuilder builder = this.CreateBuilder(rectangle); + + this.AppendScale(builder, new SizeF(2, 2)); + + Vector2 actual = this.Execute(builder, rectangle, Vector2.One); + Vector2 expected = new Vector2(-locationX + 1, -locationY + 1) * 2; + + Assert.Equal(actual, expected, Comparer); + } + + [Theory] + [InlineData(200, 100, 10, 42, 84)] + [InlineData(200, 100, 100, 42, 84)] + [InlineData(100, 200, -10, 42, 84)] + public void RotateDegrees_ShouldCreateCenteredMatrix(int width, int height, float deg, float x, float y) + { + var size = new Size(width, height); + TBuilder builder = this.CreateBuilder(size); + + this.AppendRotationDegrees(builder, deg); + + // TODO: We should also test CreateRotationMatrixDegrees() (and all TransformUtils stuff!) for correctness + Matrix3x2 matrix = TransformUtils.CreateRotationMatrixDegrees(deg, size); + + var position = new Vector2(x, y); + var expected = Vector2.Transform(position, matrix); + Vector2 actual = this.Execute(builder, new Rectangle(Point.Empty, size), position); + + Assert.Equal(actual, expected, Comparer); + } + + [Fact] + public void AppendPrependOpposite() + { + var rectangle = new Rectangle(-1, -1, 3, 3); + TBuilder b1 = this.CreateBuilder(rectangle); + TBuilder b2 = this.CreateBuilder(rectangle); + + const float pi = (float)Math.PI; + + // Forwards + this.AppendRotationRadians(b1, pi); + this.AppendScale(b1, new SizeF(2, 0.5f)); + this.AppendTranslation(b1, new PointF(123, 321)); + + // Backwards + this.PrependTranslation(b2, new PointF(123, 321)); + this.PrependScale(b2, new SizeF(2, 0.5f)); + this.PrependRotationRadians(b2, pi); + + Vector2 p1 = this.Execute(b1, rectangle, new Vector2(32, 65)); + Vector2 p2 = this.Execute(b2, rectangle, new Vector2(32, 65)); + + Assert.Equal(p1, p2, Comparer); + } + + protected TBuilder CreateBuilder(Size size) => this.CreateBuilder(new Rectangle(Point.Empty, size)); + + protected virtual TBuilder CreateBuilder(Rectangle rectangle) => (TBuilder)Activator.CreateInstance(typeof(TBuilder), rectangle); + + protected abstract void AppendTranslation(TBuilder builder, PointF translate); + protected abstract void AppendScale(TBuilder builder, SizeF scale); + protected abstract void AppendRotationRadians(TBuilder builder, float radians); + + protected abstract void PrependTranslation(TBuilder builder, PointF translate); + protected abstract void PrependScale(TBuilder builder, SizeF scale); + protected abstract void PrependRotationRadians(TBuilder builder, float radians); + + protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => + this.AppendRotationRadians(builder, ImageMaths.ToRadian(degrees)); + + protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); + + private static float Sqrt(float a) => (float)Math.Sqrt(a); + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs index 854e57d8f..47ca6cccb 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs @@ -11,7 +11,8 @@ namespace SixLabors.ImageSharp.Tests /// internal readonly struct ApproximateFloatComparer : IEqualityComparer, - IEqualityComparer + IEqualityComparer, + IEqualityComparer { private readonly float Epsilon; @@ -33,9 +34,17 @@ namespace SixLabors.ImageSharp.Tests public int GetHashCode(float obj) => obj.GetHashCode(); /// - public bool Equals(Vector4 x, Vector4 y) => this.Equals(x.X, y.X) && this.Equals(x.Y, y.Y) && this.Equals(x.Z, y.Z) && this.Equals(x.W, y.W); + public bool Equals(Vector4 a, Vector4 b) => this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z) && this.Equals(a.W, b.W); /// public int GetHashCode(Vector4 obj) => obj.GetHashCode(); + + /// + public bool Equals(Vector2 a, Vector2 b) => this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y); + + public int GetHashCode(Vector2 obj) + { + throw new System.NotImplementedException(); + } } } \ No newline at end of file From 918395681348180ec89c32474080aeae7df6fba4 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 25 Nov 2018 23:07:50 +0100 Subject: [PATCH 202/238] rename methods + extend API --- .../Processing/AffineTransformBuilder.cs | 78 +++++++++++++++---- .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 6 +- .../Transforms/AffineTransformBuilderTests.cs | 12 +-- .../Transforms/AffineTransformTests.cs | 20 ++--- 4 files changed, 82 insertions(+), 34 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 4d798f439..1620b7223 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Processing /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder PrependRotateMatrixDegrees(float degrees) + public AffineTransformBuilder PrependRotationDegrees(float degrees) => this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); /// @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Processing /// /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder PrependRotateMatrixRadians(float radians) + public AffineTransformBuilder PrependRotationRadians(float radians) => this.PrependMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); /// @@ -63,32 +63,64 @@ namespace SixLabors.ImageSharp.Processing /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder AppendRotateMatrixDegrees(float degrees) - => this.AppendRotateMatrixRadians(ImageMaths.ToRadian(degrees)); + public AffineTransformBuilder AppendRotationDegrees(float degrees) + => this.AppendRotationRadians(ImageMaths.ToRadian(degrees)); /// /// Appends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder AppendRotateMatrixRadians(float radians) + public AffineTransformBuilder AppendRotationRadians(float radians) => this.AppendMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + /// + /// Prepends a scale matrix from the given uniform scale. + /// + /// The uniform scale. + /// The . + public AffineTransformBuilder PrependScale(float scale) + => this.PrependMatrix(Matrix3x2.CreateScale(scale)); + + /// + /// Appends a scale matrix from the given uniform scale. + /// + /// The uniform scale. + /// The . + public AffineTransformBuilder AppendScale(float scale) + => this.AppendMatrix(Matrix3x2.CreateScale(scale)); + /// /// Prepends a scale matrix from the given vector scale. /// /// The horizontal and vertical scale. /// The . - public AffineTransformBuilder PrependScaleMatrix(SizeF scales) - => this.PrependMatrix(Matrix3x2Extensions.CreateScale(scales)); + public AffineTransformBuilder PrependScale(Vector2 scales) + => this.PrependMatrix(Matrix3x2.CreateScale(scales)); /// /// Appends a scale matrix from the given vector scale. /// /// The horizontal and vertical scale. /// The . - public AffineTransformBuilder AppendScaleMatrix(SizeF scales) - => this.AppendMatrix(Matrix3x2Extensions.CreateScale(scales)); + public AffineTransformBuilder AppendScale(Vector2 scales) + => this.AppendMatrix(Matrix3x2.CreateScale(scales)); + + /// + /// Prepends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public AffineTransformBuilder PrependScale(SizeF scale) + => this.PrependScale((Vector2)scale); + + /// + /// Appends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public AffineTransformBuilder AppendScale(SizeF scales) + => this.AppendScale((Vector2)scales); /// /// Prepends a centered skew matrix from the give angles in degrees. @@ -96,7 +128,7 @@ namespace SixLabors.ImageSharp.Processing /// The X angle, in degrees. /// The Y angle, in degrees. /// The . - public AffineTransformBuilder PrependSkewMatrixDegrees(float degreesX, float degreesY) + public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) => this.PrependMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); /// @@ -105,7 +137,7 @@ namespace SixLabors.ImageSharp.Processing /// The X angle, in degrees. /// The Y angle, in degrees. /// The . - public AffineTransformBuilder AppendSkewMatrixDegrees(float degreesX, float degreesY) + public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) => this.AppendMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); /// @@ -113,16 +145,32 @@ namespace SixLabors.ImageSharp.Processing /// /// The translation position. /// The . - public AffineTransformBuilder PrependTranslationMatrix(PointF position) - => this.PrependMatrix(Matrix3x2Extensions.CreateTranslation(position)); + public AffineTransformBuilder PrependTranslation(PointF position) + => this.PrependTranslation((Vector2)position); + + /// + /// Appends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public AffineTransformBuilder AppendTranslation(PointF position) + => this.AppendTranslation((Vector2)position); + + /// + /// Prepends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public AffineTransformBuilder PrependTranslation(Vector2 position) + => this.PrependMatrix(Matrix3x2.CreateTranslation(position)); /// /// Appends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder AppendTranslationMatrix(PointF position) - => this.AppendMatrix(Matrix3x2Extensions.CreateTranslation(position)); + public AffineTransformBuilder AppendTranslation(Vector2 position) + => this.AppendMatrix(Matrix3x2.CreateTranslation(position)); /// /// Prepends a raw matrix. diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 564318e5e..a29342ad4 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -74,9 +74,9 @@ namespace SixLabors.ImageSharp.Tests using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { AffineTransformBuilder builder = new AffineTransformBuilder(blend.Size()) - .AppendRotateMatrixDegrees(45F) - .AppendScaleMatrix(new SizeF(.25F, .25F)) - .AppendTranslationMatrix(new PointF(10, 10)); + .AppendRotationDegrees(45F) + .AppendScale(new SizeF(.25F, .25F)) + .AppendTranslation(new PointF(10, 10)); // Apply a background color so we can see the translation. blend.Mutate(x => x.Transform(builder).BackgroundColor(NamedColors.HotPink)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index 1b4caee14..639f4b46f 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -36,13 +36,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms }); } - protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslationMatrix(translate); - protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScaleMatrix(scale); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotateMatrixRadians(radians); + protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); - protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslationMatrix(translate); - protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScaleMatrix(scale); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotateMatrixRadians(radians); + protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); protected override Vector2 Execute( AffineTransformBuilder builder, diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index 3d7fba2c1..e78bb2c6d 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotateMatrixDegrees(30); + .AppendRotationDegrees(30); image.Mutate(c => c.Transform(builder, resampler)); image.DebugSave(provider, resamplerName); @@ -102,9 +102,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { image.DebugSave(provider, $"_original"); AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotateMatrixDegrees(angleDeg) - .AppendScaleMatrix(new SizeF(sx, sy)) - .AppendTranslationMatrix(new PointF(tx, ty)); + .AppendRotationDegrees(angleDeg) + .AppendScale(new SizeF(sx, sy)) + .AppendTranslation(new PointF(tx, ty)); this.PrintMatrix(builder.BuildMatrix()); @@ -124,8 +124,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotateMatrixDegrees(angleDeg) - .AppendScaleMatrix(new SizeF(s, s)); + .AppendRotationDegrees(angleDeg) + .AppendScale(new SizeF(s, s)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { image.DebugSave(provider, $"_original"); AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) - .AppendScaleMatrix(new SizeF(2, 1.5F)); + .AppendScale(new SizeF(2, 1.5F)); image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); @@ -179,7 +179,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) - .AppendScaleMatrix(new SizeF(1F, 2F)); + .AppendScale(new SizeF(1F, 2F)); image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); @@ -197,8 +197,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotateMatrixDegrees(50) - .AppendScaleMatrix(new SizeF(.6F, .6F)); + .AppendRotationDegrees(50) + .AppendScale(new SizeF(.6F, .6F)); image.Mutate(i => i.Transform(builder, sampler)); From 1f330306db7c7cf72b75746e88d3e885eb0722eb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 25 Nov 2018 23:18:17 +0100 Subject: [PATCH 203/238] Translation, Scale -> ProjectiveTransformBuilder --- .../Processing/AffineTransformBuilder.cs | 26 ++-- .../Processing/ProjectiveTransformBuilder.cs | 113 ++++++++++++++++-- .../ProjectiveTransformBuilderTests.cs | 54 +++------ 3 files changed, 131 insertions(+), 62 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 1620b7223..cd66272b4 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Processing public class AffineTransformBuilder { private readonly List matrices = new List(); - private readonly Rectangle rectangle; + private readonly Rectangle sourceRectangle; /// /// Initializes a new instance of the class. @@ -34,13 +34,13 @@ namespace SixLabors.ImageSharp.Processing Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); - this.rectangle = sourceRectangle; + this.sourceRectangle = sourceRectangle; } /// /// Gets the source image size. /// - internal Size Size => this.rectangle.Size; + internal Size Size => this.sourceRectangle.Size; /// /// Prepends a centered rotation matrix using the given rotation in degrees. @@ -145,32 +145,32 @@ namespace SixLabors.ImageSharp.Processing /// /// The translation position. /// The . - public AffineTransformBuilder PrependTranslation(PointF position) - => this.PrependTranslation((Vector2)position); + public AffineTransformBuilder PrependTranslation(Vector2 position) + => this.PrependMatrix(Matrix3x2.CreateTranslation(position)); /// /// Appends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder AppendTranslation(PointF position) - => this.AppendTranslation((Vector2)position); + public AffineTransformBuilder AppendTranslation(Vector2 position) + => this.AppendMatrix(Matrix3x2.CreateTranslation(position)); /// /// Prepends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder PrependTranslation(Vector2 position) - => this.PrependMatrix(Matrix3x2.CreateTranslation(position)); + public AffineTransformBuilder PrependTranslation(PointF position) + => this.PrependTranslation((Vector2)position); /// /// Appends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder AppendTranslation(Vector2 position) - => this.AppendMatrix(Matrix3x2.CreateTranslation(position)); + public AffineTransformBuilder AppendTranslation(PointF position) + => this.AppendTranslation((Vector2)position); /// /// Prepends a raw matrix. @@ -203,9 +203,9 @@ namespace SixLabors.ImageSharp.Processing Matrix3x2 matrix = Matrix3x2.Identity; // Translate the origin matrix to cater for source rectangle offsets. - if (!this.rectangle.Equals(default)) + if (!this.sourceRectangle.Equals(default)) { - matrix *= Matrix3x2.CreateTranslation(-this.rectangle.Location); + matrix *= Matrix3x2.CreateTranslation(-this.sourceRectangle.Location); } foreach (Matrix3x2 m in this.matrices) diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index be4c67518..6c5fb4625 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -14,18 +14,15 @@ namespace SixLabors.ImageSharp.Processing public class ProjectiveTransformBuilder { private readonly List matrices = new List(); - private Rectangle rectangle; + private Rectangle sourceRectangle; /// /// Initializes a new instance of the class. /// /// The source image size. public ProjectiveTransformBuilder(Size sourceSize) + : this(new Rectangle(Point.Empty, sourceSize)) { - Guard.MustBeGreaterThan(sourceSize.Width, 0, nameof(sourceSize)); - Guard.MustBeGreaterThan(sourceSize.Height, 0, nameof(sourceSize)); - - this.Size = sourceSize; } /// @@ -33,13 +30,18 @@ namespace SixLabors.ImageSharp.Processing /// /// The source rectangle. public ProjectiveTransformBuilder(Rectangle sourceRectangle) - : this(sourceRectangle.Size) - => this.rectangle = sourceRectangle; + { + Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); + Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); + + this.sourceRectangle = sourceRectangle; + } /// /// Gets the source image size. /// - internal Size Size { get; } + internal Size Size => this.sourceRectangle.Size; + /// /// Prepends a matrix that performs a tapering projective transform. @@ -61,6 +63,96 @@ namespace SixLabors.ImageSharp.Processing public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) => this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + public void AppendRotationRadians(float radians) + { + throw new System.NotImplementedException(); + } + + public void PrependRotationRadians(float radians) + { + throw new System.NotImplementedException(); + } + + /// + /// Prepends a scale matrix from the given uniform scale. + /// + /// The uniform scale. + /// The . + public ProjectiveTransformBuilder PrependScale(float scale) + => this.PrependMatrix(Matrix4x4.CreateScale(scale)); + + /// + /// Appends a scale matrix from the given uniform scale. + /// + /// The uniform scale. + /// The . + public ProjectiveTransformBuilder AppendScale(float scale) + => this.AppendMatrix(Matrix4x4.CreateScale(scale)); + + /// + /// Prepends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder PrependScale(Vector2 scales) + => this.PrependMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1f))); + + /// + /// Appends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder AppendScale(Vector2 scales) + => this.AppendMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1f))); + + /// + /// Prepends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder PrependScale(SizeF scale) + => this.PrependScale((Vector2)scale); + + /// + /// Appends a scale matrix from the given vector scale. + /// + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder AppendScale(SizeF scales) + => this.AppendScale((Vector2)scales); + + /// + /// Prepends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public ProjectiveTransformBuilder PrependTranslation(Vector2 position) + => this.PrependMatrix(Matrix4x4.CreateTranslation(new Vector3(position, 0))); + + /// + /// Appends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public ProjectiveTransformBuilder AppendTranslation(Vector2 position) + => this.AppendMatrix(Matrix4x4.CreateTranslation(new Vector3(position, 0))); + + /// + /// Prepends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public ProjectiveTransformBuilder PrependTranslation(PointF position) + => this.PrependTranslation((Vector2)position); + + /// + /// Appends a translation matrix from the given vector. + /// + /// The translation position. + /// The . + public ProjectiveTransformBuilder AppendTranslation(PointF position) + => this.AppendTranslation((Vector2)position); + /// /// Prepends a raw matrix. /// @@ -92,9 +184,9 @@ namespace SixLabors.ImageSharp.Processing Matrix4x4 matrix = Matrix4x4.Identity; // Translate the origin matrix to cater for source rectangle offsets. - if (!this.rectangle.Equals(default)) + if (!this.sourceRectangle.Equals(default)) { - matrix *= Matrix4x4.CreateTranslation(new Vector3(-this.rectangle.Location, 0)); + matrix *= Matrix4x4.CreateTranslation(new Vector3(-this.sourceRectangle.Location, 0)); } foreach (Matrix4x4 m in this.matrices) @@ -109,5 +201,6 @@ namespace SixLabors.ImageSharp.Processing /// Removes all matrices from the builder. /// public void Clear() => this.matrices.Clear(); + } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 3dfc42d4f..0d9bd301d 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -9,7 +9,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.Processing.Transforms { - public class ProjectiveTransformBuilderTests + public class ProjectiveTransformBuilderTests : TransformBuilderTestBase { [Fact] public void ConstructorAssignsProperties() @@ -34,45 +34,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); }); } - - [Fact] - public void AppendPrependOpposite() - { - var rectangle = new Rectangle(-1, -1, 3, 3); - var b1 = new ProjectiveTransformBuilder(rectangle); - var b2 = new ProjectiveTransformBuilder(rectangle); - - const float pi = (float)Math.PI; - - Matrix4x4 m4 = Matrix4x4.Identity; - m4.M31 = pi; - - // Forwards - b1.AppendMatrix(m4) - .AppendTaperMatrix(TaperSide.Left, TaperCorner.LeftOrTop, pi); - - // Backwards - b2.PrependTaperMatrix(TaperSide.Left, TaperCorner.LeftOrTop, pi) - .PrependMatrix(m4); - - Assert.Equal(b1.BuildMatrix(), b2.BuildMatrix()); - } - - [Fact] - public void BuilderCanClear() + protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + + protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + + protected override Vector2 Execute( + ProjectiveTransformBuilder builder, + Rectangle rectangle, + Vector2 sourcePoint) { - var rectangle = new Rectangle(0, 0, 3, 3); - var builder = new ProjectiveTransformBuilder(rectangle); - Matrix4x4 matrix = Matrix4x4.Identity; - matrix.M31 = (float)Math.PI; - - Assert.Equal(Matrix4x4.Identity, builder.BuildMatrix()); - - builder.AppendMatrix(matrix); - Assert.NotEqual(Matrix4x4.Identity, builder.BuildMatrix()); - - builder.Clear(); - Assert.Equal(Matrix4x4.Identity, builder.BuildMatrix()); + Matrix4x4 matrix = builder.BuildMatrix(); + return Vector2.Transform(sourcePoint, matrix); } } } From 9d71fd381d0ed653509f591289f50ddda462cb29 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 25 Nov 2018 23:29:34 +0100 Subject: [PATCH 204/238] extend ProjectiveTransformBuilder --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 2 +- .../Processing/AffineTransformBuilder.cs | 29 +++++++------- .../Processing/ProjectiveTransformBuilder.cs | 38 ++++++++++++++++--- .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 2 +- .../Transforms/AffineTransformBuilderTests.cs | 4 +- .../Transforms/AffineTransformTests.cs | 8 ++-- .../ProjectiveTransformBuilderTests.cs | 5 ++- .../Transforms/TransformBuilderTestBase.cs | 2 +- 8 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 45556741e..c0c8e07e6 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp /// Converts degrees to radians /// [MethodImpl(InliningOptions.ShortMethod)] - public static float ToRadian(float degrees) + public static float DegreesToRadians(float degrees) { return degrees * ((float)Math.PI / 180f); } diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index cd66272b4..1f26d079d 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -42,37 +42,38 @@ namespace SixLabors.ImageSharp.Processing /// internal Size Size => this.sourceRectangle.Size; + /// - /// Prepends a centered rotation matrix using the given rotation in degrees. + /// Prepends a centered rotation matrix using the given rotation in radians. /// - /// The amount of rotation, in degrees. + /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder PrependRotationDegrees(float degrees) - => this.PrependMatrix(TransformUtils.CreateRotationMatrixDegrees(degrees, this.Size)); + public AffineTransformBuilder PrependCenteredRotationRadians(float radians) + => this.PrependMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); /// - /// Prepends a centered rotation matrix using the given rotation in radians. + /// Appends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder PrependRotationRadians(float radians) - => this.PrependMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + public AffineTransformBuilder AppendCenteredRotationRadians(float radians) + => this.AppendMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); /// - /// Appends a centered rotation matrix using the given rotation in degrees. + /// Prepends a centered rotation matrix using the given rotation in degrees. /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(ImageMaths.ToRadian(degrees)); + public AffineTransformBuilder PrependCenteredRotationDegrees(float degrees) + => this.PrependCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// - /// Appends a centered rotation matrix using the given rotation in radians. + /// Appends a centered rotation matrix using the given rotation in degrees. /// - /// The amount of rotation, in radians. + /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder AppendRotationRadians(float radians) - => this.AppendMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + public AffineTransformBuilder AppendCenteredRotationDegrees(float degrees) + => this.AppendCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 6c5fb4625..58c02108a 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Processing Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); this.sourceRectangle = sourceRectangle; - } + } /// /// Gets the source image size. @@ -63,16 +63,44 @@ namespace SixLabors.ImageSharp.Processing public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) => this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); - public void AppendRotationRadians(float radians) + /// + /// Prepends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The . + public ProjectiveTransformBuilder PrependCenteredRotationRadians(float radians) { - throw new System.NotImplementedException(); + var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + return this.PrependMatrix(m); } - public void PrependRotationRadians(float radians) + /// + /// Appends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The . + public ProjectiveTransformBuilder AppendCenteredRotationRadians(float radians) { - throw new System.NotImplementedException(); + var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + return this.AppendMatrix(m); } + /// + /// Prepends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public ProjectiveTransformBuilder PrependCenteredRotationDegrees(float degrees) + => this.PrependCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + + /// + /// Appends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public ProjectiveTransformBuilder AppendCenteredRotationDegrees(float degrees) + => this.AppendCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + /// /// Prepends a scale matrix from the given uniform scale. /// diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index a29342ad4..2f8923654 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Tests using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { AffineTransformBuilder builder = new AffineTransformBuilder(blend.Size()) - .AppendRotationDegrees(45F) + .AppendCenteredRotationDegrees(45F) .AppendScale(new SizeF(.25F, .25F)) .AppendTranslation(new PointF(10, 10)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index 639f4b46f..2a43e56e7 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -38,11 +38,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependCenteredRotationRadians(radians); protected override Vector2 Execute( AffineTransformBuilder builder, diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index e78bb2c6d..f86db5641 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotationDegrees(30); + .AppendCenteredRotationDegrees(30); image.Mutate(c => c.Transform(builder, resampler)); image.DebugSave(provider, resamplerName); @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { image.DebugSave(provider, $"_original"); AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotationDegrees(angleDeg) + .AppendCenteredRotationDegrees(angleDeg) .AppendScale(new SizeF(sx, sy)) .AppendTranslation(new PointF(tx, ty)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotationDegrees(angleDeg) + .AppendCenteredRotationDegrees(angleDeg) .AppendScale(new SizeF(s, s)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); @@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) - .AppendRotationDegrees(50) + .AppendCenteredRotationDegrees(50) .AppendScale(new SizeF(.6F, .6F)); image.Mutate(i => i.Transform(builder, sampler)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 0d9bd301d..f467bed40 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -34,13 +34,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); }); } + protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); - protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); - protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependCenteredRotationRadians(radians); protected override Vector2 Execute( ProjectiveTransformBuilder builder, diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index d109387cc..3f259c9aa 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract void PrependRotationRadians(TBuilder builder, float radians); protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => - this.AppendRotationRadians(builder, ImageMaths.ToRadian(degrees)); + this.AppendRotationRadians(builder, ImageMaths.DegreesToRadians(degrees)); protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); From 9b9f469096ccda109d2a9f1f3f8217a76d93b910 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 25 Nov 2018 23:31:05 +0100 Subject: [PATCH 205/238] fix trailing whitespace warnings --- src/ImageSharp/Processing/AffineTransformBuilder.cs | 1 - src/ImageSharp/Processing/ProjectiveTransformBuilder.cs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 1f26d079d..a1305d121 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -42,7 +42,6 @@ namespace SixLabors.ImageSharp.Processing /// internal Size Size => this.sourceRectangle.Size; - /// /// Prepends a centered rotation matrix using the given rotation in radians. /// diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 58c02108a..9bcbaf834 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -42,7 +42,6 @@ namespace SixLabors.ImageSharp.Processing /// internal Size Size => this.sourceRectangle.Size; - /// /// Prepends a matrix that performs a tapering projective transform. /// @@ -229,6 +228,5 @@ namespace SixLabors.ImageSharp.Processing /// Removes all matrices from the builder. /// public void Clear() => this.matrices.Clear(); - } } \ No newline at end of file From e43e09999d49c8de52a49635c1f7f25b67a38594 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 01:09:47 +0100 Subject: [PATCH 206/238] Make AffineTransformProcessor and AffineTransformBuilder API more flexible --- .../Processing/AffineTransformBuilder.cs | 83 ++++++++----------- .../Transforms/AffineTransformProcessor.cs | 6 +- .../Processing/TransformExtensions.cs | 71 ++++++++++++++-- .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 2 +- .../Transforms/AffineTransformBuilderTests.cs | 28 +------ .../Transforms/AffineTransformTests.cs | 18 ++-- .../ProjectiveTransformBuilderTests.cs | 2 + .../Transforms/TransformBuilderTestBase.cs | 18 +++- 8 files changed, 136 insertions(+), 92 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index a1305d121..42d555f20 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Collections.Generic; using System.Numerics; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -13,34 +14,7 @@ namespace SixLabors.ImageSharp.Processing /// public class AffineTransformBuilder { - private readonly List matrices = new List(); - private readonly Rectangle sourceRectangle; - - /// - /// Initializes a new instance of the class. - /// - /// The source image size. - public AffineTransformBuilder(Size sourceSize) - : this(new Rectangle(Point.Empty, sourceSize)) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The source rectangle. - public AffineTransformBuilder(Rectangle sourceRectangle) - { - Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); - Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); - - this.sourceRectangle = sourceRectangle; - } - - /// - /// Gets the source image size. - /// - internal Size Size => this.sourceRectangle.Size; + private readonly List> matrixFactories = new List>(); /// /// Prepends a centered rotation matrix using the given rotation in radians. @@ -48,7 +22,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in radians. /// The . public AffineTransformBuilder PrependCenteredRotationRadians(float radians) - => this.PrependMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// /// Appends a centered rotation matrix using the given rotation in radians. @@ -56,7 +30,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in radians. /// The . public AffineTransformBuilder AppendCenteredRotationRadians(float radians) - => this.AppendMatrix(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); + => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// /// Prepends a centered rotation matrix using the given rotation in degrees. @@ -129,7 +103,7 @@ namespace SixLabors.ImageSharp.Processing /// The Y angle, in degrees. /// The . public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) - => this.PrependMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + => this.Prepend(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); /// /// Appends a centered skew matrix from the give angles in degrees. @@ -138,7 +112,7 @@ namespace SixLabors.ImageSharp.Processing /// The Y angle, in degrees. /// The . public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) - => this.AppendMatrix(TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, this.Size)); + => this.Append(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); /// /// Prepends a translation matrix from the given vector. @@ -179,7 +153,7 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) { - this.matrices.Insert(0, matrix); + this.matrixFactories.Insert(0, _ => matrix); return this; } @@ -190,35 +164,50 @@ namespace SixLabors.ImageSharp.Processing /// The . public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) { - this.matrices.Add(matrix); + this.matrixFactories.Add(_ => matrix); return this; } /// - /// Returns the combined matrix. + /// Returns the combined matrix for a given source size. + /// + /// The source image size + /// The . + public Matrix3x2 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); + + /// + /// Returns the combined matrix for a given source rectangle. /// + /// The rectangle in the source image /// The . - public Matrix3x2 BuildMatrix() + public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) { - Matrix3x2 matrix = Matrix3x2.Identity; + Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); + Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); // Translate the origin matrix to cater for source rectangle offsets. - if (!this.sourceRectangle.Equals(default)) - { - matrix *= Matrix3x2.CreateTranslation(-this.sourceRectangle.Location); - } + var matrix = Matrix3x2.CreateTranslation(-sourceRectangle.Location); - foreach (Matrix3x2 m in this.matrices) + Size size = sourceRectangle.Size; + + foreach (Func factory in this.matrixFactories) { - matrix *= m; + matrix *= factory(size); } return matrix; } - /// - /// Removes all matrices from the builder. - /// - public void Clear() => this.matrices.Clear(); + private AffineTransformBuilder Prepend(Func factory) + { + this.matrixFactories.Insert(0, factory); + return this; + } + + private AffineTransformBuilder Append(Func factory) + { + this.matrixFactories.Add(factory); + return this; + } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index 2370adb86..f357b6c27 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -24,13 +24,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The transform matrix. /// The sampler to perform the transform operation. - /// The source image size. - public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size sourceSize) + /// The target dimensions. + public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions) { Guard.NotNull(sampler, nameof(sampler)); this.Sampler = sampler; this.TransformMatrix = matrix; - this.TargetDimensions = TransformUtils.GetTransformedSize(sourceSize, matrix); + this.TargetDimensions = targetDimensions;; } /// diff --git a/src/ImageSharp/Processing/TransformExtensions.cs b/src/ImageSharp/Processing/TransformExtensions.cs index ea789eb3d..de4a3e5ba 100644 --- a/src/ImageSharp/Processing/TransformExtensions.cs +++ b/src/ImageSharp/Processing/TransformExtensions.cs @@ -1,8 +1,11 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Numerics; + using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Transforms; +using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing { @@ -11,6 +14,29 @@ namespace SixLabors.ImageSharp.Processing /// public static class TransformExtensions { + /// + /// Performs an affine transform of an image using the specified sampling algorithm. + /// + /// The pixel format. + /// The . + /// The source rectangle + /// The transformation matrix. + /// The size of the result image. + /// The to perform the resampling. + /// The + public static IImageProcessingContext Transform( + this IImageProcessingContext ctx, + Rectangle sourceRectangle, + Matrix3x2 transform, + Size targetDimensions, + IResampler sampler) + where TPixel : struct, IPixel + { + return ctx.ApplyProcessor( + new AffineTransformProcessor(transform, sampler, targetDimensions), + sourceRectangle); + } + /// /// Performs an affine transform of an image. /// @@ -18,7 +44,9 @@ namespace SixLabors.ImageSharp.Processing /// The image to transform. /// The affine transform builder. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, AffineTransformBuilder builder) + public static IImageProcessingContext Transform( + this IImageProcessingContext source, + AffineTransformBuilder builder) where TPixel : struct, IPixel => Transform(source, builder, KnownResamplers.Bicubic); @@ -26,13 +54,39 @@ namespace SixLabors.ImageSharp.Processing /// Performs an affine transform of an image using the specified sampling algorithm. /// /// The pixel format. - /// The image to transform. + /// The . + /// The source rectangle + /// The affine transform builder. + /// The to perform the resampling. + /// The + public static IImageProcessingContext Transform( + this IImageProcessingContext ctx, + Rectangle sourceRectangle, + AffineTransformBuilder builder, + IResampler sampler) + where TPixel : struct, IPixel + { + Matrix3x2 transform = builder.BuildMatrix(sourceRectangle); + Size targetDimensions = TransformUtils.GetTransformedSize(sourceRectangle.Size, transform); + return ctx.Transform(sourceRectangle, transform, targetDimensions, sampler); + } + + /// + /// Performs an affine transform of an image using the specified sampling algorithm. + /// + /// The pixel format. + /// The . /// The affine transform builder. /// The to perform the resampling. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, AffineTransformBuilder builder, IResampler sampler) + public static IImageProcessingContext Transform( + this IImageProcessingContext ctx, + AffineTransformBuilder builder, + IResampler sampler) where TPixel : struct, IPixel - => source.ApplyProcessor(new AffineTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); + { + return ctx.Transform(new Rectangle(Point.Empty, ctx.GetCurrentSize()), builder, sampler); + } /// /// Performs a projective transform of an image. @@ -41,7 +95,9 @@ namespace SixLabors.ImageSharp.Processing /// The image to transform. /// The affine transform builder. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, ProjectiveTransformBuilder builder) + public static IImageProcessingContext Transform( + this IImageProcessingContext source, + ProjectiveTransformBuilder builder) where TPixel : struct, IPixel => Transform(source, builder, KnownResamplers.Bicubic); @@ -53,7 +109,10 @@ namespace SixLabors.ImageSharp.Processing /// The projective transform builder. /// The to perform the resampling. /// The - public static IImageProcessingContext Transform(this IImageProcessingContext source, ProjectiveTransformBuilder builder, IResampler sampler) + public static IImageProcessingContext Transform( + this IImageProcessingContext source, + ProjectiveTransformBuilder builder, + IResampler sampler) where TPixel : struct, IPixel => source.ApplyProcessor(new ProjectiveTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); } diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 2f8923654..f3772e3aa 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Tests using (Image image = provider.GetImage()) using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { - AffineTransformBuilder builder = new AffineTransformBuilder(blend.Size()) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendCenteredRotationDegrees(45F) .AppendScale(new SizeF(.25F, .25F)) .AppendTranslation(new PointF(10, 10)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index 2a43e56e7..cbbf59caf 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -12,30 +12,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class AffineTransformBuilderTests : TransformBuilderTestBase { - [Fact] - public void ConstructorAssignsProperties() - { - var s = new Size(1, 1); - var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); - Assert.Equal(s, builder.Size); - } - - [Fact] - public void ConstructorThrowsInvalid() - { - Assert.Throws(() => - { - var s = new Size(0, 1); - var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); - }); - - Assert.Throws(() => - { - var s = new Size(1, 0); - var builder = new AffineTransformBuilder(new Rectangle(Point.Empty, s)); - }); - } - protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); @@ -44,12 +20,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependCenteredRotationRadians(radians); + protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); + protected override Vector2 Execute( AffineTransformBuilder builder, Rectangle rectangle, Vector2 sourcePoint) { - Matrix3x2 matrix = builder.BuildMatrix(); + Matrix3x2 matrix = builder.BuildMatrix(rectangle); return Vector2.Transform(sourcePoint, matrix); } } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index f86db5641..0c167d7f9 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler resampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendCenteredRotationDegrees(30); image.Mutate(c => c.Transform(builder, resampler)); @@ -101,12 +101,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { image.DebugSave(provider, $"_original"); - AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendCenteredRotationDegrees(angleDeg) .AppendScale(new SizeF(sx, sy)) .AppendTranslation(new PointF(tx, ty)); - this.PrintMatrix(builder.BuildMatrix()); + this.PrintMatrix(builder.BuildMatrix(image.Size())); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); @@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendCenteredRotationDegrees(angleDeg) .AppendScale(new SizeF(s, s)); @@ -159,10 +159,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { image.DebugSave(provider, $"_original"); - AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendScale(new SizeF(2, 1.5F)); - image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); + image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline)); image.DebugSave(provider); image.CompareToReferenceOutput(ValidatorComparer, provider); @@ -178,10 +178,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { - AffineTransformBuilder builder = new AffineTransformBuilder(rectangle) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendScale(new SizeF(1F, 2F)); - image.Mutate(i => i.Transform(builder, KnownResamplers.Spline)); + image.Mutate(i => i.Transform(rectangle, builder, KnownResamplers.Spline)); image.DebugSave(provider); image.CompareToReferenceOutput(ValidatorComparer, provider); @@ -196,7 +196,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler sampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - AffineTransformBuilder builder = new AffineTransformBuilder(image.Size()) + AffineTransformBuilder builder = new AffineTransformBuilder() .AppendCenteredRotationDegrees(50) .AppendScale(new SizeF(.6F, .6F)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index f467bed40..14ed57033 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -35,6 +35,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms }); } + protected override ProjectiveTransformBuilder CreateBuilder(Rectangle rectangle) => new ProjectiveTransformBuilder(rectangle); + protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index 3f259c9aa..648ed5861 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -129,9 +129,25 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Assert.Equal(p1, p2, Comparer); } + [Theory] + [InlineData(0, 1)] + [InlineData(1, 0)] + [InlineData(-1, 0)] + public void ThrowsForInvalidSizes(int width, int height) + { + var size = new Size(width, height); + + Assert.ThrowsAny( + () => + { + TBuilder builder = this.CreateBuilder(size); + this.Execute(builder, new Rectangle(Point.Empty, size), Vector2.Zero); + }); + } + protected TBuilder CreateBuilder(Size size) => this.CreateBuilder(new Rectangle(Point.Empty, size)); - protected virtual TBuilder CreateBuilder(Rectangle rectangle) => (TBuilder)Activator.CreateInstance(typeof(TBuilder), rectangle); + protected abstract TBuilder CreateBuilder(Rectangle rectangle); protected abstract void AppendTranslation(TBuilder builder, PointF translate); protected abstract void AppendScale(TBuilder builder, SizeF scale); From f9f58fa570c28397ff7cb87668ec17e8de08acc4 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 01:19:53 +0100 Subject: [PATCH 207/238] fix rotate and skew processors --- .../Processors/Transforms/RotateProcessor.cs | 10 +++++++++- .../Processing/Processors/Transforms/SkewProcessor.cs | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs index 57cca4bf9..69ecf5921 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Numerics; + using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.ParallelUtils; @@ -34,12 +36,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The sampler to perform the rotating operation. /// The source image size public RotateProcessor(float degrees, IResampler sampler, Size sourceSize) - : base( + : this( TransformUtils.CreateRotationMatrixDegrees(degrees, sourceSize), sampler, sourceSize) => this.Degrees = degrees; + // Helper constructor + private RotateProcessor(Matrix3x2 rotationMatrix, IResampler sampler, Size sourceSize) + : base(rotationMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, rotationMatrix)) + { + } + /// /// Gets the angle of rotation in degrees. /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs index 4a006a9df..c7b1d7410 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Numerics; + using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; @@ -32,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The sampler to perform the skew operation. /// The source image size public SkewProcessor(float degreesX, float degreesY, IResampler sampler, Size sourceSize) - : base( + : this( TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, sourceSize), sampler, sourceSize) @@ -41,6 +43,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.DegreesY = degreesY; } + // Helper constructor: + private SkewProcessor(Matrix3x2 skewMatrix, IResampler sampler, Size sourceSize) + : base(skewMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, skewMatrix)) + { + } + /// /// Gets the angle of rotation along the x-axis in degrees. /// From 25b580a31d77ab23a0405a4a3e15691508690edf Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 01:29:31 +0100 Subject: [PATCH 208/238] StyleCop --- .../Processors/Transforms/AffineTransformProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index f357b6c27..aabaa63cf 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Guard.NotNull(sampler, nameof(sampler)); this.Sampler = sampler; this.TransformMatrix = matrix; - this.TargetDimensions = targetDimensions;; + this.TargetDimensions = targetDimensions; } /// From fb6c407026f14e651ecb32f064eb0e4377602c6b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 02:37:10 +0100 Subject: [PATCH 209/238] Rotation around custom center point. Rename PrependCenteredRotationRadians back to PrependRotationRadians --- .../Processing/AffineTransformBuilder.cs | 40 ++++++++++++---- .../Processing/ProjectiveTransformBuilder.cs | 35 ++++++++++++-- .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 2 +- .../Transforms/AffineTransformBuilderTests.cs | 8 +++- .../Transforms/AffineTransformTests.cs | 8 ++-- .../ProjectiveTransformBuilderTests.cs | 8 +++- .../Transforms/TransformBuilderTestBase.cs | 46 +++++++++++++++++-- 7 files changed, 121 insertions(+), 26 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 42d555f20..eab75cfdb 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -20,33 +20,55 @@ namespace SixLabors.ImageSharp.Processing /// Prepends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. + /// The rotation center point /// The . - public AffineTransformBuilder PrependCenteredRotationRadians(float radians) - => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + public AffineTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) + => this.PrependMatrix(Matrix3x2.CreateRotation(radians, centerPoint)); /// /// Appends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. + /// The rotation center point + /// The . + public AffineTransformBuilder AppendRotationRadians(float radians, Vector2 centerPoint) + => this.AppendMatrix(Matrix3x2.CreateRotation(radians, centerPoint)); + + /// + /// Prepends a rotation matrix using the given rotation angle in radians + /// and the image center point as rotation center. + /// + /// The amount of rotation, in radians. + /// The . + public AffineTransformBuilder PrependRotationRadians(float radians) + => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + + /// + /// Appends a rotation matrix using the given rotation angle in radians + /// and the image center point as rotation center. + /// + /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder AppendCenteredRotationRadians(float radians) + public AffineTransformBuilder AppendRotationRadians(float radians) => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// - /// Prepends a centered rotation matrix using the given rotation in degrees. + /// Prepends a rotation matrix using the given rotation angle in degrees + /// and the image center point as rotation center. /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder PrependCenteredRotationDegrees(float degrees) - => this.PrependCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + public AffineTransformBuilder PrependRotationDegrees(float degrees) + => this.PrependRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// - /// Appends a centered rotation matrix using the given rotation in degrees. + /// Appends a rotation matrix using the given rotation angle in degrees + /// and the image center point as rotation center. /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder AppendCenteredRotationDegrees(float degrees) - => this.AppendCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + public AffineTransformBuilder AppendRotationDegrees(float degrees) + => this.AppendRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 9bcbaf834..8bde90d51 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Collections.Generic; using System.Numerics; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -67,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing /// /// The amount of rotation, in radians. /// The . - public ProjectiveTransformBuilder PrependCenteredRotationRadians(float radians) + public ProjectiveTransformBuilder PrependRotationRadians(float radians) { var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); return this.PrependMatrix(m); @@ -78,27 +79,51 @@ namespace SixLabors.ImageSharp.Processing /// /// The amount of rotation, in radians. /// The . - public ProjectiveTransformBuilder AppendCenteredRotationRadians(float radians) + public ProjectiveTransformBuilder AppendRotationRadians(float radians) { var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); return this.AppendMatrix(m); } + /// + /// Appends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The rotation center. + /// The . + internal ProjectiveTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) + { + var m = Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0)); + return this.PrependMatrix(m); + } + + /// + /// Appends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The rotation center. + /// The . + internal ProjectiveTransformBuilder AppendRotationRadians(float radians, Vector2 centerPoint) + { + var m = Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0)); + return this.AppendMatrix(m); + } + /// /// Prepends a centered rotation matrix using the given rotation in degrees. /// /// The amount of rotation, in degrees. /// The . public ProjectiveTransformBuilder PrependCenteredRotationDegrees(float degrees) - => this.PrependCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + => this.PrependRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// /// Appends a centered rotation matrix using the given rotation in degrees. /// /// The amount of rotation, in degrees. /// The . - public ProjectiveTransformBuilder AppendCenteredRotationDegrees(float degrees) - => this.AppendCenteredRotationRadians(ImageMaths.DegreesToRadians(degrees)); + public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) + => this.AppendRotationRadians(ImageMaths.DegreesToRadians(degrees)); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index f3772e3aa..374454afb 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Tests using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { AffineTransformBuilder builder = new AffineTransformBuilder() - .AppendCenteredRotationDegrees(45F) + .AppendRotationDegrees(45F) .AppendScale(new SizeF(.25F, .25F)) .AppendTranslation(new PointF(10, 10)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index cbbf59caf..e02585168 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -14,11 +14,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 center) => + builder.AppendRotationRadians(radians, center); protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependCenteredRotationRadians(radians); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians, Vector2 center) => + builder.PrependRotationRadians(radians, center); protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs index 0c167d7f9..ed6d3ef2b 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformTests.cs @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder() - .AppendCenteredRotationDegrees(30); + .AppendRotationDegrees(30); image.Mutate(c => c.Transform(builder, resampler)); image.DebugSave(provider, resamplerName); @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { image.DebugSave(provider, $"_original"); AffineTransformBuilder builder = new AffineTransformBuilder() - .AppendCenteredRotationDegrees(angleDeg) + .AppendRotationDegrees(angleDeg) .AppendScale(new SizeF(sx, sy)) .AppendTranslation(new PointF(tx, ty)); @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder() - .AppendCenteredRotationDegrees(angleDeg) + .AppendRotationDegrees(angleDeg) .AppendScale(new SizeF(s, s)); image.Mutate(i => i.Transform(builder, KnownResamplers.Bicubic)); @@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { AffineTransformBuilder builder = new AffineTransformBuilder() - .AppendCenteredRotationDegrees(50) + .AppendRotationDegrees(50) .AppendScale(new SizeF(.6F, .6F)); image.Mutate(i => i.Transform(builder, sampler)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 14ed57033..01448ac59 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -39,11 +39,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); - protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendCenteredRotationRadians(radians); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 center) => + builder.AppendRotationRadians(radians, center); protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); - protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependCenteredRotationRadians(radians); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 center) => + builder.PrependRotationRadians(radians, center); protected override Vector2 Execute( ProjectiveTransformBuilder builder, diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index 648ed5861..badf43013 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -87,7 +87,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms [InlineData(200, 100, 10, 42, 84)] [InlineData(200, 100, 100, 42, 84)] [InlineData(100, 200, -10, 42, 84)] - public void RotateDegrees_ShouldCreateCenteredMatrix(int width, int height, float deg, float x, float y) + public void AppendRotationDegrees_WithoutSpecificRotationCenter_RotationIsCenteredAroundImageCenter( + int width, + int height, + float deg, + float x, + float y) { var size = new Size(width, height); TBuilder builder = this.CreateBuilder(size); @@ -97,13 +102,41 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms // TODO: We should also test CreateRotationMatrixDegrees() (and all TransformUtils stuff!) for correctness Matrix3x2 matrix = TransformUtils.CreateRotationMatrixDegrees(deg, size); - var position = new Vector2(x, y); + var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); Vector2 actual = this.Execute(builder, new Rectangle(Point.Empty, size), position); Assert.Equal(actual, expected, Comparer); } - + + [Theory] + [InlineData(200, 100, 10, 30, 61, 42, 84)] + [InlineData(200, 100, 100, 30, 10, 20, 84)] + [InlineData(100, 200, -10, 30, 20, 11, 84)] + public void AppendRotationDegrees_WithRotationCenter( + int width, + int height, + float deg, + float cx, + float cy, + float x, + float y) + { + var size = new Size(width, height); + TBuilder builder = this.CreateBuilder(size); + + var centerPoint = new Vector2(cx, cy); + this.AppendRotationDegrees(builder, deg, centerPoint); + + var matrix = Matrix3x2.CreateRotation(ImageMaths.DegreesToRadians(deg), centerPoint); + + var position = new Vector2(x, y); + var expected = Vector2.Transform(position, matrix); + Vector2 actual = this.Execute(builder, new Rectangle(Point.Empty, size), position); + + Assert.Equal(actual, expected, Comparer); + } + [Fact] public void AppendPrependOpposite() { @@ -116,10 +149,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms // Forwards this.AppendRotationRadians(b1, pi); this.AppendScale(b1, new SizeF(2, 0.5f)); + this.AppendRotationRadians(b1, pi / 2, new Vector2(-0.5f, -0.1f)); this.AppendTranslation(b1, new PointF(123, 321)); // Backwards this.PrependTranslation(b2, new PointF(123, 321)); + this.PrependRotationRadians(b2, pi / 2, new Vector2(-0.5f, -0.1f)); this.PrependScale(b2, new SizeF(2, 0.5f)); this.PrependRotationRadians(b2, pi); @@ -152,14 +187,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract void AppendTranslation(TBuilder builder, PointF translate); protected abstract void AppendScale(TBuilder builder, SizeF scale); protected abstract void AppendRotationRadians(TBuilder builder, float radians); + protected abstract void AppendRotationRadians(TBuilder builder, float radians, Vector2 center); protected abstract void PrependTranslation(TBuilder builder, PointF translate); protected abstract void PrependScale(TBuilder builder, SizeF scale); protected abstract void PrependRotationRadians(TBuilder builder, float radians); + protected abstract void PrependRotationRadians(TBuilder b1, float v, Vector2 vector2); protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => this.AppendRotationRadians(builder, ImageMaths.DegreesToRadians(degrees)); + protected virtual void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 center) => + this.AppendRotationRadians(builder, ImageMaths.DegreesToRadians(degrees), center); + protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); private static float Sqrt(float a) => (float)Math.Sqrt(a); From 42b1bd115d4e94c8168582d20ee02c7ffb2b32f6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 16:11:38 +0100 Subject: [PATCH 210/238] printing ReferenceKernelMap --- .../KernelMapTests.ReferenceKernelMap.cs | 9 ++++- .../Processors/Transforms/KernelMapTests.cs | 39 +++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 932ea5494..cf0e94e8b 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms /// /// Simplified reference implementation for functionality. /// - public class ReferenceKernelMap + internal class ReferenceKernelMap { private readonly ReferenceKernel[] kernels; @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } - public struct ReferenceKernel + internal struct ReferenceKernel { public ReferenceKernel(int left, float[] values) { @@ -94,6 +94,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public float[] Values { get; } public int Length => this.Values.Length; + + public static implicit operator ReferenceKernel(ResizeKernel orig) + { + return new ReferenceKernel(orig.Left, orig.GetValues().ToArray()); + } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 7abc1c312..555ed1567 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos3), 8, 6 }, // TODO: What's wrong here: - // { nameof(KnownResamplers.Lanczos3), 20, 12 }, + { nameof(KnownResamplers.Lanczos3), 20, 12 }, {nameof(KnownResamplers.Lanczos8), 500, 200 }, {nameof(KnownResamplers.Lanczos8), 100, 10 }, @@ -61,8 +61,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var referenceMap = ReferenceKernelMap.Calculate(resampler, destSize, srcSize); #if DEBUG - string text = PrintKernelMap(kernelMap); - this.Output.WriteLine(text); + this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); + this.Output.WriteLine($"Reference KernelMap:\n{PrintKernelMap(referenceMap)}\n"); #endif for (int i = 0; i < kernelMap.DestinationSize; i++) @@ -73,19 +73,42 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms Assert.Equal(referenceKernel.Length, kernel.Length); Assert.Equal(referenceKernel.Left, kernel.Left); - Assert.True(kernel.GetValues().SequenceEqual(referenceKernel.Values)); + float[] expectedValues = referenceKernel.Values; + Span actualValues = kernel.GetValues(); + + Assert.Equal(expectedValues.Length, actualValues.Length); + + var comparer = new ApproximateFloatComparer(1e-6f); + + for (int x = 0; x < expectedValues.Length; x++) + { + Assert.True( + comparer.Equals(expectedValues[x], actualValues[x]), + $"{expectedValues[x]} != {actualValues[x]} @ (Row:{i}, Col:{x})"); + } } } - private static string PrintKernelMap(KernelMap kernelMap) + private static string PrintKernelMap(KernelMap kernelMap) => + PrintKernelMap(kernelMap, km => km.DestinationSize, (km, i) => km.GetKernel(i)); + + private static string PrintKernelMap(ReferenceKernelMap kernelMap) => + PrintKernelMap(kernelMap, km => km.DestinationSize, (km, i) => km.GetKernel(i)); + + private static string PrintKernelMap( + TKernelMap kernelMap, + Func getDestinationSize, + Func getKernel) { var bld = new StringBuilder(); - for (int i = 0; i < kernelMap.DestinationSize; i++) + int destinationSize = getDestinationSize(kernelMap); + + for (int i = 0; i < destinationSize; i++) { - ResizeKernel kernel = kernelMap.GetKernel(i); + ReferenceKernel kernel = getKernel(kernelMap, i); bld.Append($"({kernel.Left:D3}) || "); - Span span = kernel.GetValues(); + Span span = kernel.Values; for (int j = 0; j < kernel.Length; j++) { From eed22c56caced6bc9cee383c072b316ea9492a02 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 26 Nov 2018 16:48:29 +0100 Subject: [PATCH 211/238] fixed a bug in KernelMap caused by overlapping memory areas --- .../Processors/Transforms/KernelMap.cs | 11 +++++++++-- .../Processors/Transforms/KernelMapTests.cs | 16 +++++++--------- .../Processing/Processors/Transforms/SkewTest.cs | 14 +------------- .../ImageSharp.Tests/TestUtilities/TestUtils.cs | 13 +++++++++++++ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index 3f984fef0..3f2bf8dda 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.periodicRegionMin = period + radius; this.periodicRegionMax = destinationSize - radius; - int width = radius * 2; + int width = (radius * 2) + 1; this.data = memoryAllocator.Allocate2D(width, destinationSize, AllocationOptions.Clean); this.kernels = new ResizeKernel[destinationSize]; } @@ -141,8 +141,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// private ResizeKernel CreateKernel(int destIdx, int left, int rightIdx) { - int flatStartIndex = destIdx * this.data.Width; int length = rightIdx - left + 1; + + if (length > this.data.Width) + { + throw new InvalidOperationException($"Error in KernelMap.CreateKernel({destIdx},{left},{rightIdx}): left > this.data.Width"); + } + + int flatStartIndex = destIdx * this.data.Width; + Memory bufferSlice = this.data.Memory.Slice(flatStartIndex, length); return new ResizeKernel(left, bufferSlice); } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 555ed1567..c5916ce0b 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Runtime.InteropServices; using System.Text; using SixLabors.ImageSharp.PixelFormats; @@ -40,25 +41,22 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos3), 9, 12 }, { nameof(KnownResamplers.Lanczos3), 6, 8 }, { nameof(KnownResamplers.Lanczos3), 8, 6 }, - - // TODO: What's wrong here: { nameof(KnownResamplers.Lanczos3), 20, 12 }, - {nameof(KnownResamplers.Lanczos8), 500, 200 }, - {nameof(KnownResamplers.Lanczos8), 100, 10 }, - {nameof(KnownResamplers.Lanczos8), 100, 80 }, - {nameof(KnownResamplers.Lanczos8), 10, 100 }, + { nameof(KnownResamplers.Lanczos8), 500, 200 }, + { nameof(KnownResamplers.Lanczos8), 100, 10 }, + { nameof(KnownResamplers.Lanczos8), 100, 80 }, + { nameof(KnownResamplers.Lanczos8), 10, 100 }, }; [Theory] [MemberData(nameof(KernelMapData))] public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { - var resampler = (IResampler)typeof(KnownResamplers).GetProperty(resamplerName).GetValue(null); - - var kernelMap = KernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); + IResampler resampler = TestUtils.GetResampler(resamplerName); var referenceMap = ReferenceKernelMap.Calculate(resampler, destSize, srcSize); + var kernelMap = KernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); #if DEBUG this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs index d1d2ea077..29c51543f 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SkewTest.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { foreach (string resamplerName in ResamplerNames) { - IResampler sampler = GetResampler(resamplerName); + IResampler sampler = TestUtils.GetResampler(resamplerName); using (Image image = provider.GetImage()) { image.Mutate(i => i.Skew(x, y, sampler)); @@ -68,17 +68,5 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } } - - private static IResampler GetResampler(string name) - { - PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); - - if (property is null) - { - throw new Exception($"No resampler named '{name}"); - } - - return (IResampler)property.GetValue(null); - } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index d7755ff7a..5ea0bccf0 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -10,6 +10,7 @@ using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.Primitives; @@ -284,5 +285,17 @@ namespace SixLabors.ImageSharp.Tests } public static string AsInvariantString(this FormattableString formattable) => System.FormattableString.Invariant(formattable); + + public static IResampler GetResampler(string name) + { + PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); + + if (property is null) + { + throw new Exception($"No resampler named '{name}"); + } + + return (IResampler)property.GetValue(null); + } } } \ No newline at end of file From 281899246391c73dd6d475d9018da0465cf5a4b9 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 26 Nov 2018 18:16:47 +0000 Subject: [PATCH 212/238] Use existing method. (There's precedence) --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 14 +------------- .../Processing/AffineTransformBuilder.cs | 4 ++-- .../Processing/ProjectiveTransformBuilder.cs | 5 ++--- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index c0c8e07e6..8720140e1 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -125,19 +125,7 @@ namespace SixLabors.ImageSharp /// should be power of 2. /// [MethodImpl(InliningOptions.ShortMethod)] - public static int ModuloP2(int x, int m) - { - return x & (m - 1); - } - - /// - /// Converts degrees to radians - /// - [MethodImpl(InliningOptions.ShortMethod)] - public static float DegreesToRadians(float degrees) - { - return degrees * ((float)Math.PI / 180f); - } + public static int ModuloP2(int x, int m) => x & (m - 1); /// /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation. diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index eab75cfdb..a91d1f0d2 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder PrependRotationDegrees(float degrees) - => this.PrependRotationRadians(ImageMaths.DegreesToRadians(degrees)); + => this.PrependRotationRadians(MathFExtensions.DegreeToRadian(degrees)); /// /// Appends a rotation matrix using the given rotation angle in degrees @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(ImageMaths.DegreesToRadians(degrees)); + => this.AppendRotationRadians(MathFExtensions.DegreeToRadian(degrees)); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 8bde90d51..ad6ef20bb 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Collections.Generic; using System.Numerics; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -115,7 +114,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public ProjectiveTransformBuilder PrependCenteredRotationDegrees(float degrees) - => this.PrependRotationRadians(ImageMaths.DegreesToRadians(degrees)); + => this.PrependRotationRadians(MathFExtensions.DegreeToRadian(degrees)); /// /// Appends a centered rotation matrix using the given rotation in degrees. @@ -123,7 +122,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(ImageMaths.DegreesToRadians(degrees)); + => this.AppendRotationRadians(MathFExtensions.DegreeToRadian(degrees)); /// /// Prepends a scale matrix from the given uniform scale. From f6ed06bb5262aa3c18803691ca58fa9dcbe5bc64 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 26 Nov 2018 18:22:39 +0000 Subject: [PATCH 213/238] Remove "Matrix" suffix --- src/ImageSharp/Processing/ProjectiveTransformBuilder.cs | 4 ++-- .../Processing/Transforms/ProjectiveTransformTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index ad6ef20bb..dff9bc6d9 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Processing /// An enumeration that indicates on which corners to taper the rectangle. /// The amount to taper. /// The . - public ProjectiveTransformBuilder PrependTaperMatrix(TaperSide side, TaperCorner corner, float fraction) + public ProjectiveTransformBuilder PrependTaper(TaperSide side, TaperCorner corner, float fraction) => this.PrependMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); /// @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing /// An enumeration that indicates on which corners to taper the rectangle. /// The amount to taper. /// The . - public ProjectiveTransformBuilder AppendTaperMatrix(TaperSide side, TaperCorner corner, float fraction) + public ProjectiveTransformBuilder AppendTaper(TaperSide side, TaperCorner corner, float fraction) => this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); /// diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs index 0362d75a0..9436b7828 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) - .AppendTaperMatrix(TaperSide.Right, TaperCorner.Both, .5F); + .AppendTaper(TaperSide.Right, TaperCorner.Both, .5F); image.Mutate(i => i.Transform(builder, sampler)); @@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) - .AppendTaperMatrix(taperSide, taperCorner, .5F); + .AppendTaper(taperSide, taperCorner, .5F); image.Mutate(i => i.Transform(builder)); From 1705a5a9dc87097f5a640c1ae2228f735491a357 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 26 Nov 2018 22:59:31 +0000 Subject: [PATCH 214/238] Update dependencies --- src/ImageSharp.Drawing/ImageSharp.Drawing.csproj | 4 ++-- .../Converters/CIeLchToCieLabConverter.cs | 2 +- .../Converters/CieLabToCieLchConverter.cs | 2 +- .../Converters/CieLchuvToCieLuvConverter.cs | 2 +- .../Converters/CieLuvToCieLchuvConverter.cs | 2 +- src/ImageSharp/ImageSharp.csproj | 2 +- src/ImageSharp/Processing/AffineTransformBuilder.cs | 4 ++-- src/ImageSharp/Processing/KnownFilterMatrices.cs | 2 +- .../Processing/ProjectiveTransformBuilder.cs | 9 ++------- .../Processing/Transforms/TransformBuilderTestBase.cs | 10 ++++------ 10 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index 1cb3f444f..ae5069be1 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -38,8 +38,8 @@ - - + + All diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs index dd352db80..40d8c5bc6 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation // Conversion algorithm described here: // https://en.wikipedia.org/wiki/Lab_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC float l = input.L, c = input.C, hDegrees = input.H; - float hRadians = MathFExtensions.DegreeToRadian(hDegrees); + float hRadians = GeometryUtilities.DegreeToRadian(hDegrees); float a = c * MathF.Cos(hRadians); float b = c * MathF.Sin(hRadians); diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs index 81196604e..2b859205a 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation float l = input.L, a = input.A, b = input.B; float c = MathF.Sqrt((a * a) + (b * b)); float hRadians = MathF.Atan2(b, a); - float hDegrees = MathFExtensions.RadianToDegree(hRadians); + float hDegrees = GeometryUtilities.RadianToDegree(hRadians); // Wrap the angle round at 360. hDegrees %= 360; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs index 4f5a20bec..ba5b8bfb7 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation // Conversion algorithm described here: // https://en.wikipedia.org/wiki/CIELUV#Cylindrical_representation_.28CIELCH.29 float l = input.L, c = input.C, hDegrees = input.H; - float hRadians = MathFExtensions.DegreeToRadian(hDegrees); + float hRadians = GeometryUtilities.DegreeToRadian(hDegrees); float u = c * MathF.Cos(hRadians); float v = c * MathF.Sin(hRadians); diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs index 297c18c5c..3c7d356a5 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation float l = input.L, a = input.U, b = input.V; float c = MathF.Sqrt((a * a) + (b * b)); float hRadians = MathF.Atan2(b, a); - float hDegrees = MathFExtensions.RadianToDegree(hRadians); + float hDegrees = GeometryUtilities.RadianToDegree(hRadians); // Wrap the angle round at 360. hDegrees %= 360; diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 29d29d50d..c19c92426 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -42,7 +42,7 @@ - + All diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index a91d1f0d2..ed5aa987f 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder PrependRotationDegrees(float degrees) - => this.PrependRotationRadians(MathFExtensions.DegreeToRadian(degrees)); + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Appends a rotation matrix using the given rotation angle in degrees @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public AffineTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(MathFExtensions.DegreeToRadian(degrees)); + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/src/ImageSharp/Processing/KnownFilterMatrices.cs b/src/ImageSharp/Processing/KnownFilterMatrices.cs index 4f5e3c869..cf0d19ff8 100644 --- a/src/ImageSharp/Processing/KnownFilterMatrices.cs +++ b/src/ImageSharp/Processing/KnownFilterMatrices.cs @@ -322,7 +322,7 @@ namespace SixLabors.ImageSharp.Processing degrees += 360; } - float radian = MathFExtensions.DegreeToRadian(degrees); + float radian = GeometryUtilities.DegreeToRadian(degrees); float cosRadian = MathF.Cos(radian); float sinRadian = MathF.Sin(radian); diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index dff9bc6d9..750f2f5d0 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -114,7 +114,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public ProjectiveTransformBuilder PrependCenteredRotationDegrees(float degrees) - => this.PrependRotationRadians(MathFExtensions.DegreeToRadian(degrees)); + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Appends a centered rotation matrix using the given rotation in degrees. @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in degrees. /// The . public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(MathFExtensions.DegreeToRadian(degrees)); + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Prepends a scale matrix from the given uniform scale. @@ -247,10 +247,5 @@ namespace SixLabors.ImageSharp.Processing return matrix; } - - /// - /// Removes all matrices from the builder. - /// - public void Clear() => this.matrices.Clear(); } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index badf43013..dffa3c7ac 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -3,8 +3,6 @@ using System; using System.Numerics; - -using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; @@ -128,7 +126,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms var centerPoint = new Vector2(cx, cy); this.AppendRotationDegrees(builder, deg, centerPoint); - var matrix = Matrix3x2.CreateRotation(ImageMaths.DegreesToRadians(deg), centerPoint); + var matrix = Matrix3x2.CreateRotation(GeometryUtilities.DegreeToRadian(deg), centerPoint); var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); @@ -195,13 +193,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract void PrependRotationRadians(TBuilder b1, float v, Vector2 vector2); protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => - this.AppendRotationRadians(builder, ImageMaths.DegreesToRadians(degrees)); + this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees)); protected virtual void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 center) => - this.AppendRotationRadians(builder, ImageMaths.DegreesToRadians(degrees), center); + this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees), center); protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); - + private static float Sqrt(float a) => (float)Math.Sqrt(a); } } \ No newline at end of file From d992d85ef0c3c32d92b56c32a754f07f704dfa5a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 27 Nov 2018 00:46:32 +0000 Subject: [PATCH 215/238] Match APIs --- .../Processing/AffineTransformBuilder.cs | 114 +++++----- .../ProjectiveTransformProcessor.cs | 6 +- .../Processing/ProjectiveTransformBuilder.cs | 210 ++++++++---------- .../Processing/TransformExtensions.cs | 96 +++++--- .../Transforms/AffineTransformBuilderTests.cs | 15 +- .../ProjectiveTransformBuilderTests.cs | 40 +--- .../Transforms/ProjectiveTransformTests.cs | 6 +- .../Transforms/TransformBuilderTestBase.cs | 12 +- 8 files changed, 246 insertions(+), 253 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index ed5aa987f..29c37d7bf 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -17,22 +17,13 @@ namespace SixLabors.ImageSharp.Processing private readonly List> matrixFactories = new List>(); /// - /// Prepends a centered rotation matrix using the given rotation in radians. - /// - /// The amount of rotation, in radians. - /// The rotation center point - /// The . - public AffineTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) - => this.PrependMatrix(Matrix3x2.CreateRotation(radians, centerPoint)); - - /// - /// Appends a centered rotation matrix using the given rotation in radians. + /// Prepends a rotation matrix using the given rotation angle in degrees + /// and the image center point as rotation center. /// - /// The amount of rotation, in radians. - /// The rotation center point + /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder AppendRotationRadians(float radians, Vector2 centerPoint) - => this.AppendMatrix(Matrix3x2.CreateRotation(radians, centerPoint)); + public AffineTransformBuilder PrependRotationDegrees(float degrees) + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Prepends a rotation matrix using the given rotation angle in radians @@ -44,31 +35,40 @@ namespace SixLabors.ImageSharp.Processing => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// - /// Appends a rotation matrix using the given rotation angle in radians - /// and the image center point as rotation center. + /// Prepends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. + /// The rotation origin point. /// The . - public AffineTransformBuilder AppendRotationRadians(float radians) - => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + public AffineTransformBuilder PrependRotationRadians(float radians, Vector2 origin) + => this.PrependMatrix(Matrix3x2.CreateRotation(radians, origin)); /// - /// Prepends a rotation matrix using the given rotation angle in degrees + /// Appends a rotation matrix using the given rotation angle in degrees /// and the image center point as rotation center. /// /// The amount of rotation, in degrees. /// The . - public AffineTransformBuilder PrependRotationDegrees(float degrees) - => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); + public AffineTransformBuilder AppendRotationDegrees(float degrees) + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// - /// Appends a rotation matrix using the given rotation angle in degrees + /// Appends a rotation matrix using the given rotation angle in radians /// and the image center point as rotation center. /// - /// The amount of rotation, in degrees. + /// The amount of rotation, in radians. /// The . - public AffineTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); + public AffineTransformBuilder AppendRotationRadians(float radians) + => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + + /// + /// Appends a centered rotation matrix using the given rotation in radians. + /// + /// The amount of rotation, in radians. + /// The rotation origin point. + /// The . + public AffineTransformBuilder AppendRotationRadians(float radians, Vector2 origin) + => this.AppendMatrix(Matrix3x2.CreateRotation(radians, origin)); /// /// Prepends a scale matrix from the given uniform scale. @@ -79,12 +79,12 @@ namespace SixLabors.ImageSharp.Processing => this.PrependMatrix(Matrix3x2.CreateScale(scale)); /// - /// Appends a scale matrix from the given uniform scale. + /// Prepends a scale matrix from the given vector scale. /// - /// The uniform scale. + /// The horizontal and vertical scale. /// The . - public AffineTransformBuilder AppendScale(float scale) - => this.AppendMatrix(Matrix3x2.CreateScale(scale)); + public AffineTransformBuilder PrependScale(SizeF scale) + => this.PrependScale((Vector2)scale); /// /// Prepends a scale matrix from the given vector scale. @@ -95,28 +95,28 @@ namespace SixLabors.ImageSharp.Processing => this.PrependMatrix(Matrix3x2.CreateScale(scales)); /// - /// Appends a scale matrix from the given vector scale. + /// Appends a scale matrix from the given uniform scale. /// - /// The horizontal and vertical scale. + /// The uniform scale. /// The . - public AffineTransformBuilder AppendScale(Vector2 scales) - => this.AppendMatrix(Matrix3x2.CreateScale(scales)); + public AffineTransformBuilder AppendScale(float scale) + => this.AppendMatrix(Matrix3x2.CreateScale(scale)); /// - /// Prepends a scale matrix from the given vector scale. + /// Appends a scale matrix from the given vector scale. /// - /// The horizontal and vertical scale. + /// The horizontal and vertical scale. /// The . - public AffineTransformBuilder PrependScale(SizeF scale) - => this.PrependScale((Vector2)scale); + public AffineTransformBuilder AppendScale(SizeF scales) + => this.AppendScale((Vector2)scales); /// /// Appends a scale matrix from the given vector scale. /// /// The horizontal and vertical scale. /// The . - public AffineTransformBuilder AppendScale(SizeF scales) - => this.AppendScale((Vector2)scales); + public AffineTransformBuilder AppendScale(Vector2 scales) + => this.AppendMatrix(Matrix3x2.CreateScale(scales)); /// /// Prepends a centered skew matrix from the give angles in degrees. @@ -141,66 +141,58 @@ namespace SixLabors.ImageSharp.Processing /// /// The translation position. /// The . - public AffineTransformBuilder PrependTranslation(Vector2 position) - => this.PrependMatrix(Matrix3x2.CreateTranslation(position)); + public AffineTransformBuilder PrependTranslation(PointF position) + => this.PrependTranslation((Vector2)position); /// - /// Appends a translation matrix from the given vector. + /// Prepends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder AppendTranslation(Vector2 position) - => this.AppendMatrix(Matrix3x2.CreateTranslation(position)); + public AffineTransformBuilder PrependTranslation(Vector2 position) + => this.PrependMatrix(Matrix3x2.CreateTranslation(position)); /// - /// Prepends a translation matrix from the given vector. + /// Appends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder PrependTranslation(PointF position) - => this.PrependTranslation((Vector2)position); + public AffineTransformBuilder AppendTranslation(PointF position) + => this.AppendTranslation((Vector2)position); /// /// Appends a translation matrix from the given vector. /// /// The translation position. /// The . - public AffineTransformBuilder AppendTranslation(PointF position) - => this.AppendTranslation((Vector2)position); + public AffineTransformBuilder AppendTranslation(Vector2 position) + => this.AppendMatrix(Matrix3x2.CreateTranslation(position)); /// /// Prepends a raw matrix. /// /// The matrix to prepend. /// The . - public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) - { - this.matrixFactories.Insert(0, _ => matrix); - return this; - } + public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) => this.Prepend(_ => matrix); /// /// Appends a raw matrix. /// /// The matrix to append. /// The . - public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) - { - this.matrixFactories.Add(_ => matrix); - return this; - } + public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) => this.Append(_ => matrix); /// /// Returns the combined matrix for a given source size. /// - /// The source image size + /// The source image size. /// The . public Matrix3x2 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); /// /// Returns the combined matrix for a given source rectangle. /// - /// The rectangle in the source image + /// The rectangle in the source image. /// The . public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) { diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index bfde1769c..273156e2e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -24,13 +24,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The transform matrix. /// The sampler to perform the transform operation. - /// The source image size. - public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size sourceSize) + /// The target dimensions. + public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size targetDimensions) { Guard.NotNull(sampler, nameof(sampler)); this.Sampler = sampler; this.TransformMatrix = matrix; - this.TargetDimensions = TransformUtils.GetTransformedSize(sourceSize, matrix); + this.TargetDimensions = targetDimensions; } /// diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 750f2f5d0..a905467bb 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Collections.Generic; using System.Numerics; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -13,34 +14,7 @@ namespace SixLabors.ImageSharp.Processing /// public class ProjectiveTransformBuilder { - private readonly List matrices = new List(); - private Rectangle sourceRectangle; - - /// - /// Initializes a new instance of the class. - /// - /// The source image size. - public ProjectiveTransformBuilder(Size sourceSize) - : this(new Rectangle(Point.Empty, sourceSize)) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The source rectangle. - public ProjectiveTransformBuilder(Rectangle sourceRectangle) - { - Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); - Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); - - this.sourceRectangle = sourceRectangle; - } - - /// - /// Gets the source image size. - /// - internal Size Size => this.sourceRectangle.Size; + private readonly List> matrixFactories = new List>(); /// /// Prepends a matrix that performs a tapering projective transform. @@ -50,7 +24,7 @@ namespace SixLabors.ImageSharp.Processing /// The amount to taper. /// The . public ProjectiveTransformBuilder PrependTaper(TaperSide side, TaperCorner corner, float fraction) - => this.PrependMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + => this.Prepend(size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); /// /// Appends a matrix that performs a tapering projective transform. @@ -60,7 +34,15 @@ namespace SixLabors.ImageSharp.Processing /// The amount to taper. /// The . public ProjectiveTransformBuilder AppendTaper(TaperSide side, TaperCorner corner, float fraction) - => this.AppendMatrix(TransformUtils.CreateTaperMatrix(this.Size, side, corner, fraction)); + => this.Append(size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); + + /// + /// Prepends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public ProjectiveTransformBuilder PrependRotationDegrees(float degrees) + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Prepends a centered rotation matrix using the given rotation in radians. @@ -68,33 +50,32 @@ namespace SixLabors.ImageSharp.Processing /// The amount of rotation, in radians. /// The . public ProjectiveTransformBuilder PrependRotationRadians(float radians) - { - var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); - return this.PrependMatrix(m); - } + => this.Prepend(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); /// /// Appends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. + /// The rotation center. /// The . - public ProjectiveTransformBuilder AppendRotationRadians(float radians) - { - var m = new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, this.Size)); - return this.AppendMatrix(m); - } + internal ProjectiveTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) + => this.PrependMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0))); + + /// + /// Appends a centered rotation matrix using the given rotation in degrees. + /// + /// The amount of rotation, in degrees. + /// The . + public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); /// /// Appends a centered rotation matrix using the given rotation in radians. /// /// The amount of rotation, in radians. - /// The rotation center. /// The . - internal ProjectiveTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) - { - var m = Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0)); - return this.PrependMatrix(m); - } + public ProjectiveTransformBuilder AppendRotationRadians(float radians) + => this.Append(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); /// /// Appends a centered rotation matrix using the given rotation in radians. @@ -103,80 +84,69 @@ namespace SixLabors.ImageSharp.Processing /// The rotation center. /// The . internal ProjectiveTransformBuilder AppendRotationRadians(float radians, Vector2 centerPoint) - { - var m = Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0)); - return this.AppendMatrix(m); - } + => this.AppendMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0))); /// - /// Prepends a centered rotation matrix using the given rotation in degrees. + /// Prepends a scale matrix from the given uniform scale. /// - /// The amount of rotation, in degrees. - /// The . - public ProjectiveTransformBuilder PrependCenteredRotationDegrees(float degrees) - => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); + /// The uniform scale. + /// The . + public ProjectiveTransformBuilder PrependScale(float scale) + => this.PrependMatrix(Matrix4x4.CreateScale(scale)); /// - /// Appends a centered rotation matrix using the given rotation in degrees. + /// Prepends a scale matrix from the given vector scale. /// - /// The amount of rotation, in degrees. - /// The . - public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) - => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees)); + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder PrependScale(SizeF scale) + => this.PrependScale((Vector2)scale); /// - /// Prepends a scale matrix from the given uniform scale. + /// Prepends a scale matrix from the given vector scale. /// - /// The uniform scale. - /// The . - public ProjectiveTransformBuilder PrependScale(float scale) - => this.PrependMatrix(Matrix4x4.CreateScale(scale)); + /// The horizontal and vertical scale. + /// The . + public ProjectiveTransformBuilder PrependScale(Vector2 scales) + => this.PrependMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1F))); /// /// Appends a scale matrix from the given uniform scale. /// /// The uniform scale. - /// The . + /// The . public ProjectiveTransformBuilder AppendScale(float scale) => this.AppendMatrix(Matrix4x4.CreateScale(scale)); /// - /// Prepends a scale matrix from the given vector scale. + /// Appends a scale matrix from the given vector scale. /// /// The horizontal and vertical scale. - /// The . - public ProjectiveTransformBuilder PrependScale(Vector2 scales) - => this.PrependMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1f))); + /// The . + public ProjectiveTransformBuilder AppendScale(SizeF scales) + => this.AppendScale((Vector2)scales); /// /// Appends a scale matrix from the given vector scale. /// /// The horizontal and vertical scale. - /// The . + /// The . public ProjectiveTransformBuilder AppendScale(Vector2 scales) - => this.AppendMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1f))); - - /// - /// Prepends a scale matrix from the given vector scale. - /// - /// The horizontal and vertical scale. - /// The . - public ProjectiveTransformBuilder PrependScale(SizeF scale) - => this.PrependScale((Vector2)scale); + => this.AppendMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1F))); /// - /// Appends a scale matrix from the given vector scale. + /// Prepends a translation matrix from the given vector. /// - /// The horizontal and vertical scale. - /// The . - public ProjectiveTransformBuilder AppendScale(SizeF scales) - => this.AppendScale((Vector2)scales); + /// The translation position. + /// The . + public ProjectiveTransformBuilder PrependTranslation(PointF position) + => this.PrependTranslation((Vector2)position); /// /// Prepends a translation matrix from the given vector. /// /// The translation position. - /// The . + /// The . public ProjectiveTransformBuilder PrependTranslation(Vector2 position) => this.PrependMatrix(Matrix4x4.CreateTranslation(new Vector3(position, 0))); @@ -184,68 +154,72 @@ namespace SixLabors.ImageSharp.Processing /// Appends a translation matrix from the given vector. /// /// The translation position. - /// The . - public ProjectiveTransformBuilder AppendTranslation(Vector2 position) - => this.AppendMatrix(Matrix4x4.CreateTranslation(new Vector3(position, 0))); - - /// - /// Prepends a translation matrix from the given vector. - /// - /// The translation position. - /// The . - public ProjectiveTransformBuilder PrependTranslation(PointF position) - => this.PrependTranslation((Vector2)position); + /// The . + public ProjectiveTransformBuilder AppendTranslation(PointF position) + => this.AppendTranslation((Vector2)position); /// /// Appends a translation matrix from the given vector. /// /// The translation position. - /// The . - public ProjectiveTransformBuilder AppendTranslation(PointF position) - => this.AppendTranslation((Vector2)position); + /// The . + public ProjectiveTransformBuilder AppendTranslation(Vector2 position) + => this.AppendMatrix(Matrix4x4.CreateTranslation(new Vector3(position, 0))); /// /// Prepends a raw matrix. /// /// The matrix to prepend. /// The . - public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) - { - this.matrices.Insert(0, matrix); - return this; - } + public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) => this.Prepend(_ => matrix); /// /// Appends a raw matrix. /// /// The matrix to append. /// The . - public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) - { - this.matrices.Add(matrix); - return this; - } + public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) => this.Append(_ => matrix); + + /// + /// Returns the combined matrix for a given source size. + /// + /// The source image size. + /// The . + public Matrix4x4 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); /// - /// Returns the combined matrix. + /// Returns the combined matrix for a given source rectangle. /// + /// The rectangle in the source image. /// The . - public Matrix4x4 BuildMatrix() + public Matrix4x4 BuildMatrix(Rectangle sourceRectangle) { - Matrix4x4 matrix = Matrix4x4.Identity; + Guard.MustBeGreaterThan(sourceRectangle.Width, 0, nameof(sourceRectangle)); + Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); // Translate the origin matrix to cater for source rectangle offsets. - if (!this.sourceRectangle.Equals(default)) - { - matrix *= Matrix4x4.CreateTranslation(new Vector3(-this.sourceRectangle.Location, 0)); - } + var matrix = Matrix4x4.CreateTranslation(new Vector3(-sourceRectangle.Location, 0)); + + Size size = sourceRectangle.Size; - foreach (Matrix4x4 m in this.matrices) + foreach (Func factory in this.matrixFactories) { - matrix *= m; + matrix *= factory(size); } return matrix; } + + private ProjectiveTransformBuilder Prepend(Func factory) + { + this.matrixFactories.Insert(0, factory); + return this; + } + + private ProjectiveTransformBuilder Append(Func factory) + { + this.matrixFactories.Add(factory); + return this; + } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/TransformExtensions.cs b/src/ImageSharp/Processing/TransformExtensions.cs index de4a3e5ba..db14b6baf 100644 --- a/src/ImageSharp/Processing/TransformExtensions.cs +++ b/src/ImageSharp/Processing/TransformExtensions.cs @@ -15,40 +15,32 @@ namespace SixLabors.ImageSharp.Processing public static class TransformExtensions { /// - /// Performs an affine transform of an image using the specified sampling algorithm. + /// Performs an affine transform of an image. /// /// The pixel format. - /// The . - /// The source rectangle - /// The transformation matrix. - /// The size of the result image. - /// The to perform the resampling. + /// The image to transform. + /// The affine transform builder. /// The public static IImageProcessingContext Transform( - this IImageProcessingContext ctx, - Rectangle sourceRectangle, - Matrix3x2 transform, - Size targetDimensions, - IResampler sampler) + this IImageProcessingContext source, + AffineTransformBuilder builder) where TPixel : struct, IPixel - { - return ctx.ApplyProcessor( - new AffineTransformProcessor(transform, sampler, targetDimensions), - sourceRectangle); - } + => Transform(source, builder, KnownResamplers.Bicubic); /// - /// Performs an affine transform of an image. + /// Performs an affine transform of an image using the specified sampling algorithm. /// /// The pixel format. - /// The image to transform. + /// The . /// The affine transform builder. + /// The to perform the resampling. /// The public static IImageProcessingContext Transform( - this IImageProcessingContext source, - AffineTransformBuilder builder) + this IImageProcessingContext ctx, + AffineTransformBuilder builder, + IResampler sampler) where TPixel : struct, IPixel - => Transform(source, builder, KnownResamplers.Bicubic); + => ctx.Transform(new Rectangle(Point.Empty, ctx.GetCurrentSize()), builder, sampler); /// /// Performs an affine transform of an image using the specified sampling algorithm. @@ -76,16 +68,22 @@ namespace SixLabors.ImageSharp.Processing /// /// The pixel format. /// The . - /// The affine transform builder. + /// The source rectangle + /// The transformation matrix. + /// The size of the result image. /// The to perform the resampling. /// The public static IImageProcessingContext Transform( this IImageProcessingContext ctx, - AffineTransformBuilder builder, + Rectangle sourceRectangle, + Matrix3x2 transform, + Size targetDimensions, IResampler sampler) where TPixel : struct, IPixel { - return ctx.Transform(new Rectangle(Point.Empty, ctx.GetCurrentSize()), builder, sampler); + return ctx.ApplyProcessor( + new AffineTransformProcessor(transform, sampler, targetDimensions), + sourceRectangle); } /// @@ -105,15 +103,59 @@ namespace SixLabors.ImageSharp.Processing /// Performs a projective transform of an image using the specified sampling algorithm. /// /// The pixel format. - /// The image to transform. + /// The . /// The projective transform builder. /// The to perform the resampling. /// The public static IImageProcessingContext Transform( - this IImageProcessingContext source, + this IImageProcessingContext ctx, + ProjectiveTransformBuilder builder, + IResampler sampler) + where TPixel : struct, IPixel + => ctx.Transform(new Rectangle(Point.Empty, ctx.GetCurrentSize()), builder, sampler); + + /// + /// Performs a projective transform of an image using the specified sampling algorithm. + /// + /// The pixel format. + /// The . + /// The source rectangle + /// The projective transform builder. + /// The to perform the resampling. + /// The + public static IImageProcessingContext Transform( + this IImageProcessingContext ctx, + Rectangle sourceRectangle, ProjectiveTransformBuilder builder, IResampler sampler) where TPixel : struct, IPixel - => source.ApplyProcessor(new ProjectiveTransformProcessor(builder.BuildMatrix(), sampler, builder.Size)); + { + Matrix4x4 transform = builder.BuildMatrix(sourceRectangle); + Size targetDimensions = TransformUtils.GetTransformedSize(sourceRectangle.Size, transform); + return ctx.Transform(sourceRectangle, transform, targetDimensions, sampler); + } + + /// + /// Performs a projective transform of an image using the specified sampling algorithm. + /// + /// The pixel format. + /// The . + /// The source rectangle + /// The transformation matrix. + /// The size of the result image. + /// The to perform the resampling. + /// The + public static IImageProcessingContext Transform( + this IImageProcessingContext ctx, + Rectangle sourceRectangle, + Matrix4x4 transform, + Size targetDimensions, + IResampler sampler) + where TPixel : struct, IPixel + { + return ctx.ApplyProcessor( + new ProjectiveTransformProcessor(transform, sampler, targetDimensions), + sourceRectangle); + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index e02585168..bdc66641a 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -1,28 +1,31 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using SixLabors.ImageSharp.Processing; -using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; -using Xunit; namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class AffineTransformBuilderTests : TransformBuilderTestBase { protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 center) => builder.AppendRotationRadians(radians, center); protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians, Vector2 center) => - builder.PrependRotationRadians(radians, center); + + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) => + builder.PrependRotationRadians(radians, origin); protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); @@ -35,4 +38,4 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms return Vector2.Transform(sourcePoint, matrix); } } -} +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 01448ac59..287d7be49 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -1,60 +1,40 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using SixLabors.ImageSharp.Processing; using SixLabors.Primitives; -using Xunit; namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class ProjectiveTransformBuilderTests : TransformBuilderTestBase { - [Fact] - public void ConstructorAssignsProperties() - { - var s = new Size(1, 1); - var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); - Assert.Equal(s, builder.Size); - } - - [Fact] - public void ConstructorThrowsInvalid() - { - Assert.Throws(() => - { - var s = new Size(0, 1); - var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); - }); - - Assert.Throws(() => - { - var s = new Size(1, 0); - var builder = new ProjectiveTransformBuilder(new Rectangle(Point.Empty, s)); - }); - } - - protected override ProjectiveTransformBuilder CreateBuilder(Rectangle rectangle) => new ProjectiveTransformBuilder(rectangle); + protected override ProjectiveTransformBuilder CreateBuilder(Rectangle rectangle) => new ProjectiveTransformBuilder(); protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 center) => builder.AppendRotationRadians(radians, center); protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); - protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 center) => - builder.PrependRotationRadians(radians, center); + + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => + builder.PrependRotationRadians(radians, origin); protected override Vector2 Execute( ProjectiveTransformBuilder builder, Rectangle rectangle, Vector2 sourcePoint) { - Matrix4x4 matrix = builder.BuildMatrix(); + Matrix4x4 matrix = builder.BuildMatrix(rectangle); return Vector2.Transform(sourcePoint, matrix); } } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs index 9436b7828..1da660d22 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms IResampler sampler = GetResampler(resamplerName); using (Image image = provider.GetImage()) { - ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() .AppendTaper(TaperSide.Right, TaperCorner.Both, .5F); image.Mutate(i => i.Transform(builder, sampler)); @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { using (Image image = provider.GetImage()) { - ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() .AppendTaper(taperSide, taperCorner, .5F); image.Mutate(i => i.Transform(builder)); @@ -113,7 +113,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Matrix4x4 matrix = Matrix4x4.Identity; matrix.M13 = 0.01F; - ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder(image.Size()) + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() .AppendMatrix(matrix); image.Mutate(i => i.Transform(builder)); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index dffa3c7ac..720c87ced 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -18,7 +18,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms new TheoryData { // scale, translate, source, expectedDest - { Vector2.One, Vector2.Zero, Vector2.Zero, Vector2.Zero }, { Vector2.One, Vector2.Zero, new Vector2(10, 20), new Vector2(10, 20) }, { Vector2.One, new Vector2(3, 1), new Vector2(10, 20), new Vector2(13, 21) }, @@ -44,7 +43,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms new TheoryData { // translate, scale, source, expectedDest - { Vector2.Zero, Vector2.One, Vector2.Zero, Vector2.Zero }, { Vector2.Zero, Vector2.One, new Vector2(10, 20), new Vector2(10, 20) }, { new Vector2(3, 1), new Vector2(2, 0.5f), new Vector2(10, 20), new Vector2(26, 10.5f) }, @@ -183,14 +181,20 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract TBuilder CreateBuilder(Rectangle rectangle); protected abstract void AppendTranslation(TBuilder builder, PointF translate); + protected abstract void AppendScale(TBuilder builder, SizeF scale); + protected abstract void AppendRotationRadians(TBuilder builder, float radians); + protected abstract void AppendRotationRadians(TBuilder builder, float radians, Vector2 center); protected abstract void PrependTranslation(TBuilder builder, PointF translate); + protected abstract void PrependScale(TBuilder builder, SizeF scale); + protected abstract void PrependRotationRadians(TBuilder builder, float radians); - protected abstract void PrependRotationRadians(TBuilder b1, float v, Vector2 vector2); + + protected abstract void PrependRotationRadians(TBuilder builder, float radians, Vector2 origin); protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees)); @@ -199,7 +203,5 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees), center); protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); - - private static float Sqrt(float a) => (float)Math.Sqrt(a); } } \ No newline at end of file From 091ff6b5f545761e7f4f1a7fab17c538ac048221 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 27 Nov 2018 10:15:52 +0000 Subject: [PATCH 216/238] Add large jpeg to 32bit skip --- tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 5977e59cf..15f7f92a8 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -49,7 +49,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Issues.NoEoiProgressive517, TestImages.Jpeg.Issues.BadRstProgressive518, TestImages.Jpeg.Issues.InvalidEOI695, - TestImages.Jpeg.Issues.ExifResizeOutOfRange696 + TestImages.Jpeg.Issues.ExifResizeOutOfRange696, + TestImages.Jpeg.Issues.ExifGetString750Transform }; return !TestEnvironment.Is64BitProcess && largeImagesToSkipOn32Bit.Contains(provider.SourceFileOrDescription); From 34a20c82f104183b236fdef57ad83f889d0f7d9e Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 27 Nov 2018 10:23:06 +0000 Subject: [PATCH 217/238] Remove unused variables --- .../Processors/Transforms/AffineTransformProcessor.cs | 4 +--- .../Processors/Transforms/ProjectiveTransformProcessor.cs | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index aabaa63cf..5a3b5943b 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -69,14 +69,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Handle tranforms that result in output identical to the original. if (this.TransformMatrix.Equals(default) || this.TransformMatrix.Equals(Matrix3x2.Identity)) { - // The cloned will be blank here copy all the pixel data over + // The clone will be blank here copy all the pixel data over source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); return; } - int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; - var targetBounds = new Rectangle(Point.Empty, this.TargetDimensions); // Convert from screen to world space. diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index 273156e2e..98d488a42 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -65,14 +65,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Handle tranforms that result in output identical to the original. if (this.TransformMatrix.Equals(default) || this.TransformMatrix.Equals(Matrix4x4.Identity)) { - // The cloned will be blank here copy all the pixel data over + // The clone will be blank here copy all the pixel data over source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); return; } - int height = this.TargetDimensions.Height; int width = this.TargetDimensions.Width; - var targetBounds = new Rectangle(Point.Empty, this.TargetDimensions); // Convert from screen to world space. @@ -129,7 +127,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { // Use the single precision position to calculate correct bounding pixels // otherwise we get rogue pixels outside of the bounds. - var v3 = Vector3.Transform(new Vector3(x, y, 1), matrix); + var v3 = Vector3.Transform(new Vector3(x, y, 1F), matrix); Vector2 point = new Vector2(v3.X, v3.Y) / MathF.Max(v3.Z, Epsilon); kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); From adc9d76481fdd707fb6c6b793bacd2bdc25f2435 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 27 Nov 2018 12:12:42 +0000 Subject: [PATCH 218/238] Add Rotate(degrees, origin) --- .../Processing/AffineTransformBuilder.cs | 22 ++++++++++-- .../Processing/ProjectiveTransformBuilder.cs | 34 ++++++++++++++----- .../Transforms/AffineTransformBuilderTests.cs | 7 ++-- .../ProjectiveTransformBuilderTests.cs | 7 ++-- .../Transforms/TransformBuilderTestBase.cs | 8 ++--- 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index 29c37d7bf..ef0b24f81 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -35,7 +35,16 @@ namespace SixLabors.ImageSharp.Processing => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// - /// Prepends a centered rotation matrix using the given rotation in radians. + /// Prepends a rotation matrix using the given rotation in degrees at the given origin. + /// + /// The amount of rotation, in degrees. + /// The rotation origin point. + /// The . + public AffineTransformBuilder PrependRotationDegrees(float degrees, Vector2 origin) + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees), origin); + + /// + /// Prepends a rotation matrix using the given rotation in radians at the given origin. /// /// The amount of rotation, in radians. /// The rotation origin point. @@ -62,7 +71,16 @@ namespace SixLabors.ImageSharp.Processing => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); /// - /// Appends a centered rotation matrix using the given rotation in radians. + /// Appends a rotation matrix using the given rotation in degrees at the given origin. + /// + /// The amount of rotation, in degrees. + /// The rotation origin point. + /// The . + public AffineTransformBuilder AppendRotationDegrees(float degrees, Vector2 origin) + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees), origin); + + /// + /// Appends a rotation matrix using the given rotation in radians at the given origin. /// /// The amount of rotation, in radians. /// The rotation origin point. diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index a905467bb..5a19b890d 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -53,13 +53,22 @@ namespace SixLabors.ImageSharp.Processing => this.Prepend(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); /// - /// Appends a centered rotation matrix using the given rotation in radians. + /// Prepends a centered rotation matrix using the given rotation in degrees at the given origin. + /// + /// The amount of rotation, in radians. + /// The rotation origin point. + /// The . + internal ProjectiveTransformBuilder PrependRotationDegrees(float degrees, Vector2 origin) + => this.PrependRotationRadians(GeometryUtilities.DegreeToRadian(degrees), origin); + + /// + /// Prepends a centered rotation matrix using the given rotation in radians at the given origin. /// /// The amount of rotation, in radians. - /// The rotation center. + /// The rotation origin point. /// The . - internal ProjectiveTransformBuilder PrependRotationRadians(float radians, Vector2 centerPoint) - => this.PrependMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0))); + internal ProjectiveTransformBuilder PrependRotationRadians(float radians, Vector2 origin) + => this.PrependMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(origin, 0))); /// /// Appends a centered rotation matrix using the given rotation in degrees. @@ -78,13 +87,22 @@ namespace SixLabors.ImageSharp.Processing => this.Append(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); /// - /// Appends a centered rotation matrix using the given rotation in radians. + /// Appends a centered rotation matrix using the given rotation in degrees at the given origin. + /// + /// The amount of rotation, in radians. + /// The rotation origin point. + /// The . + internal ProjectiveTransformBuilder AppendRotationDegrees(float degrees, Vector2 origin) + => this.AppendRotationRadians(GeometryUtilities.DegreeToRadian(degrees), origin); + + /// + /// Appends a centered rotation matrix using the given rotation in radians at the given origin. /// /// The amount of rotation, in radians. - /// The rotation center. + /// The rotation origin point. /// The . - internal ProjectiveTransformBuilder AppendRotationRadians(float radians, Vector2 centerPoint) - => this.AppendMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(centerPoint, 0))); + internal ProjectiveTransformBuilder AppendRotationRadians(float radians, Vector2 origin) + => this.AppendMatrix(Matrix4x4.CreateRotationZ(radians, new Vector3(origin, 0))); /// /// Prepends a scale matrix from the given uniform scale. diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index bdc66641a..14b867264 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -15,8 +15,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 center) => - builder.AppendRotationRadians(radians, center); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) => builder.AppendRotationRadians(radians, origin); + + protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); + + protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 287d7be49..9f58826cd 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -17,8 +17,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); - protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 center) => - builder.AppendRotationRadians(radians, center); + protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => builder.AppendRotationRadians(radians, origin); + + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); + + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index 720c87ced..43ad756e0 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -186,7 +186,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract void AppendRotationRadians(TBuilder builder, float radians); - protected abstract void AppendRotationRadians(TBuilder builder, float radians, Vector2 center); + protected abstract void AppendRotationRadians(TBuilder builder, float radians, Vector2 origin); protected abstract void PrependTranslation(TBuilder builder, PointF translate); @@ -196,11 +196,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract void PrependRotationRadians(TBuilder builder, float radians, Vector2 origin); - protected virtual void AppendRotationDegrees(TBuilder builder, float degrees) => - this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees)); + protected abstract void AppendRotationDegrees(TBuilder builder, float degrees); - protected virtual void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 center) => - this.AppendRotationRadians(builder, GeometryUtilities.DegreeToRadian(degrees), center); + protected abstract void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 origin); protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); } From 8cd07dc750d8f10211486e687256349a8a38b981 Mon Sep 17 00:00:00 2001 From: Anton Firsov Date: Tue, 27 Nov 2018 21:37:57 +0100 Subject: [PATCH 219/238] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 188c11ff3..19941e65e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -20,6 +20,11 @@ * Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes. +#### **Running tests and Debugging** + +* Expected test output is pulled in as a submodule from the [ImageSharp.Tests.Images repository](https://github.com/SixLabors/Imagesharp.Tests.Images/tree/master/ReferenceOutput). To succesfully run tests, make sure that you have updated the submodules! +* Debugging (running tests in Debug mode) is only supported on .NET Core 2.1, because of JIT Code Generation bugs like dotnet/coreclr#16443 or dotnet/coreclr#20657 + #### **Do you have questions about consuming the library or the source code?** * Ask any question about how to use ImageSharp in the [ImageSharp Gitter Chat Room](https://gitter.im/ImageSharp/General). From 435be3c302498240a514212906961041a77bf5b8 Mon Sep 17 00:00:00 2001 From: Anton Firsov Date: Tue, 27 Nov 2018 21:41:01 +0100 Subject: [PATCH 220/238] Fix links --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 19941e65e..01c09d223 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -23,7 +23,7 @@ #### **Running tests and Debugging** * Expected test output is pulled in as a submodule from the [ImageSharp.Tests.Images repository](https://github.com/SixLabors/Imagesharp.Tests.Images/tree/master/ReferenceOutput). To succesfully run tests, make sure that you have updated the submodules! -* Debugging (running tests in Debug mode) is only supported on .NET Core 2.1, because of JIT Code Generation bugs like dotnet/coreclr#16443 or dotnet/coreclr#20657 +* Debugging (running tests in Debug mode) is only supported on .NET Core 2.1, because of JIT Code Generation bugs like [dotnet/coreclr#16443](https://github.com/dotnet/coreclr/issues/16443) or [dotnet/coreclr#20657](https://github.com/dotnet/coreclr/issues/20657) #### **Do you have questions about consuming the library or the source code?** From d3af53125506a387b3733a832a218f2dd754fdf8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 27 Nov 2018 20:44:35 +0100 Subject: [PATCH 221/238] refactor KernelMap initialization --- .../Processors/Transforms/KernelMap.cs | 94 +++++++++++-------- .../KernelMapTests.ReferenceKernelMap.cs | 4 +- .../Processors/Transforms/KernelMapTests.cs | 18 +++- .../Processors/Transforms/ResizeTests.cs | 31 +++++- 4 files changed, 102 insertions(+), 45 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs index 3f2bf8dda..96eb97649 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs @@ -15,28 +15,38 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal class KernelMap : IDisposable { - private readonly Buffer2D data; + private readonly IResampler sampler; - private readonly ResizeKernel[] kernels; + private readonly int sourceSize; + + private readonly float ratio; - private int period; + private readonly float scale; - private int radius; + private readonly int radius; - private int periodicRegionMin; + private readonly Buffer2D data; - private int periodicRegionMax; + private readonly ResizeKernel[] kernels; - private KernelMap(MemoryAllocator memoryAllocator, int destinationSize, int radius, int period) + private KernelMap( + MemoryAllocator memoryAllocator, + IResampler sampler, + int sourceSize, + int destinationSize, + int bufferHeight, + float ratio, + float scale, + int radius) { - this.DestinationSize = destinationSize; - this.period = period; + this.sampler = sampler; + this.ratio = ratio; + this.scale = scale; this.radius = radius; - this.periodicRegionMin = period + radius; - this.periodicRegionMax = destinationSize - radius; - - int width = (radius * 2) + 1; - this.data = memoryAllocator.Allocate2D(width, destinationSize, AllocationOptions.Clean); + this.sourceSize = sourceSize; + this.DestinationSize = destinationSize; + int maxWidth = (radius * 2) + 1; + this.data = memoryAllocator.Allocate2D(maxWidth, bufferHeight, AllocationOptions.Clean); this.kernels = new ResizeKernel[destinationSize]; } @@ -79,61 +89,69 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; - int radius = (int)MathF.Ceiling(scale * sampler.Radius); - var result = new KernelMap(memoryAllocator, destinationSize, radius, period); - for (int i = 0; i < destinationSize; i++) + var result = new KernelMap( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + destinationSize, + ratio, + scale, + radius); + + result.BasicInit(); + + return result; + } + + private void BasicInit() + { + for (int i = 0; i < this.DestinationSize; i++) { - float center = ((i + .5F) * ratio) - .5F; + float center = ((i + .5F) * this.ratio) - .5F; // Keep inside bounds. - int left = (int)MathF.Ceiling(center - radius); + int left = (int)MathF.Ceiling(center - this.radius); if (left < 0) { left = 0; } - int right = (int)MathF.Floor(center + radius); - if (right > sourceSize - 1) + int right = (int)MathF.Floor(center + this.radius); + if (right > this.sourceSize - 1) { - right = sourceSize - 1; + right = this.sourceSize - 1; } float sum = 0; - ResizeKernel ws = result.CreateKernel(i, left, right); - result.kernels[i] = ws; + ResizeKernel kernel = this.CreateKernel(i, left, right); + this.kernels[i] = kernel; - ref float weightsBaseRef = ref MemoryMarshal.GetReference(ws.GetValues()); + ref float kernelBaseRef = ref MemoryMarshal.GetReference(kernel.GetValues()); for (int j = left; j <= right; j++) { - float weight = sampler.GetValue((j - center) / scale); - sum += weight; + float value = this.sampler.GetValue((j - center) / this.scale); + sum += value; // weights[j - left] = weight: - Unsafe.Add(ref weightsBaseRef, j - left) = weight; + Unsafe.Add(ref kernelBaseRef, j - left) = value; } // Normalize, best to do it here rather than in the pixel loop later on. if (sum > 0) { - for (int w = 0; w < ws.Length; w++) + for (int w = 0; w < kernel.Length; w++) { // weights[w] = weights[w] / sum: - ref float wRef = ref Unsafe.Add(ref weightsBaseRef, w); - wRef /= sum; + ref float kRef = ref Unsafe.Add(ref kernelBaseRef, w); + kRef /= sum; } } } - - return result; - } - - private int ReduceIndex(int destIndex) - { - return destIndex; } /// diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index cf0e94e8b..3786ec6e3 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public ReferenceKernel GetKernel(int destinationIndex) => this.kernels[destinationIndex]; - public static ReferenceKernelMap Calculate(IResampler sampler, int destinationSize, int sourceSize) + public static ReferenceKernelMap Calculate(IResampler sampler, int destinationSize, int sourceSize, bool normalize = true) { float ratio = (float)sourceSize / destinationSize; float scale = ratio; @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms result.Add(new ReferenceKernel(left, values)); - if (sum > 0) + if (sum > 0 && normalize) { for (int w = 0; w < values.Length; w++) { diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index c5916ce0b..69de5dbbf 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -35,6 +35,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Bicubic), 500, 200 }, { nameof(KnownResamplers.Bicubic), 200, 500 }, + { nameof(KnownResamplers.Bicubic), 10, 25 }, + { nameof(KnownResamplers.Lanczos3), 16, 12 }, { nameof(KnownResamplers.Lanczos3), 12, 16 }, { nameof(KnownResamplers.Lanczos3), 12, 9 }, @@ -43,12 +45,26 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos3), 8, 6 }, { nameof(KnownResamplers.Lanczos3), 20, 12 }, + { nameof(KnownResamplers.Lanczos3), 5, 25 }, + { nameof(KnownResamplers.Lanczos3), 5, 50 }, + { nameof(KnownResamplers.Lanczos8), 500, 200 }, { nameof(KnownResamplers.Lanczos8), 100, 10 }, { nameof(KnownResamplers.Lanczos8), 100, 80 }, { nameof(KnownResamplers.Lanczos8), 10, 100 }, }; + [Theory] + [MemberData(nameof(KernelMapData))] + public void PrintNonNormalizedKernelMap(string resamplerName, int srcSize, int destSize) + { + IResampler resampler = TestUtils.GetResampler(resamplerName); + + var kernelMap = ReferenceKernelMap.Calculate(resampler, destSize, srcSize, false); + + this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); + } + [Theory] [MemberData(nameof(KernelMapData))] public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) @@ -60,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms #if DEBUG this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); - this.Output.WriteLine($"Reference KernelMap:\n{PrintKernelMap(referenceMap)}\n"); + // this.Output.WriteLine($"Reference KernelMap:\n{PrintKernelMap(referenceMap)}\n"); #endif for (int i = 0; i < kernelMap.DestinationSize; i++) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index bec64e4d3..42cb083f1 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -11,6 +11,7 @@ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.Primitives; using Xunit; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { @@ -20,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F); - public static readonly TheoryData AllReSamplers = + public static readonly TheoryData AllResamplers = new TheoryData { { "Bicubic", KnownResamplers.Bicubic }, @@ -40,9 +41,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms }; [Theory] - [WithTestPatternImages(nameof(AllReSamplers), 100, 100, DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllReSamplers), DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllReSamplers), DefaultPixelType, 0.3f)] + [WithTestPatternImages(nameof(AllResamplers), 100, 100, DefaultPixelType, 0.5f)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.5f)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.3f)] public void Resize_WorksWithAllResamplers(TestImageProvider provider, string name, IResampler sampler, float ratio) where TPixel : struct, IPixel { @@ -57,6 +58,28 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } + [Theory] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 1)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 10)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Lanczos3), 10)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Lanczos8), 10)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 10)] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 1)] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 5)] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 5)] + public void ScaleUp(TestImageProvider provider, string samplerName, float ratio) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage()) + { + SizeF newSize = image.Size() * ratio; + image.Mutate(x => x.Resize((Size)newSize, TestUtils.GetResampler(samplerName), false)); + FormattableString details = $"{samplerName}_{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; + + image.DebugSave(provider, details); + } + } + [Theory] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)] From ca61df8e64408be8e5616f4eb33dba1ccca51bdc Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 00:51:15 +0100 Subject: [PATCH 222/238] rename KernelMap to ResizeKernelMap, introduce MosaicKernelMap, move source code --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 3 +- src/ImageSharp/ImageSharp.csproj.DotSettings | 4 +- .../{ => Resamplers}/BicubicResampler.cs | 0 .../{ => Resamplers}/BoxResampler.cs | 0 .../{ => Resamplers}/CatmullRomResampler.cs | 0 .../{ => Resamplers}/HermiteResampler.cs | 0 .../{ => Resamplers}/Lanczos2Resampler.cs | 0 .../{ => Resamplers}/Lanczos3Resampler.cs | 0 .../{ => Resamplers}/Lanczos5Resampler.cs | 0 .../{ => Resamplers}/Lanczos8Resampler.cs | 0 .../MitchellNetravaliResampler.cs | 0 .../NearestNeighborResampler.cs | 0 .../{ => Resamplers}/RobidouxResampler.cs | 0 .../RobidouxSharpResampler.cs | 0 .../{ => Resamplers}/SplineResampler.cs | 0 .../{ => Resamplers}/TriangleResampler.cs | 0 .../{ => Resamplers}/WelchResampler.cs | 0 .../Transforms/{ => Resize}/ResizeKernel.cs | 22 +++--- .../Resize/ResizeKernelMap.MosaicKernelMap.cs | 46 ++++++++++++ .../ResizeKernelMap.cs} | 70 ++++++++++++------- .../{ => Resize}/ResizeProcessor.cs | 8 +-- .../KernelMapTests.ReferenceKernelMap.cs | 2 +- .../Processors/Transforms/KernelMapTests.cs | 4 +- .../Processors/Transforms/ResizeTests.cs | 1 + 24 files changed, 115 insertions(+), 45 deletions(-) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/BicubicResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/BoxResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/CatmullRomResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/HermiteResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/Lanczos2Resampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/Lanczos3Resampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/Lanczos5Resampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/Lanczos8Resampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/MitchellNetravaliResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/NearestNeighborResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/RobidouxResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/RobidouxSharpResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/SplineResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/TriangleResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resamplers}/WelchResampler.cs (100%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resize}/ResizeKernel.cs (81%) create mode 100644 src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs rename src/ImageSharp/Processing/Processors/Transforms/{KernelMap.cs => Resize/ResizeKernelMap.cs} (69%) rename src/ImageSharp/Processing/Processors/Transforms/{ => Resize}/ResizeProcessor.cs (98%) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index f07ccb03b..45cb52fd9 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -5,6 +5,7 @@ using System; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.Primitives; namespace SixLabors.ImageSharp @@ -98,7 +99,7 @@ namespace SixLabors.ImageSharp /// /// Determine the Least Common Multiple (LCM) of two numbers. - /// TODO: This method might be useful for building a more compact + /// TODO: This method might be useful for building a more compact /// public static int LeastCommonMultiple(int a, int b) { diff --git a/src/ImageSharp/ImageSharp.csproj.DotSettings b/src/ImageSharp/ImageSharp.csproj.DotSettings index cd75f91b7..a7337240a 100644 --- a/src/ImageSharp/ImageSharp.csproj.DotSettings +++ b/src/ImageSharp/ImageSharp.csproj.DotSettings @@ -5,4 +5,6 @@ True True True - True \ No newline at end of file + True + True + True \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/BicubicResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/BicubicResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/BoxResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/BoxResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/CatmullRomResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CatmullRomResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/CatmullRomResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/CatmullRomResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/HermiteResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/HermiteResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/HermiteResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/HermiteResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/Lanczos2Resampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos2Resampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/Lanczos2Resampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos2Resampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/Lanczos3Resampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos3Resampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/Lanczos3Resampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos3Resampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/Lanczos5Resampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos5Resampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/Lanczos5Resampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos5Resampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/Lanczos8Resampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos8Resampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/Lanczos8Resampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/Lanczos8Resampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/MitchellNetravaliResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/MitchellNetravaliResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/MitchellNetravaliResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/MitchellNetravaliResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/NearestNeighborResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/NearestNeighborResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/RobidouxResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/RobidouxResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/RobidouxResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/RobidouxResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/RobidouxSharpResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/RobidouxSharpResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/RobidouxSharpResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/RobidouxSharpResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/SplineResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/SplineResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/SplineResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/SplineResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/TriangleResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/TriangleResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/WelchResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs similarity index 100% rename from src/ImageSharp/Processing/Processors/Transforms/WelchResampler.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs similarity index 81% rename from src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index 1ce9c9c91..1183de754 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -11,18 +11,21 @@ using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// - /// Points to a collection of of weights allocated in . + /// Points to a collection of of weights allocated in . /// - internal struct ResizeKernel + internal unsafe struct ResizeKernel { + private readonly float* bufferPtr; + /// /// Initializes a new instance of the struct. /// [MethodImpl(InliningOptions.ShortMethod)] - internal ResizeKernel(int left, Memory bufferSlice) + internal ResizeKernel(int left, float* bufferPtr, int length) { this.Left = left; - this.BufferSlice = bufferSlice; + this.bufferPtr = bufferPtr; + this.Length = length; } /// @@ -30,22 +33,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// public int Left { get; } - /// - /// Gets the slice of the buffer containing the weights values. - /// - public Memory BufferSlice { get; } - /// /// Gets the the length of the kernel /// - public int Length => this.BufferSlice.Length; + public int Length { get; } /// - /// Gets the span representing the portion of the that this window covers + /// Gets the span representing the portion of the that this window covers /// /// The [MethodImpl(InliningOptions.ShortMethod)] - public Span GetValues() => this.BufferSlice.Span; + public Span GetValues() => new Span(this.bufferPtr, this.Length); /// /// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this instance. diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs new file mode 100644 index 000000000..b815d05cb --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs @@ -0,0 +1,46 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +using SixLabors.Memory; + +namespace SixLabors.ImageSharp.Processing.Processors.Transforms +{ + /// + /// Contains + /// + internal partial class ResizeKernelMap + { + /// + /// Memory-optimized where repeating rows are stored only once. + /// + private sealed class MosaicKernelMap : ResizeKernelMap + { + private readonly int period; + + private readonly int cornerInterval; + + public MosaicKernelMap( + MemoryAllocator memoryAllocator, + IResampler sampler, + int sourceSize, + int destinationSize, + float ratio, + float scale, + int radius, + int period, + int cornerInterval) + : base( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + (cornerInterval * 2) + period, + ratio, + scale, + radius) + { + this.cornerInterval = cornerInterval; + this.period = period; + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs similarity index 69% rename from src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 96eb97649..443db72d9 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/KernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -11,9 +12,10 @@ using SixLabors.Memory; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// - /// Holds the values in an optimized contigous memory region. + /// Provides values from an optimized, + /// contigous memory region. /// - internal class KernelMap : IDisposable + internal partial class ResizeKernelMap : IDisposable { private readonly IResampler sampler; @@ -25,11 +27,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private readonly int radius; + private readonly MemoryHandle pinHandle; + private readonly Buffer2D data; private readonly ResizeKernel[] kernels; - private KernelMap( + private ResizeKernelMap( MemoryAllocator memoryAllocator, IResampler sampler, int sourceSize, @@ -47,16 +51,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.DestinationSize = destinationSize; int maxWidth = (radius * 2) + 1; this.data = memoryAllocator.Allocate2D(maxWidth, bufferHeight, AllocationOptions.Clean); + this.pinHandle = this.data.Memory.Pin(); this.kernels = new ResizeKernel[destinationSize]; } public int DestinationSize { get; } /// - /// Disposes instance releasing it's backing buffer. + /// Disposes instance releasing it's backing buffer. /// public void Dispose() { + this.pinHandle.Dispose(); this.data.Dispose(); } @@ -73,8 +79,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The destination size /// The source size /// The to use for buffer allocations - /// The - public static KernelMap Calculate( + /// The + public static ResizeKernelMap Calculate( IResampler sampler, int destinationSize, int sourceSize, @@ -88,25 +94,40 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms scale = 1F; } - int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; int radius = (int)MathF.Ceiling(scale * sampler.Radius); - - var result = new KernelMap( - memoryAllocator, - sampler, - sourceSize, - destinationSize, - destinationSize, - ratio, - scale, - radius); - - result.BasicInit(); + int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; + float center0 = (ratio - 1) * 0.5f; + int cornerInterval = (int)MathF.Ceiling((radius - center0 - 1) / ratio); + + bool useMosaic = 2 * (cornerInterval + period) < destinationSize; + + ResizeKernelMap result = useMosaic + ? new ResizeKernelMap( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + destinationSize, + ratio, + scale, + radius) + : new MosaicKernelMap( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + ratio, + scale, + radius, + period, + cornerInterval); + + result.Init(); return result; } - private void BasicInit() + protected virtual void Init() { for (int i = 0; i < this.DestinationSize; i++) { @@ -157,7 +178,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Slices a weights value at the given positions. /// - private ResizeKernel CreateKernel(int destIdx, int left, int rightIdx) + private unsafe ResizeKernel CreateKernel(int destIdx, int left, int rightIdx) { int length = rightIdx - left + 1; @@ -166,10 +187,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms throw new InvalidOperationException($"Error in KernelMap.CreateKernel({destIdx},{left},{rightIdx}): left > this.data.Width"); } - int flatStartIndex = destIdx * this.data.Width; + Span rowSpan = this.data.GetRowSpan(destIdx); - Memory bufferSlice = this.data.Memory.Slice(flatStartIndex, length); - return new ResizeKernel(left, bufferSlice); + ref float rowReference = ref MemoryMarshal.GetReference(rowSpan); + float* rowPtr = (float*)Unsafe.AsPointer(ref rowReference); + return new ResizeKernel(left, rowPtr, length); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs similarity index 98% rename from src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs index 7c9d39fc5..189e21de7 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs @@ -27,8 +27,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms where TPixel : struct, IPixel { // The following fields are not immutable but are optionally created on demand. - private KernelMap horizontalKernelMap; - private KernelMap verticalKernelMap; + private ResizeKernelMap horizontalKernelMap; + private ResizeKernelMap verticalKernelMap; /// /// Initializes a new instance of the class. @@ -165,13 +165,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { // Since all image frame dimensions have to be the same we can calculate this for all frames. MemoryAllocator memoryAllocator = source.GetMemoryAllocator(); - this.horizontalKernelMap = KernelMap.Calculate( + this.horizontalKernelMap = ResizeKernelMap.Calculate( this.Sampler, this.ResizeRectangle.Width, sourceRectangle.Width, memoryAllocator); - this.verticalKernelMap = KernelMap.Calculate( + this.verticalKernelMap = ResizeKernelMap.Calculate( this.Sampler, this.ResizeRectangle.Height, sourceRectangle.Height, diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 3786ec6e3..85a930fb9 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public partial class KernelMapTests { /// - /// Simplified reference implementation for functionality. + /// Simplified reference implementation for functionality. /// internal class ReferenceKernelMap { diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 69de5dbbf..4d005576c 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms IResampler resampler = TestUtils.GetResampler(resamplerName); var referenceMap = ReferenceKernelMap.Calculate(resampler, destSize, srcSize); - var kernelMap = KernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); + var kernelMap = ResizeKernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); #if DEBUG this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } - private static string PrintKernelMap(KernelMap kernelMap) => + private static string PrintKernelMap(ResizeKernelMap kernelMap) => PrintKernelMap(kernelMap, km => km.DestinationSize, (km, i) => km.GetKernel(i)); private static string PrintKernelMap(ReferenceKernelMap kernelMap) => diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 42cb083f1..839d26e71 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -58,6 +58,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } + // TODO: Merge with the previous theory + add test images [Theory] [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 1)] [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 10)] From 72a6a7e32103cec0da0ce982149e44c4083498a0 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 01:12:17 +0100 Subject: [PATCH 223/238] preparations for implementing MosaicKernelMap --- .../Transforms/Resize/ResizeKernel.cs | 12 +- .../Resize/ResizeKernelMap.MosaicKernelMap.cs | 5 + .../Transforms/Resize/ResizeKernelMap.cs | 131 ++++++++++-------- .../KernelMapTests.ReferenceKernelMap.cs | 2 +- .../Processors/Transforms/KernelMapTests.cs | 2 +- 5 files changed, 86 insertions(+), 66 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index 1183de754..b2d7d2116 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -41,9 +41,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Gets the span representing the portion of the that this window covers /// - /// The - [MethodImpl(InliningOptions.ShortMethod)] - public Span GetValues() => new Span(this.bufferPtr, this.Length); + /// The + /// + public Span Values + { + [MethodImpl(InliningOptions.ShortMethod)] + get => new Span(this.bufferPtr, this.Length); + } /// /// Computes the sum of vectors in 'rowSpan' weighted by weight values, pointed by this instance. @@ -53,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(InliningOptions.ShortMethod)] public Vector4 Convolve(Span rowSpan) { - ref float horizontalValues = ref MemoryMarshal.GetReference(this.GetValues()); + ref float horizontalValues = ref Unsafe.AsRef(this.bufferPtr); int left = this.Left; ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), left); diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs index b815d05cb..09ae79677 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs @@ -41,6 +41,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.cornerInterval = cornerInterval; this.period = period; } + + protected override void Initialize() + { + base.Initialize(); + } } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 443db72d9..ebb15d376 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } /// - /// Returns a for an index value between 0 and destinationSize - 1. + /// Returns a for an index value between 0 and DestinationSize - 1. /// [MethodImpl(InliningOptions.ShortMethod)] public ref ResizeKernel GetKernel(int destIdx) => ref this.kernels[destIdx]; @@ -101,93 +101,104 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms bool useMosaic = 2 * (cornerInterval + period) < destinationSize; + useMosaic = false; + ResizeKernelMap result = useMosaic - ? new ResizeKernelMap( - memoryAllocator, - sampler, - sourceSize, - destinationSize, - destinationSize, - ratio, - scale, - radius) - : new MosaicKernelMap( - memoryAllocator, - sampler, - sourceSize, - destinationSize, - ratio, - scale, - radius, - period, - cornerInterval); - - result.Init(); + ? new MosaicKernelMap( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + ratio, + scale, + radius, + period, + cornerInterval) + : new ResizeKernelMap( + memoryAllocator, + sampler, + sourceSize, + destinationSize, + destinationSize, + ratio, + scale, + radius); + + result.Initialize(); return result; } - protected virtual void Init() + protected virtual void Initialize() { - for (int i = 0; i < this.DestinationSize; i++) + for (int destRowIndex = 0; destRowIndex < this.DestinationSize; destRowIndex++) { - float center = ((i + .5F) * this.ratio) - .5F; + ResizeKernel kernel = this.BuildKernelRow(destRowIndex, destRowIndex); + this.kernels[destRowIndex] = kernel; + } + } - // Keep inside bounds. - int left = (int)MathF.Ceiling(center - this.radius); - if (left < 0) - { - left = 0; - } + private ResizeKernel BuildKernelRow(int destRowIndex, int dataRowIndex) + { + float center = ((destRowIndex + .5F) * this.ratio) - .5F; - int right = (int)MathF.Floor(center + this.radius); - if (right > this.sourceSize - 1) - { - right = this.sourceSize - 1; - } + // Keep inside bounds. + int left = (int)MathF.Ceiling(center - this.radius); + if (left < 0) + { + left = 0; + } - float sum = 0; + int right = (int)MathF.Floor(center + this.radius); + if (right > this.sourceSize - 1) + { + right = this.sourceSize - 1; + } - ResizeKernel kernel = this.CreateKernel(i, left, right); - this.kernels[i] = kernel; + float sum = 0; - ref float kernelBaseRef = ref MemoryMarshal.GetReference(kernel.GetValues()); + ResizeKernel kernel = this.GetKernel(dataRowIndex, left, right); - for (int j = left; j <= right; j++) - { - float value = this.sampler.GetValue((j - center) / this.scale); - sum += value; + ref float kernelBaseRef = ref MemoryMarshal.GetReference(kernel.Values); - // weights[j - left] = weight: - Unsafe.Add(ref kernelBaseRef, j - left) = value; - } + for (int j = left; j <= right; j++) + { + float value = this.sampler.GetValue((j - center) / this.scale); + sum += value; - // Normalize, best to do it here rather than in the pixel loop later on. - if (sum > 0) + // weights[j - left] = weight: + Unsafe.Add(ref kernelBaseRef, j - left) = value; + } + + // Normalize, best to do it here rather than in the pixel loop later on. + if (sum > 0) + { + for (int w = 0; w < kernel.Length; w++) { - for (int w = 0; w < kernel.Length; w++) - { - // weights[w] = weights[w] / sum: - ref float kRef = ref Unsafe.Add(ref kernelBaseRef, w); - kRef /= sum; - } + // weights[w] = weights[w] / sum: + ref float kRef = ref Unsafe.Add(ref kernelBaseRef, w); + kRef /= sum; } } + + return kernel; } /// - /// Slices a weights value at the given positions. + /// Returns a referencing values of + /// at row . /// - private unsafe ResizeKernel CreateKernel(int destIdx, int left, int rightIdx) + private unsafe ResizeKernel GetKernel(int dataRowIndex, int left, int right) { - int length = rightIdx - left + 1; + int length = right - left + 1; if (length > this.data.Width) { - throw new InvalidOperationException($"Error in KernelMap.CreateKernel({destIdx},{left},{rightIdx}): left > this.data.Width"); + throw new InvalidOperationException( + $"Error in KernelMap.CreateKernel({dataRowIndex},{left},{right}): left > this.data.Width"); } - Span rowSpan = this.data.GetRowSpan(destIdx); + Span rowSpan = this.data.GetRowSpan(dataRowIndex); ref float rowReference = ref MemoryMarshal.GetReference(rowSpan); float* rowPtr = (float*)Unsafe.AsPointer(ref rowReference); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 85a930fb9..f7c3b27e5 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public static implicit operator ReferenceKernel(ResizeKernel orig) { - return new ReferenceKernel(orig.Left, orig.GetValues().ToArray()); + return new ReferenceKernel(orig.Left, orig.Values.ToArray()); } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 4d005576c..7b997e33f 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms Assert.Equal(referenceKernel.Length, kernel.Length); Assert.Equal(referenceKernel.Left, kernel.Left); float[] expectedValues = referenceKernel.Values; - Span actualValues = kernel.GetValues(); + Span actualValues = kernel.Values; Assert.Equal(expectedValues.Length, actualValues.Length); From 3e64863fba7d189a9c7cb0c4477347e271f275ea Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 02:16:01 +0100 Subject: [PATCH 224/238] MosaicKernelMap works! --- .../Transforms/Resize/ResizeKernel.cs | 9 ++++-- .../Resize/ResizeKernelMap.MosaicKernelMap.cs | 32 ++++++++++++++++++- .../Transforms/Resize/ResizeKernelMap.cs | 26 +++++++++------ .../Processors/Transforms/KernelMapTests.cs | 16 ++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index b2d7d2116..e10afce2e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -6,14 +6,12 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; - namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// /// Points to a collection of of weights allocated in . /// - internal unsafe struct ResizeKernel + internal readonly unsafe struct ResizeKernel { private readonly float* bufferPtr; @@ -73,5 +71,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return result; } + + internal ResizeKernel AlterLeftValue(int left) + { + return new ResizeKernel(left, this.bufferPtr, this.Length); + } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs index 09ae79677..cf660a72f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs @@ -1,5 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. + +using System; + using SixLabors.Memory; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -42,9 +45,36 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.period = period; } + internal override string Info => base.Info + $"|period:{this.period}|cornerInterval:{this.cornerInterval}"; + protected override void Initialize() { - base.Initialize(); + // Build top corner data + one period of the mosaic data: + int startOfFirstRepeatedMosaic = this.cornerInterval + this.period; + + for (int i = 0; i < startOfFirstRepeatedMosaic; i++) + { + ResizeKernel kernel = this.BuildKernel(i, i); + this.kernels[i] = kernel; + } + + // Copy the mosaics: + int bottomStartDest = this.DestinationSize - this.cornerInterval; + for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++) + { + float center = ((i + .5F) * this.ratio) - .5F; + int left = (int)MathF.Ceiling(center - this.radius); + ResizeKernel kernel = this.kernels[i - this.period]; + this.kernels[i] = kernel.AlterLeftValue(left); + } + + // Build bottom corner data: + int bottomStartData = this.cornerInterval + this.period; + for (int i = 0; i < this.cornerInterval; i++) + { + ResizeKernel kernel = this.BuildKernel(bottomStartDest + i, bottomStartData + i); + this.kernels[bottomStartDest + i] = kernel; + } } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index ebb15d376..262a39352 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -57,6 +57,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public int DestinationSize { get; } + internal virtual string Info => + $"radius:{this.radius}|sourceSize:{this.sourceSize}|destinationSize:{this.DestinationSize}|ratio:{this.ratio}|scale:{this.scale}"; + /// /// Disposes instance releasing it's backing buffer. /// @@ -97,11 +100,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int radius = (int)MathF.Ceiling(scale * sampler.Radius); int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; float center0 = (ratio - 1) * 0.5f; - int cornerInterval = (int)MathF.Ceiling((radius - center0 - 1) / ratio); + float firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; + int cornerInterval = (int)MathF.Ceiling(firstNonNegativeLeftVal); - bool useMosaic = 2 * (cornerInterval + period) < destinationSize; + // corner case for cornerInteval: + if (firstNonNegativeLeftVal == cornerInterval) + { + cornerInterval++; + } - useMosaic = false; + bool useMosaic = 2 * (cornerInterval + period) < destinationSize; ResizeKernelMap result = useMosaic ? new MosaicKernelMap( @@ -131,14 +139,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms protected virtual void Initialize() { - for (int destRowIndex = 0; destRowIndex < this.DestinationSize; destRowIndex++) + for (int i = 0; i < this.DestinationSize; i++) { - ResizeKernel kernel = this.BuildKernelRow(destRowIndex, destRowIndex); - this.kernels[destRowIndex] = kernel; + ResizeKernel kernel = this.BuildKernel(i, i); + this.kernels[i] = kernel; } } - private ResizeKernel BuildKernelRow(int destRowIndex, int dataRowIndex) + private ResizeKernel BuildKernel(int destRowIndex, int dataRowIndex) { float center = ((destRowIndex + .5F) * this.ratio) - .5F; @@ -157,7 +165,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float sum = 0; - ResizeKernel kernel = this.GetKernel(dataRowIndex, left, right); + ResizeKernel kernel = this.CreateKernel(dataRowIndex, left, right); ref float kernelBaseRef = ref MemoryMarshal.GetReference(kernel.Values); @@ -188,7 +196,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Returns a referencing values of /// at row . /// - private unsafe ResizeKernel GetKernel(int dataRowIndex, int left, int right) + private unsafe ResizeKernel CreateKernel(int dataRowIndex, int left, int right) { int length = right - left + 1; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 7b997e33f..f0a0d738b 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -48,6 +48,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos3), 5, 25 }, { nameof(KnownResamplers.Lanczos3), 5, 50 }, + { nameof(KnownResamplers.Lanczos3), 25, 5 }, + { nameof(KnownResamplers.Lanczos3), 50, 5 }, + { nameof(KnownResamplers.Lanczos3), 49, 5 }, + { nameof(KnownResamplers.Lanczos3), 31, 5 }, + { nameof(KnownResamplers.Lanczos8), 500, 200 }, { nameof(KnownResamplers.Lanczos8), 100, 10 }, { nameof(KnownResamplers.Lanczos8), 100, 80 }, @@ -75,8 +80,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var kernelMap = ResizeKernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); #if DEBUG + this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); - // this.Output.WriteLine($"Reference KernelMap:\n{PrintKernelMap(referenceMap)}\n"); #endif for (int i = 0; i < kernelMap.DestinationSize; i++) @@ -92,7 +97,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms Assert.Equal(expectedValues.Length, actualValues.Length); - var comparer = new ApproximateFloatComparer(1e-6f); + var comparer = new ApproximateFloatComparer(1e-4f); for (int x = 0; x < expectedValues.Length; x++) { @@ -116,12 +121,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { var bld = new StringBuilder(); + if (kernelMap is ResizeKernelMap actualMap) + { + bld.AppendLine(actualMap.Info); + } + int destinationSize = getDestinationSize(kernelMap); for (int i = 0; i < destinationSize; i++) { ReferenceKernel kernel = getKernel(kernelMap, i); - bld.Append($"({kernel.Left:D3}) || "); + bld.Append($"[{i:D3}] (L{kernel.Left:D3}) || "); Span span = kernel.Values; for (int j = 0; j < kernel.Length; j++) From 570fd5e1eaf4e1648d5eaec8b658a21dcdae59ee Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 02:24:35 +0100 Subject: [PATCH 225/238] format, docs, cleanup --- .../Transforms/Resize/ResizeKernel.cs | 4 ++ .../Resize/ResizeKernelMap.MosaicKernelMap.cs | 10 ++--- .../Transforms/Resize/ResizeKernelMap.cs | 37 ++++++++++++------- .../Processors/Transforms/KernelMapTests.cs | 4 +- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index e10afce2e..04bf6c3a4 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -72,6 +72,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return result; } + /// + /// Copy the contents of altering + /// to the value . + /// internal ResizeKernel AlterLeftValue(int left) { return new ResizeKernel(left, this.bufferPtr, this.Length); diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs index cf660a72f..e106b1ea0 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs @@ -24,8 +24,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public MosaicKernelMap( MemoryAllocator memoryAllocator, IResampler sampler, - int sourceSize, - int destinationSize, + int sourceLength, + int destinationLength, float ratio, float scale, int radius, @@ -34,8 +34,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms : base( memoryAllocator, sampler, - sourceSize, - destinationSize, + sourceLength, + destinationLength, (cornerInterval * 2) + period, ratio, scale, @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } // Copy the mosaics: - int bottomStartDest = this.DestinationSize - this.cornerInterval; + int bottomStartDest = this.DestinationLength - this.cornerInterval; for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++) { float center = ((i + .5F) * this.ratio) - .5F; diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 262a39352..ccb57114a 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -13,13 +13,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// /// Provides values from an optimized, - /// contigous memory region. + /// contiguous memory region. /// internal partial class ResizeKernelMap : IDisposable { private readonly IResampler sampler; - private readonly int sourceSize; + private readonly int sourceLength; private readonly float ratio; @@ -36,8 +36,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private ResizeKernelMap( MemoryAllocator memoryAllocator, IResampler sampler, - int sourceSize, - int destinationSize, + int sourceLength, + int destinationLength, int bufferHeight, float ratio, float scale, @@ -47,18 +47,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.ratio = ratio; this.scale = scale; this.radius = radius; - this.sourceSize = sourceSize; - this.DestinationSize = destinationSize; + this.sourceLength = sourceLength; + this.DestinationLength = destinationLength; int maxWidth = (radius * 2) + 1; this.data = memoryAllocator.Allocate2D(maxWidth, bufferHeight, AllocationOptions.Clean); this.pinHandle = this.data.Memory.Pin(); - this.kernels = new ResizeKernel[destinationSize]; + this.kernels = new ResizeKernel[destinationLength]; } - public int DestinationSize { get; } + /// + /// Gets the length of the destination row/column + /// + public int DestinationLength { get; } + /// + /// Gets a string of information to help debugging + /// internal virtual string Info => - $"radius:{this.radius}|sourceSize:{this.sourceSize}|destinationSize:{this.DestinationSize}|ratio:{this.ratio}|scale:{this.scale}"; + $"radius:{this.radius}|sourceSize:{this.sourceLength}|destinationSize:{this.DestinationLength}|ratio:{this.ratio}|scale:{this.scale}"; /// /// Disposes instance releasing it's backing buffer. @@ -104,7 +110,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int cornerInterval = (int)MathF.Ceiling(firstNonNegativeLeftVal); // corner case for cornerInteval: - if (firstNonNegativeLeftVal == cornerInterval) + if (firstNonNegativeLeftVal == cornerInterval) { cornerInterval++; } @@ -139,13 +145,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms protected virtual void Initialize() { - for (int i = 0; i < this.DestinationSize; i++) + for (int i = 0; i < this.DestinationLength; i++) { ResizeKernel kernel = this.BuildKernel(i, i); this.kernels[i] = kernel; } } + /// + /// Builds a for the row (in ) + /// referencing the data at row within , + /// so the data reusable by other data rows. + /// private ResizeKernel BuildKernel(int destRowIndex, int dataRowIndex) { float center = ((destRowIndex + .5F) * this.ratio) - .5F; @@ -158,9 +169,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } int right = (int)MathF.Floor(center + this.radius); - if (right > this.sourceSize - 1) + if (right > this.sourceLength - 1) { - right = this.sourceSize - 1; + right = this.sourceLength - 1; } float sum = 0; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index f0a0d738b..af98b9952 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); #endif - for (int i = 0; i < kernelMap.DestinationSize; i++) + for (int i = 0; i < kernelMap.DestinationLength; i++) { ResizeKernel kernel = kernelMap.GetKernel(i); @@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } private static string PrintKernelMap(ResizeKernelMap kernelMap) => - PrintKernelMap(kernelMap, km => km.DestinationSize, (km, i) => km.GetKernel(i)); + PrintKernelMap(kernelMap, km => km.DestinationLength, (km, i) => km.GetKernel(i)); private static string PrintKernelMap(ReferenceKernelMap kernelMap) => PrintKernelMap(kernelMap, km => km.DestinationSize, (km, i) => km.GetKernel(i)); From 450a417d34d7e2530072554fa5c8647a5be466ce Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 28 Nov 2018 14:21:53 +0000 Subject: [PATCH 226/238] Add Skew methods and tests. --- .../Processing/AffineTransformBuilder.cs | 58 ++++++++++++ .../Processors/Transforms/TransformUtils.cs | 12 +++ .../Processing/ProjectiveTransformBuilder.cs | 76 +++++++++++++++ .../Transforms/AffineTransformBuilderTests.cs | 51 +++++++--- .../ProjectiveTransformBuilderTests.cs | 30 ++++-- .../Transforms/TransformBuilderTestBase.cs | 94 ++++++++++++++++--- 6 files changed, 291 insertions(+), 30 deletions(-) diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index ef0b24f81..c3d01241c 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -145,6 +145,35 @@ namespace SixLabors.ImageSharp.Processing public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) => this.Prepend(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); + /// + /// Prepends a centered skew matrix from the give angles in radians. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The . + public AffineTransformBuilder PrependSkewRadians(float radiansX, float radiansY) + => this.Prepend(size => TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size)); + + /// + /// Prepends a skew matrix using the given angles in degrees at the given origin. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The skew origin point. + /// The . + public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY, Vector2 origin) + => this.PrependSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY), origin); + + /// + /// Prepends a skew matrix using the given angles in radians at the given origin. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The skew origin point. + /// The . + public AffineTransformBuilder PrependSkewRadians(float radiansX, float radiansY, Vector2 origin) + => this.PrependMatrix(Matrix3x2.CreateSkew(radiansX, radiansY, origin)); + /// /// Appends a centered skew matrix from the give angles in degrees. /// @@ -154,6 +183,35 @@ namespace SixLabors.ImageSharp.Processing public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) => this.Append(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); + /// + /// Appends a centered skew matrix from the give angles in radians. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The . + public AffineTransformBuilder AppendSkewRadians(float radiansX, float radiansY) + => this.Append(size => TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size)); + + /// + /// Appends a skew matrix using the given angles in degrees at the given origin. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The skew origin point. + /// The . + public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY, Vector2 origin) + => this.AppendSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY), origin); + + /// + /// Appends a skew matrix using the given angles in radians at the given origin. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The skew origin point. + /// The . + public AffineTransformBuilder AppendSkewRadians(float radiansX, float radiansY, Vector2 origin) + => this.AppendMatrix(Matrix3x2.CreateSkew(radiansX, radiansY, origin)); + /// /// Prepends a translation matrix from the given vector. /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index 6cef38f8f..24b15d309 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -46,6 +46,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateSkewDegrees(degreesX, degreesY, PointF.Empty)); + /// + /// Creates a centered skew matrix from the give angles in radians and the source size. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The source image size. + /// The . + public static Matrix3x2 CreateSkewMatrixRadians(float radiansX, float radiansY, Size size) + => CreateCenteredTransformMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateSkew(radiansX, radiansY, PointF.Empty)); + /// /// Gets the centered transform matrix based upon the source and destination rectangles. /// diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index 5a19b890d..c29941d07 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -152,6 +152,82 @@ namespace SixLabors.ImageSharp.Processing public ProjectiveTransformBuilder AppendScale(Vector2 scales) => this.AppendMatrix(Matrix4x4.CreateScale(new Vector3(scales, 1F))); + /// + /// Prepends a centered skew matrix from the give angles in degrees. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The . + internal ProjectiveTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) + => this.PrependSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY)); + + /// + /// Prepends a centered skew matrix from the give angles in radians. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The . + public ProjectiveTransformBuilder PrependSkewRadians(float radiansX, float radiansY) + => this.Prepend(size => new Matrix4x4(TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size))); + + /// + /// Prepends a skew matrix using the given angles in degrees at the given origin. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The skew origin point. + /// The . + public ProjectiveTransformBuilder PrependSkewDegrees(float degreesX, float degreesY, Vector2 origin) + => this.PrependSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY), origin); + + /// + /// Prepends a skew matrix using the given angles in radians at the given origin. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The skew origin point. + /// The . + public ProjectiveTransformBuilder PrependSkewRadians(float radiansX, float radiansY, Vector2 origin) + => this.PrependMatrix(new Matrix4x4(Matrix3x2.CreateSkew(radiansX, radiansY, origin))); + + /// + /// Appends a centered skew matrix from the give angles in degrees. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The . + internal ProjectiveTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) + => this.AppendSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY)); + + /// + /// Appends a centered skew matrix from the give angles in radians. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The . + public ProjectiveTransformBuilder AppendSkewRadians(float radiansX, float radiansY) + => this.Append(size => new Matrix4x4(TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size))); + + /// + /// Appends a skew matrix using the given angles in degrees at the given origin. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The skew origin point. + /// The . + public ProjectiveTransformBuilder AppendSkewDegrees(float degreesX, float degreesY, Vector2 origin) + => this.AppendSkewRadians(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY), origin); + + /// + /// Appends a skew matrix using the given angles in radians at the given origin. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The skew origin point. + /// The . + public ProjectiveTransformBuilder AppendSkewRadians(float radiansX, float radiansY, Vector2 origin) + => this.AppendMatrix(new Matrix4x4(Matrix3x2.CreateSkew(radiansX, radiansY, origin))); + /// /// Prepends a translation matrix from the given vector. /// diff --git a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs index 14b867264..70159e18a 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/AffineTransformBuilderTests.cs @@ -9,28 +9,55 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { public class AffineTransformBuilderTests : TransformBuilderTestBase { - protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); - protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees) + => builder.AppendRotationDegrees(degrees); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); + protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees, Vector2 origin) + => builder.AppendRotationDegrees(degrees, origin); - protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) => builder.AppendRotationRadians(radians, origin); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians) + => builder.AppendRotationRadians(radians); - protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); + protected override void AppendRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) + => builder.AppendRotationRadians(radians, origin); - protected override void AppendRotationDegrees(AffineTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); + protected override void AppendScale(AffineTransformBuilder builder, SizeF scale) + => builder.AppendScale(scale); - protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void AppendSkewDegrees(AffineTransformBuilder builder, float degreesX, float degreesY) + => builder.AppendSkewDegrees(degreesX, degreesY); - protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void AppendSkewDegrees(AffineTransformBuilder builder, float degreesX, float degreesY, Vector2 origin) + => builder.AppendSkewDegrees(degreesX, degreesY, origin); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void AppendSkewRadians(AffineTransformBuilder builder, float radiansX, float radiansY) + => builder.AppendSkewRadians(radiansX, radiansY); - protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) => - builder.PrependRotationRadians(radians, origin); + protected override void AppendSkewRadians(AffineTransformBuilder builder, float radiansX, float radiansY, Vector2 origin) + => builder.AppendSkewRadians(radiansX, radiansY, origin); - protected override AffineTransformBuilder CreateBuilder(Rectangle rectangle) => new AffineTransformBuilder(); + protected override void AppendTranslation(AffineTransformBuilder builder, PointF translate) + => builder.AppendTranslation(translate); + + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians) + => builder.PrependRotationRadians(radians); + + protected override void PrependRotationRadians(AffineTransformBuilder builder, float radians, Vector2 origin) + => builder.PrependRotationRadians(radians, origin); + + protected override void PrependScale(AffineTransformBuilder builder, SizeF scale) + => builder.PrependScale(scale); + + protected override void PrependSkewRadians(AffineTransformBuilder builder, float radiansX, float radiansY) + => builder.PrependSkewRadians(radiansX, radiansY); + + protected override void PrependSkewRadians(AffineTransformBuilder builder, float radiansX, float radiansY, Vector2 origin) + => builder.PrependSkewRadians(radiansX, radiansY, origin); + + protected override void PrependTranslation(AffineTransformBuilder builder, PointF translate) + => builder.PrependTranslation(translate); protected override Vector2 Execute( AffineTransformBuilder builder, diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs index 9f58826cd..d82cd1689 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformBuilderTests.cs @@ -11,24 +11,42 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms { protected override ProjectiveTransformBuilder CreateBuilder(Rectangle rectangle) => new ProjectiveTransformBuilder(); - protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); - protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); + protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.AppendRotationRadians(radians); protected override void AppendRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => builder.AppendRotationRadians(radians, origin); - protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees) => builder.AppendRotationDegrees(degrees); + protected override void AppendScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.AppendScale(scale); - protected override void AppendRotationDegrees(ProjectiveTransformBuilder builder, float degrees, Vector2 origin) => builder.AppendRotationDegrees(degrees, origin); + protected override void AppendSkewDegrees(ProjectiveTransformBuilder builder, float degreesX, float degreesY) + => builder.AppendSkewDegrees(degreesX, degreesY); - protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void AppendSkewDegrees(ProjectiveTransformBuilder builder, float degreesX, float degreesY, Vector2 origin) + => builder.AppendSkewDegrees(degreesX, degreesY, origin); - protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + protected override void AppendSkewRadians(ProjectiveTransformBuilder builder, float radiansX, float radiansY) + => builder.AppendSkewRadians(radiansX, radiansY); + + protected override void AppendSkewRadians(ProjectiveTransformBuilder builder, float radiansX, float radiansY, Vector2 origin) + => builder.AppendSkewRadians(radiansX, radiansY, origin); + + protected override void AppendTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.AppendTranslation(translate); protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians) => builder.PrependRotationRadians(radians); + protected override void PrependScale(ProjectiveTransformBuilder builder, SizeF scale) => builder.PrependScale(scale); + + protected override void PrependSkewRadians(ProjectiveTransformBuilder builder, float radiansX, float radiansY) + => builder.PrependSkewRadians(radiansX, radiansY); + + protected override void PrependSkewRadians(ProjectiveTransformBuilder builder, float radiansX, float radiansY, Vector2 origin) + => builder.PrependSkewRadians(radiansX, radiansY, origin); + + protected override void PrependTranslation(ProjectiveTransformBuilder builder, PointF translate) => builder.PrependTranslation(translate); + protected override void PrependRotationRadians(ProjectiveTransformBuilder builder, float radians, Vector2 origin) => builder.PrependRotationRadians(radians, origin); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index 43ad756e0..71e3b7179 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -86,17 +86,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void AppendRotationDegrees_WithoutSpecificRotationCenter_RotationIsCenteredAroundImageCenter( int width, int height, - float deg, + float degrees, float x, float y) { var size = new Size(width, height); TBuilder builder = this.CreateBuilder(size); - this.AppendRotationDegrees(builder, deg); + this.AppendRotationDegrees(builder, degrees); // TODO: We should also test CreateRotationMatrixDegrees() (and all TransformUtils stuff!) for correctness - Matrix3x2 matrix = TransformUtils.CreateRotationMatrixDegrees(deg, size); + Matrix3x2 matrix = TransformUtils.CreateRotationMatrixDegrees(degrees, size); var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms public void AppendRotationDegrees_WithRotationCenter( int width, int height, - float deg, + float degrees, float cx, float cy, float x, @@ -122,9 +122,63 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms TBuilder builder = this.CreateBuilder(size); var centerPoint = new Vector2(cx, cy); - this.AppendRotationDegrees(builder, deg, centerPoint); + this.AppendRotationDegrees(builder, degrees, centerPoint); - var matrix = Matrix3x2.CreateRotation(GeometryUtilities.DegreeToRadian(deg), centerPoint); + var matrix = Matrix3x2.CreateRotation(GeometryUtilities.DegreeToRadian(degrees), centerPoint); + + var position = new Vector2(x, y); + var expected = Vector2.Transform(position, matrix); + Vector2 actual = this.Execute(builder, new Rectangle(Point.Empty, size), position); + + Assert.Equal(actual, expected, Comparer); + } + + [Theory] + [InlineData(200, 100, 10, 10, 42, 84)] + [InlineData(200, 100, 100, 100, 42, 84)] + [InlineData(100, 200, -10, -10, 42, 84)] + public void AppendSkewDegrees_WithoutSpecificSkewCenter_SkewIsCenteredAroundImageCenter( + int width, + int height, + float degreesX, + float degreesY, + float x, + float y) + { + var size = new Size(width, height); + TBuilder builder = this.CreateBuilder(size); + + this.AppendSkewDegrees(builder, degreesX, degreesY); + + Matrix3x2 matrix = TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size); + + var position = new Vector2(x, y); + var expected = Vector2.Transform(position, matrix); + Vector2 actual = this.Execute(builder, new Rectangle(Point.Empty, size), position); + Assert.Equal(actual, expected, Comparer); + } + + [Theory] + [InlineData(200, 100, 10, 10, 30, 61, 42, 84)] + [InlineData(200, 100, 100, 100, 30, 10, 20, 84)] + [InlineData(100, 200, -10, -10, 30, 20, 11, 84)] + public void AppendSkewDegrees_WithSkewCenter( + int width, + int height, + float degreesX, + float degreesY, + float cx, + float cy, + float x, + float y) + { + var size = new Size(width, height); + TBuilder builder = this.CreateBuilder(size); + + var centerPoint = new Vector2(cx, cy); + this.AppendSkewDegrees(builder, degreesX, degreesY, centerPoint); + + var matrix = Matrix3x2.CreateSkew(GeometryUtilities.DegreeToRadian(degreesX), GeometryUtilities.DegreeToRadian(degreesY), centerPoint); var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); @@ -144,14 +198,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms // Forwards this.AppendRotationRadians(b1, pi); + this.AppendSkewRadians(b1, pi, pi); this.AppendScale(b1, new SizeF(2, 0.5f)); this.AppendRotationRadians(b1, pi / 2, new Vector2(-0.5f, -0.1f)); + this.AppendSkewRadians(b1, pi, pi / 2, new Vector2(-0.5f, -0.1f)); this.AppendTranslation(b1, new PointF(123, 321)); // Backwards this.PrependTranslation(b2, new PointF(123, 321)); + this.PrependSkewRadians(b2, pi, pi / 2, new Vector2(-0.5f, -0.1f)); this.PrependRotationRadians(b2, pi / 2, new Vector2(-0.5f, -0.1f)); this.PrependScale(b2, new SizeF(2, 0.5f)); + this.PrependSkewRadians(b2, pi, pi); this.PrependRotationRadians(b2, pi); Vector2 p1 = this.Execute(b1, rectangle, new Vector2(32, 65)); @@ -180,25 +238,37 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms protected abstract TBuilder CreateBuilder(Rectangle rectangle); - protected abstract void AppendTranslation(TBuilder builder, PointF translate); + protected abstract void AppendRotationDegrees(TBuilder builder, float degrees); - protected abstract void AppendScale(TBuilder builder, SizeF scale); + protected abstract void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 origin); protected abstract void AppendRotationRadians(TBuilder builder, float radians); protected abstract void AppendRotationRadians(TBuilder builder, float radians, Vector2 origin); - protected abstract void PrependTranslation(TBuilder builder, PointF translate); + protected abstract void AppendScale(TBuilder builder, SizeF scale); - protected abstract void PrependScale(TBuilder builder, SizeF scale); + protected abstract void AppendSkewDegrees(TBuilder builder, float degreesX, float degreesY); + + protected abstract void AppendSkewDegrees(TBuilder builder, float degreesX, float degreesY, Vector2 origin); + + protected abstract void AppendSkewRadians(TBuilder builder, float radiansX, float radiansY); + + protected abstract void AppendSkewRadians(TBuilder builder, float radiansX, float radiansY, Vector2 origin); + + protected abstract void AppendTranslation(TBuilder builder, PointF translate); protected abstract void PrependRotationRadians(TBuilder builder, float radians); protected abstract void PrependRotationRadians(TBuilder builder, float radians, Vector2 origin); - protected abstract void AppendRotationDegrees(TBuilder builder, float degrees); + protected abstract void PrependScale(TBuilder builder, SizeF scale); - protected abstract void AppendRotationDegrees(TBuilder builder, float degrees, Vector2 origin); + protected abstract void PrependSkewRadians(TBuilder builder, float radiansX, float radiansY); + + protected abstract void PrependSkewRadians(TBuilder builder, float radiansX, float radiansY, Vector2 origin); + + protected abstract void PrependTranslation(TBuilder builder, PointF translate); protected abstract Vector2 Execute(TBuilder builder, Rectangle rectangle, Vector2 sourcePoint); } From 3641b303056b2199c4e25c8654e24ca34609ee38 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 18:44:28 +0100 Subject: [PATCH 227/238] cleanup & undo WIP project setup --- src/ImageSharp.Drawing/ImageSharp.Drawing.csproj | 3 +-- src/ImageSharp/ImageSharp.csproj | 3 +-- ...KernelMap.cs => ResizeKernelMap.PeriodicKernelMap.cs} | 6 +++--- .../Processors/Transforms/Resize/ResizeKernelMap.cs | 2 +- tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj | 3 +-- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +-- .../Transforms/KernelMapTests.ReferenceKernelMap.cs | 6 +++--- .../Processing/Processors/Transforms/KernelMapTests.cs | 9 ++++----- 8 files changed, 15 insertions(+), 20 deletions(-) rename src/ImageSharp/Processing/Processors/Transforms/Resize/{ResizeKernelMap.MosaicKernelMap.cs => ResizeKernelMap.PeriodicKernelMap.cs} (94%) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index 6341e1771..1cb3f444f 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -5,8 +5,7 @@ $(packageversion) 0.0.1 SixLabors and contributors - - netcoreapp2.1 + netstandard1.3;netstandard2.0 7.3 true true diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index e2f55e3c6..29d29d50d 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,8 +5,7 @@ $(packageversion) 0.0.1 Six Labors and contributors - - netcoreapp2.1 + netstandard1.3;netstandard2.0;netcoreapp2.1;net472 true true SixLabors.ImageSharp diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs similarity index 94% rename from src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs rename to src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs index e106b1ea0..b7b581c18 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.MosaicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs @@ -8,20 +8,20 @@ using SixLabors.Memory; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { /// - /// Contains + /// Contains /// internal partial class ResizeKernelMap { /// /// Memory-optimized where repeating rows are stored only once. /// - private sealed class MosaicKernelMap : ResizeKernelMap + private sealed class PeriodicKernelMap : ResizeKernelMap { private readonly int period; private readonly int cornerInterval; - public MosaicKernelMap( + public PeriodicKernelMap( MemoryAllocator memoryAllocator, IResampler sampler, int sourceLength, diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index ccb57114a..011a4ffa2 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms bool useMosaic = 2 * (cornerInterval + period) < destinationSize; ResizeKernelMap result = useMosaic - ? new MosaicKernelMap( + ? new PeriodicKernelMap( memoryAllocator, sampler, sourceSize, diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 04a4541b2..a705c9bac 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -1,7 +1,6 @@  - - netcoreapp2.1 + netcoreapp2.1;net461 Exe True SixLabors.ImageSharp.Benchmarks diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 75ac7450c..86c1a7a25 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,7 +1,6 @@  - - netcoreapp2.1 + net462;net472;netcoreapp2.1 True latest full diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index f7c3b27e5..12c701609 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms scale = 1F; } - float radius = MathF.Ceiling(scale * sampler.Radius); + float radius = (float)Math.Ceiling(scale * sampler.Radius); var result = new List(); @@ -42,13 +42,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms float center = ((i + .5F) * ratio) - .5F; // Keep inside bounds. - int left = (int)MathF.Ceiling(center - radius); + int left = (int)Math.Ceiling(center - radius); if (left < 0) { left = 0; } - int right = (int)MathF.Floor(center + radius); + int right = (int)Math.Floor(center + radius); if (right > sourceSize - 1) { right = sourceSize - 1; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index af98b9952..962c599e6 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -1,12 +1,11 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; using System.Text; -using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Transforms; -using SixLabors.Primitives; using Xunit; using Xunit.Abstractions; From 28bc47c6ece8f28836b6ae2482e2b328cae7a3af Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 23:20:57 +0100 Subject: [PATCH 228/238] additional extensive testing --- .../KernelMapTests.ReferenceKernelMap.cs | 21 +++--- .../Processors/Transforms/KernelMapTests.cs | 70 +++++++++++++++++-- 2 files changed, 76 insertions(+), 15 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 12c701609..9a7052b5a 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -25,21 +26,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public static ReferenceKernelMap Calculate(IResampler sampler, int destinationSize, int sourceSize, bool normalize = true) { - float ratio = (float)sourceSize / destinationSize; - float scale = ratio; + double ratio = (double)sourceSize / destinationSize; + double scale = ratio; if (scale < 1F) { scale = 1F; } - float radius = (float)Math.Ceiling(scale * sampler.Radius); + double radius = (double)Math.Ceiling(scale * sampler.Radius); var result = new List(); for (int i = 0; i < destinationSize; i++) { - float center = ((i + .5F) * ratio) - .5F; + double center = ((i + .5) * ratio) - .5; // Keep inside bounds. int left = (int)Math.Ceiling(center - radius); @@ -54,20 +55,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms right = sourceSize - 1; } - float sum = 0; + double sum = 0; - float[] values = new float[right - left + 1]; + double[] values = new double[right - left + 1]; for (int j = left; j <= right; j++) { - float weight = sampler.GetValue((j - center) / scale); + double weight = sampler.GetValue((float)((j - center) / scale)); sum += weight; values[j - left] = weight; } - result.Add(new ReferenceKernel(left, values)); - if (sum > 0 && normalize) { for (int w = 0; w < values.Length; w++) @@ -75,6 +74,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms values[w] /= sum; } } + + float[] floatVals = values.Select(v => (float)v).ToArray(); + + result.Add(new ReferenceKernel(left, floatVals)); } return new ReferenceKernelMap(result.ToArray()); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index 962c599e6..dfbd7a28b 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using System.Text; using SixLabors.ImageSharp.Processing; @@ -58,6 +61,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos8), 10, 100 }, }; + public static TheoryData GeneratedImageResizeData = + GenerateImageResizeData(); + + [Theory] [MemberData(nameof(KernelMapData))] public void PrintNonNormalizedKernelMap(string resamplerName, int srcSize, int destSize) @@ -71,7 +78,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms [Theory] [MemberData(nameof(KernelMapData))] + //[MemberData(nameof(GeneratedImageResizeData))] public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) + { + VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); + } + + [Theory] + [MemberData(nameof(GeneratedImageResizeData))] + public void KernelMapContentIsCorrect_ExtendedGeneratedValues(string resamplerName, int srcSize, int destSize) + { + VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); + } + + + private static void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { IResampler resampler = TestUtils.GetResampler(resamplerName); @@ -79,8 +100,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var kernelMap = ResizeKernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); #if DEBUG - this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); - this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); + // this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); + // this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); #endif for (int i = 0; i < kernelMap.DestinationLength; i++) @@ -89,14 +110,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms ReferenceKernel referenceKernel = referenceMap.GetKernel(i); - Assert.Equal(referenceKernel.Length, kernel.Length); - Assert.Equal(referenceKernel.Left, kernel.Left); + Assert.True( + referenceKernel.Length == kernel.Length, + $"referenceKernel.Length != kernel.Length: {referenceKernel.Length} != {kernel.Length}"); + Assert.True( + referenceKernel.Left == kernel.Left, + $"referenceKernel.Left != kernel.Left: {referenceKernel.Left} != {kernel.Left}"); float[] expectedValues = referenceKernel.Values; Span actualValues = kernel.Values; - + Assert.Equal(expectedValues.Length, actualValues.Length); - var comparer = new ApproximateFloatComparer(1e-4f); + var comparer = new ApproximateFloatComparer(1e-6f); for (int x = 0; x < expectedValues.Length; x++) { @@ -145,5 +170,38 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms return bld.ToString(); } + + + private static TheoryData GenerateImageResizeData() + { + var result = new TheoryData(); + + string[] resamplerNames = typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static) + .Select(p => p.Name).ToArray(); + + int[] dimensionVals = + { + // Arbitrary, small dimensions: + 9, 10, 11, 13, 49, 50, 53, 99, 100, 199, 200, 201, 299, 300, 301, + + // Typical image sizes: + 640, 480, 800, 600, 1024, 768, 1280, 960, 1536, 1180, 1600, 1200, 2048, 1536, 2240, 1680, 2560, + 1920, 3032, 2008, 3072, 2304, 3264, 2448 + }; + + IOrderedEnumerable<(int s, int d)> source2Dest = dimensionVals + .SelectMany(s => dimensionVals.Select(d => (s, d))) + .OrderBy(x => x.s + x.d); + + foreach (string resampler in resamplerNames) + { + foreach ((int s, int d) x in source2Dest) + { + result.Add(resampler, x.s, x.d); + } + } + + return result; + } } } \ No newline at end of file From b745ffaf5e2c7c3529f0c82573ed899fcdbeab5b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 28 Nov 2018 23:21:30 +0100 Subject: [PATCH 229/238] use double precision in KernelMap calculations --- .../Transforms/Resize/ResizeKernel.cs | 10 +++ .../ResizeKernelMap.PeriodicKernelMap.cs | 8 +-- .../Transforms/Resize/ResizeKernelMap.cs | 66 ++++++++++--------- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index 04bf6c3a4..f349634ac 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -80,5 +80,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { return new ResizeKernel(left, this.bufferPtr, this.Length); } + + internal void Fill(Span values) + { + DebugGuard.IsTrue(values.Length == this.Length, nameof(values), "ResizeKernel.Fill: values.Length != this.Length!"); + + for (int i = 0; i < this.Length; i++) + { + this.Values[i] = (float)values[i]; + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs index b7b581c18..e0f5ad261 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs @@ -26,8 +26,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms IResampler sampler, int sourceLength, int destinationLength, - float ratio, - float scale, + double ratio, + double scale, int radius, int period, int cornerInterval) @@ -62,8 +62,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int bottomStartDest = this.DestinationLength - this.cornerInterval; for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++) { - float center = ((i + .5F) * this.ratio) - .5F; - int left = (int)MathF.Ceiling(center - this.radius); + double center = ((i + .5) * this.ratio) - .5; + int left = (int)Math.Ceiling(center - this.radius); ResizeKernel kernel = this.kernels[i - this.period]; this.kernels[i] = kernel.AlterLeftValue(left); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 011a4ffa2..4cd9928d3 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -17,13 +17,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal partial class ResizeKernelMap : IDisposable { + private readonly MemoryAllocator memoryAllocator; + private readonly IResampler sampler; private readonly int sourceLength; - private readonly float ratio; + private readonly double ratio; - private readonly float scale; + private readonly double scale; private readonly int radius; @@ -39,10 +41,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int sourceLength, int destinationLength, int bufferHeight, - float ratio, - float scale, + double ratio, + double scale, int radius) { + this.memoryAllocator = memoryAllocator; this.sampler = sampler; this.ratio = ratio; this.scale = scale; @@ -95,19 +98,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int sourceSize, MemoryAllocator memoryAllocator) { - float ratio = (float)sourceSize / destinationSize; - float scale = ratio; + double ratio = (double)sourceSize / destinationSize; + double scale = ratio; if (scale < 1F) { scale = 1F; } - int radius = (int)MathF.Ceiling(scale * sampler.Radius); + int radius = (int)Math.Ceiling(scale * sampler.Radius); int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; - float center0 = (ratio - 1) * 0.5f; - float firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; - int cornerInterval = (int)MathF.Ceiling(firstNonNegativeLeftVal); + double center0 = (ratio - 1) * 0.5f; + double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; + int cornerInterval = (int)Math.Ceiling(firstNonNegativeLeftVal); // corner case for cornerInteval: if (firstNonNegativeLeftVal == cornerInterval) @@ -159,45 +162,48 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// private ResizeKernel BuildKernel(int destRowIndex, int dataRowIndex) { - float center = ((destRowIndex + .5F) * this.ratio) - .5F; + double center = ((destRowIndex + .5) * this.ratio) - .5; // Keep inside bounds. - int left = (int)MathF.Ceiling(center - this.radius); + int left = (int)Math.Ceiling(center - this.radius); if (left < 0) { left = 0; } - int right = (int)MathF.Floor(center + this.radius); + int right = (int)Math.Floor(center + this.radius); if (right > this.sourceLength - 1) { right = this.sourceLength - 1; } - float sum = 0; - ResizeKernel kernel = this.CreateKernel(dataRowIndex, left, right); - ref float kernelBaseRef = ref MemoryMarshal.GetReference(kernel.Values); - - for (int j = left; j <= right; j++) + using (IMemoryOwner tempBuffer = this.memoryAllocator.Allocate(kernel.Length)) { - float value = this.sampler.GetValue((j - center) / this.scale); - sum += value; + Span kernelValues = tempBuffer.GetSpan(); + double sum = 0; - // weights[j - left] = weight: - Unsafe.Add(ref kernelBaseRef, j - left) = value; - } + for (int j = left; j <= right; j++) + { + double value = this.sampler.GetValue((float)((j - center) / this.scale)); + sum += value; - // Normalize, best to do it here rather than in the pixel loop later on. - if (sum > 0) - { - for (int w = 0; w < kernel.Length; w++) + kernelValues[j - left] = value; + } + + // Normalize, best to do it here rather than in the pixel loop later on. + if (sum > 0) { - // weights[w] = weights[w] / sum: - ref float kRef = ref Unsafe.Add(ref kernelBaseRef, w); - kRef /= sum; + for (int j = 0; j < kernel.Length; j++) + { + // weights[w] = weights[w] / sum: + ref double kRef = ref kernelValues[j]; + kRef /= sum; + } } + + kernel.Fill(kernelValues); } return kernel; From 86125550ad7b6415f26d84c80f0fcc904fb9bbf8 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 01:05:07 +0100 Subject: [PATCH 230/238] cherry pick test cases from auto-generated set --- .../Processors/Transforms/KernelMapTests.cs | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index dfbd7a28b..d0ff62a91 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -59,6 +59,30 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos8), 100, 10 }, { nameof(KnownResamplers.Lanczos8), 100, 80 }, { nameof(KnownResamplers.Lanczos8), 10, 100 }, + + // Accuracy-related regression-test cases cherry-picked from GeneratedImageResizeData + { nameof(KnownResamplers.Box), 201, 100 }, + { nameof(KnownResamplers.Box), 199, 99 }, + { nameof(KnownResamplers.Box), 10, 299 }, + { nameof(KnownResamplers.Box), 299, 10 }, + { nameof(KnownResamplers.Box), 301, 300 }, + { nameof(KnownResamplers.Box), 1180, 480 }, + + { nameof(KnownResamplers.Lanczos2), 3264, 3032 }, + + { nameof(KnownResamplers.Bicubic), 1280, 2240 }, + { nameof(KnownResamplers.Bicubic), 1920, 1680 }, + { nameof(KnownResamplers.Bicubic), 3072, 2240 }, + + { nameof(KnownResamplers.Welch), 300, 2008 }, + + // ResizeKernel.Length -related regression tests cherry-picked from GeneratedImageResizeData + { nameof(KnownResamplers.Bicubic), 10, 50 }, + { nameof(KnownResamplers.Bicubic), 49, 301 }, + { nameof(KnownResamplers.Bicubic), 301, 49 }, + { nameof(KnownResamplers.Bicubic), 1680, 1200 }, + { nameof(KnownResamplers.Box), 13, 299 }, + { nameof(KnownResamplers.Lanczos5), 3032, 600 }, }; public static TheoryData GeneratedImageResizeData = @@ -78,18 +102,21 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms [Theory] [MemberData(nameof(KernelMapData))] - //[MemberData(nameof(GeneratedImageResizeData))] public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); } + // Comprehensive but expensive tests, for KernelMap generation + // Enabling them can kill your IDE: +#if false [Theory] [MemberData(nameof(GeneratedImageResizeData))] public void KernelMapContentIsCorrect_ExtendedGeneratedValues(string resamplerName, int srcSize, int destSize) { VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); } +#endif private static void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) @@ -103,6 +130,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms // this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); // this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); #endif + var comparer = new ApproximateFloatComparer(1e-6f); for (int i = 0; i < kernelMap.DestinationLength; i++) { @@ -121,7 +149,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms Assert.Equal(expectedValues.Length, actualValues.Length); - var comparer = new ApproximateFloatComparer(1e-6f); + for (int x = 0; x < expectedValues.Length; x++) { @@ -177,7 +205,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var result = new TheoryData(); string[] resamplerNames = typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static) - .Select(p => p.Name).ToArray(); + .Select(p => p.Name) + .Where(name => name != nameof(KnownResamplers.NearestNeighbor)) + .ToArray(); int[] dimensionVals = { From 7fcae0351fccf8c4e7c6b9c098f66eaf04f3140a Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 02:34:49 +0100 Subject: [PATCH 231/238] introduce TolerantMath --- src/ImageSharp/Common/Helpers/TolerantMath.cs | 75 ++++++++++ .../Transforms/Resize/ResizeKernelMap.cs | 47 ++++--- .../Helpers/ImageMathsTests.cs | 3 +- .../Helpers/TolerantMathTests.cs | 130 ++++++++++++++++++ .../KernelMapTests.ReferenceKernelMap.cs | 6 + .../Processors/Transforms/KernelMapTests.cs | 15 +- 6 files changed, 243 insertions(+), 33 deletions(-) create mode 100644 src/ImageSharp/Common/Helpers/TolerantMath.cs create mode 100644 tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs new file mode 100644 index 000000000..b9b3b8ea1 --- /dev/null +++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs @@ -0,0 +1,75 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp +{ + /// + /// Implements math operations using tolerant comparison. + /// + internal struct TolerantMath + { + private readonly double epsilon; + + private readonly double negEpsilon; + + public TolerantMath(double epsilon) + { + DebugGuard.MustBeGreaterThan(epsilon, 0, nameof(epsilon)); + + this.epsilon = epsilon; + this.negEpsilon = -epsilon; + } + + public static TolerantMath Default { get; } = new TolerantMath(1e-8); + + /// + /// == 0 + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsZero(double a) => a > this.negEpsilon && a < this.epsilon; + + /// + /// > 0 + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsPositive(double a) => a > this.epsilon; + + /// + /// < 0 + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsNegative(double a) => a < this.negEpsilon; + + /// + /// == + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool AreEqual(double a, double b) => this.IsZero(a - b); + + /// + /// > + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsGreater(double a, double b) => a > b + this.epsilon; + + /// + /// < + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsLess(double a, double b) => a < b - this.epsilon; + + /// + /// >= + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsGreaterOrEqual(double a, double b) => a >= b - this.epsilon; + + /// + /// <= + /// + [MethodImpl(InliningOptions.ShortMethod)] + public bool IsLessOrEqual(double a, double b) => b >= a - this.epsilon; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 4cd9928d3..468e0d844 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -17,8 +17,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal partial class ResizeKernelMap : IDisposable { - private readonly MemoryAllocator memoryAllocator; - private readonly IResampler sampler; private readonly int sourceLength; @@ -35,6 +33,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private readonly ResizeKernel[] kernels; + // To avoid both GC allocations, and MemoryAllocator ceremony: + private readonly double[] tempValues; + private ResizeKernelMap( MemoryAllocator memoryAllocator, IResampler sampler, @@ -45,7 +46,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms double scale, int radius) { - this.memoryAllocator = memoryAllocator; this.sampler = sampler; this.ratio = ratio; this.scale = scale; @@ -56,6 +56,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.data = memoryAllocator.Allocate2D(maxWidth, bufferHeight, AllocationOptions.Clean); this.pinHandle = this.data.Memory.Pin(); this.kernels = new ResizeKernel[destinationLength]; + this.tempValues = new double[maxWidth]; } /// @@ -113,7 +114,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int cornerInterval = (int)Math.Ceiling(firstNonNegativeLeftVal); // corner case for cornerInteval: - if (firstNonNegativeLeftVal == cornerInterval) + // TODO: Implement library-wide utils for tolerant comparison + if (Math.Abs(firstNonNegativeLeftVal - cornerInterval) < 1e-8) { cornerInterval++; } @@ -179,33 +181,30 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms ResizeKernel kernel = this.CreateKernel(dataRowIndex, left, right); - using (IMemoryOwner tempBuffer = this.memoryAllocator.Allocate(kernel.Length)) - { - Span kernelValues = tempBuffer.GetSpan(); - double sum = 0; + Span kernelValues = this.tempValues.AsSpan().Slice(0, kernel.Length); + double sum = 0; - for (int j = left; j <= right; j++) - { - double value = this.sampler.GetValue((float)((j - center) / this.scale)); - sum += value; + for (int j = left; j <= right; j++) + { + double value = this.sampler.GetValue((float)((j - center) / this.scale)); + sum += value; - kernelValues[j - left] = value; - } + kernelValues[j - left] = value; + } - // Normalize, best to do it here rather than in the pixel loop later on. - if (sum > 0) + // Normalize, best to do it here rather than in the pixel loop later on. + if (sum > 0) + { + for (int j = 0; j < kernel.Length; j++) { - for (int j = 0; j < kernel.Length; j++) - { - // weights[w] = weights[w] / sum: - ref double kRef = ref kernelValues[j]; - kRef /= sum; - } + // weights[w] = weights[w] / sum: + ref double kRef = ref kernelValues[j]; + kRef /= sum; } - - kernel.Fill(kernelValues); } + kernel.Fill(kernelValues); + return kernel; } diff --git a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs index 75ef611a5..018fabd98 100644 --- a/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ImageMathsTests.cs @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System; +using Xunit; namespace SixLabors.ImageSharp.Tests.Helpers { - using Xunit; - public class ImageMathsTests { [Theory] diff --git a/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs new file mode 100644 index 000000000..d488d6491 --- /dev/null +++ b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs @@ -0,0 +1,130 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; + +using Xunit; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Tests.Helpers +{ + public class TolerantMathTests + { + private readonly TolerantMath tolerantMath = new TolerantMath(0.1); + + [Theory] + [InlineData(0)] + [InlineData(0.01)] + [InlineData(-0.05)] + public void IsZero_WhenTrue(double a) + { + Assert.True(this.tolerantMath.IsZero(a)); + } + + [Theory] + [InlineData(0.11)] + [InlineData(-0.101)] + [InlineData(42)] + public void IsZero_WhenFalse(double a) + { + Assert.False(this.tolerantMath.IsZero(a)); + } + + [Theory] + [InlineData(0.11)] + [InlineData(100)] + public void IsPositive_WhenTrue(double a) + { + Assert.True(this.tolerantMath.IsPositive(a)); + } + + [Theory] + [InlineData(0.09)] + [InlineData(-0.1)] + [InlineData(-1000)] + public void IsPositive_WhenFalse(double a) + { + Assert.False(this.tolerantMath.IsPositive(a)); + } + + [Theory] + [InlineData(-0.11)] + [InlineData(-100)] + public void IsNegative_WhenTrue(double a) + { + Assert.True(this.tolerantMath.IsNegative(a)); + } + + [Theory] + [InlineData(-0.09)] + [InlineData(0.1)] + [InlineData(1000)] + public void IsNegative_WhenFalse(double a) + { + Assert.False(this.tolerantMath.IsNegative(a)); + } + + [Theory] + [InlineData(4.2, 4.2)] + [InlineData(4.2, 4.25)] + [InlineData(-Math.PI, -Math.PI + 0.05)] + [InlineData(999999.2, 999999.25)] + public void AreEqual_WhenTrue(double a, double b) + { + Assert.True(this.tolerantMath.AreEqual(a, b)); + } + + [Theory] + [InlineData(1, 2)] + [InlineData(-1000000, -1000000.2)] + public void AreEqual_WhenFalse(double a, double b) + { + Assert.False(this.tolerantMath.AreEqual(a, b)); + } + + [Theory] + [InlineData(2, 1.8)] + [InlineData(-20, -20.2)] + [InlineData(0.1, -0.1)] + [InlineData(100, 10)] + public void IsGreater_IsLess_WhenTrue(double a, double b) + { + Assert.True(this.tolerantMath.IsGreater(a, b)); + Assert.True(this.tolerantMath.IsLess(b, a)); + } + + [Theory] + [InlineData(2, 1.95)] + [InlineData(-20, -20.02)] + [InlineData(0.01, -0.01)] + [InlineData(999999, 999999.09)] + public void IsGreater_IsLess_WhenFalse(double a, double b) + { + Assert.False(this.tolerantMath.IsGreater(a, b)); + Assert.False(this.tolerantMath.IsLess(b, a)); + } + + [Theory] + [InlineData(3, 2)] + [InlineData(3, 2.99)] + [InlineData(2.99, 3)] + [InlineData(-5, -6)] + [InlineData(-5, -5.05)] + [InlineData(-5.05, -5)] + public void IsGreaterOrEqual_IsLessOrEqual_WhenTrue(double a, double b) + { + Assert.True(this.tolerantMath.IsGreaterOrEqual(a, b)); + Assert.True(this.tolerantMath.IsLessOrEqual(b, a)); + } + + [Theory] + [InlineData(2, 3)] + [InlineData(2.89, 3)] + [InlineData(-3, -2.89)] + public void IsGreaterOrEqual_IsLessOrEqual_WhenFalse(double a, double b) + { + Assert.False(this.tolerantMath.IsGreaterOrEqual(a, b)); + Assert.False(this.tolerantMath.IsLessOrEqual(b, a)); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 9a7052b5a..31907b06d 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -40,6 +41,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms for (int i = 0; i < destinationSize; i++) { + if (i == 21 || i == 64) + { + Debug.Print("lol"); + } + double center = ((i + .5) * ratio) - .5; // Keep inside bounds. diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index d0ff62a91..dc7a441e9 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -104,22 +104,23 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms [MemberData(nameof(KernelMapData))] public void KernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { - VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); + this.VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); } - // Comprehensive but expensive tests, for KernelMap generation - // Enabling them can kill your IDE: + // Comprehensive but expensive tests, for ResizeKernelMap. + // Enabling them can kill you, but sometimes you have to wear the burden! + // AppVeyor will never follow you to these shadows of Mordor. #if false [Theory] [MemberData(nameof(GeneratedImageResizeData))] public void KernelMapContentIsCorrect_ExtendedGeneratedValues(string resamplerName, int srcSize, int destSize) { - VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); + this.VerifyKernelMapContentIsCorrect(resamplerName, srcSize, destSize); } #endif - private static void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) + private void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { IResampler resampler = TestUtils.GetResampler(resamplerName); @@ -127,8 +128,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms var kernelMap = ResizeKernelMap.Calculate(resampler, destSize, srcSize, Configuration.Default.MemoryAllocator); #if DEBUG - // this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); - // this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); + this.Output.WriteLine($"Expected KernelMap:\n{PrintKernelMap(referenceMap)}\n"); + this.Output.WriteLine($"Actual KernelMap:\n{PrintKernelMap(kernelMap)}\n"); #endif var comparer = new ApproximateFloatComparer(1e-6f); From a5c5f618b3dc8d38c56599a7ab0d8ab5214615a1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 02:54:31 +0100 Subject: [PATCH 232/238] TolerantMath: implemented Floor and Ceiling --- src/ImageSharp/Common/Helpers/TolerantMath.cs | 28 +++++++++++++- .../Helpers/TolerantMathTests.cs | 38 +++++++++++++++++++ .../ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs index b9b3b8ea1..d95aea9de 100644 --- a/src/ImageSharp/Common/Helpers/TolerantMath.cs +++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs @@ -1,12 +1,14 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp { /// - /// Implements math operations using tolerant comparison. + /// Implements basic math operations using tolerant comparison + /// whenever an equality check is needed. /// internal struct TolerantMath { @@ -71,5 +73,29 @@ namespace SixLabors.ImageSharp /// [MethodImpl(InliningOptions.ShortMethod)] public bool IsLessOrEqual(double a, double b) => b >= a - this.epsilon; + + [MethodImpl(InliningOptions.ShortMethod)] + public double Ceiling(double a) + { + double rem = Math.IEEERemainder(a, 1); + if (this.IsZero(rem)) + { + return Math.Round(a); + } + + return Math.Ceiling(a); + } + + [MethodImpl(InliningOptions.ShortMethod)] + public double Floor(double a) + { + double rem = Math.IEEERemainder(a, 1); + if (this.IsZero(rem)) + { + return Math.Round(a); + } + + return Math.Floor(a); + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs index d488d6491..6c7a1f275 100644 --- a/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs +++ b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs @@ -126,5 +126,43 @@ namespace SixLabors.ImageSharp.Tests.Helpers Assert.False(this.tolerantMath.IsGreaterOrEqual(a, b)); Assert.False(this.tolerantMath.IsLessOrEqual(b, a)); } + + [Theory] + [InlineData(3.5, 4.0)] + [InlineData(3.89, 4.0)] + [InlineData(4.09, 4.0)] + [InlineData(4.11, 5.0)] + [InlineData(0.11, 1)] + [InlineData(0.05, 0)] + [InlineData(-0.5, 0)] + [InlineData(-0.95, -1)] + [InlineData(-1.05, -1)] + [InlineData(-1.5, -1)] + public void Ceiling(double value, double expected) + { + double actual = this.tolerantMath.Ceiling(value); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, 1)] + [InlineData(0.99, 1)] + [InlineData(0.5, 0)] + [InlineData(0.01, 0)] + [InlineData(-0.09, 0)] + [InlineData(-0.11, -1)] + [InlineData(-100.11, -101)] + [InlineData(-100.09, -100)] + public void Floor(double value, double expected) + { + double plz1 = Math.IEEERemainder(1.1, 1); + double plz2 = Math.IEEERemainder(0.9, 1); + + double plz3 = Math.IEEERemainder(-1.1, 1); + double plz4 = Math.IEEERemainder(-0.9, 1); + + double actual = this.tolerantMath.Floor(value); + Assert.Equal(expected, actual); + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 86c1a7a25..75ac7450c 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,6 +1,7 @@  - net462;net472;netcoreapp2.1 + + netcoreapp2.1 True latest full From 0c7aee9f5d4dbea2f4b0a3aa4b27c0d6438999b7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 03:05:38 +0100 Subject: [PATCH 233/238] robust ResizeKernelMap calculations using TolerantMath --- .../Resize/ResizeKernelMap.PeriodicKernelMap.cs | 2 +- .../Transforms/Resize/ResizeKernelMap.cs | 15 ++++++++------- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +-- .../KernelMapTests.ReferenceKernelMap.cs | 16 +++++++++------- .../Processors/Transforms/KernelMapTests.cs | 1 - 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs index e0f5ad261..4b81aaa64 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.PeriodicKernelMap.cs @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int i = startOfFirstRepeatedMosaic; i < bottomStartDest; i++) { double center = ((i + .5) * this.ratio) - .5; - int left = (int)Math.Ceiling(center - this.radius); + int left = (int)TolerantMath.Ceiling(center - this.radius); ResizeKernel kernel = this.kernels[i - this.period]; this.kernels[i] = kernel.AlterLeftValue(left); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 468e0d844..347aaf0be 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal partial class ResizeKernelMap : IDisposable { + private static readonly TolerantMath TolerantMath = TolerantMath.Default; + private readonly IResampler sampler; private readonly int sourceLength; @@ -107,15 +109,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms scale = 1F; } - int radius = (int)Math.Ceiling(scale * sampler.Radius); + int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius); int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; - double center0 = (ratio - 1) * 0.5f; + double center0 = (ratio - 1) * 0.5; double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; - int cornerInterval = (int)Math.Ceiling(firstNonNegativeLeftVal); + int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal); // corner case for cornerInteval: - // TODO: Implement library-wide utils for tolerant comparison - if (Math.Abs(firstNonNegativeLeftVal - cornerInterval) < 1e-8) + if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval)) { cornerInterval++; } @@ -167,13 +168,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms double center = ((destRowIndex + .5) * this.ratio) - .5; // Keep inside bounds. - int left = (int)Math.Ceiling(center - this.radius); + int left = (int)TolerantMath.Ceiling(center - this.radius); if (left < 0) { left = 0; } - int right = (int)Math.Floor(center + this.radius); + int right = (int)TolerantMath.Floor(center + this.radius); if (right > this.sourceLength - 1) { right = this.sourceLength - 1; diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 75ac7450c..86c1a7a25 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,7 +1,6 @@  - - netcoreapp2.1 + net462;net472;netcoreapp2.1 True latest full diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs index 31907b06d..54ac239ae 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs @@ -35,27 +35,29 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms scale = 1F; } - double radius = (double)Math.Ceiling(scale * sampler.Radius); + TolerantMath tolerantMath = TolerantMath.Default; + + double radius = tolerantMath.Ceiling(scale * sampler.Radius); var result = new List(); for (int i = 0; i < destinationSize; i++) { - if (i == 21 || i == 64) - { - Debug.Print("lol"); - } + //if (i == 21 || i == 64) + //{ + // Debug.Print("lol"); + //} double center = ((i + .5) * ratio) - .5; // Keep inside bounds. - int left = (int)Math.Ceiling(center - radius); + int left = (int)tolerantMath.Ceiling(center - radius); if (left < 0) { left = 0; } - int right = (int)Math.Floor(center + radius); + int right = (int)tolerantMath.Floor(center + radius); if (right > sourceSize - 1) { right = sourceSize - 1; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index dc7a441e9..c9f20cd27 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -119,7 +119,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } #endif - private void VerifyKernelMapContentIsCorrect(string resamplerName, int srcSize, int destSize) { IResampler resampler = TestUtils.GetResampler(resamplerName); From 90a2f32f3aae0307de2310b8f1e6a1b1eac28e84 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 03:54:29 +0100 Subject: [PATCH 234/238] update submodule, skip debug-only test case --- .../Processing/Processors/Transforms/KernelMapTests.cs | 6 +++++- tests/Images/External | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs index c9f20cd27..783c3c5af 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs @@ -60,6 +60,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { nameof(KnownResamplers.Lanczos8), 100, 80 }, { nameof(KnownResamplers.Lanczos8), 10, 100 }, + // Resize_WorksWithAllResamplers_Rgba32_CalliphoraPartial_Box-0.5: + { nameof(KnownResamplers.Box), 378, 149 }, + { nameof(KnownResamplers.Box), 349, 174 }, + // Accuracy-related regression-test cases cherry-picked from GeneratedImageResizeData { nameof(KnownResamplers.Box), 201, 100 }, { nameof(KnownResamplers.Box), 199, 99 }, @@ -89,7 +93,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms GenerateImageResizeData(); - [Theory] + [Theory(Skip = "Only for debugging and development")] [MemberData(nameof(KernelMapData))] public void PrintNonNormalizedKernelMap(string resamplerName, int srcSize, int destSize) { diff --git a/tests/Images/External b/tests/Images/External index ed8a7b0b6..5b18d8c95 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit ed8a7b0b6fe1b2e2a7c822aa617103ae31192655 +Subproject commit 5b18d8c95acffb773012881870ba6f521ba13128 From 36231b0b03aed55586b8dee9452aa89d2fa05258 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 04:14:46 +0100 Subject: [PATCH 235/238] remove outdated TODO note --- src/ImageSharp/Common/Helpers/ImageMaths.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs index 45cb52fd9..9e03c0d3d 100644 --- a/src/ImageSharp/Common/Helpers/ImageMaths.cs +++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs @@ -99,7 +99,6 @@ namespace SixLabors.ImageSharp /// /// Determine the Least Common Multiple (LCM) of two numbers. - /// TODO: This method might be useful for building a more compact /// public static int LeastCommonMultiple(int a, int b) { From 3538e9839fcf74956d2a19d9409577311efc545c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 14:51:06 +0100 Subject: [PATCH 236/238] test code cleanup --- ...esizeKernelMapTests.ReferenceKernelMap.cs} | 12 ++++------ ...nelMapTests.cs => ResizeKernelMapTests.cs} | 4 ++-- .../Processors/Transforms/ResizeTests.cs | 23 ------------------- 3 files changed, 6 insertions(+), 33 deletions(-) rename tests/ImageSharp.Tests/Processing/Processors/Transforms/{KernelMapTests.ReferenceKernelMap.cs => ResizeKernelMapTests.ReferenceKernelMap.cs} (93%) rename tests/ImageSharp.Tests/Processing/Processors/Transforms/{KernelMapTests.cs => ResizeKernelMapTests.cs} (98%) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs similarity index 93% rename from tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs rename to tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs index 54ac239ae..7d842c4e1 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs @@ -1,13 +1,14 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using SixLabors.ImageSharp.Processing.Processors.Transforms; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { - public partial class KernelMapTests + public partial class ResizeKernelMapTests { /// /// Simplified reference implementation for functionality. @@ -43,11 +44,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms for (int i = 0; i < destinationSize; i++) { - //if (i == 21 || i == 64) - //{ - // Debug.Print("lol"); - //} - double center = ((i + .5) * ratio) - .5; // Keep inside bounds. diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs similarity index 98% rename from tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs rename to tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs index 783c3c5af..08b294913 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/KernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs @@ -15,11 +15,11 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { - public partial class KernelMapTests + public partial class ResizeKernelMapTests { private ITestOutputHelper Output { get; } - public KernelMapTests(ITestOutputHelper output) + public ResizeKernelMapTests(ITestOutputHelper output) { this.Output = output; } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 839d26e71..b4aff53e8 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -58,29 +58,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } } - // TODO: Merge with the previous theory + add test images - [Theory] - [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 1)] - [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 10)] - [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Lanczos3), 10)] - [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.Lanczos8), 10)] - [WithTestPatternImages(100, 100, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 10)] - [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 1)] - [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.NearestNeighbor), 5)] - [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, nameof(KnownResamplers.Bicubic), 5)] - public void ScaleUp(TestImageProvider provider, string samplerName, float ratio) - where TPixel : struct, IPixel - { - using (Image image = provider.GetImage()) - { - SizeF newSize = image.Size() * ratio; - image.Mutate(x => x.Resize((Size)newSize, TestUtils.GetResampler(samplerName), false)); - FormattableString details = $"{samplerName}_{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; - - image.DebugSave(provider, details); - } - } - [Theory] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)] From 756324e844b2cde36da369343e5bb9a40323e810 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 16:49:46 +0100 Subject: [PATCH 237/238] better comments + TolerantMath made readonly --- src/ImageSharp/Common/Helpers/TolerantMath.cs | 2 +- .../Transforms/Resize/ResizeKernelMap.cs | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs index d95aea9de..5347efcc0 100644 --- a/src/ImageSharp/Common/Helpers/TolerantMath.cs +++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp /// Implements basic math operations using tolerant comparison /// whenever an equality check is needed. /// - internal struct TolerantMath + internal readonly struct TolerantMath { private readonly double epsilon; diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index 347aaf0be..f6edf9786 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -110,20 +110,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius); + + // 'ratio' is a rational number. + // Multiplying it by LCM(sourceSize, destSize)/sourceSize will result in a whole number "again". + // This value is determining the length of the periods in repeating kernel map rows. int period = ImageMaths.LeastCommonMultiple(sourceSize, destinationSize) / sourceSize; + + // the center position at i == 0: double center0 = (ratio - 1) * 0.5; double firstNonNegativeLeftVal = (radius - center0 - 1) / ratio; + + // The number of rows building a "stairway" at the top and the bottom of the kernel map + // corresponding to the corners of the image. + // If we do not normalize the kernel values, these rows also fit the periodic logic, + // however, it's just simpler to calculate them separately. int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal); - // corner case for cornerInteval: + // If firstNonNegativeLeftVal was an integral value, we don't need Ceiling: if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval)) { cornerInterval++; } - bool useMosaic = 2 * (cornerInterval + period) < destinationSize; + // If 'cornerInterval' is too big compared to 'period', we can't apply the periodic optimization. + // If we don't have at least 2 periods, we go with the basic implementation: + bool hasAtLeast2Periods = 2 * (cornerInterval + period) < destinationSize; - ResizeKernelMap result = useMosaic + ResizeKernelMap result = hasAtLeast2Periods ? new PeriodicKernelMap( memoryAllocator, sampler, From 5cbe335d95f23171c13669559e1ee0643da79268 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 17:03:46 +0100 Subject: [PATCH 238/238] improve comments again --- .../Processors/Transforms/Resize/ResizeKernelMap.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index f6edf9786..2ab574df2 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -104,9 +104,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms double ratio = (double)sourceSize / destinationSize; double scale = ratio; - if (scale < 1F) + if (scale < 1) { - scale = 1F; + scale = 1; } int radius = (int)TolerantMath.Ceiling(scale * sampler.Radius); @@ -126,7 +126,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // however, it's just simpler to calculate them separately. int cornerInterval = (int)TolerantMath.Ceiling(firstNonNegativeLeftVal); - // If firstNonNegativeLeftVal was an integral value, we don't need Ceiling: + // If firstNonNegativeLeftVal was an integral value, we need firstNonNegativeLeftVal+1 + // instead of Ceiling: if (TolerantMath.AreEqual(firstNonNegativeLeftVal, cornerInterval)) { cornerInterval++;