Browse Source

Normalize some reference swapping

pull/2189/head
James Jackson-South 4 years ago
parent
commit
3fb4787c3a
  1. 48
      src/ImageSharp/Common/Helpers/RuntimeUtility.cs
  2. 3
      src/ImageSharp/Common/Helpers/UnitConverter.cs
  3. 59
      src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
  4. 64
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
  5. 31
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  6. 12
      src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs
  7. 3
      src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs

48
src/ImageSharp/Common/Helpers/RuntimeUtility.cs

@ -0,0 +1,48 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Common.Helpers
{
/// <summary>
/// A helper class that with utility methods for dealing with references, and other low-level details.
/// </summary>
internal static class RuntimeUtility
{
/// <summary>
/// Swaps the two references.
/// </summary>
/// <typeparam name="T">The type to swap.</typeparam>
/// <param name="a">The first item.</param>
/// <param name="b">The second item.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(ref T a, ref T b)
{
// Tuple swap uses 2 more IL bytes
#pragma warning disable IDE0180 // Use tuple to swap values
T tmp = a;
#pragma warning restore IDE0180 // Use tuple to swap values
a = b;
b = tmp;
}
/// <summary>
/// Swaps the two references.
/// </summary>
/// <typeparam name="T">The type to swap.</typeparam>
/// <param name="a">The first item.</param>
/// <param name="b">The second item.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(ref Span<T> a, ref Span<T> b)
{
// Tuple swap uses 2 more IL bytes
#pragma warning disable IDE0180 // Use tuple to swap values
Span<T> tmp = a;
#pragma warning restore IDE0180 // Use tuple to swap values
a = b;
b = tmp;
}
}
}

3
src/ImageSharp/Common/Helpers/UnitConverter.cs

@ -114,11 +114,10 @@ namespace SixLabors.ImageSharp.Common.Helpers
case PixelResolutionUnit.PixelsPerCentimeter:
break;
case PixelResolutionUnit.PixelsPerMeter:
{
unit = PixelResolutionUnit.PixelsPerCentimeter;
horizontal = MeterToCm(horizontal);
vertical = MeterToCm(vertical);
}
break;
default:

59
src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs

@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
@ -226,48 +227,46 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
ref short elemRef = ref Unsafe.As<Block8x8, short>(ref this);
// row #0
Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8));
Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16));
Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24));
Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32));
Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40));
Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48));
Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56));
// row #1
Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17));
Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25));
Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33));
Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41));
Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49));
Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57));
// row #2
Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26));
Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34));
Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42));
Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50));
Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58));
// row #3
Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35));
Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43));
Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51));
Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59));
// row #4
Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44));
Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52));
Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60));
// row #5
Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53));
Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61));
// row #6
Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62));
static void Swap(ref short a, ref short b) => (b, a) = (a, b);
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62));
}
/// <summary>

64
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using SixLabors.ImageSharp.Common.Helpers;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Formats.Jpeg.Components
@ -496,53 +497,46 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
ref float elemRef = ref Unsafe.As<Block8x8F, float>(ref this);
// row #0
Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8));
Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16));
Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24));
Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32));
Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40));
Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48));
Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56));
// row #1
Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17));
Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25));
Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33));
Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41));
Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49));
Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57));
// row #2
Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26));
Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34));
Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42));
Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50));
Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58));
// row #3
Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35));
Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43));
Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51));
Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59));
// row #4
Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44));
Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52));
Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60));
// row #5
Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53));
Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53));
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61));
// row #6
Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62));
static void Swap(ref float a, ref float b)
{
float tmp = a;
a = b;
b = tmp;
}
RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62));
}
[MethodImpl(InliningOptions.ShortMethod)]

