mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 132 additions and 134 deletions
@ -0,0 +1,83 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using SixLabors.ImageSharp.Advanced; |
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.Common; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// On-stack worker struct to efficiently encapsulate the TPixel -> Rgb24 -> YCbCr conversion chain of 8x8 pixel blocks.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel type to work on</typeparam>
|
||||
|
internal struct YCbCrForwardConverter<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The Y component
|
||||
|
/// </summary>
|
||||
|
public Block8x8F Y; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The Cb component
|
||||
|
/// </summary>
|
||||
|
public Block8x8F Cb; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The Cr component
|
||||
|
/// </summary>
|
||||
|
public Block8x8F Cr; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The color conversion tables
|
||||
|
/// </summary>
|
||||
|
private RgbToYCbCrTables colorTables; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Temporal 8x8 block to hold TPixel data
|
||||
|
/// </summary>
|
||||
|
private GenericBlock8x8<TPixel> pixelBlock; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Temporal RGB block
|
||||
|
/// </summary>
|
||||
|
private GenericBlock8x8<Rgb24> rgbBlock; |
||||
|
|
||||
|
public static YCbCrForwardConverter<TPixel> Create() |
||||
|
{ |
||||
|
var result = default(YCbCrForwardConverter<TPixel>); |
||||
|
result.colorTables = RgbToYCbCrTables.Create(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a 8x8 image area inside 'pixels' at position (x,y) placing the result members of the structure (<see cref="Y"/>, <see cref="Cb"/>, <see cref="Cr"/>)
|
||||
|
/// </summary>
|
||||
|
public void Convert(IPixelSource<TPixel> pixels, int x, int y) |
||||
|
{ |
||||
|
this.pixelBlock.LoadAndStretchEdges(pixels, x, y); |
||||
|
|
||||
|
Span<Rgb24> rgbSpan = this.rgbBlock.AsSpanUnsafe(); |
||||
|
PixelOperations<TPixel>.Instance.ToRgb24(this.pixelBlock.AsSpanUnsafe(), rgbSpan, 64); |
||||
|
|
||||
|
ref float yBlockStart = ref Unsafe.As<Block8x8F, float>(ref this.Y); |
||||
|
ref float cbBlockStart = ref Unsafe.As<Block8x8F, float>(ref this.Cb); |
||||
|
ref float crBlockStart = ref Unsafe.As<Block8x8F, float>(ref this.Cr); |
||||
|
ref Rgb24 rgbStart = ref rgbSpan[0]; |
||||
|
|
||||
|
for (int i = 0; i < 64; i++) |
||||
|
{ |
||||
|
ref Rgb24 c = ref Unsafe.Add(ref rgbStart, i); |
||||
|
|
||||
|
this.colorTables.ConvertPixelInto( |
||||
|
c.R, |
||||
|
c.G, |
||||
|
c.B, |
||||
|
ref Unsafe.Add(ref yBlockStart, i), |
||||
|
ref Unsafe.Add(ref cbBlockStart, i), |
||||
|
ref Unsafe.Add(ref crBlockStart, i) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue