-
-
Notifications
You must be signed in to change notification settings - Fork 851
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
Decode Jpeg into Rgb24 when pixel type not specified #1773
Conversation
@@ -40,23 +43,20 @@ public SpectralConverter(Configuration configuration, CancellationToken cancella | |||
|
|||
private bool Converted => this.pixelRowCounter >= this.pixelBuffer.Height; | |||
|
|||
public Buffer2D<TPixel> PixelBuffer | |||
public Buffer2D<TPixel> GetPixelBuffer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is heavy lazy initialization, with side effects like CancellationToken
firing. It's better to expose such stuff from a method than a property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't like this property approach with a lot of lazy stuff behind from the start but couldn't come up with anything better. There's a lot of confusing bits of code here and there from my pr, I will work on decoder performance/refactoring next as I'm done with the encoder for now.
Codecov Report
@@ Coverage Diff @@
## master #1773 +/- ##
========================================
Coverage 84.49% 84.49%
========================================
Files 849 849
Lines 37412 37252 -160
Branches 4376 4385 +9
========================================
- Hits 31611 31477 -134
+ Misses 4947 4916 -31
- Partials 854 859 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
A lot of reading here. Will try to review tomorrow night |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a quick look over the code, not detailed review.
...arp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleBasic.cs
Outdated
Show resolved
Hide resolved
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control); | ||
|
||
int n = result.Length / 8; | ||
int n = values.Component0.Length / 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int n = values.Component0.Length / 8; | |
int n = (int)((uint)values.Component0.Length / 8); |
So the JIT will emit a bit-hack division instead of the (signed) integer division by constant.
...ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx2.cs
Outdated
Show resolved
Hide resolved
...geSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector8.cs
Outdated
Show resolved
Hide resolved
|
||
var scale = new Vector<float>(1 / this.MaximumValue); | ||
|
||
// Walking 8 elements at one step: | ||
int n = result.Length / 8; | ||
int n = values.Component0.Length / 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int n = values.Component0.Length / 8; | |
int n = (int)((uint)values.Component0.Length / 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this trick is only worth it when we are inside a tight loop or, or in a method that is expected to be called from a tight loop. In other cases I prefer readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or is it possible to achieve the same in a simpler way nint
? I changed my code everywhere to nint n = values.Component0.Length / 8;
because n
is only used for the i < n
comparison, and I like it better when the types match explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should go with readability, as you did now with nint
. Codegen isn't ideal, but this pattern {array, span}.Length / ConstantOfPowerOfTwo
is so common, that the JIT should be able to optimize this, so we don't need any hacks.
I'll have a look if there's a JIT-issue, otherwise create one.
Edit: filed dotnet/runtime#59922
ref Vector<float> ggRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref gg); | ||
ref Vector<float> bbRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref bb); | ||
|
||
int n = values.Component0.Length / 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int n = values.Component0.Length / 8; | |
int n = (int)((uint)values.Component0.Length / 8); |
or maybe create a helper for this? The casts aren't very intuitive, but codegen is quite a difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's worth it, see #1773 (comment)
...Sharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector8.cs
Outdated
Show resolved
Hide resolved
int n = values.Component0.Length / 8; | ||
for (int i = 0; i < n; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int n = values.Component0.Length / 8; | |
for (int i = 0; i < n; i++) | |
int n = (int)((uint)values.Component0.Length / 8); | |
for (nint i = 0; i < n; i++) |
Now I'll stop commenting on these -- otherwise it's too much noise generated by me 😉
...eSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector8.cs
Outdated
Show resolved
Hide resolved
src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs
Outdated
Show resolved
Hide resolved
…mageSharp into af/jpeg-pack-sandbox
Co-authored-by: Günther Foidl <gue@korporal.at>
…mageSharp into af/jpeg-pack-sandbox
Co-authored-by: Günther Foidl <gue@korporal.at>
…mageSharp into af/jpeg-pack-sandbox
...arp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleBasic.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't believe how much easier the code is to read now! I did a few readthroughs just to make sure I wasn't missing something 😄
Just @gfoidl last suggestion and it's good to go. 👍
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Günther Foidl <gue@korporal.at>
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
Outdated
Show resolved
Hide resolved
…rocessor{TPixel}.cs
Prerequisites
Description
Finish the plan defined in #1410:
PixelOperations.PackFromRgbPlanes
insteadImage<Rgb24>
from non-generic DecodeResizeProcessor<T>
: omit alpha premultiplication if the pixel type has no alpha channelFixes #1410, fixes #1121.
Performance
Did usual run of
LoadResizeSaveStressBenchmarks
on 10 core desktop. The overall effect on speed is within noise range, but there might be some 1%-ish improvement. I assume the reason is that #1462's packing actually doesn't make big difference to the packing code introduced in #1411.But memory usage dropped significantly, which is the main goal here.
Before
After
/cc @br3aker @JimBobSquarePants @saucecontrol