/// 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); } } }