Browse Source

Store diffusion errors

pull/1552/head
Brian Popow 5 years ago
parent
commit
9cb828ec2d
  1. 17
      src/ImageSharp/Formats/WebP/Lossy/QuantEnc.cs
  2. 23
      src/ImageSharp/Formats/WebP/Lossy/Vp8EncIterator.cs
  3. 6
      src/ImageSharp/Formats/WebP/Lossy/Vp8ModeScore.cs

17
src/ImageSharp/Formats/WebP/Lossy/QuantEnc.cs

@ -240,6 +240,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
rdBest.CopyScore(rdUv);
rd.ModeUv = mode;
rdUv.UvLevels.CopyTo(rd.UvLevels.AsSpan());
for (int i = 0; i < 2; i++)
{
rd.Derr[i, 0] = rdUv.Derr[i, 0];
rd.Derr[i, 1] = rdUv.Derr[i, 1];
rd.Derr[i, 2] = rdUv.Derr[i, 2];
}
Span<byte> tmp = dst;
dst = tmpDst;
tmpDst = tmp;
@ -253,6 +260,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// copy 16x8 block if needed.
LossyUtils.Vp8Copy16X8(dst, dst0);
}
// Store diffusion errors for next block.
it.StoreDiffusionErrors(rd);
}
public static int ReconstructIntra16(Vp8EncIterator it, Vp8SegmentInfo dqm, Vp8ModeScore rd, Span<byte> yuvOut, int mode)
@ -571,10 +581,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
c[3 * 16] += (short)(((C1 * err1) + (C2 * err2)) >> (DSHIFT - DSCALE));
int err3 = QuantizeSingle(c.Slice(3 * 16), mtx);
// TODO: set errors in rd
// rd->derr[ch][0] = (int8_t)err1;
// rd->derr[ch][1] = (int8_t)err2;
// rd->derr[ch][2] = (int8_t)err3;
rd.Derr[ch, 0] = err1;
rd.Derr[ch, 1] = err2;
rd.Derr[ch, 2] = err3;
}
}

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

@ -167,7 +167,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public uint[] Nz { get; }
/// <summary>
/// Gets the diffusion error.
/// Gets the top diffusion error.
/// </summary>
public sbyte[] TopDerr { get; }
@ -587,6 +587,27 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public void SetSegment(int segment) => this.CurrentMacroBlockInfo.Segment = segment;
public void StoreDiffusionErrors(Vp8ModeScore rd)
{
for (int ch = 0; ch <= 1; ++ch)
{
Span<sbyte> top = this.TopDerr.AsSpan((this.X * 4) + ch, 2);
Span<sbyte> left = this.LeftDerr.AsSpan(ch, 2);
// restore err1
left[0] = (sbyte)rd.Derr[ch, 0];
// 3/4th of err3
left[1] = (sbyte)((3 * rd.Derr[ch, 2]) >> 2);
// err2
top[0] = (sbyte)rd.Derr[ch, 1];
// 1/4th of err3.
top[1] = (sbyte)(rd.Derr[ch, 2] - left[1]);
}
}
/// <summary>
/// Returns true if iteration is finished.
/// </summary>

6
src/ImageSharp/Formats/WebP/Lossy/Vp8ModeScore.cs

@ -25,6 +25,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
this.UvLevels = new short[(4 + 4) * 16];
this.ModesI4 = new byte[16];
this.Derr = new int[2, 3];
}
/// <summary>
@ -87,6 +88,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
/// </summary>
public uint Nz { get; set; }
/// <summary>
/// Gets the diffusion errors.
/// </summary>
public int[,] Derr { get; }
public void InitScore()
{
this.D = 0;

Loading…
Cancel
Save