diff --git a/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.cs b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.cs index 664219b9b..162874f02 100644 --- a/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.cs @@ -5,6 +5,10 @@ namespace ImageSharp.Formats.Jpg using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + /// + /// Encapsulates the impementation of Jpeg SOS decoder. + /// See JpegScanDecoder.md! + /// internal unsafe struct JpegScanDecoder { /// @@ -17,6 +21,9 @@ namespace ImageSharp.Formats.Jpg /// internal const int DcTableIndex = 0; + /// + /// Holds the "large" data blocks needed for computations + /// [StructLayout(LayoutKind.Sequential)] public struct ComponentData { @@ -42,6 +49,9 @@ namespace ImageSharp.Formats.Jpg } } + /// + /// Contains pointers to the memory regions of so they can be easily passed around to pointer based utility methods of + /// public struct ComponentPointers { public Block8x8F* Block; @@ -75,12 +85,18 @@ namespace ImageSharp.Formats.Jpg Unsafe.InitBlock(this.Pointers.Dc, default(byte), sizeof(int) * JpegDecoderCore.MaxComponents); } - - // bx and by are the location of the current block, in units of 8x8 + + // bx and by are the // blocks: the third block in the first row has (bx, by) = (2, 0). + /// + /// X coordinate of the current block, in units of 8x8. (The third block in the first row has (bx, by) = (2, 0)) + /// private int bx; + /// + /// Y coordinate of the current block, in units of 8x8. (The third block in the first row has (bx, by) = (2, 0)) + /// private int by; // zigStart and zigEnd are the spectral selection bounds. diff --git a/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.md b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.md new file mode 100644 index 000000000..09e3c80bb --- /dev/null +++ b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegScanDecoder.md @@ -0,0 +1,25 @@ +## JpegScanDecoder +Encapsulates the impementation of the Jpeg top-to bottom scan decoder triggered by the `SOS` marker. +The implementation is optimized to hold most of the necessary data in a single value type, which is intended to be used as an on-stack object. + +#### Benefits: +- Maximized locality of reference by keeping most of the operation data on the stack +- Reaching this without long parameter lists, most of the values describing the state of the decoder algorithm +are members of the `JpegScanDecoder` struct +- Most of the logic related to Scan decoding is refactored & simplified now to live in the methods of `JpegScanDecoder` +- The first step is done towards separating the stream reading from block processing. They can be refactored later to be executed in two disctinct loops. + - The input processing loop can be `async` + - The block processing loop can be parallelized + +#### Data layout + +|JpegScanDecoder | +|-------------------| +|Variables | +|ComponentData | +|ComponentPointers | + +- **ComponentData** holds the "large" data blocks needed for computations (Mostly `Block8x8F`-s) +- **ComponentPointers** contains pointers to the memory regions of `ComponentData` so they can be easily passed around to pointer based utility methods of `Block8x8F` + +