-
-
Notifications
You must be signed in to change notification settings - Fork 891
Remove Jpeg Huffman Decoder Bottleneck #643
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
Merged
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
285f8dd
Begin porting stb_image
JimBobSquarePants 71903c5
Minor cleanup
JimBobSquarePants 5516bfb
Merge branch 'master' into js/new-jpeg-scan-decoder
JimBobSquarePants c8a9b30
Wire up huffman tables. (doesn't work)
JimBobSquarePants 6d928f6
Meh
JimBobSquarePants f064d95
Baseline decoding seems to work
JimBobSquarePants 31d5fa4
Merge branch 'master' into js/new-jpeg-scan-decoder
JimBobSquarePants bdd3291
Update reference types
JimBobSquarePants f597321
Merge branch 'master' into js/new-jpeg-scan-decoder
JimBobSquarePants 9e59ac1
6/10 baseline images now pass.
JimBobSquarePants 5716dbe
Merge branch 'master' into js/new-jpeg-scan-decoder
JimBobSquarePants 588e423
9/10 baseline now pass!
JimBobSquarePants 681f99f
Can now decode baseline + progressive
JimBobSquarePants c69c3ac
Split decode method.
JimBobSquarePants 1a79cfb
void methods
JimBobSquarePants f2e05bf
Minor perf changes.
JimBobSquarePants d8f4b25
Remove unused huffman table code.
JimBobSquarePants b5e2401
Delete unused code.
JimBobSquarePants cfe5b5c
Update reference images from master
JimBobSquarePants 43c818f
Add descriptive comments, remove unused, and make method static.
JimBobSquarePants 1e493ab
Split progressive AC method and rename GrowBufferUnsafe
JimBobSquarePants 8370d4f
Fix updated struct name
JimBobSquarePants 6360a8a
Update name reference
JimBobSquarePants fcabcdd
Refactor FastACTables and reduce trivial duplication.
JimBobSquarePants 69f228b
private static ordering.
JimBobSquarePants 9cb8c15
Rename struct
JimBobSquarePants bd79c84
Update Huffman table property
JimBobSquarePants d4fc8a0
Move method where it belongs.
JimBobSquarePants 65a0504
add regression test for #624
antonfirsov c21e971
ParseStream -only benchmark
antonfirsov d04611e
Introduce InliningOptions
antonfirsov 468797f
use JpegThrowHelper
antonfirsov b9a6804
separate Interleaved / Non-Interleaved code path
antonfirsov ff1a24c
simplify + uniformize blockDataRef retrieval
antonfirsov df557c9
ScanDecoder: refactor parameters to members
antonfirsov 2277896
temporal vortex attacked again
antonfirsov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // Copyright (c) Six Labors and contributors. | ||
| // Licensed under the Apache License, Version 2.0. | ||
|
|
||
| // Uncomment this for verbose profiler results: | ||
| // #define PROFILING | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| namespace SixLabors.ImageSharp | ||
| { | ||
| /// <summary> | ||
| /// Global inlining options. Helps temporarily disable inling for better profiler output. | ||
| /// </summary> | ||
| internal static class InliningOptions | ||
| { | ||
| #if PROFILING | ||
| public const MethodImplOptions ShortMethod = 0; | ||
| #else | ||
| public const MethodImplOptions ShortMethod = MethodImplOptions.AggressiveInlining; | ||
| #endif | ||
| public const MethodImplOptions ColdPath = MethodImplOptions.NoInlining; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Copyright (c) Six Labors and contributors. | ||
| // Licensed under the Apache License, Version 2.0. | ||
|
|
||
| using System.Runtime.CompilerServices; | ||
|
|
||
| namespace SixLabors.ImageSharp.Formats.Jpeg | ||
| { | ||
| internal static class JpegThrowHelper | ||
| { | ||
| /// <summary> | ||
| /// Cold path optimization for throwing <see cref="ImageFormatException"/>-s | ||
| /// </summary> | ||
| /// <param name="errorMessage">The error message for the exception</param> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowImageFormatException(string errorMessage) | ||
| { | ||
| throw new ImageFormatException(errorMessage); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowBadHuffmanCode() | ||
| { | ||
| throw new ImageFormatException("Bad Huffman code."); | ||
| } | ||
| } | ||
| } |
96 changes: 96 additions & 0 deletions
96
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FastACTables.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| // Copyright (c) Six Labors and contributors. | ||
| // Licensed under the Apache License, Version 2.0. | ||
|
|
||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
| using SixLabors.Memory; | ||
|
|
||
| namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components | ||
| { | ||
| /// <summary> | ||
| /// The collection of lookup tables used for fast AC entropy scan decoding. | ||
| /// </summary> | ||
| internal sealed class FastACTables : IDisposable | ||
| { | ||
| private Buffer2D<short> tables; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="FastACTables"/> class. | ||
| /// </summary> | ||
| /// <param name="memoryAllocator">The memory allocator used to allocate memory for image processing operations.</param> | ||
| public FastACTables(MemoryAllocator memoryAllocator) | ||
| { | ||
| this.tables = memoryAllocator.AllocateClean2D<short>(512, 4); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the <see cref="Span{Int16}"/> representing the table at the index in the collection. | ||
| /// </summary> | ||
| /// <param name="index">The table index.</param> | ||
| /// <returns><see cref="Span{Int16}"/></returns> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public ReadOnlySpan<short> GetTableSpan(int index) | ||
| { | ||
| return this.tables.GetRowSpan(index); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets a reference to the first element of the AC table indexed by <see cref="PdfJsFrameComponent.ACHuffmanTableId"/> | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public ref short GetAcTableReference(PdfJsFrameComponent component) | ||
| { | ||
| return ref this.tables.GetRowSpan(component.ACHuffmanTableId)[0]; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Builds a lookup table for fast AC entropy scan decoding. | ||
| /// </summary> | ||
| /// <param name="index">The table index.</param> | ||
| /// <param name="acHuffmanTables">The collection of AC Huffman tables.</param> | ||
| public void BuildACTableLut(int index, PdfJsHuffmanTables acHuffmanTables) | ||
| { | ||
| const int FastBits = ScanDecoder.FastBits; | ||
| Span<short> fastAC = this.tables.GetRowSpan(index); | ||
| ref PdfJsHuffmanTable huffman = ref acHuffmanTables[index]; | ||
|
|
||
| int i; | ||
| for (i = 0; i < (1 << FastBits); i++) | ||
| { | ||
| byte fast = huffman.Lookahead[i]; | ||
| fastAC[i] = 0; | ||
| if (fast < byte.MaxValue) | ||
| { | ||
| int rs = huffman.Values[fast]; | ||
| int run = (rs >> 4) & 15; | ||
| int magbits = rs & 15; | ||
| int len = huffman.Sizes[fast]; | ||
|
|
||
| if (magbits > 0 && len + magbits <= FastBits) | ||
| { | ||
| // Magnitude code followed by receive_extend code | ||
| int k = ((i << len) & ((1 << FastBits) - 1)) >> (FastBits - magbits); | ||
| int m = 1 << (magbits - 1); | ||
| if (k < m) | ||
| { | ||
| k += (int)((~0U << magbits) + 1); | ||
| } | ||
|
|
||
| // if the result is small enough, we can fit it in fastAC table | ||
| if (k >= -128 && k <= 127) | ||
| { | ||
| fastAC[i] = (short)((k * 256) + (run * 16) + (len + magbits)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <inheritdoc /> | ||
| public void Dispose() | ||
| { | ||
| this.tables?.Dispose(); | ||
| this.tables = null; | ||
| } | ||
| } | ||
| } | ||
24 changes: 24 additions & 0 deletions
24
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FixedByteBuffer512.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // Copyright (c) Six Labors and contributors. | ||
| // Licensed under the Apache License, Version 2.0. | ||
|
|
||
| using System.Runtime.CompilerServices; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components | ||
| { | ||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct FixedByteBuffer512 | ||
| { | ||
| public fixed byte Data[1 << ScanDecoder.FastBits]; | ||
|
|
||
| public byte this[int idx] | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| get | ||
| { | ||
| ref byte self = ref Unsafe.As<FixedByteBuffer512, byte>(ref this); | ||
| return Unsafe.Add(ref self, idx); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 wonder if we really need this class in it's current form. Either we should hide the
Tableproperty and encapsulate actual logic (initialization, retrieval of rows) inside the class, or we should drop it and define a helper method that createsBuffer2d<short>.Uh oh!
There was an error while loading. Please reload this page.
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 like having a class but I think you're right about the tables property. I'll hide that away and introduce a
GetTableSpan()method.