/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
/// Under the MIT License, details: License.txt.
using System;
namespace FluxJpeg.Core
{
internal class JpegQuantizationTable
{
// The table entries, stored in natural order.
private int[] table; public int[] Table { get { return table; } }
///
/// The standard JPEG luminance quantization table. Values are
/// stored in natural order.
///
public static JpegQuantizationTable K1Luminance = new JpegQuantizationTable(new int[]
{
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
}, false);
///
/// The standard JPEG luminance quantization table, scaled by
/// one-half. Values are stored in natural order.
///
public static JpegQuantizationTable K1Div2Luminance =
K1Luminance.getScaledInstance(0.5f, true);
///
/// The standard JPEG chrominance quantization table. Values are
/// stored in natural order.
///
public static JpegQuantizationTable K2Chrominance = new JpegQuantizationTable(new int[]
{
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
}, false);
///
/// The standard JPEG chrominance quantization table, scaled by
/// one-half. Values are stored in natural order.
///
public static JpegQuantizationTable K2Div2Chrominance =
K2Chrominance.getScaledInstance(0.5f, true);
///
/// Construct a new JPEG quantization table. A copy is created of
/// the table argument.
///
/// The 64-element value table, stored in natural order
public JpegQuantizationTable(int[] table)
: this(checkTable(table), true)
{
}
///
/// Private constructor that avoids unnecessary copying and argument
/// checking.
///
/// the 64-element value table, stored in natural order
/// true if a copy should be created of the given table
private JpegQuantizationTable(int[] table, bool copy)
{
this.table = copy ? (int[])table.Clone() : table;
}
private static int[] checkTable(int[] table)
{
if (table == null || table.Length != 64)
throw new ArgumentException("Invalid JPEG quantization table");
return table;
}
///
/// Retrieve a copy of this JPEG quantization table with every value
/// scaled by the given scale factor, and clamped from 1 to 255
///
/// the factor by which to scale this table
/// clamp scaled values to a maximum of 255 if baseline or from 1 to 32767 otherwise.
/// new scaled JPEG quantization table
public JpegQuantizationTable getScaledInstance(float scaleFactor,
bool forceBaseline)
{
int[] scaledTable = (int[])table.Clone();
int max = forceBaseline ? 255 : 32767;
for (int i = 0; i < scaledTable.Length; i++)
{
scaledTable[i] = (int)Math.Round(scaleFactor * (float)scaledTable[i]);
if (scaledTable[i] < 1)
scaledTable[i] = 1;
else if (scaledTable[i] > max)
scaledTable[i] = max;
}
return new JpegQuantizationTable(scaledTable, false);
}
}
}