Browse Source

A little cleanup

pull/1552/head
Brian Popow 5 years ago
parent
commit
4fa55b7a7b
  1. 5
      src/ImageSharp/Formats/WebP/BitReader/Vp8BitReader.cs
  2. 20
      src/ImageSharp/Formats/WebP/BitReader/Vp8LBitReader.cs
  3. 13
      src/ImageSharp/Formats/WebP/BitWriter/BitWriterBase.cs
  4. 10
      src/ImageSharp/Formats/WebP/BitWriter/Vp8LBitWriter.cs
  5. 10
      src/ImageSharp/Formats/WebP/Lossless/CostManager.cs
  6. 172
      src/ImageSharp/Formats/WebP/Lossless/LosslessUtils.cs
  7. 15
      src/ImageSharp/Formats/WebP/Lossless/Vp8LHistogram.cs
  8. 13
      src/ImageSharp/Formats/WebP/Lossy/Vp8Decoder.cs
  9. 23
      src/ImageSharp/Formats/WebP/Lossy/Vp8Encoder.cs
  10. 17
      src/ImageSharp/Formats/WebP/WebpDecoderCore.cs
  11. 70
      tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
  12. 12
      tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

5
src/ImageSharp/Formats/WebP/BitReader/Vp8BitReader.cs

@ -140,10 +140,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitReader
}
[MethodImpl(InliningOptions.ShortMethod)]
public bool ReadBool()
{
return this.ReadValue(1) is 1;
}
public bool ReadBool() => this.ReadValue(1) is 1;
public uint ReadValue(int nBits)
{

20
src/ImageSharp/Formats/WebP/BitReader/Vp8LBitReader.cs

@ -157,20 +157,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitReader
/// </summary>
/// <param name="numberOfBits">The number of bits to advance the position.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public void AdvanceBitPosition(int numberOfBits)
{
this.bitPos += numberOfBits;
}
public void AdvanceBitPosition(int numberOfBits) => this.bitPos += numberOfBits;
/// <summary>
/// Return the pre-fetched bits, so they can be looked up.
/// </summary>
/// <returns>The pre-fetched bits.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public ulong PrefetchBits()
{
return this.value >> (this.bitPos & (Lbits - 1));
}
public ulong PrefetchBits() => this.value >> (this.bitPos & (Lbits - 1));
/// <summary>
/// Advances the read buffer by 4 bytes to make room for reading next 32 bits.
@ -187,16 +181,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitReader
/// Returns true if there was an attempt at reading bit past the end of the buffer.
/// </summary>
/// <returns>True, if end of buffer was reached.</returns>
public bool IsEndOfStream()
{
return this.Eos || ((this.pos == this.len) && (this.bitPos > Lbits));
}
public bool IsEndOfStream() => this.Eos || ((this.pos == this.len) && (this.bitPos > Lbits));
[MethodImpl(InliningOptions.ShortMethod)]
private void DoFillBitWindow()
{
this.ShiftBytes();
}
private void DoFillBitWindow() => this.ShiftBytes();
/// <summary>
/// If not at EOS, reload up to Vp8LLbits byte-by-byte.

13
src/ImageSharp/Formats/WebP/BitWriter/BitWriterBase.cs

@ -18,11 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitWriter
/// Initializes a new instance of the <see cref="BitWriterBase"/> class.
/// </summary>
/// <param name="expectedSize">The expected size in bytes.</param>
protected BitWriterBase(int expectedSize)
{
// TODO: should we use memory allocator here?
this.buffer = new byte[expectedSize];
}
protected BitWriterBase(int expectedSize) => this.buffer = new byte[expectedSize];
/// <summary>
/// Initializes a new instance of the <see cref="BitWriterBase"/> class.
@ -36,10 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitWriter
/// Writes the encoded bytes of the image to the stream. Call Finish() before this.
/// </summary>
/// <param name="stream">The stream to write to.</param>
public void WriteToStream(Stream stream)
{
stream.Write(this.Buffer.AsSpan(0, this.NumBytes()));
}
public void WriteToStream(Stream stream) => stream.Write(this.Buffer.AsSpan(0, this.NumBytes()));
/// <summary>
/// Resizes the buffer to write to.
@ -79,8 +72,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitWriter
// Make new size multiple of 1k.
newSize = ((newSize >> 10) + 1) << 10;
// TODO: use memory allocator.
Array.Resize(ref this.buffer, newSize);
return false;

10
src/ImageSharp/Formats/WebP/BitWriter/Vp8LBitWriter.cs

@ -49,10 +49,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitWriter
/// </summary>
/// <param name="expectedSize">The expected size in bytes.</param>
public Vp8LBitWriter(int expectedSize)
: base(expectedSize)
{
this.end = this.Buffer.Length;
}
: base(expectedSize) => this.end = this.Buffer.Length;
/// <summary>
/// Initializes a new instance of the <see cref="Vp8LBitWriter"/> class.
@ -106,10 +103,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.BitWriter
}
/// <inheritdoc/>
public override int NumBytes()
{
return this.cur + ((this.used + 7) >> 3);
}
public override int NumBytes() => this.cur + ((this.used + 7) >> 3);
public Vp8LBitWriter Clone()
{

10
src/ImageSharp/Formats/WebP/Lossless/CostManager.cs

@ -267,15 +267,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
previous = previous.Next;
}
if (previous != null)
{
this.ConnectIntervals(current, previous.Next);
}
else
{
this.ConnectIntervals(current, this.head);
}
this.ConnectIntervals(current, previous != null ? previous.Next : this.head);
this.ConnectIntervals(previous, current);
}

