Browse Source

Added docs

pull/1706/head
Dmitry Pentin 5 years ago
parent
commit
174628306c
  1. 51
      src/ImageSharp/Formats/Jpeg/Components/Quantization.cs

51
src/ImageSharp/Formats/Jpeg/Components/Quantization.cs

@ -13,7 +13,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
internal static class Quantization
{
/// <summary>
/// Threshold at which given luminance quantization table should not be considered 'standard'.
/// Threshold at which given luminance quantization table should be considered 'standard'.
/// Bigger the variance - more likely it to be a non-ITU complient table.
/// </summary>
/// <remarks>
/// Jpeg does not define either 'quality' nor 'standard quantization table' properties
@ -22,7 +23,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
public const double StandardLuminanceTableVarianceThreshold = 10.0;
/// <summary>
/// Threshold at which given luminance quantization table should not be considered 'standard'.
/// Threshold at which given chrominance quantization table should be considered 'standard'.
/// Bigger the variance - more likely it to be a non-ITU complient table.
/// </summary>
/// <remarks>
/// Jpeg does not define either 'quality' nor 'standard quantization table' properties
@ -66,8 +68,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
99, 99, 99, 99, 99, 99, 99, 99,
};
// https://github.com/ImpulseAdventure/JPEGsnoop/blob/9732ee0961f100eb69bbff4a0c47438d5997abee/source/JfifDecode.cpp#L4570-L4694
public static void EstimateQuality(ref Block8x8F table, ReadOnlySpan<byte> target, out double quality, out double variance)
/// Ported from JPEGsnoop:
/// https://github.com/ImpulseAdventure/JPEGsnoop/blob/9732ee0961f100eb69bbff4a0c47438d5997abee/source/JfifDecode.cpp#L4570-L4694
/// <summary>
/// Estimates jpeg quality based on quantization table.
/// </summary>
/// <remarks>
/// This technically can be used with any given table but internal decoder code uses ITU spec tables:
/// <see cref="UnscaledQuant_Luminance"/> and <see cref="UnscaledQuant_Chrominance"/>.
/// </remarks>
/// <param name="table">Input quantization table.</param>
/// <param name="target">Quantization to estimate against.</param>
/// <param name="varianceThreshold">Variance threshold after which given table is considered non-complient.</param>
/// <param name="quality">Estimated quality</param>
/// <returns><see cref="bool"/> indicating if given table is target-complient</returns>
private static bool EstimateQuality(ref Block8x8F table, ReadOnlySpan<byte> target, double varianceThreshold, out double quality)
{
// This method can be SIMD'ified if standard table is injected as Block8x8F.
// Or when we go to full-int16 spectral code implementation and inject both tables as Block8x8.
@ -80,10 +95,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
if (table.EqualsToScalar(1))
{
// While this is a 100% to be 100 quality, any given table can be scaled to all 1's.
// According to jpeg creators, top of the line quality is 99, 100 is just a technical 'limit'.
// According to jpeg creators, top of the line quality is 99, 100 is just a technical 'limit' will affect result filesize drastically.
// Quality=100 shouldn't be used in usual use case.
quality = 100;
variance = 0;
return;
return true;
}
for (int i = 0; i < Block8x8F.Size; i++)
@ -115,7 +130,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
// If the variance is high, it is unlikely to be the case.
sumPercent /= 64.0;
sumPercentSqr /= 64.0;
variance = sumPercentSqr - (sumPercent * sumPercent);
double variance = sumPercentSqr - (sumPercent * sumPercent);
// Generate the equivalent IJQ "quality" factor
if (sumPercent <= 100.0)
@ -126,6 +141,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
quality = 5000.0 / sumPercent;
}
return variance <= varianceThreshold;
}
/// <summary>
/// Estimates jpeg luminance quality.
/// </summary>
/// <param name="luminanceTable">Luminance quantization table.</param>
/// <param name="quality">Output jpeg quality.</param>
/// <returns><see cref="bool"/> indicating if given table is ITU-complient.</returns>
public static bool EstimateLuminanceQuality(ref Block8x8F luminanceTable, out double quality)
=> EstimateQuality(ref luminanceTable, UnscaledQuant_Luminance, StandardLuminanceTableVarianceThreshold, out quality);
/// <summary>
/// Estimates jpeg chrominance quality.
/// </summary>
/// <param name="chrominanceTable">Chrominance quantization table.</param>
/// <param name="quality">Output jpeg quality.</param>
/// <returns><see cref="bool"/> indicating if given table is ITU-complient.</returns>
public static bool EstimateChrominanceQuality(ref Block8x8F chrominanceTable, out double quality)
=> EstimateQuality(ref chrominanceTable, UnscaledQuant_Chrominance, StandardChrominanceTableVarianceThreshold, out quality);
}
}

Loading…
Cancel
Save