Browse Source

Rolled back to original implementation for rounding via scalar code

pull/1761/head
Dmitry Pentin 4 years ago
parent
commit
ea09d59e08
  1. 45
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

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

@ -424,16 +424,47 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
else
#endif
{
for (int i = 0; i < Size; i++)
{
// TODO: find a way to index block & qt matrices with natural order indices for performance?
int zig = ZigZag.ZigZagOrder[i];
float divRes = block[zig] / qt[zig];
dest[i] = (short)(divRes + (divRes > 0 ? 0.5f : -0.5f));
}
Divide(ref block, ref qt);
block.RoundInto(ref dest);
}
}
[MethodImpl(InliningOptions.ShortMethod)]
private static void Divide(ref Block8x8F a, ref Block8x8F b)
{
a.V0L /= b.V0L;
a.V0R /= b.V0R;
a.V1L /= b.V1L;
a.V1R /= b.V1R;
a.V2L /= b.V2L;
a.V2R /= b.V2R;
a.V3L /= b.V3L;
a.V3R /= b.V3R;
a.V4L /= b.V4L;
a.V4R /= b.V4R;
a.V5L /= b.V5L;
a.V5R /= b.V5R;
a.V6L /= b.V6L;
a.V6R /= b.V6R;
a.V7L /= b.V7L;
a.V7R /= b.V7R;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor)
{
var neg = new Vector4(-1);
var add = new Vector4(.5F);
// sign(dividend) = max(min(dividend, 1), -1)
Vector4 sign = Numerics.Clamp(dividend, neg, Vector4.One);
// AlmostRound(dividend/divisor) = dividend/divisor + 0.5*sign(dividend)
// TODO: This is wrong but I have no idea how to fix it without if-else operator
// sign here is a value in range [-1..1], it can be equal to -0.2 for example which is wrong
return (dividend / divisor) + (sign * add);
}
public void RoundInto(ref Block8x8 dest)
{
for (int i = 0; i < Size; i++)

Loading…
Cancel
Save