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