/// <inheritdoc /> public ValueTask InvokeAsync(TiffImageDecoderContext context, ITiffImageDecoderPipelineNode next) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (next is null) { throw new ArgumentNullException(nameof(next)); } TiffYCbCrConverter8 converter = _converter; int bytesPerScanline = 3 * context.SourceImageSize.Width; Memory <byte> source = context.UncompressedData.Slice(context.SourceReadOffset.Y * bytesPerScanline); ReadOnlySpan <byte> sourceSpan = source.Span; using TiffPixelBufferWriter <TiffRgba32> writer = context.GetWriter <TiffRgba32>(); int rows = context.ReadSize.Height; int cols = context.ReadSize.Width; for (int row = 0; row < rows; row++) { using TiffPixelSpanHandle <TiffRgba32> pixelSpanHandle = writer.GetRowSpan(row); ReadOnlySpan <byte> rowSourceSpan = sourceSpan.Slice(3 * context.SourceReadOffset.X, 3 * context.ReadSize.Width); Span <TiffRgba32> rowDestinationSpan = pixelSpanHandle.GetSpan(); converter.ConvertToRgba32(rowSourceSpan, rowDestinationSpan, cols); sourceSpan = sourceSpan.Slice(bytesPerScanline); } return(next.RunAsync(context)); }
/// <inheritdoc /> public ValueTask InvokeAsync(TiffImageDecoderContext context, ITiffImageDecoderPipelineNode next) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (next is null) { throw new ArgumentNullException(nameof(next)); } TiffYCbCrConverter8 converter = _converter; int skippedRowOffset = context.SourceImageSize.Width * context.SourceReadOffset.Y; int planarByteCount = context.SourceImageSize.Width * context.SourceImageSize.Height; ReadOnlySpan <byte> sourceSpan = context.UncompressedData.Span; ReadOnlySpan <byte> sourceY = sourceSpan.Slice(0, planarByteCount); ReadOnlySpan <byte> sourceCb = sourceSpan.Slice(planarByteCount, planarByteCount); ReadOnlySpan <byte> sourceCr = sourceSpan.Slice(2 * planarByteCount, planarByteCount); using TiffPixelBufferWriter <TiffRgba32> writer = context.GetWriter <TiffRgba32>(); int rows = context.ReadSize.Height; int cols = context.ReadSize.Width; for (int row = 0; row < rows; row++) { using TiffPixelSpanHandle <TiffRgba32> pixelSpanHandle = writer.GetRowSpan(row); Span <TiffRgba32> rowDestinationSpan = pixelSpanHandle.GetSpan(); int rowOffset = skippedRowOffset + row * context.SourceImageSize.Width + context.SourceReadOffset.X; for (int col = 0; col < cols; col++) { int componentOffset = rowOffset + col; rowDestinationSpan[col] = converter.ConvertToRgba32(sourceY[componentOffset], sourceCb[componentOffset], sourceCr[componentOffset]); } } return(next.RunAsync(context)); }