31
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -8,6 +8,7 @@ using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Png.Chunks;
using SixLabors.ImageSharp.Formats.Png.Filters;
@ -520,27 +521,27 @@ namespace SixLabors.ImageSharp.Formats.Png
if (sum < min)
{
min = sum;
SwapSpans(ref filter, ref attempt);
RuntimeUtility.Swap(ref filter, ref attempt);
}
UpFilter.Encode(current, previous, attempt, out sum);
if (sum < min)
{
min = sum;
SwapSpans(ref filter, ref attempt);
RuntimeUtility.Swap(ref filter, ref attempt);
}
AverageFilter.Encode(current, previous, attempt, this.bytesPerPixel, out sum);
if (sum < min)
{
min = sum;
SwapSpans(ref filter, ref attempt);
RuntimeUtility.Swap(ref filter, ref attempt);
}
PaethFilter.Encode(current, previous, attempt, this.bytesPerPixel, out sum);
if (sum < min)
{
SwapSpans(ref filter, ref attempt);
RuntimeUtility.Swap(ref filter, ref attempt);
}
}
@ -749,21 +750,21 @@ namespace SixLabors.ImageSharp.Formats.Png
return;
}
const int MaxLatinCode = 255;
const int maxLatinCode = 255;
for (int i = 0; i < meta.TextData.Count; i++)
{
PngTextData textData = meta.TextData[i];
bool hasUnicodeCharacters = false;
foreach (var c in textData.Value)
foreach (char c in textData.Value)
{
if (c > MaxLatinCode)
if (c > maxLatinCode)
{
hasUnicodeCharacters = true;
break;
}
}
if (hasUnicodeCharacters || (!string.IsNullOrWhiteSpace(textData.LanguageTag) || !string.IsNullOrWhiteSpace(textData.TranslatedKeyword)))
if (hasUnicodeCharacters || !string.IsNullOrWhiteSpace(textData.LanguageTag) || !string.IsNullOrWhiteSpace(textData.TranslatedKeyword))
{
// Write iTXt chunk.
byte[] keywordBytes = PngConstants.Encoding.GetBytes(textData.Keyword);
@ -1206,18 +1207,12 @@ namespace SixLabors.ImageSharp.Formats.Png
return scanlineLength / mod;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SwapScanlineBuffers()
{
IMemoryOwner<byte> temp = this.previousScanline;
this.previousScanline = this.currentScanline;
this.currentScanline = temp;
}
private static void SwapSpans<T>(ref Span<T> a, ref Span<T> b)
{
Span<T> t = b;
b = a;
a = t;
ref IMemoryOwner<byte> prev = ref this.previousScanline;
ref IMemoryOwner<byte> current = ref this.currentScanline;
RuntimeUtility.Swap(ref prev, ref current);
}
}
}

12
src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs

@ -6,6 +6,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
@ -75,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
if (mode == 0 || rdCur.Score < rdBest.Score)
{
(rdBest, rdCur) = (rdCur, rdBest);
RuntimeUtility.Swap(ref rdBest, ref rdCur);
it.SwapOut();
}
}
@ -174,9 +175,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
rdi4.CopyScore(rdTmp);
bestMode = mode;
Span<byte> tmp = tmpDst;
tmpDst = bestBlock;
bestBlock = tmp;
RuntimeUtility.Swap(ref tmpDst, ref bestBlock);
tmpLevels.CopyTo(rdBest.YAcLevels.AsSpan(it.I4 * 16, 16));
}
}
@ -258,9 +258,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
rd.Derr[i, 2] = rdUv.Derr[i, 2];
}
Span<byte> tmp = dst;
dst = tmpDst;
tmpDst = tmp;
RuntimeUtility.Swap(ref tmpDst, ref dst);
}
}

3
src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License.
using System;
using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
@ -754,7 +755,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public void SwapOut()
{
#pragma warning disable IDE0180 // Use tuple to swap values
byte[] tmp = this.YuvOut;
#pragma warning restore IDE0180 // Use tuple to swap values
this.YuvOut = this.YuvOut2;
this.YuvOut2 = tmp;
}

Loading…
Cancel
Save