|
|
|
@ -2,24 +2,22 @@ |
|
|
|
// Copyright (c) James Jackson-South and contributors.
|
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
// </copyright>
|
|
|
|
|
|
|
|
namespace ImageSharp.Formats.Jpg |
|
|
|
{ |
|
|
|
using System; |
|
|
|
using System.Buffers; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Represents an image made up of three color components (luminance, blue chroma, red chroma)
|
|
|
|
/// Represents an image made up of three color components (luminance, blue chroma, red chroma)
|
|
|
|
/// </summary>
|
|
|
|
internal class YCbCrImage : IDisposable |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="YCbCrImage"/> class.
|
|
|
|
/// Initializes a new instance of the <see cref="YCbCrImage" /> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="width">The width.</param>
|
|
|
|
/// <param name="height">The height.</param>
|
|
|
|
/// <param name="ratio">The ratio.</param>
|
|
|
|
public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio, int yOffset, int cOffset) |
|
|
|
public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio) |
|
|
|
{ |
|
|
|
int cw, ch; |
|
|
|
YCbCrSize(width, height, ratio, out cw, out ch); |
|
|
|
@ -27,134 +25,120 @@ namespace ImageSharp.Formats.Jpg |
|
|
|
this.CbPixels = CleanPooler<byte>.RentCleanArray(cw * ch); |
|
|
|
this.CrPixels = CleanPooler<byte>.RentCleanArray(cw * ch); |
|
|
|
this.Ratio = ratio; |
|
|
|
this.YOffset = yOffset; |
|
|
|
this.COffset = cOffset; |
|
|
|
this.YOffset = 0; |
|
|
|
this.COffset = 0; |
|
|
|
this.YStride = width; |
|
|
|
this.CStride = cw; |
|
|
|
this.X = 0; |
|
|
|
this.Y = 0; |
|
|
|
} |
|
|
|
|
|
|
|
public JpegPixelArea YChannel => new JpegPixelArea(this.YPixels, this.YStride, this.YOffset); |
|
|
|
|
|
|
|
public JpegPixelArea CbChannel => new JpegPixelArea(this.CbPixels, this.CStride, this.COffset); |
|
|
|
|
|
|
|
public JpegPixelArea CrChannel => new JpegPixelArea(this.CrPixels, this.CStride, this.COffset); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Prevents a default instance of the <see cref="YCbCrImage"/> class from being created.
|
|
|
|
/// </summary>
|
|
|
|
private YCbCrImage(int yOffset, int cOffset) |
|
|
|
{ |
|
|
|
this.YOffset = yOffset; |
|
|
|
this.COffset = cOffset; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Provides enumeration of the various available subsample ratios.
|
|
|
|
/// Provides enumeration of the various available subsample ratios.
|
|
|
|
/// </summary>
|
|
|
|
public enum YCbCrSubsampleRatio |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio444
|
|
|
|
/// YCbCrSubsampleRatio444
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio444, |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio422
|
|
|
|
/// YCbCrSubsampleRatio422
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio422, |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio420
|
|
|
|
/// YCbCrSubsampleRatio420
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio420, |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio440
|
|
|
|
/// YCbCrSubsampleRatio440
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio440, |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio411
|
|
|
|
/// YCbCrSubsampleRatio411
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio411, |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// YCbCrSubsampleRatio410
|
|
|
|
/// YCbCrSubsampleRatio410
|
|
|
|
/// </summary>
|
|
|
|
YCbCrSubsampleRatio410, |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the luminance components channel.
|
|
|
|
/// Gets an offseted <see cref="JpegPixelArea" /> to the Cb channel
|
|
|
|
/// </summary>
|
|
|
|
public byte[] YPixels { get; } |
|
|
|
public JpegPixelArea CbChannel => new JpegPixelArea(this.CbPixels, this.CStride, this.COffset); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the blue chroma components channel.
|
|
|
|
/// Gets the blue chroma components channel.
|
|
|
|
/// </summary>
|
|
|
|
public byte[] CbPixels { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the red chroma components channel.
|
|
|
|
/// Gets the index of the first element of red or blue chroma.
|
|
|
|
/// </summary>
|
|
|
|
public byte[] CrPixels { get; } |
|
|
|
public int COffset { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the Y slice index delta between vertically adjacent pixels.
|
|
|
|
/// Gets an offseted <see cref="JpegPixelArea" /> to the Cr channel
|
|
|
|
/// </summary>
|
|
|
|
public int YStride { get; } |
|
|
|
public JpegPixelArea CrChannel => new JpegPixelArea(this.CrPixels, this.CStride, this.COffset); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the red and blue chroma slice index delta between vertically adjacent pixels
|
|
|
|
/// that map to separate chroma samples.
|
|
|
|
/// Gets the red chroma components channel.
|
|
|
|
/// </summary>
|
|
|
|
public byte[] CrPixels { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the red and blue chroma slice index delta between vertically adjacent pixels
|
|
|
|
/// that map to separate chroma samples.
|
|
|
|
/// </summary>
|
|
|
|
public int CStride { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the index of the first luminance element.
|
|
|
|
/// Gets or sets the subsampling ratio.
|
|
|
|
/// </summary>
|
|
|
|
public int YOffset { get; } |
|
|
|
public YCbCrSubsampleRatio Ratio { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the index of the first element of red or blue chroma.
|
|
|
|
/// Gets an offseted <see cref="JpegPixelArea" /> to the Y channel
|
|
|
|
/// </summary>
|
|
|
|
public int COffset { get; } |
|
|
|
public JpegPixelArea YChannel => new JpegPixelArea(this.YPixels, this.YStride, this.YOffset); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the horizontal position.
|
|
|
|
/// Gets the index of the first luminance element.
|
|
|
|
/// </summary>
|
|
|
|
public int X { get; set; } |
|
|
|
public int YOffset { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the vertical position.
|
|
|
|
/// Gets the luminance components channel.
|
|
|
|
/// </summary>
|
|
|
|
public int Y { get; set; } |
|
|
|
|
|
|
|
public byte[] YPixels { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the subsampling ratio.
|
|
|
|
/// Gets the Y slice index delta between vertically adjacent pixels.
|
|
|
|
/// </summary>
|
|
|
|
public YCbCrSubsampleRatio Ratio { get; set; } |
|
|
|
public int YStride { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the offset of the first luminance component at the given row
|
|
|
|
/// Disposes the <see cref="YCbCrImage" /> returning rented arrays to the pools.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="y">The row number.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// The <see cref="int"/>.
|
|
|
|
/// </returns>
|
|
|
|
public int GetRowYOffset(int y) |
|
|
|
public void Dispose() |
|
|
|
{ |
|
|
|
return y * this.YStride; |
|
|
|
CleanPooler<byte>.ReturnArray(this.YPixels); |
|
|
|
CleanPooler<byte>.ReturnArray(this.CrPixels); |
|
|
|
CleanPooler<byte>.ReturnArray(this.CbPixels); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the offset of the first chroma component at the given row
|
|
|
|
/// Returns the offset of the first chroma component at the given row
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="y">The row number.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// The <see cref="int"/>.
|
|
|
|
/// The <see cref="int" />.
|
|
|
|
/// </returns>
|
|
|
|
public int GetRowCOffset(int y) |
|
|
|
{ |
|
|
|
@ -176,14 +160,31 @@ namespace ImageSharp.Formats.Jpg |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the height and width of the chroma components
|
|
|
|
/// Returns the offset of the first luminance component at the given row
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="y">The row number.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// The <see cref="int" />.
|
|
|
|
/// </returns>
|
|
|
|
public int GetRowYOffset(int y) |
|
|
|
{ |
|
|
|
return y * this.YStride; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the height and width of the chroma components
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="width">The width.</param>
|
|
|
|
/// <param name="height">The height.</param>
|
|
|
|
/// <param name="ratio">The subsampling ratio.</param>
|
|
|
|
/// <param name="chromaWidth">The chroma width.</param>
|
|
|
|
/// <param name="chromaHeight">The chroma height.</param>
|
|
|
|
private static void YCbCrSize(int width, int height, YCbCrSubsampleRatio ratio, out int chromaWidth, out int chromaHeight) |
|
|
|
private static void YCbCrSize( |
|
|
|
int width, |
|
|
|
int height, |
|
|
|
YCbCrSubsampleRatio ratio, |
|
|
|
out int chromaWidth, |
|
|
|
out int chromaHeight) |
|
|
|
{ |
|
|
|
switch (ratio) |
|
|
|
{ |
|
|
|
@ -215,12 +216,5 @@ namespace ImageSharp.Formats.Jpg |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void Dispose() |
|
|
|
{ |
|
|
|
CleanPooler<byte>.ReturnArray(this.YPixels); |
|
|
|
CleanPooler<byte>.ReturnArray(this.CrPixels); |
|
|
|
CleanPooler<byte>.ReturnArray(this.CbPixels); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |