Browse Source

Fix some mistakes during macro block analysis

pull/1552/head
Brian Popow 6 years ago
parent
commit
05f1466a4e
  1. 61
      src/ImageSharp/Formats/WebP/Lossy/Vp8EncIterator.cs
  2. 6
      src/ImageSharp/Formats/WebP/Lossy/Vp8Encoder.cs

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

@ -87,20 +87,18 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
this.YuvOut2 = new byte[WebPConstants.Bps * 16];
this.YuvP = new byte[(32 * WebPConstants.Bps) + (16 * WebPConstants.Bps) + (8 * WebPConstants.Bps)]; // I16+Chroma+I4 preds
this.YLeft = new byte[32];
this.ULeft = new byte[32];
this.VLeft = new byte[32];
this.UvLeft = new byte[32];
this.TopNz = new int[9];
this.LeftNz = new int[9];
// To match the C++ initial values, initialize all with 204.
// To match the C++ initial values of the reference implementation, initialize all with 204.
byte defaultInitVal = 204;
this.YuvIn.AsSpan().Fill(defaultInitVal);
this.YuvOut.AsSpan().Fill(defaultInitVal);
this.YuvOut2.AsSpan().Fill(defaultInitVal);
this.YuvP.AsSpan().Fill(defaultInitVal);
this.YLeft.AsSpan().Fill(defaultInitVal);
this.ULeft.AsSpan().Fill(defaultInitVal);
this.VLeft.AsSpan().Fill(defaultInitVal);
this.UvLeft.AsSpan().Fill(defaultInitVal);
for (int i = -255; i <= 255 + 255; ++i)
{
@ -146,14 +144,9 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
public byte[] YLeft { get; set; }
/// <summary>
/// Gets or sets the left u samples.
/// Gets or sets the left uv samples.
/// </summary>
public byte[] ULeft { get; set; }
/// <summary>
/// Gets or sets the left v samples.
/// </summary>
public byte[] VLeft { get; set; }
public byte[] UvLeft { get; set; }
/// <summary>
/// Gets or sets the top luma samples at position 'X'.
@ -228,8 +221,8 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
else
{
Span<byte> yLeft = this.YLeft.AsSpan();
Span<byte> uLeft = this.ULeft.AsSpan();
Span<byte> vLeft = this.VLeft.AsSpan();
Span<byte> uLeft = this.UvLeft.AsSpan(0, 16);
Span<byte> vLeft = this.UvLeft.AsSpan(16, 16);
if (this.Y == 0)
{
yLeft[0] = 127;
@ -366,12 +359,11 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
private void SetIntra4Mode(byte[] modes)
{
int modesIdx = 0;
Span<byte> preds = this.Preds.Slice(this.predIdx);
int predIdx = this.predIdx;
for (int y = 4; y > 0; --y)
{
// TODO:
// memcpy(preds, modes, 4 * sizeof(*modes));
preds = preds.Slice(this.predsWidth);
modes.AsSpan(modesIdx, 4).CopyTo(this.Preds.Slice(predIdx));
predIdx += this.predsWidth;
modesIdx += 4;
}
@ -457,12 +449,12 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
private void MakeChroma8Preds()
{
Span<byte> left = this.X != 0 ? this.ULeft.AsSpan() : null;
Span<byte> left = this.X != 0 ? this.UvLeft.AsSpan() : null;
Span<byte> top = this.Y != 0 ? this.UvTop.Slice(this.uvTopIdx) : null;
this.EncPredChroma8(this.YuvP, left, top);
}
// luma 16x16 prediction (paragraph 12.3)
// luma 16x16 prediction (paragraph 12.3).
private void EncPredLuma16(Span<byte> dst, Span<byte> left, Span<byte> top)
{
this.DcMode(dst.Slice(I16DC16), left, top, 16, 16, 5);
@ -471,16 +463,16 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
this.TrueMotion(dst.Slice(I16TM16), left, top, 16);
}
// Chroma 8x8 prediction (paragraph 12.2)
// Chroma 8x8 prediction (paragraph 12.2).
private void EncPredChroma8(Span<byte> dst, Span<byte> left, Span<byte> top)
{
// U block
// U block.
this.DcMode(dst.Slice(C8DC8), left, top, 8, 8, 4);
this.VerticalPred(dst.Slice(C8VE8), top, 8);
this.HorizontalPred(dst.Slice(C8HE8), left, 8);
this.TrueMotion(dst.Slice(C8TM8), left, top, 8);
// V block
// V block.
dst = dst.Slice(8);
if (top != null)
{
@ -529,6 +521,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
else if (left != null)
{
// left but no top.
left = left.Slice(1); // in the reference implementation, left starts at -1.
for (j = 0; j < size; ++j)
{
dc += left[j];
@ -628,16 +621,17 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
private void ImportBlock(Span<byte> src, int srcStride, Span<byte> dst, int w, int h, int size)
{
int dstIdx = 0;
int srcIdx = 0;
for (int i = 0; i < h; ++i)
{
src.Slice(0, w).CopyTo(dst.Slice(dstIdx));
src.Slice(srcIdx, w).CopyTo(dst.Slice(dstIdx));
if (w < size)
{
dst.Slice(dstIdx, size - w).Fill(dst[dstIdx + w - 1]);
}
dstIdx += WebPConstants.Bps;
src = src.Slice(srcStride);
srcIdx += srcStride;
}
for (int i = h; i < size; ++i)
@ -650,10 +644,11 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
private void ImportLine(Span<byte> src, int srcStride, Span<byte> dst, int len, int totalLen)
{
int i;
int srcIdx = 0;
for (i = 0; i < len; ++i)
{
dst[i] = src[i];
src = src.Slice(srcStride);
dst[i] = src[srcIdx];
srcIdx += srcStride;
}
for (; i < totalLen; ++i)
@ -686,30 +681,24 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
this.nzIdx = 0;
this.yTopIdx = 0;
this.uvTopIdx = 0;
this.predIdx = y * 4 * this.predsWidth;
this.InitLeft();
// TODO:
// it->preds_ = enc->preds_ + y * 4 * enc->preds_w_;
}
private void InitLeft()
{
Span<byte> yLeft = this.YLeft.AsSpan();
Span<byte> uLeft = this.ULeft.AsSpan();
Span<byte> vLeft = this.VLeft.AsSpan();
Span<byte> uLeft = this.UvLeft.AsSpan(0, 16);
Span<byte> vLeft = this.UvLeft.AsSpan(16, 16);
byte val = (byte)((this.Y > 0) ? 129 : 127);
yLeft[0] = val;
uLeft[0] = val;
vLeft[0] = val;
uLeft[16] = val;
vLeft[16] = val;
yLeft.Slice(1, 16).Fill(129);
uLeft.Slice(1, 8).Fill(129);
vLeft.Slice(1, 8).Fill(129);
uLeft.Slice(1 + 16, 8).Fill(129);
vLeft.Slice(1 + 16, 8).Fill(129);
this.LeftNz[8] = 0;
}

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

@ -167,7 +167,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
alphas[bestAlpha]++;
it.CurrentMacroBlockInfo.Alpha = bestAlpha; // For later remapping.
return bestAlpha; // Mixed susceptibility (not just luma)
return bestAlpha; // Mixed susceptibility (not just luma).
}
private void ConvertRgbToYuv<TPixel>(Image<TPixel> image)
@ -420,8 +420,8 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
[MethodImpl(InliningOptions.ShortMethod)]
private int Interpolate(int v)
{
int tabPos = v >> (WebPConstants.GammaTabFix + 2); // integer part
int x = v & ((WebPConstants.GammaTabScale << 2) - 1); // fractional part
int tabPos = v >> (WebPConstants.GammaTabFix + 2); // integer part.
int x = v & ((WebPConstants.GammaTabScale << 2) - 1); // fractional part.
int v0 = WebPLookupTables.LinearToGammaTab[tabPos];
int v1 = WebPLookupTables.LinearToGammaTab[tabPos + 1];
int y = (v1 * x) + (v0 * ((WebPConstants.GammaTabScale << 2) - x)); // interpolate

Loading…
Cancel
Save