Repository navigation
Various Jpeg optimizations - #768
Conversation
…Suite as a static class
Codecov Report
@@ Coverage Diff @@
## master #768 +/- ##
=========================================
Coverage ? 88.49%
=========================================
Files ? 997
Lines ? 42504
Branches ? 3150
=========================================
Hits ? 37613
Misses ? 4204
Partials ? 687
Continue to review full report at Codecov.
|
JimBobSquarePants
left a comment
There was a problem hiding this comment.
Impressive! The benchmark results make for interesting stuff.
How long were you working on this, looks like it must have taken a while?
| @@ -506,8 +515,7 @@ private void DecodeBlockProgressiveDC( | |||
|
|
|||
| private void DecodeBlockProgressiveAC( | |||
| JpegComponent component, | |||
There was a problem hiding this comment.
component is unused now.
| private Image<TPixel> PostProcessIntoImage<TPixel>() | ||
| where TPixel : struct, IPixel<TPixel> | ||
| { | ||
| var image = Image.CreateUninitialized<TPixel>( |
There was a problem hiding this comment.
I wonder where else we can apply this?
There was a problem hiding this comment.
Everywhere, where we can make sure that the operation is about to fill the whole image.
So all decoders. Copying processors: not sure, they are a bit more complicated because of the swapping logic.
There was a problem hiding this comment.
We might not be able to use it in gif as individual frames sometimes only contain data in some pixels but both png and bmp should definitely benefit.
| [MethodImpl(InliningOptions.ShortMethod)] | ||
| public static bool IsDefined(int value) | ||
| { | ||
| return Array.BinarySearch(Values, 0, Values.Length, value) > 0; |
| // 'Decode Jpeg - System.Drawing' | Jpg/baseline/jpeg420exif.jpg | 17.063 ms | 2.6096 ms | 0.1474 ms | 1.00 | 0.00 | 218.7500 | - | - | 757.04 KB | | ||
| // 'Decode Jpeg - ImageSharp' | Jpg/baseline/jpeg420exif.jpg | 41.366 ms | 1.0115 ms | 0.0572 ms | 2.42 | 0.02 | - | - | - | 21.94 KB | | ||
| // | | | | | | | | | | | | ||
| // 'Decode Jpeg - System.Drawing' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 428.282 ms | 94.9163 ms | 5.3629 ms | 1.00 | 0.00 | 2375.0000 | - | - | 7403.76 KB | |
There was a problem hiding this comment.
This makes me think that your IDCT/Colorspace code is very fast and we're still missing an optimization opportunity somewhere in the Huffman decoding process.
Looking through the MozJpeg/LibJpegTurbo code there's decode_mcu_fast and decode_mcu_slow in jdhuff.c which seems to back this up.
There was a problem hiding this comment.
There was a problem hiding this comment.
My thought is that S.D is slow for progressive images for some reason.
That's what I mean. They're not able to use an optimized path. Looking at jdphuff.c there's no fast/slow branching so they have to do what we do. I think for us to match them, we should look at the jdhuff.c file and see what we can make of it and how it compares to our baseline decoder.
|
Yeah I've been working on this a lot, almost all evenings during the last week. My next move is to apply similar basic refactors to ResizeProcessor before dismounting the whole thing. |
…tion Various Jpeg optimizations


Prerequisites
Summary
This PR contains various optimizations for
JpegDecoder, resulting in a~10%speedup. We are decoding common 420/YCbCr baseline images only 2.4-2.5 slower than System.Drawing now.I had a hard time squeezing the last drops, we probably can't do much more here before .NET Core 3.0.
Optimizations
JpegComponent.GetBlockReference(x,y)with.GetRowSpan(y)Image.CreateUninitialized<TPixel>(...)because decoders do not need pre-initialized image buffers. Introduced in Jpeg, can be used in other decoders as well.Block8x8->Block8x8Fconversion (Block8x8F.LoadFrom(...)) usingVector.Widen(...)andVector.ConvertToSingle(...)(.NET Core 2.1 / .NET 4.7.2 only)Block8x8F.CopyTo(...)for 2x2 scale casesExifReader.ToEnum<T>(...)Chore
TestImages\Input\JpgTestImages.Jpeg.BenchmarkSuiteBenchmark results
Only .NET Core 2.1 for now, using the benchmark DecodeJpeg_ImageSpecific (renamed from
DecodeJpeg).Before
After