summaryrefslogtreecommitdiffstats
path: root/plug-ins/file-jpeg/jpeg-quality.c
diff options
context:
space:
mode:
Diffstat (limited to 'plug-ins/file-jpeg/jpeg-quality.c')
-rw-r--r--plug-ins/file-jpeg/jpeg-quality.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/plug-ins/file-jpeg/jpeg-quality.c b/plug-ins/file-jpeg/jpeg-quality.c
new file mode 100644
index 0000000..52bd2c7
--- /dev/null
+++ b/plug-ins/file-jpeg/jpeg-quality.c
@@ -0,0 +1,148 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * jpeg-quality.c
+ * Copyright (C) 2007 Raphaƫl Quinet <raphael@gimp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <glib/gstdio.h>
+
+#include <jpeglib.h>
+
+#include "jpeg-quality.h"
+
+/*
+ * Note that although 0 is a valid quality for IJG's JPEG library, the
+ * baseline quantization tables for quality 0 and 1 are identical (all
+ * divisors are set to the maximum value 255). So 0 can be used here
+ * to flag unusual settings.
+ */
+
+/* sum of the luminance divisors for quality = 0..100 (IJG standard tables) */
+static gint std_luminance_sum[101] =
+{
+ G_MAXINT,
+ 16320, 16315, 15946, 15277, 14655, 14073, 13623, 13230, 12859, 12560, 12240,
+ 11861, 11456, 11081, 10714, 10360, 10027, 9679, 9368, 9056, 8680, 8331,
+ 7995, 7668, 7376, 7084, 6823, 6562, 6345, 6125, 5939, 5756, 5571,
+ 5421, 5240, 5086, 4976, 4829, 4719, 4616, 4463, 4393, 4280, 4166,
+ 4092, 3980, 3909, 3835, 3755, 3688, 3621, 3541, 3467, 3396, 3323,
+ 3247, 3170, 3096, 3021, 2952, 2874, 2804, 2727, 2657, 2583, 2509,
+ 2437, 2362, 2290, 2211, 2136, 2068, 1996, 1915, 1858, 1773, 1692,
+ 1620, 1552, 1477, 1398, 1326, 1251, 1179, 1109, 1031, 961, 884,
+ 814, 736, 667, 592, 518, 441, 369, 292, 221, 151, 86,
+ 64
+};
+
+/* sum of the chrominance divisors for quality = 0..100 (IJG standard tables) */
+static gint std_chrominance_sum[101] =
+{
+ G_MAXINT,
+ 16320, 16320, 16320, 16218, 16010, 15731, 15523, 15369, 15245, 15110, 14985,
+ 14864, 14754, 14635, 14526, 14429, 14346, 14267, 14204, 13790, 13121, 12511,
+ 11954, 11453, 11010, 10567, 10175, 9787, 9455, 9122, 8844, 8565, 8288,
+ 8114, 7841, 7616, 7447, 7227, 7060, 6897, 6672, 6562, 6396, 6226,
+ 6116, 5948, 5838, 5729, 5614, 5505, 5396, 5281, 5172, 5062, 4947,
+ 4837, 4726, 4614, 4506, 4395, 4282, 4173, 4061, 3950, 3839, 3727,
+ 3617, 3505, 3394, 3284, 3169, 3060, 2949, 2836, 2780, 2669, 2556,
+ 2445, 2336, 2221, 2111, 2000, 1888, 1778, 1666, 1555, 1444, 1332,
+ 1223, 1110, 999, 891, 779, 668, 558, 443, 333, 224, 115,
+ 64
+};
+
+/**
+ * jpeg_detect_quality:
+ * @cinfo: a pointer to a JPEG decompressor info.
+ *
+ * Returns the exact or estimated quality value that was used to save
+ * the JPEG image by analyzing the quantization table divisors.
+ *
+ * If an exact match for the IJG quantization tables is found, then a
+ * quality setting in the range 1..100 is returned. If the quality
+ * can only be estimated, then a negative number in the range -1..-100
+ * is returned; its absolute value represents the maximum IJG quality
+ * setting to use. If the quality cannot be reliably determined, then
+ * 0 is returned.
+ *
+ * This function must be called after jpeg_read_header() so that
+ * @cinfo contains the quantization tables read from the DQT markers
+ * in the file.
+ *
+ * Return Value: the JPEG quality setting in the range 1..100, -1..-100 or 0.
+ */
+gint
+jpeg_detect_quality (struct jpeg_decompress_struct *cinfo)
+{
+ gint t;
+ gint i;
+ gint sum[3];
+ gint q;
+
+ /* files using CMYK or having 4 quantization tables are unusual */
+ if (!cinfo || cinfo->output_components > 3 || cinfo->quant_tbl_ptrs[3])
+ return 0;
+
+ /* Most files use table 0 for luminance divisors (Y) and table 1 for
+ * chrominance divisors (Cb and Cr). Some files use separate tables
+ * for Cb and Cr, so table 2 may also be used.
+ */
+ for (t = 0; t < 3; t++)
+ {
+ sum[t] = 0;
+ if (cinfo->quant_tbl_ptrs[t])
+ for (i = 0; i < DCTSIZE2; i++)
+ sum[t] += cinfo->quant_tbl_ptrs[t]->quantval[i];
+ }
+
+ if (cinfo->output_components > 1)
+ {
+ gint sums;
+
+ if (sum[0] < 64 || sum[1] < 64)
+ return 0;
+
+ /* compare with the chrominance table having the lowest sum */
+ if (sum[1] < sum[2] || sum[2] <= 0)
+ sums = sum[0] + sum[1];
+ else
+ sums = sum[0] + sum[2];
+
+ q = 100;
+ while (sums > std_luminance_sum[q] + std_chrominance_sum[q])
+ q--;
+
+ if (sum[0] == std_luminance_sum[q] && sum[1] == std_chrominance_sum[q])
+ return q;
+ else
+ return -q;
+ }
+ else
+ {
+ if (sum[0] < 64)
+ return 0;
+
+ q = 100;
+ while (sum[0] > std_luminance_sum[q])
+ q--;
+
+ if (sum[0] == std_luminance_sum[q])
+ return q;
+ else
+ return -q;
+ }
+}