diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index b58e99a10..cf21dd226 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -835,7 +835,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// so we save it in the metadata
if (!Quantization.EstimateLuminanceQuality(ref table, out int quality))
{
- jpegMetadata.LumaQuantizationTable = table.RoundAsInt16Block();
+ jpegMetadata.LuminanceQuantizationTable = table;
}
jpegMetadata.LuminanceQuality = quality;
@@ -850,7 +850,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// so we save it in the metadata
if (!Quantization.EstimateChrominanceQuality(ref table, out int quality))
{
- jpegMetadata.ChromaQuantizationTable = table.RoundAsInt16Block();
+ jpegMetadata.ChromaQuantizationTable = table;
}
jpegMetadata.ChrominanceQuality = quality;
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
index 593937b92..fea24111c 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
@@ -646,34 +646,66 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
/// Initializes quntization tables.
///
+ ///
+ /// We take quality values in a hierarchical order:
+ /// 1. Check if encoder has set quality
+ /// 2. Check if metadata has special table for encoding
+ /// 3. Check if metadata has set quality
+ /// 4. Take default quality value - 75
+ ///
/// Color components count.
/// Jpeg metadata instance.
/// Output luminance quantization table.
/// Output chrominance quantization table.
private void InitQuantizationTables(int componentCount, JpegMetadata metadata, out Block8x8F luminanceQuantTable, out Block8x8F chrominanceQuantTable)
{
- // We take quality values in a hierarchical order:
- // 1. Check if encoder has set quality
- // 2. Check if metadata has special table for encoding
- // 3. Check if metadata has set quality
- // 4. Take default quality value - 75
- int lumaQuality = Numerics.Clamp(
- this.luminanceQuality ?? metadata.LuminanceQuality ?? DefaultQualityValue,
- min: 1,
- max: 100);
-
- luminanceQuantTable = Quantization.ScaleLuminanceTable(lumaQuality);
+ // encoder quality
+ if (this.luminanceQuality.HasValue)
+ {
+ int lumaQuality = Numerics.Clamp(this.luminanceQuality.Value, 1, 100);
+ luminanceQuantTable = Quantization.ScaleLuminanceTable(lumaQuality);
+ }
+
+ // non-standard table
+ else if (metadata.LuminanceQuantizationTable.HasValue)
+ {
+ luminanceQuantTable = metadata.LuminanceQuantizationTable.Value;
+ }
+
+ // metadata or default quality
+ else
+ {
+ int lumaQuality = Numerics.Clamp(metadata.LuminanceQuality ?? DefaultQualityValue, 1, 100);
+ luminanceQuantTable = Quantization.ScaleLuminanceTable(lumaQuality);
+ }
+
chrominanceQuantTable = default;
if (componentCount > 1)
{
- int chromaQuality = Numerics.Clamp(
- this.chrominanceQuality ?? metadata.ChrominanceQuality ?? DefaultQualityValue,
- min: 1,
- max: 100);
+ int chromaQuality;
- this.subsample ??= chromaQuality >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420;
+ // encoder quality
+ if (this.chrominanceQuality.HasValue)
+ {
+ chromaQuality = Numerics.Clamp(this.chrominanceQuality.Value, 1, 100);
+ chrominanceQuantTable = Quantization.ScaleLuminanceTable(chromaQuality);
+ }
+
+ // non-standard table
+ else if (metadata.ChromaQuantizationTable.HasValue)
+ {
+ chromaQuality = metadata.ChrominanceQuality.Value;
+ chrominanceQuantTable = metadata.ChromaQuantizationTable.Value;
+ }
+
+ // metadata or default quality
+ else
+ {
+ chromaQuality = Numerics.Clamp(metadata.ChrominanceQuality ?? DefaultQualityValue, 1, 100);
+ chrominanceQuantTable = Quantization.ScaleChrominanceTable(chromaQuality);
+ }
- chrominanceQuantTable = Quantization.ScaleChrominanceTable(chromaQuality);
+ this.subsample = chromaQuality >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420;
}
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs b/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs
index 8b3332ef8..4a58c6946 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs
@@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
this.ColorType = other.ColorType;
- this.LumaQuantizationTable = other.LumaQuantizationTable;
+ this.LuminanceQuantizationTable = other.LuminanceQuantizationTable;
this.ChromaQuantizationTable = other.ChromaQuantizationTable;
this.LuminanceQuality = other.LuminanceQuality;
this.ChrominanceQuality = other.ChrominanceQuality;
@@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
/// Would be null if jpeg was encoded using table from ITU spec
///
- internal Block8x8? LumaQuantizationTable { get; set; }
+ internal Block8x8F? LuminanceQuantizationTable { get; set; }
///
/// Gets or sets chrominance qunatization table derived from jpeg image.
@@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
/// Would be null if jpeg was encoded using table from ITU spec
///
- internal Block8x8? ChromaQuantizationTable { get; set; }
+ internal Block8x8F? ChromaQuantizationTable { get; set; }
///
/// Gets or sets the jpeg luminance quality.
@@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
/// Gets a value indicating whether jpeg luminance data was encoded using ITU complient quantization table.
///
- public bool UsesStandardLuminanceTable => !this.LumaQuantizationTable.HasValue;
+ public bool UsesStandardLuminanceTable => !this.LuminanceQuantizationTable.HasValue;
///
/// Gets a value indicating whether jpeg luminance data was encoded using ITU complient quantization table.