Browse Source

Better Block8x8F clamp

pull/230/head
James Jackson-South 9 years ago
parent
commit
d2db3163c4
  1. 125
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
  2. 38
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
  3. 10
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

125
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs

@ -5,53 +5,120 @@
// ReSharper disable InconsistentNaming
// <auto-generated />
#pragma warning disable
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace ImageSharp.Formats.Jpg
{
using System.Numerics;
using System.Runtime.CompilerServices;
internal partial struct Block8x8F
{
private static readonly Vector4 CMin4 = new Vector4(-128f);
private static readonly Vector4 CMax4 = new Vector4(127f);
private static readonly Vector4 COff4 = new Vector4(128f);
private static readonly Vector4 CMin4 = new Vector4(0F);
private static readonly Vector4 CMax4 = new Vector4(255F);
private static readonly Vector4 COff4 = new Vector4(128F);
/// <summary>
/// Transpose the block into d
/// Transpose the block into the destination block.
/// </summary>
/// <param name="d">Destination</param>
/// <param name="d">The destination block</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TransposeInto(ref Block8x8F d)
{
d.V0L.X = V0L.X; d.V1L.X = V0L.Y; d.V2L.X = V0L.Z; d.V3L.X = V0L.W; d.V4L.X = V0R.X; d.V5L.X = V0R.Y; d.V6L.X = V0R.Z; d.V7L.X = V0R.W;
d.V0L.Y = V1L.X; d.V1L.Y = V1L.Y; d.V2L.Y = V1L.Z; d.V3L.Y = V1L.W; d.V4L.Y = V1R.X; d.V5L.Y = V1R.Y; d.V6L.Y = V1R.Z; d.V7L.Y = V1R.W;
d.V0L.Z = V2L.X; d.V1L.Z = V2L.Y; d.V2L.Z = V2L.Z; d.V3L.Z = V2L.W; d.V4L.Z = V2R.X; d.V5L.Z = V2R.Y; d.V6L.Z = V2R.Z; d.V7L.Z = V2R.W;
d.V0L.W = V3L.X; d.V1L.W = V3L.Y; d.V2L.W = V3L.Z; d.V3L.W = V3L.W; d.V4L.W = V3R.X; d.V5L.W = V3R.Y; d.V6L.W = V3R.Z; d.V7L.W = V3R.W;
d.V0R.X = V4L.X; d.V1R.X = V4L.Y; d.V2R.X = V4L.Z; d.V3R.X = V4L.W; d.V4R.X = V4R.X; d.V5R.X = V4R.Y; d.V6R.X = V4R.Z; d.V7R.X = V4R.W;
d.V0R.Y = V5L.X; d.V1R.Y = V5L.Y; d.V2R.Y = V5L.Z; d.V3R.Y = V5L.W; d.V4R.Y = V5R.X; d.V5R.Y = V5R.Y; d.V6R.Y = V5R.Z; d.V7R.Y = V5R.W;
d.V0R.Z = V6L.X; d.V1R.Z = V6L.Y; d.V2R.Z = V6L.Z; d.V3R.Z = V6L.W; d.V4R.Z = V6R.X; d.V5R.Z = V6R.Y; d.V6R.Z = V6R.Z; d.V7R.Z = V6R.W;
d.V0R.W = V7L.X; d.V1R.W = V7L.Y; d.V2R.W = V7L.Z; d.V3R.W = V7L.W; d.V4R.W = V7R.X; d.V5R.W = V7R.Y; d.V6R.W = V7R.Z; d.V7R.W = V7R.W;
d.V0L.X = V0L.X;
d.V1L.X = V0L.Y;
d.V2L.X = V0L.Z;
d.V3L.X = V0L.W;
d.V4L.X = V0R.X;
d.V5L.X = V0R.Y;
d.V6L.X = V0R.Z;
d.V7L.X = V0R.W;
d.V0L.Y = V1L.X;
d.V1L.Y = V1L.Y;
d.V2L.Y = V1L.Z;
d.V3L.Y = V1L.W;
d.V4L.Y = V1R.X;
d.V5L.Y = V1R.Y;
d.V6L.Y = V1R.Z;
d.V7L.Y = V1R.W;
d.V0L.Z = V2L.X;
d.V1L.Z = V2L.Y;
d.V2L.Z = V2L.Z;
d.V3L.Z = V2L.W;
d.V4L.Z = V2R.X;
d.V5L.Z = V2R.Y;
d.V6L.Z = V2R.Z;
d.V7L.Z = V2R.W;
d.V0L.W = V3L.X;
d.V1L.W = V3L.Y;
d.V2L.W = V3L.Z;
d.V3L.W = V3L.W;
d.V4L.W = V3R.X;
d.V5L.W = V3R.Y;
d.V6L.W = V3R.Z;
d.V7L.W = V3R.W;
d.V0R.X = V4L.X;
d.V1R.X = V4L.Y;
d.V2R.X = V4L.Z;
d.V3R.X = V4L.W;
d.V4R.X = V4R.X;
d.V5R.X = V4R.Y;
d.V6R.X = V4R.Z;
d.V7R.X = V4R.W;
d.V0R.Y = V5L.X;
d.V1R.Y = V5L.Y;
d.V2R.Y = V5L.Z;
d.V3R.Y = V5L.W;
d.V4R.Y = V5R.X;
d.V5R.Y = V5R.Y;
d.V6R.Y = V5R.Z;
d.V7R.Y = V5R.W;
d.V0R.Z = V6L.X;
d.V1R.Z = V6L.Y;
d.V2R.Z = V6L.Z;
d.V3R.Z = V6L.W;
d.V4R.Z = V6R.X;
d.V5R.Z = V6R.Y;
d.V6R.Z = V6R.Z;
d.V7R.Z = V6R.W;
d.V0R.W = V7L.X;
d.V1R.W = V7L.Y;
d.V2R.W = V7L.Z;
d.V3R.W = V7L.W;
d.V4R.W = V7R.X;
d.V5R.W = V7R.Y;
d.V6R.W = V7R.Z;
d.V7R.W = V7R.W;
}
/// <summary>
/// Level shift by +128, clip to [0, 255]
/// </summary>
/// <param name="d">Destination</param>
/// <param name="d">The destination block</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void TransformByteConvetibleColorValuesInto(ref Block8x8F d)
{
d.V0L = Vector4.Max(Vector4.Min(V0L, CMax4), CMin4) + COff4;d.V0R = Vector4.Max(Vector4.Min(V0R, CMax4), CMin4) + COff4;
d.V1L = Vector4.Max(Vector4.Min(V1L, CMax4), CMin4) + COff4;d.V1R = Vector4.Max(Vector4.Min(V1R, CMax4), CMin4) + COff4;
d.V2L = Vector4.Max(Vector4.Min(V2L, CMax4), CMin4) + COff4;d.V2R = Vector4.Max(Vector4.Min(V2R, CMax4), CMin4) + COff4;
d.V3L = Vector4.Max(Vector4.Min(V3L, CMax4), CMin4) + COff4;d.V3R = Vector4.Max(Vector4.Min(V3R, CMax4), CMin4) + COff4;
d.V4L = Vector4.Max(Vector4.Min(V4L, CMax4), CMin4) + COff4;d.V4R = Vector4.Max(Vector4.Min(V4R, CMax4), CMin4) + COff4;
d.V5L = Vector4.Max(Vector4.Min(V5L, CMax4), CMin4) + COff4;d.V5R = Vector4.Max(Vector4.Min(V5R, CMax4), CMin4) + COff4;
d.V6L = Vector4.Max(Vector4.Min(V6L, CMax4), CMin4) + COff4;d.V6R = Vector4.Max(Vector4.Min(V6R, CMax4), CMin4) + COff4;
d.V7L = Vector4.Max(Vector4.Min(V7L, CMax4), CMin4) + COff4;d.V7R = Vector4.Max(Vector4.Min(V7R, CMax4), CMin4) + COff4;
d.V0L = Vector4.Clamp(V0L + COff4, CMin4, CMax4);
d.V0R = Vector4.Clamp(V0R + COff4, CMin4, CMax4);
d.V1L = Vector4.Clamp(V1L + COff4, CMin4, CMax4);
d.V1R = Vector4.Clamp(V1R + COff4, CMin4, CMax4);
d.V2L = Vector4.Clamp(V2L + COff4, CMin4, CMax4);
d.V2R = Vector4.Clamp(V2R + COff4, CMin4, CMax4);
d.V3L = Vector4.Clamp(V3L + COff4, CMin4, CMax4);
d.V3R = Vector4.Clamp(V3R + COff4, CMin4, CMax4);
d.V4L = Vector4.Clamp(V4L + COff4, CMin4, CMax4);
d.V4R = Vector4.Clamp(V4R + COff4, CMin4, CMax4);
d.V5L = Vector4.Clamp(V5L + COff4, CMin4, CMax4);
d.V5R = Vector4.Clamp(V5R + COff4, CMin4, CMax4);
d.V6L = Vector4.Clamp(V6L + COff4, CMin4, CMax4);
d.V6R = Vector4.Clamp(V6R + COff4, CMin4, CMax4);
d.V7L = Vector4.Clamp(V7L + COff4, CMin4, CMax4);
d.V7R = Vector4.Clamp(V7R + COff4, CMin4, CMax4);
}
}
}

