Browse Source

Huffman table cleanup

pull/2120/head
Dmitry Pentin 4 years ago
parent
commit
ade236e872
  1. 26
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs
  2. 51
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs
  3. 2
      src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
  4. 196
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.FrameConfig.cs
  5. 226
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

26
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs

@ -26,32 +26,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
/// </remarks> /// </remarks>
internal readonly struct HuffmanLut internal readonly struct HuffmanLut
{ {
/// <summary>
/// The compiled representations of theHuffmanSpec.
/// </summary>
public static readonly HuffmanLut[] TheHuffmanLut = new HuffmanLut[4];
public static readonly HuffmanLut[] DcHuffmanLut = new HuffmanLut[2];
public static readonly HuffmanLut[] AcHuffmanLut = new HuffmanLut[2];
/// <summary>
/// Initializes static members of the <see cref="HuffmanLut"/> struct.
/// </summary>
static HuffmanLut()
{
// Initialize the Huffman tables
for (int i = 0; i < HuffmanSpec.TheHuffmanSpecs.Length; i++)
{
TheHuffmanLut[i] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[i]);
}
// TODO: REWRITE THIS
DcHuffmanLut[0] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[0]);
DcHuffmanLut[1] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[2]);
AcHuffmanLut[0] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[1]);
AcHuffmanLut[1] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[3]);
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="HuffmanLut"/> struct. /// Initializes a new instance of the <see cref="HuffmanLut"/> struct.
/// </summary> /// </summary>

51
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs

@ -8,16 +8,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
/// </summary> /// </summary>
public readonly struct HuffmanSpec public readonly struct HuffmanSpec
{ {
#pragma warning disable SA1118 // ParameterMustNotSpanMultipleLines
/// <summary> /// <summary>
/// The Huffman encoding specifications. /// Huffman talbe specification for luminance DC.
/// This encoder uses the same Huffman encoding for all images.
/// </summary> /// </summary>
public static readonly HuffmanSpec[] TheHuffmanSpecs = /// <remarks>
{ /// This is an example specification taken from the jpeg specification paper.
// Luminance DC. /// </remarks>
new HuffmanSpec( public static readonly HuffmanSpec LuminanceDC = new(
new byte[] new byte[]
{ {
0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
@ -26,10 +23,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
new byte[] new byte[]
{ {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}), });
// Luminance AC. /// <summary>
new HuffmanSpec( /// Huffman talbe specification for luminance AC.
/// </summary>
/// <remarks>
/// This is an example specification taken from the jpeg specification paper.
/// </remarks>
public static readonly HuffmanSpec LuminanceAC = new(
new byte[] new byte[]
{ {
0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0,
@ -61,10 +63,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa 0xf9, 0xfa
}), });
// Chrominance DC. /// <summary>
new HuffmanSpec( /// Huffman talbe specification for chrominance DC.
/// </summary>
/// <remarks>
/// This is an example specification taken from the jpeg specification paper.
/// </remarks>
public static readonly HuffmanSpec ChrominanceDC = new(
new byte[] new byte[]
{ {
0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
@ -73,10 +80,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
new byte[] new byte[]
{ {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}), });
// Chrominance AC. /// <summary>
new HuffmanSpec( /// Huffman talbe specification for chrominance DC.
/// </summary>
/// <remarks>
/// This is an example specification taken from the jpeg specification paper.
/// </remarks>
public static readonly HuffmanSpec ChrominanceAC = new(
new byte[] new byte[]
{ {
0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0,
@ -108,9 +120,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa 0xf9, 0xfa
}) });
};
#pragma warning restore SA1118 // ParameterMustNotSpanMultipleLines
/// <summary> /// <summary>
/// Gets count[i] - The number of codes of length i bits. /// Gets count[i] - The number of codes of length i bits.
/// </summary> /// </summary>

2
src/ImageSharp/Formats/Jpeg/JpegEncoder.cs

@ -41,8 +41,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc/> /// <inheritdoc/>
public JpegEncodingColor? ColorType { get; set; } public JpegEncodingColor? ColorType { get; set; }
internal JpegFrameConfig FrameConfig { get; set; }
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>. /// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
/// </summary> /// </summary>

196
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.FrameConfig.cs

@ -0,0 +1,196 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder;
namespace SixLabors.ImageSharp.Formats.Jpeg
{
/// <summary>
/// Image encoder for writing an image to a stream as a jpeg.
/// </summary>
internal sealed unsafe partial class JpegEncoderCore
{
private static JpegFrameConfig[] CreateFrameConfigs()
{
var defaultLuminanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 0, HuffmanSpec.LuminanceDC);
var defaultLuminanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 0, HuffmanSpec.LuminanceAC);
var defaultChrominanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 1, HuffmanSpec.ChrominanceDC);
var defaultChrominanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 1, HuffmanSpec.ChrominanceAC);
var defaultLuminanceQuantTable = new JpegQuantizationTableConfig(0, Quantization.LuminanceTable);
var defaultChrominanceQuantTable = new JpegQuantizationTableConfig(1, Quantization.ChrominanceTable);
var yCbCrHuffmanConfigs = new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC,
defaultChrominanceHuffmanDC,
defaultChrominanceHuffmanAC,
};
var yCbCrQuantTableConfigs = new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable,
defaultChrominanceQuantTable,
};
return new JpegFrameConfig[]
{
// YCbCr 4:4:4
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio444,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:2:2
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio422,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 2, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:2:0
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio420,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 2, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:1:1
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio411,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 4, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:1:0
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio410,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 4, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// Luminance
new JpegFrameConfig(
JpegColorSpace.Grayscale,
JpegEncodingColor.Luminance,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 0, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
}),
// Rgb
new JpegFrameConfig(
JpegColorSpace.RGB,
JpegEncodingColor.Rgb,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 82, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 71, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 66, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformUnknown
},
// Cmyk
new JpegFrameConfig(
JpegColorSpace.Cmyk,
JpegEncodingColor.Cmyk,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformUnknown,
},
// YccK
new JpegFrameConfig(
JpegColorSpace.Ycck,
JpegEncodingColor.Ycck,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformYcck,
},
};
}
}
}

