Browse Source

Add AggressiveInlining where it seemed appropriate

pull/1147/head
Brian Popow 6 years ago
parent
commit
e78b48c837
  1. 2
      src/ImageSharp/Formats/WebP/AlphaDecoder.cs
  2. 66
      src/ImageSharp/Formats/WebP/LosslessUtils.cs
  3. 33
      src/ImageSharp/Formats/WebP/LossyUtils.cs
  4. 4
      src/ImageSharp/Formats/WebP/Vp8BitReader.cs
  5. 4
      src/ImageSharp/Formats/WebP/Vp8LBitReader.cs
  6. 6
      src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs
  7. 5
      src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs

2
src/ImageSharp/Formats/WebP/AlphaDecoder.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.WebP namespace SixLabors.ImageSharp.Formats.WebP
@ -293,6 +294,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return true; return true;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int GradientPredictor(byte a, byte b, byte c) private static int GradientPredictor(byte a, byte b, byte c)
{ {
int g = a + b - c; int g = a + b - c;

66
src/ImageSharp/Formats/WebP/LosslessUtils.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
@ -109,7 +110,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
while (y < yEnd) while (y < yEnd)
{ {
int predRowIdx = predRowIdxStart; int predRowIdx = predRowIdxStart;
Vp8LMultipliers m = default(Vp8LMultipliers); var m = default(Vp8LMultipliers);
int srcSafeEnd = pixelPos + safeWidth; int srcSafeEnd = pixelPos + safeWidth;
int srcEnd = pixelPos + width; int srcEnd = pixelPos + width;
while (pixelPos < srcSafeEnd) while (pixelPos < srcSafeEnd)
@ -273,6 +274,24 @@ namespace SixLabors.ImageSharp.Formats.WebP
output.CopyTo(pixelData); output.CopyTo(pixelData);
} }
public static void ExpandColorMap(int numColors, Span<uint> transformData, Span<uint> newColorMap)
{
newColorMap[0] = transformData[0];
Span<byte> data = MemoryMarshal.Cast<uint, byte>(transformData);
Span<byte> newData = MemoryMarshal.Cast<uint, byte>(newColorMap);
int i;
for (i = 4; i < 4 * numColors; ++i)
{
// Equivalent to AddPixelEq(), on a byte-basis.
newData[i] = (byte)((data[i] + newData[i - 4]) & 0xff);
}
for (; i < 4 * newColorMap.Length; ++i)
{
newData[i] = 0; // black tail.
}
}
private static void PredictorAdd0(Span<uint> input, int startIdx, int numberOfPixels, Span<uint> output) private static void PredictorAdd0(Span<uint> input, int startIdx, int numberOfPixels, Span<uint> output)
{ {
int endIdx = startIdx + numberOfPixels; int endIdx = startIdx + numberOfPixels;
@ -425,79 +444,93 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor0() private static uint Predictor0()
{ {
return WebPConstants.ArgbBlack; return WebPConstants.ArgbBlack;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor1(uint left, Span<uint> top) private static uint Predictor1(uint left, Span<uint> top)
{ {
return left; return left;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor2(uint left, Span<uint> top, int idx) private static uint Predictor2(uint left, Span<uint> top, int idx)
{ {
return top[idx]; return top[idx];
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor3(uint left, Span<uint> top, int idx) private static uint Predictor3(uint left, Span<uint> top, int idx)
{ {
return top[idx + 1]; return top[idx + 1];
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor4(uint left, Span<uint> top, int idx) private static uint Predictor4(uint left, Span<uint> top, int idx)
{ {
return top[idx - 1]; return top[idx - 1];
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor5(uint left, Span<uint> top, int idx) private static uint Predictor5(uint left, Span<uint> top, int idx)
{ {
uint pred = Average3(left, top[idx], top[idx + 1]); uint pred = Average3(left, top[idx], top[idx + 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor6(uint left, Span<uint> top, int idx) private static uint Predictor6(uint left, Span<uint> top, int idx)
{ {
uint pred = Average2(left, top[idx - 1]); uint pred = Average2(left, top[idx - 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor7(uint left, Span<uint> top, int idx) private static uint Predictor7(uint left, Span<uint> top, int idx)
{ {
uint pred = Average2(left, top[idx]); uint pred = Average2(left, top[idx]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor8(uint left, Span<uint> top, int idx) private static uint Predictor8(uint left, Span<uint> top, int idx)
{ {
uint pred = Average2(top[idx - 1], top[idx]); uint pred = Average2(top[idx - 1], top[idx]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor9(uint left, Span<uint> top, int idx) private static uint Predictor9(uint left, Span<uint> top, int idx)
{ {
uint pred = Average2(top[idx], top[idx + 1]); uint pred = Average2(top[idx], top[idx + 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor10(uint left, Span<uint> top, int idx) private static uint Predictor10(uint left, Span<uint> top, int idx)
{ {
uint pred = Average4(left, top[idx - 1], top[idx], top[idx + 1]); uint pred = Average4(left, top[idx - 1], top[idx], top[idx + 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor11(uint left, Span<uint> top, int idx) private static uint Predictor11(uint left, Span<uint> top, int idx)
{ {
uint pred = Select(top[idx], left, top[idx - 1]); uint pred = Select(top[idx], left, top[idx - 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor12(uint left, Span<uint> top, int idx) private static uint Predictor12(uint left, Span<uint> top, int idx)
{ {
uint pred = ClampedAddSubtractFull(left, top[idx], top[idx - 1]); uint pred = ClampedAddSubtractFull(left, top[idx], top[idx - 1]);
return pred; return pred;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Predictor13(uint left, Span<uint> top, int idx) private static uint Predictor13(uint left, Span<uint> top, int idx)
{ {
uint pred = ClampedAddSubtractHalf(left, top[idx], top[idx - 1]); uint pred = ClampedAddSubtractHalf(left, top[idx], top[idx - 1]);
@ -529,16 +562,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
return ((uint)a << 24) | ((uint)r << 16) | ((uint)g << 8) | (uint)b; return ((uint)a << 24) | ((uint)r << 16) | ((uint)g << 8) | (uint)b;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int AddSubtractComponentHalf(int a, int b) private static int AddSubtractComponentHalf(int a, int b)
{ {
return (int)Clip255((uint)(a + ((a - b) / 2))); return (int)Clip255((uint)(a + ((a - b) / 2)));
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int AddSubtractComponentFull(int a, int b, int c) private static int AddSubtractComponentFull(int a, int b, int c)
{ {
return (int)Clip255((uint)(a + b - c)); return (int)Clip255((uint)(a + b - c));
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Clip255(uint a) private static uint Clip255(uint a)
{ {
if (a < 256) if (a < 256)
@ -559,6 +595,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return (paMinusPb <= 0) ? a : b; return (paMinusPb <= 0) ? a : b;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int Sub3(int a, int b, int c) private static int Sub3(int a, int b, int c)
{ {
int pb = b - c; int pb = b - c;
@ -566,16 +603,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
return Math.Abs(pb) - Math.Abs(pa); return Math.Abs(pb) - Math.Abs(pa);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average2(uint a0, uint a1) private static uint Average2(uint a0, uint a1)
{ {
return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1); return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average3(uint a0, uint a1, uint a2) private static uint Average3(uint a0, uint a1, uint a2)
{ {
return Average2(Average2(a0, a2), a1); return Average2(Average2(a0, a2), a1);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average4(uint a0, uint a1, uint a2, uint a3) private static uint Average4(uint a0, uint a1, uint a2, uint a3)
{ {
return Average2(Average2(a0, a1), Average2(a2, a3)); return Average2(Average2(a0, a1), Average2(a2, a3));
@ -584,6 +624,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// <summary> /// <summary>
/// Computes sampled size of 'size' when sampling using 'sampling bits'. /// Computes sampled size of 'size' when sampling using 'sampling bits'.
/// </summary> /// </summary>
[MethodImpl(InliningOptions.ShortMethod)]
public static int SubSampleSize(int size, int samplingBits) public static int SubSampleSize(int size, int samplingBits)
{ {
return (size + (1 << samplingBits) - 1) >> samplingBits; return (size + (1 << samplingBits) - 1) >> samplingBits;
@ -592,6 +633,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// <summary> /// <summary>
/// Sum of each component, mod 256. /// Sum of each component, mod 256.
/// </summary> /// </summary>
[MethodImpl(InliningOptions.ShortMethod)]
private static uint AddPixels(uint a, uint b) private static uint AddPixels(uint a, uint b)
{ {
uint alphaAndGreen = (a & 0xff00ff00u) + (b & 0xff00ff00u); uint alphaAndGreen = (a & 0xff00ff00u) + (b & 0xff00ff00u);
@ -602,6 +644,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// <summary> /// <summary>
/// Difference of each component, mod 256. /// Difference of each component, mod 256.
/// </summary> /// </summary>
[MethodImpl(InliningOptions.ShortMethod)]
private static uint SubPixels(uint a, uint b) private static uint SubPixels(uint a, uint b)
{ {
uint alphaAndGreen = 0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u); uint alphaAndGreen = 0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u);
@ -609,34 +652,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
return (alphaAndGreen & 0xff00ff00u) | (redAndBlue & 0x00ff00ffu); return (alphaAndGreen & 0xff00ff00u) | (redAndBlue & 0x00ff00ffu);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint GetArgbIndex(uint idx) private static uint GetArgbIndex(uint idx)
{ {
return (idx >> 8) & 0xff; return (idx >> 8) & 0xff;
} }
public static void ExpandColorMap(int numColors, Span<uint> transformData, Span<uint> newColorMap) [MethodImpl(InliningOptions.ShortMethod)]
{
newColorMap[0] = transformData[0];
Span<byte> data = MemoryMarshal.Cast<uint, byte>(transformData);
Span<byte> newData = MemoryMarshal.Cast<uint, byte>(newColorMap);
int i;
for (i = 4; i < 4 * numColors; ++i)
{
// Equivalent to AddPixelEq(), on a byte-basis.
newData[i] = (byte)((data[i] + newData[i - 4]) & 0xff);
}
for (; i < 4 * newColorMap.Length; ++i)
{
newData[i] = 0; // black tail.
}
}
private static int ColorTransformDelta(sbyte colorPred, sbyte color) private static int ColorTransformDelta(sbyte colorPred, sbyte color)
{ {
return ((int)colorPred * color) >> 5; return ((int)colorPred * color) >> 5;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void ColorCodeToMultipliers(uint colorCode, ref Vp8LMultipliers m) private static void ColorCodeToMultipliers(uint colorCode, ref Vp8LMultipliers m)
{ {
m.GreenToRed = (byte)(colorCode & 0xff); m.GreenToRed = (byte)(colorCode & 0xff);

33
src/ImageSharp/Formats/WebP/LossyUtils.cs

@ -3,11 +3,13 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.WebP namespace SixLabors.ImageSharp.Formats.WebP
{ {
internal static class LossyUtils internal static class LossyUtils
{ {
[MethodImpl(InliningOptions.ShortMethod)]
private static void Put16(int v, Span<byte> dst) private static void Put16(int v, Span<byte> dst)
{ {
for (int j = 0; j < 16; ++j) for (int j = 0; j < 16; ++j)
@ -28,6 +30,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
Put16(dc >> 5, dst); Put16(dc >> 5, dst);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void TM16(Span<byte> dst, Span<byte> yuv, int offset) public static void TM16(Span<byte> dst, Span<byte> yuv, int offset)
{ {
TrueMotion(dst, yuv, offset, 16); TrueMotion(dst, yuv, offset, 16);
@ -83,6 +86,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
Put16(dc >> 4, dst); Put16(dc >> 4, dst);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void DC16NoTopLeft(Span<byte> dst) public static void DC16NoTopLeft(Span<byte> dst)
{ {
// DC with no top and left samples. // DC with no top and left samples.
@ -101,6 +105,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
Put8x8uv((byte)(dc0 >> 4), dst); Put8x8uv((byte)(dc0 >> 4), dst);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void TM8uv(Span<byte> dst, Span<byte> yuv, int offset) public static void TM8uv(Span<byte> dst, Span<byte> yuv, int offset)
{ {
// TrueMotion // TrueMotion
@ -159,6 +164,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
Put8x8uv((byte)(dc0 >> 3), dst); Put8x8uv((byte)(dc0 >> 3), dst);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void DC8uvNoTopLeft(Span<byte> dst) public static void DC8uvNoTopLeft(Span<byte> dst)
{ {
// DC with nothing. // DC with nothing.
@ -180,6 +186,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void TM4(Span<byte> dst, Span<byte> yuv, int offset) public static void TM4(Span<byte> dst, Span<byte> yuv, int offset)
{ {
TrueMotion(dst, yuv, offset, 4); TrueMotion(dst, yuv, offset, 4);
@ -601,11 +608,13 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void VFilter16(Span<byte> p, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void VFilter16(Span<byte> p, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop26(p, offset, stride, 1, 16, thresh, ithresh, hevThresh); FilterLoop26(p, offset, stride, 1, 16, thresh, ithresh, hevThresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void HFilter16(Span<byte> p, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void HFilter16(Span<byte> p, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop26(p, offset, 1, stride, 16, thresh, ithresh, hevThresh); FilterLoop26(p, offset, 1, stride, 16, thresh, ithresh, hevThresh);
@ -630,36 +639,42 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
// 8-pixels wide variant, for chroma filtering. // 8-pixels wide variant, for chroma filtering.
[MethodImpl(InliningOptions.ShortMethod)]
public static void VFilter8(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void VFilter8(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop26(u, offset, stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop26(u, offset, stride, 1, 8, thresh, ithresh, hevThresh);
FilterLoop26(v, offset, stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, stride, 1, 8, thresh, ithresh, hevThresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void HFilter8(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void HFilter8(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop26(u, offset, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop26(u, offset, 1, stride, 8, thresh, ithresh, hevThresh);
FilterLoop26(v, offset, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, 1, stride, 8, thresh, ithresh, hevThresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void VFilter8i(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void VFilter8i(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop24(u, offset + (4 * stride), stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop24(u, offset + (4 * stride), stride, 1, 8, thresh, ithresh, hevThresh);
FilterLoop24(v, offset + (4 * stride), stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop24(v, offset + (4 * stride), stride, 1, 8, thresh, ithresh, hevThresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void HFilter8i(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh) public static void HFilter8i(Span<byte> u, Span<byte> v, int offset, int stride, int thresh, int ithresh, int hevThresh)
{ {
FilterLoop24(u, offset + 4, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop24(u, offset + 4, 1, stride, 8, thresh, ithresh, hevThresh);
FilterLoop24(v, offset + 4, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop24(v, offset + 4, 1, stride, 8, thresh, ithresh, hevThresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static uint LoadUv(byte u, byte v) public static uint LoadUv(byte u, byte v)
{ {
// We process u and v together stashed into 32bit(16bit each). // We process u and v together stashed into 32bit(16bit each).
return (uint)(u | (v << 16)); return (uint)(u | (v << 16));
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static void YuvToBgr(int y, int u, int v, Span<byte> bgr) public static void YuvToBgr(int y, int u, int v, Span<byte> bgr)
{ {
bgr[0] = (byte)YuvToB(y, u); bgr[0] = (byte)YuvToB(y, u);
@ -667,16 +682,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
bgr[2] = (byte)YuvToR(y, v); bgr[2] = (byte)YuvToR(y, v);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static int YuvToR(int y, int v) public static int YuvToR(int y, int v)
{ {
return Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234); return Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static int YuvToG(int y, int u, int v) public static int YuvToG(int y, int u, int v)
{ {
return Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708); return Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708);
} }
[MethodImpl(InliningOptions.ShortMethod)]
public static int YuvToB(int y, int u) public static int YuvToB(int y, int u)
{ {
return Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685); return Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685);
@ -795,6 +813,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
p[offset + (2 * step)] = WebPLookupTables.Clip1[q2 - a3]; p[offset + (2 * step)] = WebPLookupTables.Clip1[q2 - a3];
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static bool NeedsFilter(Span<byte> p, int offset, int step, int t) private static bool NeedsFilter(Span<byte> p, int offset, int step, int t)
{ {
int p1 = p[offset + (-2 * step)]; int p1 = p[offset + (-2 * step)];
@ -824,6 +843,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
WebPLookupTables.Abs0[q2 - q1] <= it && WebPLookupTables.Abs0[q1 - q0] <= it; WebPLookupTables.Abs0[q2 - q1] <= it && WebPLookupTables.Abs0[q1 - q0] <= it;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static bool Hev(Span<byte> p, int offset, int step, int thresh) private static bool Hev(Span<byte> p, int offset, int step, int thresh)
{ {
int p1 = p[offset - (2 * step)]; int p1 = p[offset - (2 * step)];
@ -833,16 +853,19 @@ namespace SixLabors.ImageSharp.Formats.WebP
return (WebPLookupTables.Abs0[p1 - p0] > thresh) || (WebPLookupTables.Abs0[q1 - q0] > thresh); return (WebPLookupTables.Abs0[p1 - p0] > thresh) || (WebPLookupTables.Abs0[q1 - q0] > thresh);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int MultHi(int v, int coeff) private static int MultHi(int v, int coeff)
{ {
return (v * coeff) >> 8; return (v * coeff) >> 8;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void Store(Span<byte> dst, int x, int y, int v) private static void Store(Span<byte> dst, int x, int y, int v)
{ {
dst[x + (y * WebPConstants.Bps)] = Clip8B(dst[x + (y * WebPConstants.Bps)] + (v >> 3)); dst[x + (y * WebPConstants.Bps)] = Clip8B(dst[x + (y * WebPConstants.Bps)] + (v >> 3));
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void Store2(Span<byte> dst, int y, int dc, int d, int c) private static void Store2(Span<byte> dst, int y, int dc, int d, int c)
{ {
Store(dst, 0, y, dc + d); Store(dst, 0, y, dc + d);
@ -851,27 +874,32 @@ namespace SixLabors.ImageSharp.Formats.WebP
Store(dst, 3, y, dc - d); Store(dst, 3, y, dc - d);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int Mul1(int a) private static int Mul1(int a)
{ {
return ((a * 20091) >> 16) + a; return ((a * 20091) >> 16) + a;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int Mul2(int a) private static int Mul2(int a)
{ {
return (a * 35468) >> 16; return (a * 35468) >> 16;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static byte Clip8B(int v) private static byte Clip8B(int v)
{ {
return (byte)((v & ~0xff) is 0 ? v : (v < 0) ? 0 : 255); return (byte)((v & ~0xff) is 0 ? v : (v < 0) ? 0 : 255);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static byte Clip8(int v) private static byte Clip8(int v)
{ {
int yuvMask = (256 << 6) - 1; int yuvMask = (256 << 6) - 1;
return (byte)(((v & ~yuvMask) is 0) ? (v >> 6) : (v < 0) ? 0 : 255); return (byte)(((v & ~yuvMask) is 0) ? (v >> 6) : (v < 0) ? 0 : 255);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void Put8x8uv(byte value, Span<byte> dst) private static void Put8x8uv(byte value, Span<byte> dst)
{ {
for (int j = 0; j < 8; ++j) for (int j = 0; j < 8; ++j)
@ -881,6 +909,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void Memset(Span<byte> dst, byte value, int startIdx, int count) private static void Memset(Span<byte> dst, byte value, int startIdx, int count)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
@ -889,21 +918,25 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static byte Avg2(byte a, byte b) private static byte Avg2(byte a, byte b)
{ {
return (byte)((a + b + 1) >> 1); return (byte)((a + b + 1) >> 1);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static byte Avg3(byte a, byte b, byte c) private static byte Avg3(byte a, byte b, byte c)
{ {
return (byte)((a + (2 * b) + c + 2) >> 2); return (byte)((a + (2 * b) + c + 2) >> 2);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static void Dst(Span<byte> dst, int x, int y, byte v) private static void Dst(Span<byte> dst, int x, int y, byte v)
{ {
dst[x + (y * WebPConstants.Bps)] = v; dst[x + (y * WebPConstants.Bps)] = v;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int Clamp255(int x) private static int Clamp255(int x)
{ {
return x < 0 ? 0 : (x > 255 ? 255 : x); return x < 0 ? 0 : (x > 255 ? 255 : x);

4
src/ImageSharp/Formats/WebP/Vp8BitReader.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.WebP namespace SixLabors.ImageSharp.Formats.WebP
@ -139,6 +140,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return (v ^ (int)mask) - (int)mask; return (v ^ (int)mask) - (int)mask;
} }
[MethodImpl(InliningOptions.ShortMethod)]
public bool ReadBool() public bool ReadBool()
{ {
return this.ReadValue(1) is 1; return this.ReadValue(1) is 1;
@ -215,6 +217,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
} }
[MethodImpl(InliningOptions.ShortMethod)]
private ulong ByteSwap64(ulong x) private ulong ByteSwap64(ulong x)
{ {
x = ((x & 0xffffffff00000000ul) >> 32) | ((x & 0x00000000fffffffful) << 32); x = ((x & 0xffffffff00000000ul) >> 32) | ((x & 0x00000000fffffffful) << 32);
@ -224,6 +227,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
} }
// Returns 31 ^ clz(n) = log2(n).Returns 31 ^ clz(n) = log2(n). // Returns 31 ^ clz(n) = log2(n).Returns 31 ^ clz(n) = log2(n).
[MethodImpl(InliningOptions.ShortMethod)]
private int BitsLog2Floor(uint n) private int BitsLog2Floor(uint n)
{ {
int logValue = 0; int logValue = 0;

4
src/ImageSharp/Formats/WebP/Vp8LBitReader.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.WebP namespace SixLabors.ImageSharp.Formats.WebP
@ -142,6 +143,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// Reads a single bit from the stream. /// Reads a single bit from the stream.
/// </summary> /// </summary>
/// <returns>True if the bit read was 1, false otherwise.</returns> /// <returns>True if the bit read was 1, false otherwise.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public bool ReadBit() public bool ReadBit()
{ {
uint bit = this.ReadValue(1); uint bit = this.ReadValue(1);
@ -152,6 +154,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// For jumping over a number of bits in the bit stream when accessed with PrefetchBits and FillBitWindow. /// For jumping over a number of bits in the bit stream when accessed with PrefetchBits and FillBitWindow.
/// </summary> /// </summary>
/// <param name="numberOfBits">The number of bits to advance the position.</param> /// <param name="numberOfBits">The number of bits to advance the position.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public void AdvanceBitPosition(int numberOfBits) public void AdvanceBitPosition(int numberOfBits)
{ {
this.bitPos += numberOfBits; this.bitPos += numberOfBits;
@ -161,6 +164,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
/// Return the pre-fetched bits, so they can be looked up. /// Return the pre-fetched bits, so they can be looked up.
/// </summary> /// </summary>
/// <returns>The pre-fetched bits.</returns> /// <returns>The pre-fetched bits.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public ulong PrefetchBits() public ulong PrefetchBits()
{ {
return this.value >> (this.bitPos & (Lbits - 1)); return this.value >> (this.bitPos & (Lbits - 1));

6
src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs

@ -5,6 +5,7 @@ using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
@ -960,12 +961,14 @@ namespace SixLabors.ImageSharp.Formats.WebP
return tableSpan[0].Value; return tableSpan[0].Value;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private HTreeGroup[] GetHTreeGroupForPos(Vp8LMetadata metadata, int x, int y) private HTreeGroup[] GetHTreeGroupForPos(Vp8LMetadata metadata, int x, int y)
{ {
uint metaIndex = this.GetMetaIndex(metadata.HuffmanImage, metadata.HuffmanXSize, metadata.HuffmanSubSampleBits, x, y); uint metaIndex = this.GetMetaIndex(metadata.HuffmanImage, metadata.HuffmanXSize, metadata.HuffmanSubSampleBits, x, y);
return metadata.HTreeGroups.AsSpan((int)metaIndex).ToArray(); return metadata.HTreeGroups.AsSpan((int)metaIndex).ToArray();
} }
[MethodImpl(InliningOptions.ShortMethod)]
private uint GetMetaIndex(IMemoryOwner<uint> huffmanImage, int xSize, int bits, int x, int y) private uint GetMetaIndex(IMemoryOwner<uint> huffmanImage, int xSize, int bits, int x, int y)
{ {
if (bits is 0) if (bits is 0)
@ -1006,12 +1009,14 @@ namespace SixLabors.ImageSharp.Formats.WebP
return (int)(offset + this.bitReader.ReadValue(extraBits) + 1); return (int)(offset + this.bitReader.ReadValue(extraBits) + 1);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private int GetCopyLength(int lengthSymbol) private int GetCopyLength(int lengthSymbol)
{ {
// Length and distance prefixes are encoded the same way. // Length and distance prefixes are encoded the same way.
return this.GetCopyDistance(lengthSymbol); return this.GetCopyDistance(lengthSymbol);
} }
[MethodImpl(InliningOptions.ShortMethod)]
private int AccumulateHCode(HuffmanCode hCode, int shift, HuffmanCode huff) private int AccumulateHCode(HuffmanCode hCode, int shift, HuffmanCode huff)
{ {
huff.BitsUsed += hCode.BitsUsed; huff.BitsUsed += hCode.BitsUsed;
@ -1019,6 +1024,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return hCode.BitsUsed; return hCode.BitsUsed;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static byte GetAlphaValue(int val) private static byte GetAlphaValue(int val)
{ {
return (byte)((val >> 8) & 0xff); return (byte)((val >> 8) & 0xff);

5
src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
@ -1362,6 +1363,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return io; return io;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static uint NzCodeBits(uint nzCoeffs, int nz, int dcNz) private static uint NzCodeBits(uint nzCoeffs, int nz, int dcNz)
{ {
nzCoeffs <<= 2; nzCoeffs <<= 2;
@ -1369,12 +1371,14 @@ namespace SixLabors.ImageSharp.Formats.WebP
return nzCoeffs; return nzCoeffs;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static Vp8BandProbas[] GetBandsRow(Vp8BandProbas[,] bands, int rowIdx) private static Vp8BandProbas[] GetBandsRow(Vp8BandProbas[,] bands, int rowIdx)
{ {
Vp8BandProbas[] bandsRow = Enumerable.Range(0, bands.GetLength(1)).Select(x => bands[rowIdx, x]).ToArray(); Vp8BandProbas[] bandsRow = Enumerable.Range(0, bands.GetLength(1)).Select(x => bands[rowIdx, x]).ToArray();
return bandsRow; return bandsRow;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int CheckMode(int mbx, int mby, int mode) private static int CheckMode(int mbx, int mby, int mode)
{ {
// B_DC_PRED // B_DC_PRED
@ -1395,6 +1399,7 @@ namespace SixLabors.ImageSharp.Formats.WebP
return mode; return mode;
} }
[MethodImpl(InliningOptions.ShortMethod)]
private static int Clip(int value, int max) private static int Clip(int value, int max)
{ {
return value < 0 ? 0 : value > max ? max : value; return value < 0 ? 0 : value > max ? max : value;

Loading…
Cancel
Save