Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSE41 version of UpSample #1836

Merged
merged 28 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7191aca
Move UpSample to YuvConversion class
brianpopow Nov 17, 2021
59a11bf
Add SSE41 version of UpSample
brianpopow Nov 17, 2021
e6921e1
Merge branch 'master' into bp/upscalesse
brianpopow Nov 17, 2021
2a03d00
Upsample last block
brianpopow Nov 18, 2021
3f43883
Fix shuffle masks
brianpopow Nov 18, 2021
ec18321
Fix last block
brianpopow Nov 18, 2021
806a2ee
Merge branch 'master' into bp/upscalesse
brianpopow Nov 18, 2021
c223d2e
Avoid implicit casting
JimBobSquarePants Nov 19, 2021
8985ed6
Merge branch 'master' into bp/upscalesse
JimBobSquarePants Nov 19, 2021
5954924
Add upsample tests
brianpopow Nov 19, 2021
1eb1e82
Avoid allocating uvBuffer on each upscale call
brianpopow Nov 19, 2021
d3a7a4a
Merge branch 'master' into bp/upscalesse
brianpopow Nov 19, 2021
c59ae02
Change some methods to be private
brianpopow Nov 19, 2021
c5170f9
Re-grouping the code to do identical operations
brianpopow Nov 19, 2021
0c05727
Add InliningOptions.ShortMethod to LoadHigh
brianpopow Nov 19, 2021
d58dde0
Group load uv vectors together
brianpopow Nov 19, 2021
7cf0c32
Pass in parameters as ref to UpSample32Pixels
brianpopow Nov 19, 2021
d10a747
Merge branch 'master' into bp/upscalesse
brianpopow Nov 21, 2021
d6b25e7
Merge branch 'master' into bp/upscalesse
brianpopow Nov 23, 2021
cc5f7af
Better version of LoadHigh
brianpopow Nov 24, 2021
65870b9
Avoid branching inside loop
brianpopow Nov 24, 2021
984a725
Merge branch 'master' into bp/upscalesse
brianpopow Nov 24, 2021
6293f72
Use ref parameters in ConvertYuv444ToBgrSse41
brianpopow Nov 24, 2021
2ca81ae
Fill buffers with default values only in Debug mode
brianpopow Nov 24, 2021
cded607
Allocate clean buffers
brianpopow Nov 24, 2021
22537b2
Revert "Allocate clean buffers": the tmp buffers does not need to be …
brianpopow Nov 24, 2021
7775c34
Group loading y, u, v together
brianpopow Nov 25, 2021
8f6e9ba
Merge branch 'master' into bp/upscalesse
brianpopow Nov 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 5 additions & 58 deletions src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -692,16 +692,17 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
int mbw = io.MbW;
int uvw = (mbw + 1) / 2;
int y = io.MbY;
byte[] uvBuffer = new byte[(14 * 32) + 15];

if (y == 0)
{
// First line is special cased. We mirror the u/v samples at boundary.
this.UpSample(curY, null, curU, curV, curU, curV, dst, null, mbw);
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst, default, mbw, uvBuffer);
}
else
{
// We can finish the left-over line from previous call.
this.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw);
YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw, uvBuffer);
numLinesOut++;
}

Expand All @@ -714,7 +715,7 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
topV = curV;
curU = curU.Slice(io.UvStride);
curV = curV.Slice(io.UvStride);
this.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw);
YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw, uvBuffer);
curY = curY.Slice(ioStride2);
dst = dst.Slice(bufferStride2);
}
Expand All @@ -736,67 +737,13 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io)
// Process the very last row of even-sized picture.
if ((yEnd & 1) == 0)
{
this.UpSample(curY, null, curU, curV, curU, curV, dst.Slice(bufferStride), null, mbw);
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw, uvBuffer);
}
}

return numLinesOut;
}

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)
{
int xStep = 3;
int lastPixelPair = (len - 1) >> 1;
uint tluv = YuvConversion.LoadUv(topU[0], topV[0]); // top-left sample
uint luv = YuvConversion.LoadUv(curU[0], curV[0]); // left-sample
uint uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2;
YuvConversion.YuvToBgr(topY[0], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst);

if (bottomY != null)
{
uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2;
YuvConversion.YuvToBgr(bottomY[0], (int)uv0 & 0xff, (int)(uv0 >> 16), bottomDst);
}

for (int x = 1; x <= lastPixelPair; x++)
{
uint tuv = YuvConversion.LoadUv(topU[x], topV[x]); // top sample
uint uv = YuvConversion.LoadUv(curU[x], curV[x]); // sample

// Precompute invariant values associated with first and second diagonals.
uint avg = tluv + tuv + luv + uv + 0x00080008u;
uint diag12 = (avg + (2 * (tuv + luv))) >> 3;
uint diag03 = (avg + (2 * (tluv + uv))) >> 3;
uv0 = (diag12 + tluv) >> 1;
uint uv1 = (diag03 + tuv) >> 1;
int xMul2 = x * 2;
YuvConversion.YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep));
YuvConversion.YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep));

if (bottomY != null)
{
uv0 = (diag03 + luv) >> 1;
uv1 = (diag12 + uv) >> 1;
YuvConversion.YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep));
YuvConversion.YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep));
}

tluv = tuv;
luv = uv;
}

if ((len & 1) == 0)
{
uv0 = ((3 * tluv) + luv + 0x00020002u) >> 2;
YuvConversion.YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep));
if (bottomY != null)
{
uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2;
YuvConversion.YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep));
}
}
}

private void DoTransform(uint bits, Span<short> src, Span<byte> dst, Span<int> scratch)
{
switch (bits >> 30)
Expand Down
Loading