Skip to content

Commit

Permalink
Merge pull request #1800 from SixLabors/bp/avoiddictionarys
Browse files Browse the repository at this point in the history
Webp: Use byte arrays instead of Dictionary's for lookups
  • Loading branch information
brianpopow committed Nov 1, 2021
2 parents 527e0fb + 414e4a8 commit d021222
Show file tree
Hide file tree
Showing 2 changed files with 234 additions and 57 deletions.
48 changes: 24 additions & 24 deletions src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -934,11 +934,11 @@ private static void DoFilter2(Span<byte> p, int offset, int step)
int p0 = p[offset - step];
int q0 = p[offset];
int q1 = p[offset + step];
int a = (3 * (q0 - p0)) + WebpLookupTables.Sclip1[p1 - q1];
int a1 = WebpLookupTables.Sclip2[(a + 4) >> 3];
int a2 = WebpLookupTables.Sclip2[(a + 3) >> 3];
p[offset - step] = WebpLookupTables.Clip1[p0 + a2];
p[offset] = WebpLookupTables.Clip1[q0 - a1];
int a = (3 * (q0 - p0)) + WebpLookupTables.Sclip1[p1 - q1 + 1020];
int a1 = WebpLookupTables.Sclip2[((a + 4) >> 3) + 112];
int a2 = WebpLookupTables.Sclip2[((a + 3) >> 3) + 112];
p[offset - step] = WebpLookupTables.Clip1[p0 + a2 + 255];
p[offset] = WebpLookupTables.Clip1[q0 - a1 + 255];
}

private static void DoFilter4(Span<byte> p, int offset, int step)
Expand All @@ -950,13 +950,13 @@ private static void DoFilter4(Span<byte> p, int offset, int step)
int q0 = p[offset];
int q1 = p[offset + step];
int a = 3 * (q0 - p0);
int a1 = WebpLookupTables.Sclip2[(a + 4) >> 3];
int a2 = WebpLookupTables.Sclip2[(a + 3) >> 3];
int a1 = WebpLookupTables.Sclip2[((a + 4) >> 3) + 112];
int a2 = WebpLookupTables.Sclip2[((a + 3) >> 3) + 112];
int a3 = (a1 + 1) >> 1;
p[offsetMinus2Step] = WebpLookupTables.Clip1[p1 + a3];
p[offset - step] = WebpLookupTables.Clip1[p0 + a2];
p[offset] = WebpLookupTables.Clip1[q0 - a1];
p[offset + step] = WebpLookupTables.Clip1[q1 - a3];
p[offsetMinus2Step] = WebpLookupTables.Clip1[p1 + a3 + 255];
p[offset - step] = WebpLookupTables.Clip1[p0 + a2 + 255];
p[offset] = WebpLookupTables.Clip1[q0 - a1 + 255];
p[offset + step] = WebpLookupTables.Clip1[q1 - a3 + 255];
}

private static void DoFilter6(Span<byte> p, int offset, int step)
Expand All @@ -971,18 +971,18 @@ private static void DoFilter6(Span<byte> p, int offset, int step)
int q0 = p[offset];
int q1 = p[offset + step];
int q2 = p[offset + step2];
int a = WebpLookupTables.Sclip1[(3 * (q0 - p0)) + WebpLookupTables.Sclip1[p1 - q1]];
int a = WebpLookupTables.Sclip1[(3 * (q0 - p0)) + WebpLookupTables.Sclip1[p1 - q1 + 1020] + 1020];

// a is in [-128,127], a1 in [-27,27], a2 in [-18,18] and a3 in [-9,9]
int a1 = ((27 * a) + 63) >> 7; // eq. to ((3 * a + 7) * 9) >> 7
int a2 = ((18 * a) + 63) >> 7; // eq. to ((2 * a + 7) * 9) >> 7
int a3 = ((9 * a) + 63) >> 7; // eq. to ((1 * a + 7) * 9) >> 7
p[offset - step3] = WebpLookupTables.Clip1[p2 + a3];
p[offset - step2] = WebpLookupTables.Clip1[p1 + a2];
p[offsetMinusStep] = WebpLookupTables.Clip1[p0 + a1];
p[offset] = WebpLookupTables.Clip1[q0 - a1];
p[offset + step] = WebpLookupTables.Clip1[q1 - a2];
p[offset + step2] = WebpLookupTables.Clip1[q2 - a3];
p[offset - step3] = WebpLookupTables.Clip1[p2 + a3 + 255];
p[offset - step2] = WebpLookupTables.Clip1[p1 + a2 + 255];
p[offsetMinusStep] = WebpLookupTables.Clip1[p0 + a1 + 255];
p[offset] = WebpLookupTables.Clip1[q0 - a1 + 255];
p[offset + step] = WebpLookupTables.Clip1[q1 - a2 + 255];
p[offset + step2] = WebpLookupTables.Clip1[q2 - a3 + 255];
}

[MethodImpl(InliningOptions.ShortMethod)]
Expand All @@ -992,7 +992,7 @@ private static bool NeedsFilter(Span<byte> p, int offset, int step, int t)
int p0 = p[offset - step];
int q0 = p[offset];
int q1 = p[offset + step];
return (4 * WebpLookupTables.Abs0[p0 - q0]) + WebpLookupTables.Abs0[p1 - q1] <= t;
return (4 * WebpLookupTables.Abs0[p0 - q0 + 255]) + WebpLookupTables.Abs0[p1 - q1 + 255] <= t;
}

private static bool NeedsFilter2(Span<byte> p, int offset, int step, int t, int it)
Expand All @@ -1007,14 +1007,14 @@ private static bool NeedsFilter2(Span<byte> p, int offset, int step, int t, int
int q1 = p[offset + step];
int q2 = p[offset + step2];
int q3 = p[offset + step3];
if ((4 * WebpLookupTables.Abs0[p0 - q0]) + WebpLookupTables.Abs0[p1 - q1] > t)
if ((4 * WebpLookupTables.Abs0[p0 - q0 + 255]) + WebpLookupTables.Abs0[p1 - q1 + 255] > t)
{
return false;
}

return WebpLookupTables.Abs0[p3 - p2] <= it && WebpLookupTables.Abs0[p2 - p1] <= it &&
WebpLookupTables.Abs0[p1 - p0] <= it && WebpLookupTables.Abs0[q3 - q2] <= it &&
WebpLookupTables.Abs0[q2 - q1] <= it && WebpLookupTables.Abs0[q1 - q0] <= it;
return WebpLookupTables.Abs0[p3 - p2 + 255] <= it && WebpLookupTables.Abs0[p2 - p1 + 255] <= it &&
WebpLookupTables.Abs0[p1 - p0 + 255] <= it && WebpLookupTables.Abs0[q3 - q2 + 255] <= it &&
WebpLookupTables.Abs0[q2 - q1 + 255] <= it && WebpLookupTables.Abs0[q1 - q0 + 255] <= it;
}

[MethodImpl(InliningOptions.ShortMethod)]
Expand All @@ -1024,7 +1024,7 @@ private static bool Hev(Span<byte> p, int offset, int step, int thresh)
int p0 = p[offset - step];
int q0 = p[offset];
int q1 = p[offset + step];
return WebpLookupTables.Abs0[p1 - p0] > thresh || WebpLookupTables.Abs0[q1 - q0] > thresh;
return WebpLookupTables.Abs0[p1 - p0 + 255] > thresh || WebpLookupTables.Abs0[q1 - q0 + 255] > thresh;
}

[MethodImpl(InliningOptions.ShortMethod)]
Expand Down
Loading

0 comments on commit d021222

Please sign in to comment.