172
src/ImageSharp/Formats/WebP/Lossless/LosslessUtils.cs

@ -61,10 +61,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
[MethodImpl(InliningOptions.ShortMethod)]
public static int MaxFindCopyLength(int len)
{
return (len < BackwardReferenceEncoder.MaxLength) ? len : BackwardReferenceEncoder.MaxLength;
}
public static int MaxFindCopyLength(int len) => (len < BackwardReferenceEncoder.MaxLength) ? len : BackwardReferenceEncoder.MaxLength;
public static int PrefixEncodeBits(int distance, ref int extraBits)
{
@ -92,7 +89,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
else
{
return PrefixEncodeNoLUT(distance, ref extraBits, ref extraBitsValue);
return PrefixEncodeNoLut(distance, ref extraBits, ref extraBitsValue);
}
}
@ -107,9 +104,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 8 <= numPixels; i += 8)
{
var idx = p + i;
@ -129,9 +126,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
@ -151,9 +148,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = SimdUtils.Shuffle.MmShuffle(2, 2, 0, 0);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
@ -199,9 +196,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 8 <= numPixels; i += 8)
{
var idx = p + i;
@ -221,9 +218,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
@ -243,9 +240,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
{
var mask = SimdUtils.Shuffle.MmShuffle(2, 2, 0, 0);
int numPixels = pixelData.Length;
int i;
fixed (uint* p = pixelData)
{
int i;
for (i = 0; i + 4 <= numPixels; i += 4)
{
var idx = p + i;
@ -757,19 +754,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
/// <summary>
/// Fast calculation of log2(v) for integer input.
/// </summary>
public static float FastLog2(uint v)
{
return (v < LogLookupIdxMax) ? WebpLookupTables.Log2Table[v] : FastLog2Slow(v);
}
public static float FastLog2(uint v) => (v < LogLookupIdxMax) ? WebpLookupTables.Log2Table[v] : FastLog2Slow(v);
/// <summary>
/// Fast calculation of v * log2(v) for integer input.
/// </summary>
[MethodImpl(InliningOptions.ShortMethod)]
public static float FastSLog2(uint v)
{
return (v < LogLookupIdxMax) ? WebpLookupTables.SLog2Table[v] : FastSLog2Slow(v);
}
public static float FastSLog2(uint v) => (v < LogLookupIdxMax) ? WebpLookupTables.SLog2Table[v] : FastSLog2Slow(v);
[MethodImpl(InliningOptions.ShortMethod)]
public static void ColorCodeToMultipliers(uint colorCode, ref Vp8LMultipliers m)
@ -779,17 +770,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
m.RedToBlue = (byte)((colorCode >> 16) & 0xff);
}
// 100 -> 0
// 80..99 -> 1
// 60..79 -> 2
// 40..59 -> 3
// 20..39 -> 4
// 0..19 -> 5
[MethodImpl(InliningOptions.ShortMethod)]
public static int NearLosslessBits(int nearLosslessQuality)
{
// 100 -> 0
// 80..99 -> 1
// 60..79 -> 2
// 40..59 -> 3
// 20..39 -> 4
// 0..19 -> 5
return 5 - (nearLosslessQuality / 20);
}
public static int NearLosslessBits(int nearLosslessQuality) => 5 - (nearLosslessQuality / 20);
private static float FastSLog2Slow(uint v)
{
@ -834,8 +822,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
do
{
++logCnt;
v = v >> 1;
y = y << 1;
v >>= 1;
y <<= 1;
}
while (v >= LogLookupIdxMax);
@ -870,7 +858,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
return code;
}
private static int PrefixEncodeNoLUT(int distance, ref int extraBits, ref int extraBitsValue)
private static int PrefixEncodeNoLut(int distance, ref int extraBits, ref int extraBitsValue)
{
int highestBit = WebpCommonUtils.BitsLog2Floor((uint)--distance);
int secondHighestBit = (distance >> (highestBit - 1)) & 1;
@ -1020,76 +1008,40 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor2(uint left, uint* top)
{
return top[0];
}
public static uint Predictor2(uint left, uint* top) => top[0];
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor3(uint left, uint* top)
{
return top[1];
}
public static uint Predictor3(uint left, uint* top) => top[1];
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor4(uint left, uint* top)
{
return top[-1];
}
public static uint Predictor4(uint left, uint* top) => top[-1];
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor5(uint left, uint* top)
{
return Average3(left, top[0], top[1]);
}
public static uint Predictor5(uint left, uint* top) => Average3(left, top[0], top[1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor6(uint left, uint* top)
{
return Average2(left, top[-1]);
}
public static uint Predictor6(uint left, uint* top) => Average2(left, top[-1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor7(uint left, uint* top)
{
return Average2(left, top[0]);
}
public static uint Predictor7(uint left, uint* top) => Average2(left, top[0]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor8(uint left, uint* top)
{
return Average2(top[-1], top[0]);
}
public static uint Predictor8(uint left, uint* top) => Average2(top[-1], top[0]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor9(uint left, uint* top)
{
return Average2(top[0], top[1]);
}
public static uint Predictor9(uint left, uint* top) => Average2(top[0], top[1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor10(uint left, uint* top)
{
return Average4(left, top[-1], top[0], top[1]);
}
public static uint Predictor10(uint left, uint* top) => Average4(left, top[-1], top[0], top[1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor11(uint left, uint* top)
{
return Select(top[0], left, top[-1]);
}
public static uint Predictor11(uint left, uint* top) => Select(top[0], left, top[-1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor12(uint left, uint* top)
{
return ClampedAddSubtractFull(left, top[0], top[-1]);
}
public static uint Predictor12(uint left, uint* top) => ClampedAddSubtractFull(left, top[0], top[-1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static uint Predictor13(uint left, uint* top)
{
return ClampedAddSubtractHalf(left, top[0], top[-1]);
}
public static uint Predictor13(uint left, uint* top) => ClampedAddSubtractHalf(left, top[0], top[-1]);
[MethodImpl(InliningOptions.ShortMethod)]
public static void PredictorSub0(uint* input, int numPixels, uint* output)
@ -1233,10 +1185,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
/// Computes sampled size of 'size' when sampling using 'sampling bits'.
/// </summary>
[MethodImpl(InliningOptions.ShortMethod)]
public static int SubSampleSize(int size, int samplingBits)
{
return (size + (1 << samplingBits) - 1) >> samplingBits;
}
public static int SubSampleSize(int size, int samplingBits) => (size + (1 << samplingBits) - 1) >> samplingBits;
/// <summary>
/// Sum of each component, mod 256.
@ -1251,10 +1200,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
// For sign-extended multiplying constants, pre-shifted by 5:
[MethodImpl(InliningOptions.ShortMethod)]
public static short Cst5b(int x)
{
return (short)(((short)(x << 8)) >> 5);
}
public static short Cst5b(int x) => (short)(((short)(x << 8)) >> 5);
private static uint ClampedAddSubtractFull(uint c0, uint c1, uint c2)
{
@ -1285,29 +1231,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
[MethodImpl(InliningOptions.ShortMethod)]
private static int AddSubtractComponentHalf(int a, int b)
{
return (int)Clip255((uint)(a + ((a - b) / 2)));
}
private static int AddSubtractComponentHalf(int a, int b) => (int)Clip255((uint)(a + ((a - b) / 2)));
[MethodImpl(InliningOptions.ShortMethod)]
private static int AddSubtractComponentFull(int a, int b, int c)
{
return (int)Clip255((uint)(a + b - c));
}
private static int AddSubtractComponentFull(int a, int b, int c) => (int)Clip255((uint)(a + b - c));
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Clip255(uint a)
{
return a < 256 ? a : ~a >> 24;
}
private static uint Clip255(uint a) => a < 256 ? a : ~a >> 24;
#if SUPPORTS_RUNTIME_INTRINSICS
[MethodImpl(InliningOptions.ShortMethod)]
private static Vector128<int> MkCst16(int hi, int lo)
{
return Vector128.Create((hi << 16) | (lo & 0xffff));
}
private static Vector128<int> MkCst16(int hi, int lo) => Vector128.Create((hi << 16) | (lo & 0xffff));
#endif
private static uint Select(uint a, uint b, uint c)
@ -1329,39 +1263,21 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average2(uint a0, uint a1)
{
return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
}
private static uint Average2(uint a0, uint a1) => (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average3(uint a0, uint a1, uint a2)
{
return Average2(Average2(a0, a2), a1);
}
private static uint Average3(uint a0, uint a1, uint a2) => Average2(Average2(a0, a2), a1);
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Average4(uint a0, uint a1, uint a2, uint a3)
{
return Average2(Average2(a0, a1), Average2(a2, a3));
}
private static uint Average4(uint a0, uint a1, uint a2, uint a3) => Average2(Average2(a0, a1), Average2(a2, a3));
[MethodImpl(InliningOptions.ShortMethod)]
private static uint GetArgbIndex(uint idx)
{
return (idx >> 8) & 0xff;
}
private static uint GetArgbIndex(uint idx) => (idx >> 8) & 0xff;
[MethodImpl(InliningOptions.ShortMethod)]
private static int ColorTransformDelta(sbyte colorPred, sbyte color)
{
return (colorPred * color) >> 5;
}
private static int ColorTransformDelta(sbyte colorPred, sbyte color) => (colorPred * color) >> 5;
[MethodImpl(InliningOptions.ShortMethod)]
private static sbyte U32ToS8(uint v)
{
return (sbyte)(v & 0xff);
}
private static sbyte U32ToS8(uint v) => (sbyte)(v & 0xff);
}
}

15
src/ImageSharp/Formats/WebP/Lossless/Vp8LHistogram.cs

@ -54,10 +54,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
/// <param name="refs">The backward references to initialize the histogram with.</param>
/// <param name="paletteCodeBits">The palette code bits.</param>
public Vp8LHistogram(Vp8LBackwardRefs refs, int paletteCodeBits)
: this(paletteCodeBits)
{
this.StoreRefs(refs);
}
: this(paletteCodeBits) => this.StoreRefs(refs);
/// <summary>
/// Initializes a new instance of the <see cref="Vp8LHistogram"/> class.
@ -171,10 +168,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
}
public int NumCodes()
{
return WebpConstants.NumLiteralCodes + WebpConstants.NumLengthCodes + ((this.PaletteCodeBits > 0) ? (1 << this.PaletteCodeBits) : 0);
}
public int NumCodes() => WebpConstants.NumLiteralCodes + WebpConstants.NumLengthCodes + ((this.PaletteCodeBits > 0) ? (1 << this.PaletteCodeBits) : 0);
/// <summary>
/// Estimate how many bits the combined entropy of literals and distance approximately maps to.
@ -631,9 +625,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossless
}
[MethodImpl(InliningOptions.ShortMethod)]
private static int ClipMax(int v, int max)
{
return (v > max) ? max : v;
}
private static int ClipMax(int v, int max) => (v > max) ? max : v;
}
}

13
src/ImageSharp/Formats/WebP/Lossy/Vp8Decoder.cs

@ -241,18 +241,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossy
public Vp8MacroBlock CurrentMacroBlock => this.MacroBlockInfo[this.MbX];
public Vp8MacroBlock LeftMacroBlock
{
get
{
if (this.leftMacroBlock == null)
{
this.leftMacroBlock = new Vp8MacroBlock();
}
return this.leftMacroBlock;
}
}
public Vp8MacroBlock LeftMacroBlock => this.leftMacroBlock ??= new Vp8MacroBlock();
public Vp8MacroBlockData CurrentBlockData => this.MacroBlockData[this.MbX];

23
src/ImageSharp/Formats/WebP/Lossy/Vp8Encoder.cs

@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossy
/// <summary>
/// Gets the probabilities.
/// </summary>
public Vp8EncProba Proba { get; private set; }
public Vp8EncProba Proba { get; }
/// <summary>
/// Gets the segment features.
@ -157,17 +157,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossy
/// <summary>
/// Gets the segment infos.
/// </summary>
public Vp8SegmentInfo[] SegmentInfos { get; private set; }
public Vp8SegmentInfo[] SegmentInfos { get; }
/// <summary>
/// Gets the macro block info's.
/// </summary>
public Vp8MacroBlockInfo[] MbInfo { get; private set; }
public Vp8MacroBlockInfo[] MbInfo { get; }
/// <summary>
/// Gets the filter header.
/// </summary>
public Vp8FilterHeader FilterHeader { get; private set; }
public Vp8FilterHeader FilterHeader { get; }
/// <summary>
/// Gets or sets the global susceptibility.
@ -825,15 +825,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossy
it.SetSkip(false); // not skipped.
it.SetSegment(0); // default segment, spec-wise.
int bestAlpha;
if (this.method <= 1)
{
bestAlpha = it.FastMbAnalyze(this.quality);
}
else
{
bestAlpha = it.MbAnalyzeBestIntra16Mode();
}
int bestAlpha = this.method <= 1 ? it.FastMbAnalyze(this.quality) : it.MbAnalyzeBestIntra16Mode();
bestUvAlpha = it.MbAnalyzeBestUvMode();
@ -1348,10 +1340,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp.Lossy
}
[MethodImpl(InliningOptions.ShortMethod)]
private static double GetPsnr(long mse, long size)
{
return (mse > 0 && size > 0) ? 10.0f * Math.Log10(255.0f * 255.0f * size / mse) : 99;
}
private static double GetPsnr(long mse, long size) => (mse > 0 && size > 0) ? 10.0f * Math.Log10(255.0f * 255.0f * size / mse) : 99;
[MethodImpl(InliningOptions.ShortMethod)]
private static int GetProba(int a, int b)

17
src/ImageSharp/Formats/WebP/WebpDecoderCore.cs

@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp
// 3 reserved bytes should follow which are supposed to be zero.
this.currentStream.Read(this.buffer, 0, 3);
if (this.buffer[0] != 0 || this.buffer[1] != 0 | this.buffer[2] != 0)
if (this.buffer[0] != 0 || this.buffer[1] != 0 || this.buffer[2] != 0)
{
WebpThrowHelper.ThrowImageFormatException("reserved bytes should be zero");
}
@ -527,15 +527,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Webp
/// </summary>
/// <param name="chunkType">The chunk type.</param>
/// <returns>True, if its an optional chunk type.</returns>
private static bool IsOptionalVp8XChunk(WebpChunkType chunkType)
private static bool IsOptionalVp8XChunk(WebpChunkType chunkType) => chunkType switch
{
return chunkType switch
{
WebpChunkType.Alpha => true,
WebpChunkType.Animation => true,
WebpChunkType.Iccp => true,
_ => false
};
}
WebpChunkType.Alpha => true,
WebpChunkType.Animation => true,
WebpChunkType.Iccp => true,
_ => false
};
}
}

70
tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs

@ -133,89 +133,47 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
}
[Fact]
public void SubtractGreen_Works()
{
RunSubstractGreenTest();
}
public void SubtractGreen_Works() => RunSubstractGreenTest();
[Fact]
public void AddGreenToBlueAndRed_Works()
{
RunAddGreenToBlueAndRedTest();
}
public void AddGreenToBlueAndRed_Works() => RunAddGreenToBlueAndRedTest();
[Fact]
public void TransformColor_Works()
{
RunTransformColorTest();
}
public void TransformColor_Works() => RunTransformColorTest();
[Fact]
public void TransformColorInverse_Works()
{
RunTransformColorInverseTest();
}
public void TransformColorInverse_Works() => RunTransformColorInverseTest();
#if SUPPORTS_RUNTIME_INTRINSICS
[Fact]
public void SubtractGreen_WithHardwareIntrinsics_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.AllowAll);
}
public void SubtractGreen_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.AllowAll);
[Fact]
public void SubtractGreen_WithoutAvx_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.DisableAVX);
}
public void SubtractGreen_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.DisableAVX);
[Fact]
public void SubtractGreen_WithoutAvxOrSSSE3_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSSE3);
}
public void SubtractGreen_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubstractGreenTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSSE3);
[Fact]
public void AddGreenToBlueAndRed_WithHardwareIntrinsics_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.AllowAll);
}
public void AddGreenToBlueAndRed_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.AllowAll);
[Fact]
public void AddGreenToBlueAndRed_WithoutAvx_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX);
}
public void AddGreenToBlueAndRed_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX);
[Fact]
public void AddGreenToBlueAndRed_WithoutAvxOrSSSE3_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableSSSE3);
}
public void AddGreenToBlueAndRed_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableSSSE3);
[Fact]
public void TransformColor_WithHardwareIntrinsics_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.AllowAll);
}
public void TransformColor_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.AllowAll);
[Fact]
public void TransformColor_WithoutSSE2_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.DisableSSE2);
}
public void TransformColor_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.DisableSSE2);
[Fact]
public void TransformColorInverse_WithHardwareIntrinsics_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.AllowAll);
}
public void TransformColorInverse_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.AllowAll);
[Fact]
public void TransformColorInverse_WithoutSSE2_Works()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.DisableSSE2);
}
public void TransformColorInverse_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.DisableSSE2);
#endif
}
}

12
tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

@ -336,8 +336,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
[Theory]
[WithFile(Lossless.LossLessCorruptImage3, PixelTypes.Rgba32)]
public void WebpDecoder_ThrowImageFormatException_OnInvalidImages<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
where TPixel : unmanaged, IPixel<TPixel> =>
Assert.Throws<ImageFormatException>(
() =>
{
@ -345,14 +344,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
{
}
});
}
[Theory]
[WithFile(Lossless.Earth, PixelTypes.Rgba32)]
public void ProfileTestLossless<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage(WebpDecoder);
}
}
}

Loading…
Cancel
Save