226
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary> /// <summary>
/// Image encoder for writing an image to a stream as a jpeg. /// Image encoder for writing an image to a stream as a jpeg.
/// </summary> /// </summary>
internal sealed unsafe class JpegEncoderCore : IImageEncoderInternals internal sealed unsafe partial class JpegEncoderCore : IImageEncoderInternals
{ {
/// <summary> /// <summary>
/// The available encodable frame configs. /// The available encodable frame configs.
@ -244,8 +244,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
const int MaxBytesApp1 = 65533; // 64k - 2 padding bytes const int maxBytesApp1 = 65533; // 64k - 2 padding bytes
const int MaxBytesWithExifId = 65527; // Max - 6 bytes for EXIF header. const int maxBytesWithExifId = 65527; // Max - 6 bytes for EXIF header.
byte[] data = exifProfile.ToByteArray(); byte[] data = exifProfile.ToByteArray();
@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// We can write up to a maximum of 64 data to the initial marker so calculate boundaries. // We can write up to a maximum of 64 data to the initial marker so calculate boundaries.
int exifMarkerLength = Components.Decoder.ProfileResolver.ExifMarker.Length; int exifMarkerLength = Components.Decoder.ProfileResolver.ExifMarker.Length;
int remaining = exifMarkerLength + data.Length; int remaining = exifMarkerLength + data.Length;
int bytesToWrite = remaining > MaxBytesApp1 ? MaxBytesApp1 : remaining; int bytesToWrite = remaining > maxBytesApp1 ? maxBytesApp1 : remaining;
int app1Length = bytesToWrite + 2; int app1Length = bytesToWrite + 2;
// Write the app marker, EXIF marker, and data // Write the app marker, EXIF marker, and data
@ -267,9 +267,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
remaining -= bytesToWrite; remaining -= bytesToWrite;
// If the exif data exceeds 64K, write it in multiple APP1 Markers // If the exif data exceeds 64K, write it in multiple APP1 Markers
for (int idx = MaxBytesWithExifId; idx < data.Length; idx += MaxBytesWithExifId) for (int idx = maxBytesWithExifId; idx < data.Length; idx += maxBytesWithExifId)
{ {
bytesToWrite = remaining > MaxBytesWithExifId ? MaxBytesWithExifId : remaining; bytesToWrite = remaining > maxBytesWithExifId ? maxBytesWithExifId : remaining;
app1Length = bytesToWrite + 2 + exifMarkerLength; app1Length = bytesToWrite + 2 + exifMarkerLength;
this.WriteApp1Header(app1Length); this.WriteApp1Header(app1Length);
@ -293,7 +293,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </exception> /// </exception>
private void WriteIptcProfile(IptcProfile iptcProfile) private void WriteIptcProfile(IptcProfile iptcProfile)
{ {
const int Max = 65533; const int maxBytes = 65533;
if (iptcProfile is null || !iptcProfile.Values.Any()) if (iptcProfile is null || !iptcProfile.Values.Any())
{ {
return; return;
@ -306,9 +306,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
if (data.Length > Max) if (data.Length > maxBytes)
{ {
throw new ImageFormatException($"Iptc profile size exceeds limit of {Max} bytes"); throw new ImageFormatException($"Iptc profile size exceeds limit of {maxBytes} bytes");
} }
int app13Length = 2 + Components.Decoder.ProfileResolver.AdobePhotoshopApp13Marker.Length + int app13Length = 2 + Components.Decoder.ProfileResolver.AdobePhotoshopApp13Marker.Length +
@ -340,9 +340,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
const int XmpOverheadLength = 29; const int xmpOverheadLength = 29;
const int Max = 65533; const int maxBytes = 65533;
const int MaxData = Max - XmpOverheadLength; const int maxData = maxBytes - xmpOverheadLength;
byte[] data = xmpProfile.Data; byte[] data = xmpProfile.Data;
@ -358,9 +358,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{ {
int length = dataLength; // Number of bytes to write. int length = dataLength; // Number of bytes to write.
if (length > MaxData) if (length > maxData)
{ {
length = MaxData; length = maxData;
} }
dataLength -= length; dataLength -= length;
@ -410,9 +410,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
const int IccOverheadLength = 14; const int iccOverheadLength = 14;
const int Max = 65533; const int maxBytes = 65533;
const int MaxData = Max - IccOverheadLength; const int maxData = maxBytes - iccOverheadLength;
byte[] data = iccProfile.ToByteArray(); byte[] data = iccProfile.ToByteArray();
@ -423,9 +423,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// Calculate the number of markers we'll need, rounding up of course. // Calculate the number of markers we'll need, rounding up of course.
int dataLength = data.Length; int dataLength = data.Length;
int count = dataLength / MaxData; int count = dataLength / maxData;
if (count * MaxData != dataLength) if (count * maxData != dataLength)
{ {
count++; count++;
} }
@ -438,9 +438,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{ {
int length = dataLength; // Number of bytes to write. int length = dataLength; // Number of bytes to write.
if (length > MaxData) if (length > maxData)
{ {
length = MaxData; length = maxData;
} }
dataLength -= length; dataLength -= length;
@ -468,7 +468,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.buffer[12] = (byte)current; // The position within the collection. this.buffer[12] = (byte)current; // The position within the collection.
this.buffer[13] = (byte)count; // The total number of profiles. this.buffer[13] = (byte)count; // The total number of profiles.
this.outputStream.Write(this.buffer, 0, IccOverheadLength); this.outputStream.Write(this.buffer, 0, iccOverheadLength);
this.outputStream.Write(data, offset, length); this.outputStream.Write(data, offset, length);
current++; current++;
@ -712,187 +712,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return frameConfig; return frameConfig;
} }
private static JpegFrameConfig[] CreateFrameConfigs()
{
var defaultLuminanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 0, HuffmanSpec.TheHuffmanSpecs[0]);
var defaultLuminanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 0, HuffmanSpec.TheHuffmanSpecs[1]);
var defaultChrominanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 1, HuffmanSpec.TheHuffmanSpecs[2]);
var defaultChrominanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 1, HuffmanSpec.TheHuffmanSpecs[3]);
var defaultLuminanceQuantTable = new JpegQuantizationTableConfig(0, Quantization.LuminanceTable);
var defaultChrominanceQuantTable = new JpegQuantizationTableConfig(1, Quantization.ChrominanceTable);
var yCbCrHuffmanConfigs = new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC,
defaultChrominanceHuffmanDC,
defaultChrominanceHuffmanAC,
};
var yCbCrQuantTableConfigs = new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable,
defaultChrominanceQuantTable,
};
return new JpegFrameConfig[]
{
// YCbCr 4:4:4
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio444,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:2:2
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio422,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 2, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:2:0
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio420,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 2, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:1:1
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio411,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 4, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// YCbCr 4:1:0
new JpegFrameConfig(
JpegColorSpace.YCbCr,
JpegEncodingColor.YCbCrRatio410,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 4, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
},
yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs),
// Luminance
new JpegFrameConfig(
JpegColorSpace.Grayscale,
JpegEncodingColor.Luminance,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 0, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
}),
// Rgb
new JpegFrameConfig(
JpegColorSpace.RGB,
JpegEncodingColor.Rgb,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 82, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 71, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 66, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformUnknown
},
// Cmyk
new JpegFrameConfig(
JpegColorSpace.Cmyk,
JpegEncodingColor.Cmyk,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformUnknown,
},
// YccK
new JpegFrameConfig(
JpegColorSpace.Ycck,
JpegEncodingColor.Ycck,
new JpegComponentConfig[]
{
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
},
new JpegHuffmanTableConfig[]
{
defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC
},
new JpegQuantizationTableConfig[]
{
defaultLuminanceQuantTable
})
{
AdobeColorTransformMarkerFlag = JpegConstants.Adobe.ColorTransformYcck,
},
};
}
} }
} }

Loading…
Cancel
Save