/// <inheritdoc />
        public void Decompress(TiffDecompressionContext context, ReadOnlyMemory <byte> input, Memory <byte> output)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // Identify this block
            JpegDecoder decoder = Interlocked.Exchange(ref _decoder, null) ?? LoadJpegDecoder();

            decoder.MemoryPool = context.MemoryPool;
            decoder.SetInput(input);
            decoder.Identify();

            // Validate we are capable of decoding this.
            TiffSize outputBufferSize = context.ImageSize;

            if (decoder.Width < outputBufferSize.Width || decoder.Height < outputBufferSize.Height)
            {
                throw new InvalidDataException("Image dimension is too small.");
            }

            // Check number of components
            if (decoder.NumberOfComponents != _numberOfComponents)
            {
                throw new InvalidDataException($"Expect {_numberOfComponents} components, but got {decoder.NumberOfComponents} components in the JPEG stream.");
            }

            JpegBlockOutputWriter outputWriter;

            if (decoder.Precision == 8)
            {
                if (context.BitsPerSample.GetFirstOrDefault() != 8)
                {
                    throw new InvalidDataException("Precision of 8 bit is not expected.");
                }
                outputWriter = new JpegBuffer8BitOutputWriter(outputBufferSize.Width, context.SkippedScanlines, context.SkippedScanlines + context.RequestedScanlines, decoder.NumberOfComponents, output);
            }
            else if (decoder.Precision < 8)
            {
                if (context.BitsPerSample.GetFirstOrDefault() != 8)
                {
                    throw new InvalidDataException($"Precision of {decoder.Precision} bit is not expected.");
                }
                outputWriter = new JpegBufferAny8BitOutputWriter(outputBufferSize.Width, context.SkippedScanlines, context.SkippedScanlines + context.RequestedScanlines, decoder.NumberOfComponents, decoder.Precision, output);
            }
            else if (decoder.Precision <= 16)
            {
                if (context.BitsPerSample.GetFirstOrDefault() != 16)
                {
                    throw new InvalidDataException($"Precision of {decoder.Precision} bit is not expected.");
                }
                outputWriter = new JpegBufferAny16BitOutputWriter(outputBufferSize.Width, context.SkippedScanlines, context.SkippedScanlines + context.RequestedScanlines, decoder.NumberOfComponents, decoder.Precision, output);
            }
            else
            {
                throw new InvalidDataException($"Precision of {decoder.Precision} bit is not expected.");
            }

            // Decode
            decoder.SetOutputWriter(outputWriter);
            decoder.Decode();

            // Reset state
            decoder.ResetInput();
            decoder.ResetHeader();
            decoder.ResetOutputWriter();

            // Cache the instances
            Interlocked.CompareExchange(ref _decoder, decoder, null);
        }