153 lines
5.3 KiB
C
153 lines
5.3 KiB
C
|
/* PIKA - Photo and Image Kooker Application
|
||
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||
|
*
|
||
|
* Original copyright, applying to most contents (license remains unchanged):
|
||
|
* 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.
|
||
|
*
|
||
|
* Returns: 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;
|
||
|
}
|
||
|
}
|