38
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt

@ -11,31 +11,29 @@
<#@ output extension=".cs" #>
// <auto-generated />
#pragma warning disable
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
<#
char[] coordz = {'X', 'Y', 'Z', 'W'};
#>
namespace ImageSharp.Formats.Jpg
{
using System.Numerics;
using System.Runtime.CompilerServices;
internal partial struct Block8x8F
{
private static readonly Vector4 CMin4 = new Vector4(-128f);
private static readonly Vector4 CMax4 = new Vector4(127f);
private static readonly Vector4 COff4 = new Vector4(128f);
private static readonly Vector4 CMin4 = new Vector4(0F);
private static readonly Vector4 CMax4 = new Vector4(255F);
private static readonly Vector4 COff4 = new Vector4(128F);
/// <summary>
/// Transpose the block into d
/// Transpose the block into the destination block.
/// </summary>
/// <param name="d">Destination</param>
/// <param name="d">The destination block</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TransposeInto(ref Block8x8F d)
{
<#
PushIndent(" ");
PushIndent(" ");
for (int i = 0; i < 8; i++)
{
@ -44,13 +42,16 @@ namespace ImageSharp.Formats.Jpg
for (int j = 0; j < 8; j++)
{
if(i > 0 && j == 0){
WriteLine("");
}
char srcCoord = coordz[j % 4];
char srcSide = (j / 4) % 2 == 0 ? 'L' : 'R';
string expression = $"d.V{j}{destSide}.{destCoord} = V{i}{srcSide}.{srcCoord}; ";
string expression = $"d.V{j}{destSide}.{destCoord} = V{i}{srcSide}.{srcCoord};\r\n";
Write(expression);
}
WriteLine("");
}
PopIndent();
#>
@ -59,27 +60,24 @@ namespace ImageSharp.Formats.Jpg
/// <summary>
/// Level shift by +128, clip to [0, 255]
/// </summary>
/// <param name="d">Destination</param>
/// <param name="d">The destination block</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void TransformByteConvetibleColorValuesInto(ref Block8x8F d)
{
<#
PushIndent(" ");
PushIndent(" ");
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 2; j++)
{
char side = j == 0 ? 'L' : 'R';
Write($"d.V{i}{side} = Vector4.Max(Vector4.Min(V{i}{side}, CMax4), CMin4) + COff4;");
Write($"d.V{i}{side} = Vector4.Clamp(V{i}{side} + COff4, CMin4, CMax4);\r\n");
}
WriteLine("");
}
PopIndent();
#>
}
}
}

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

@ -57,6 +57,9 @@ namespace ImageSharp.Formats.Jpg
public Vector4 V7R;
#pragma warning restore SA1600 // ElementsMustBeDocumented
private static readonly Vector4 NegativeOne = new Vector4(-1);
private static readonly Vector4 Offset = new Vector4(.5F);
/// <summary>
/// Get/Set scalar elements at a given index
/// </summary>
@ -402,12 +405,11 @@ namespace ImageSharp.Formats.Jpg
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor)
{
// sign(v) = max(min(v, 1), -1)
Vector4 sign = Vector4.Min(dividend, Vector4.One);
sign = Vector4.Max(sign, new Vector4(-1));
// sign(dividend) = max(min(dividend, 1), -1)
var sign = Vector4.Clamp(dividend, NegativeOne, Vector4.One);
// AlmostRound(dividend/divisor) = dividend/divisior + 0.5*sign(dividend)
return (dividend / divisor) + (sign * new Vector4(0.5f));
return (dividend / divisor) + (sign * Offset);
}
}
}
Loading…
Cancel
Save