Remove Jpeg Huffman Decoder Bottleneck#643
Conversation
Codecov Report
@@ Coverage Diff @@
## master #643 +/- ##
==========================================
+ Coverage 89.16% 89.31% +0.14%
==========================================
Files 890 893 +3
Lines 37946 38020 +74
Branches 2661 2667 +6
==========================================
+ Hits 33835 33956 +121
+ Misses 3302 3267 -35
+ Partials 809 797 -12
Continue to review full report at Codecov.
|
antonfirsov
left a comment
There was a problem hiding this comment.
Good job, but I think the code is worth an other refactor/cleanup round before we move on.
It might be also worth to investigate if we can reduce the code duplications.
| @@ -9,14 +9,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components | |||
| [StructLayout(LayoutKind.Sequential)] | |||
| internal unsafe struct FixedInt64Buffer18 | |||
There was a problem hiding this comment.
The type name should be renamed accordingly.
| /// <summary> | ||
| /// The collection of lookup tables used for fast AC entropy scan decoding. | ||
| /// </summary> | ||
| internal sealed class FastACTables : IDisposable |
There was a problem hiding this comment.
I wonder if we really need this class in it's current form. Either we should hide the Table property and encapsulate actual logic (initialization, retrieval of rows) inside the class, or we should drop it and define a helper method that creates Buffer2d<short>.
There was a problem hiding this comment.
I like having a class but I think you're right about the tables property. I'll hide that away and introduce a GetTableSpan() method.
| private byte marker; | ||
| private bool badMarker; | ||
| private long markerPosition; | ||
| private int todo; |
There was a problem hiding this comment.
Would be nice to have better names or some comments about the semantics of less trivial variables.
| PdfJsFrameComponent component = this.components[k]; | ||
| ref short blockDataRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast<Block8x8, short>(component.SpectralBlocks.Span)); | ||
| ref PdfJsHuffmanTable dcHuffmanTable = ref dcHuffmanTables[component.DCHuffmanTableId]; | ||
| ref PdfJsHuffmanTable acHuffmanTable = ref acHuffmanTables[component.ACHuffmanTableId]; |
There was a problem hiding this comment.
acHuffmanTable and fastAC are unused
There was a problem hiding this comment.
Sometimes I miss Resharper.
There was a problem hiding this comment.
Got the unused, different line though so Github won't see it.
| } | ||
| } | ||
|
|
||
| private void DecodeBlockProgressiveAC( |
There was a problem hiding this comment.
The method is quite long, might be worth to refactor internal branches into separate methods.
There was a problem hiding this comment.
I'll split out the Refinement part into a separate method.
| private int PeekBits() => (int)((this.codeBuffer >> (32 - FastBits)) & ((1 << FastBits) - 1)); | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| private uint LRot(uint x, int y) => (x << y) | (x >> (32 - y)); |
| /// Builds a lookup table for fast AC entropy scan decoding. | ||
| /// </summary> | ||
| /// <param name="index">The table index.</param> | ||
| private void BuildFastACTable(int index) |
There was a problem hiding this comment.
This should be probably a member of the FastACTables class.
| @@ -9,14 +9,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components | |||
| [StructLayout(LayoutKind.Sequential)] | |||
| internal unsafe struct FixedInt16Buffer18 | |||
There was a problem hiding this comment.
Should we rename the struct because it no longer is a short/ Int16?
antonfirsov
left a comment
There was a problem hiding this comment.
Everything looks good for a merge now!
|
@JimBobSquarePants pushed some code simplification, and a benchmark to quickly test Baseline, Before:Baseline, After: |
|
Nice changes! That class looks very clean now and I like the inline and error helpers! How the hell does S.D decode the full stream so damn quickly, it's infuriating! |
|
Don't ask how, but it's possible to optimize huffman decoding with SIMD. |
|
I'm gonna merge this now to work on namespacing. |
Remove Jpeg Huffman Decoder Bottleneck
Prerequisites
Description
Replaces the slow PdfJsScanDecoder implementation with a much faster implementation based on Stb_Image. Now it's no longer a bottleneck. Fixes #601
We're creeping slowly closer to System.Drawing now for jpeg decoding.
New Benchmarks
Before Performance Trace

After Performance Trace

I'm genuinely amazed I managed to pull this off!