Skip to content

Commit 9c95389

Browse files
authored
Merge branch 'master' into bp/shanonsse
2 parents f4fe9ba + b67a8db commit 9c95389

4 files changed

Lines changed: 500 additions & 58 deletions

File tree

src/ImageSharp/Formats/Webp/Lossy/Vp8Decoder.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,14 @@ public Vp8Decoder(Vp8FrameHeader frameHeader, Vp8PictureHeader pictureHeader, Vp
7676
this.TmpVBuffer = memoryAllocator.Allocate<byte>((int)width);
7777
this.Pixels = memoryAllocator.Allocate<byte>((int)(width * height * 4));
7878

79+
#if DEBUG
80+
// Filling those buffers with 205, is only useful for debugging,
81+
// so the default values are the same as the reference libwebp implementation.
7982
this.YuvBuffer.Memory.Span.Fill(205);
8083
this.CacheY.Memory.Span.Fill(205);
8184
this.CacheU.Memory.Span.Fill(205);
8285
this.CacheV.Memory.Span.Fill(205);
86+
#endif
8387

8488
this.Vp8BitReaders = new Vp8BitReader[WebpConstants.MaxNumPartitions];
8589
}

src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -692,16 +692,17 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
692692
int mbw = io.MbW;
693693
int uvw = (mbw + 1) / 2;
694694
int y = io.MbY;
695+
byte[] uvBuffer = new byte[(14 * 32) + 15];
695696

696697
if (y == 0)
697698
{
698699
// First line is special cased. We mirror the u/v samples at boundary.
699-
this.UpSample(curY, null, curU, curV, curU, curV, dst, null, mbw);
700+
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst, default, mbw, uvBuffer);
700701
}
701702
else
702703
{
703704
// We can finish the left-over line from previous call.
704-
this.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw);
705+
YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw, uvBuffer);
705706
numLinesOut++;
706707
}
707708

@@ -714,7 +715,7 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
714715
topV = curV;
715716
curU = curU.Slice(io.UvStride);
716717
curV = curV.Slice(io.UvStride);
717-
this.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw);
718+
YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw, uvBuffer);
718719
curY = curY.Slice(ioStride2);
719720
dst = dst.Slice(bufferStride2);
720721
}
@@ -736,67 +737,13 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
736737
// Process the very last row of even-sized picture.
737738
if ((yEnd & 1) == 0)
738739
{
739-
this.UpSample(curY, null, curU, curV, curU, curV, dst.Slice(bufferStride), null, mbw);
740+
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw, uvBuffer);
740741
}
741742
}
742743

743744
return numLinesOut;
744745
}
745746

746-
private void UpSample(Span<byte> topY, Span<byte> bottomY, Span<byte> topU, Span<byte> topV, Span<byte> curU, Span<byte> curV, Span<byte> topDst, Span<byte> bottomDst, int len)
747-
{
748-
int xStep = 3;
749-
int lastPixelPair = (len - 1) >> 1;
750-
uint tluv = YuvConversion.LoadUv(topU[0], topV[0]); // top-left sample
751-
uint luv = YuvConversion.LoadUv(curU[0], curV[0]); // left-sample
752-
uint uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2;
753-
YuvConversion.YuvToBgr(topY[0], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst);
754-
755-
if (bottomY != null)
756-
{
757-
uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2;
758-
YuvConversion.YuvToBgr(bottomY[0], (int)uv0 & 0xff, (int)(uv0 >> 16), bottomDst);
759-
}
760-
761-
for (int x = 1; x <= lastPixelPair; x++)
762-
{
763-
uint tuv = YuvConversion.LoadUv(topU[x], topV[x]); // top sample
764-
uint uv = YuvConversion.LoadUv(curU[x], curV[x]); // sample
765-
766-
// Precompute invariant values associated with first and second diagonals.
767-
uint avg = tluv + tuv + luv + uv + 0x00080008u;
768-
uint diag12 = (avg + (2 * (tuv + luv))) >> 3;
769-
uint diag03 = (avg + (2 * (tluv + uv))) >> 3;
770-
uv0 = (diag12 + tluv) >> 1;
771-
uint uv1 = (diag03 + tuv) >> 1;
772-
int xMul2 = x * 2;
773-
YuvConversion.YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep));
774-
YuvConversion.YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep));
775-
776-
if (bottomY != null)
777-
{
778-
uv0 = (diag03 + luv) >> 1;
779-
uv1 = (diag12 + uv) >> 1;
780-
YuvConversion.YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep));
781-
YuvConversion.YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep));
782-
}
783-
784-
tluv = tuv;
785-
luv = uv;
786-
}
787-
788-
if ((len & 1) == 0)
789-
{
790-
uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2;
791-
YuvConversion.YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep));
792-
if (bottomY != null)
793-
{
794-
uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2;
795-
YuvConversion.YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep));
796-
}
797-
}
798-
}
799-
800747
private void DoTransform(uint bits, Span<short> src, Span<byte> dst, Span<int> scratch)
801748
{
802749
switch (bits >> 30)

0 commit comments

Comments
 (0)