~ubuntu-branches/ubuntu/gutsy/gimp/gutsy

« back to all changes in this revision

Viewing changes to plug-ins/jpeg/jpegqual.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-30 18:06:49 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20070930180649-f647f0cxj32tgyn3
Tags: 2.4.0~rc3-1ubuntu1
* Resynchronized with Debian.
* Remaining Ubuntu changes:
  - 02_help-message.patch, 03_gimp.desktop.in.in.patch: Distro changes.
  - Weave i18n magic in the rules file.
  - Munge Maintainer field as per spec.
* Ubuntu changes dropped:
  - 10_dont_show_wizard.patch: Unused, upstream doesn't call it anymore.
  - Use dh_icons.
* Disabled the print plugin, and removed the Conflicts/Replaces on
  gimp-print.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * This program analyzes the quantization tables of the JPEG files
22
22
 * given on the command line and displays their quality settings.
23
23
 *
24
 
 * It can be used to validate the formula used in jpeg_detect_quality(),
25
 
 * by comparing the quality reported for different JPEG files.
 
24
 * It is useful for developers or maintainers of the JPEG plug-in
 
25
 * because it can be used to validate the formula used in
 
26
 * jpeg_detect_quality(), by comparing the quality reported for
 
27
 * different JPEG files.
26
28
 *
27
29
 * It can also dump quantization tables so that they can be integrated
28
30
 * into this program and recognized later.  This can be used to identify
33
35
 * TODO:
34
36
 * - rename this program!
35
37
 * - update quant_info[].
36
 
 * - get rid of the command-line option '--name' (too cumbersome to use).
37
 
 * - rewrite the parser for command-line options and use GOption instead.
38
38
 * - reorganize the options: 2 groups for print options and for selection.
39
39
 * - re-add the code to compare different formulas for approx. IJG quality.
40
40
 */
41
41
 
42
42
#include <stdio.h>
43
43
#include <string.h>
 
44
#include <setjmp.h>
44
45
#include <glib.h>
45
46
 
46
47
#include <jpeglib.h>
 
48
#include <jerror.h>
47
49
 
48
50
#include "jpeg-quality.h"
49
51
 
50
52
/* command-line options */
51
 
typedef struct
52
 
{
53
 
  const gchar *option;
54
 
  const gchar *description;
55
 
} OptionDesc;
56
 
 
57
 
static const OptionDesc options_desc[] =
58
 
  {
59
 
    { "-h, --help",
60
 
      "Display this help message" },
61
 
    { "-s, --summary",
62
 
      "Print summary information and IJG quality (enabled by default)" },
63
 
    { "-t, --tables",
64
 
      "Dump quantization tables" },
65
 
    { "-c, --c-tables",
66
 
      "Dump quantization tables as C code" },
67
 
    { "-n, --name <name>",
68
 
      "Camera or software name (used when printing tables)" },
69
 
    { "-u, --unknown",
70
 
      "Only print information about files with unknown tables" },
71
 
    { NULL, NULL }
72
 
  };
73
 
 
74
 
static gboolean  option_summary      = TRUE;
75
 
static gboolean  option_ctable       = FALSE;
76
 
static gboolean  option_table_2cols  = FALSE;
77
 
static gchar    *option_name         = NULL;
78
 
static gboolean  option_unknown      = FALSE;
79
 
#if 0 /* FIXME */
 
53
static gboolean      option_summary      = FALSE;
 
54
static gboolean      option_ctable       = FALSE;
 
55
static gboolean      option_table_2cols  = FALSE;
 
56
static gboolean      option_unknown      = FALSE;
 
57
static gboolean      option_ignore_err   = FALSE;
 
58
 
 
59
static GOptionEntry  option_entries[] =
 
60
{
 
61
  { "ignore-errors", 'i', 0, G_OPTION_ARG_NONE, &option_ignore_err,
 
62
    "Continue processing other files after a JPEG error", NULL },
 
63
  { "summary",  's', 0, G_OPTION_ARG_NONE, &option_summary,
 
64
    "Print summary information and closest IJG quality", NULL },
 
65
  { "tables",   't', 0, G_OPTION_ARG_NONE, &option_table_2cols,
 
66
    "Dump quantization tables", NULL },
 
67
  { "c-tables", 'c', 0, G_OPTION_ARG_NONE, &option_ctable,
 
68
    "Dump quantization tables as C code", NULL },
 
69
  { "ctables",  0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &option_ctable,
 
70
    NULL, NULL },
 
71
  { "unknown",  'u', 0, G_OPTION_ARG_NONE, &option_unknown,
 
72
    "Only print information about files with unknown tables", NULL },
 
73
  { NULL }
 
74
};
 
75
 
 
76
/* information about known JPEG quantization tables */
 
77
typedef struct
 
78
{
 
79
  /* const guint  hash; */        /* hash of luminance/chrominance tables */
 
80
  const gint   lum_sum;           /* sum of luminance table divisors */
 
81
  const gint   chrom_sum;         /* sum of chrominance table divisors */
 
82
  const gint   subsmp_h;          /* horizontal subsampling (1st component) */
 
83
  const gint   subsmp_v;          /* vertical subsampling (1st component) */
 
84
  const gint   num_quant_tables;  /* number of tables (< 0 if no grayscale) */
 
85
  const gchar *source_name;       /* name of software of device */
 
86
  const gchar *setting_name;      /* name of quality setting */
 
87
  const gint   ijg_qual;          /* closest IJG quality setting */
 
88
} QuantInfo;
 
89
 
 
90
static const QuantInfo quant_info[] =
 
91
{
 
92
  {    64,    64, 0, 0,  2, "IJG JPEG Library", "quality 100", 100 },
 
93
  {    86,   115, 0, 0,  2, "IJG JPEG Library", "quality 99", 99 },
 
94
  {   151,   224, 0, 0,  2, "IJG JPEG Library", "quality 98", 98 },
 
95
  {   221,   333, 0, 0,  2, "IJG JPEG Library", "quality 97", 97 },
 
96
  {   292,   443, 0, 0,  2, "IJG JPEG Library", "quality 96", 96 },
 
97
  {   369,   558, 0, 0,  2, "IJG JPEG Library", "quality 95", 95 },
 
98
  {   441,   668, 0, 0,  2, "IJG JPEG Library", "quality 94", 94 },
 
99
  {   518,   779, 0, 0,  2, "IJG JPEG Library", "quality 93", 93 },
 
100
  {   592,   891, 0, 0,  2, "IJG JPEG Library", "quality 92", 92 },
 
101
  {   667,   999, 0, 0,  2, "IJG JPEG Library", "quality 91", 91 },
 
102
  {   736,  1110, 0, 0,  2, "IJG JPEG Library", "quality 90", 90 },
 
103
  {   814,  1223, 0, 0,  2, "IJG JPEG Library", "quality 89", 89 },
 
104
  {   884,  1332, 0, 0,  2, "IJG JPEG Library", "quality 88", 88 },
 
105
  {   961,  1444, 0, 0,  2, "IJG JPEG Library", "quality 87", 87 },
 
106
  {  1031,  1555, 0, 0,  2, "IJG JPEG Library", "quality 86", 86 },
 
107
  {  1109,  1666, 0, 0,  2, "IJG JPEG Library", "quality 85", 85 },
 
108
  {  1179,  1778, 0, 0,  2, "IJG JPEG Library", "quality 84", 84 },
 
109
  {  1251,  1888, 0, 0,  2, "IJG JPEG Library", "quality 83", 83 },
 
110
  {  1326,  2000, 0, 0,  2, "IJG JPEG Library", "quality 82", 82 },
 
111
  {  1398,  2111, 0, 0,  2, "IJG JPEG Library", "quality 81", 81 },
 
112
  {  1477,  2221, 0, 0,  2, "IJG JPEG Library", "quality 80", 80 },
 
113
  {  1552,  2336, 0, 0,  2, "IJG JPEG Library", "quality 79", 79 },
 
114
  {  1620,  2445, 0, 0,  2, "IJG JPEG Library", "quality 78", 78 },
 
115
  {  1692,  2556, 0, 0,  2, "IJG JPEG Library", "quality 77", 77 },
 
116
  {  1773,  2669, 0, 0,  2, "IJG JPEG Library", "quality 76", 76 },
 
117
  {  1858,  2780, 0, 0,  2, "IJG JPEG Library", "quality 75", 75 },
 
118
  {  1915,  2836, 0, 0,  2, "IJG JPEG Library", "quality 74", 74 },
 
119
  {  1996,  2949, 0, 0,  2, "IJG JPEG Library", "quality 73", 73 },
 
120
  {  2068,  3060, 0, 0,  2, "IJG JPEG Library", "quality 72", 72 },
 
121
  {  2136,  3169, 0, 0,  2, "IJG JPEG Library", "quality 71", 71 },
 
122
  {  2211,  3284, 0, 0,  2, "IJG JPEG Library", "quality 70", 70 },
 
123
  {  2290,  3394, 0, 0,  2, "IJG JPEG Library", "quality 69", 69 },
 
124
  {  2362,  3505, 0, 0,  2, "IJG JPEG Library", "quality 68", 68 },
 
125
  {  2437,  3617, 0, 0,  2, "IJG JPEG Library", "quality 67", 67 },
 
126
  {  2509,  3727, 0, 0,  2, "IJG JPEG Library", "quality 66", 66 },
 
127
  {  2583,  3839, 0, 0,  2, "IJG JPEG Library", "quality 65", 65 },
 
128
  {  2657,  3950, 0, 0,  2, "IJG JPEG Library", "quality 64", 64 },
 
129
  {  2727,  4061, 0, 0,  2, "IJG JPEG Library", "quality 63", 63 },
 
130
  {  2804,  4173, 0, 0,  2, "IJG JPEG Library", "quality 62", 62 },
 
131
  {  2874,  4282, 0, 0,  2, "IJG JPEG Library", "quality 61", 61 },
 
132
  {  2952,  4395, 0, 0,  2, "IJG JPEG Library", "quality 60", 60 },
 
133
  {  3021,  4506, 0, 0,  2, "IJG JPEG Library", "quality 59", 59 },
 
134
  {  3096,  4614, 0, 0,  2, "IJG JPEG Library", "quality 58", 58 },
 
135
  {  3170,  4726, 0, 0,  2, "IJG JPEG Library", "quality 57", 57 },
 
136
  {  3247,  4837, 0, 0,  2, "IJG JPEG Library", "quality 56", 56 },
 
137
  {  3323,  4947, 0, 0,  2, "IJG JPEG Library", "quality 55", 55 },
 
138
  {  3396,  5062, 0, 0,  2, "IJG JPEG Library", "quality 54", 54 },
 
139
  {  3467,  5172, 0, 0,  2, "IJG JPEG Library", "quality 53", 53 },
 
140
  {  3541,  5281, 0, 0,  2, "IJG JPEG Library", "quality 52", 52 },
 
141
  {  3621,  5396, 0, 0,  2, "IJG JPEG Library", "quality 51", 51 },
 
142
  {  3688,  5505, 0, 0,  2, "IJG JPEG Library", "quality 50", 50 },
 
143
  {  3755,  5614, 0, 0,  2, "IJG JPEG Library", "quality 49", 49 },
 
144
  {  3835,  5729, 0, 0,  2, "IJG JPEG Library", "quality 48", 48 },
 
145
  {  3909,  5838, 0, 0,  2, "IJG JPEG Library", "quality 47", 47 },
 
146
  {  3980,  5948, 0, 0,  2, "IJG JPEG Library", "quality 46", 46 },
 
147
  {  4092,  6116, 0, 0,  2, "IJG JPEG Library", "quality 45", 45 },
 
148
  {  4166,  6226, 0, 0,  2, "IJG JPEG Library", "quality 44", 44 },
 
149
  {  4280,  6396, 0, 0,  2, "IJG JPEG Library", "quality 43", 43 },
 
150
  {  4393,  6562, 0, 0,  2, "IJG JPEG Library", "quality 42", 42 },
 
151
  {  4463,  6672, 0, 0,  2, "IJG JPEG Library", "quality 41", 41 },
 
152
  {  4616,  6897, 0, 0,  2, "IJG JPEG Library", "quality 40", 40 },
 
153
  {  4719,  7060, 0, 0,  2, "IJG JPEG Library", "quality 39", 39 },
 
154
  {  4829,  7227, 0, 0,  2, "IJG JPEG Library", "quality 38", 38 },
 
155
  {  4976,  7447, 0, 0,  2, "IJG JPEG Library", "quality 37", 37 },
 
156
  {  5086,  7616, 0, 0,  2, "IJG JPEG Library", "quality 36", 36 },
 
157
  {  5240,  7841, 0, 0,  2, "IJG JPEG Library", "quality 35", 35 },
 
158
  {  5421,  8114, 0, 0,  2, "IJG JPEG Library", "quality 34", 34 },
 
159
  {  5571,  8288, 0, 0,  2, "IJG JPEG Library", "quality 33", 33 },
 
160
  {  5756,  8565, 0, 0,  2, "IJG JPEG Library", "quality 32", 32 },
 
161
  {  5939,  8844, 0, 0,  2, "IJG JPEG Library", "quality 31", 31 },
 
162
  {  6125,  9122, 0, 0,  2, "IJG JPEG Library", "quality 30", 30 },
 
163
  {  6345,  9455, 0, 0,  2, "IJG JPEG Library", "quality 29", 29 },
 
164
  {  6562,  9787, 0, 0,  2, "IJG JPEG Library", "quality 28", 28 },
 
165
  {  6823, 10175, 0, 0,  2, "IJG JPEG Library", "quality 27", 27 },
 
166
  {  7084, 10567, 0, 0,  2, "IJG JPEG Library", "quality 26", 26 },
 
167
  {  7376, 11010, 0, 0,  2, "IJG JPEG Library", "quality 25", 25 },
 
168
  {  7668, 11453, 0, 0,  2, "IJG JPEG Library", "quality 24", 24 },
 
169
  {  7995, 11954, 0, 0,  2, "IJG JPEG Library", "quality 23", 23 },
 
170
  {  8331, 12511, 0, 0,  2, "IJG JPEG Library", "quality 22", 22 },
 
171
  {  8680, 13121, 0, 0,  2, "IJG JPEG Library", "quality 21", 21 },
 
172
  {  9056, 13790, 0, 0,  2, "IJG JPEG Library", "quality 20", 20 },
 
173
  {  9368, 14204, 0, 0,  2, "IJG JPEG Library", "quality 19", 19 },
 
174
  {  9679, 14267, 0, 0,  2, "IJG JPEG Library", "quality 18", 18 },
 
175
  { 10027, 14346, 0, 0,  2, "IJG JPEG Library", "quality 17", 17 },
 
176
  { 10360, 14429, 0, 0,  2, "IJG JPEG Library", "quality 16", 16 },
 
177
  { 10714, 14526, 0, 0,  2, "IJG JPEG Library", "quality 15", 15 },
 
178
  { 11081, 14635, 0, 0,  2, "IJG JPEG Library", "quality 14", 14 },
 
179
  { 11456, 14754, 0, 0,  2, "IJG JPEG Library", "quality 13", 13 },
 
180
  { 11861, 14864, 0, 0,  2, "IJG JPEG Library", "quality 12", 12 },
 
181
  { 12240, 14985, 0, 0,  2, "IJG JPEG Library", "quality 11", 11 },
 
182
  { 12560, 15110, 0, 0,  2, "IJG JPEG Library", "quality 10", 10 },
 
183
  { 12859, 15245, 0, 0,  2, "IJG JPEG Library", "quality 9", 9 },
 
184
  { 13230, 15369, 0, 0,  2, "IJG JPEG Library", "quality 8", 8 },
 
185
  { 13623, 15523, 0, 0,  2, "IJG JPEG Library", "quality 7", 7 },
 
186
  { 14073, 15731, 0, 0,  2, "IJG JPEG Library", "quality 6", 6 },
 
187
  { 14655, 16010, 0, 0,  2, "IJG JPEG Library", "quality 5", 5 },
 
188
  { 15277, 16218, 0, 0,  2, "IJG JPEG Library", "quality 4", 4 },
 
189
  { 15946, 16320, 0, 0,  2, "IJG JPEG Library", "quality 3", 3 },
 
190
  { 16315, 16320, 0, 0,  2, "IJG JPEG Library", "quality 2", 2 },
 
191
  { 16320, 16320, 0, 0,  2, "IJG JPEG Library", "quality 1", 1 },
 
192
  { 16320, 16320, 0, 0,  2, "IJG JPEG Library", "quality 0", 1 },
 
193
  {  8008, 11954, 0, 0,  2, "IJG JPEG Library", "not baseline 23", -22 },
 
194
  {  8370, 12511, 0, 0,  2, "IJG JPEG Library", "not baseline 22", -21 },
 
195
  {  8774, 13121, 0, 0,  2, "IJG JPEG Library", "not baseline 21", -20 },
 
196
  {  9234, 13790, 0, 0,  2, "IJG JPEG Library", "not baseline 20", -19 },
 
197
  {  9700, 14459, 0, 0,  2, "IJG JPEG Library", "not baseline 19", -17 },
 
198
  { 10209, 15236, 0, 0,  2, "IJG JPEG Library", "not baseline 18", -14 },
 
199
  { 10843, 16182, 0, 0,  2, "IJG JPEG Library", "not baseline 17", -11 },
 
200
  { 11505, 17183, 0, 0,  2, "IJG JPEG Library", "not baseline 16", -7 },
 
201
  { 12279, 18351, 0, 0,  2, "IJG JPEG Library", "not baseline 15", -5 },
 
202
  { 13166, 19633, 0, 0,  2, "IJG JPEG Library", "not baseline 14", 0 },
 
203
  { 14160, 21129, 0, 0,  2, "IJG JPEG Library", "not baseline 13", 0 },
 
204
  { 15344, 22911, 0, 0,  2, "IJG JPEG Library", "not baseline 12", 0 },
 
205
  { 16748, 24969, 0, 0,  2, "IJG JPEG Library", "not baseline 11", 0 },
 
206
  { 18440, 27525, 0, 0,  2, "IJG JPEG Library", "not baseline 10", 0 },
 
207
  { 20471, 30529, 0, 0,  2, "IJG JPEG Library", "not baseline 9", 0 },
 
208
  { 23056, 34422, 0, 0,  2, "IJG JPEG Library", "not baseline 8", 0 },
 
209
  { 26334, 39314, 0, 0,  2, "IJG JPEG Library", "not baseline 7", 0 },
 
210
  { 30719, 45876, 0, 0,  2, "IJG JPEG Library", "not baseline 6", 0 },
 
211
  { 36880, 55050, 0, 0,  2, "IJG JPEG Library", "not baseline 5", 0 },
 
212
  { 46114, 68840, 0, 0,  2, "IJG JPEG Library", "not baseline 4", 0 },
 
213
  { 61445, 91697, 0, 0,  2, "IJG JPEG Library", "not baseline 3", 0 },
 
214
  { 92200, 137625, 0, 0,  2, "IJG JPEG Library", "not baseline 2", 0 },
 
215
  { 184400, 275250, 0, 0,  2, "IJG JPEG Library", "not baseline 1", 0 },
 
216
  { 184400, 275250, 0, 0,  2, "IJG JPEG Library", "not baseline 0", 0 },
 
217
 
 
218
  /* FIXME: the following entries are incomplete and need to be verified */
 
219
 
 
220
  {   319,   665, 2, 1, -2, "ACD ?", "?", -94 },
 
221
  {   436,   996, 2, 1, -2, "ACD ?", "?", -92 },
 
222
  {   664,  1499, 2, 1, -2, "ACD ?", "?", -88 },
 
223
  {  1590,  3556, 2, 2, -2, "ACD ?", "?", -71 },
 
224
  {   109,   171, 1, 1,  2, "Adobe Photoshop CS or CS2", "quality 12", -98 },
 
225
  {   303,   466, 1, 1,  2, "Adobe Photoshop CS or CS2, Camera Raw 3", "quality 11", -95 },
 
226
  {   535,   750, 1, 1,  2, "Adobe Photoshop 7.0 (or CS2)", "quality 10", -93 },
 
227
  {   668,   830, 1, 1,  2, "Adobe Photoshop 7.0, CS, CS2", "quality 9", -91 },
 
228
  {   794,   895, 1, 1,  2, "Adobe Photoshop 7.0, CS, CS2", "quality 8", -90 },
 
229
  {   971,   950, 1, 1,  2, "Adobe Photoshop CS2", "quality 7", -89 },
 
230
  {   884,   831, 2, 2,  2, "Adobe Photoshop CS2", "quality 6", -90 },
 
231
  {  1032,   889, 2, 2,  2, "Adobe Photoshop CS2", "quality 5", -89 },
 
232
  {  1126,   940, 2, 2,  2, "Adobe Photoshop CS2", "quality 4", -88 },
 
233
  {  1216,   977, 2, 2,  2, "Adobe Photoshop CS2", "quality 3", -88 },
 
234
  {  1281,   998, 2, 2,  2, "Adobe Photoshop CS2", "quality 2", -87 },
 
235
  {  1484,  1083, 2, 2,  2, "Adobe Photoshop CS2", "quality 1", -86 },
 
236
  {  1582,  1108, 2, 2,  2, "Adobe Photoshop 7.0, CS, CS2", "quality 0", -85 },
 
237
  {    95,   168, 1, 1,  2, "Adobe Photoshop CS2", "save for web 100", -98 },
 
238
  {   234,   445, 1, 1,  2, "Adobe Photoshop CS2", "save for web 90", -96 },
 
239
  {   406,   724, 1, 1,  2, "Adobe Photoshop CS2", "save for web 80", -93 },
 
240
  {   646,  1149, 1, 1,  2, "Adobe Photoshop CS2", "save for web 70", -90 },
 
241
  {   974,  1769, 1, 1,  2, "Adobe Photoshop CS2", "save for web 60", -85 },
 
242
  {  1221,  1348, 2, 2,  2, "Adobe Photoshop CS2", "save for web 50", -86 },
 
243
  {  1821,  1997, 2, 2,  2, "Adobe Photoshop CS2", "save for web 40", -79 },
 
244
  {  2223,  2464, 2, 2,  2, "Adobe Photoshop CS2", "save for web 30", -74 },
 
245
  {  2575,  2903, 2, 2,  2, "Adobe Photoshop CS2", "save for web 20", -70 },
 
246
  {  3514,  3738, 2, 2,  2, "Adobe Photoshop CS2", "save for web 10", -60 },
 
247
  {    95,   166, 1, 1,  2, "Adobe Photoshop 7.0, CS, CS2 or Lightroom", "quality 12", -98 },
 
248
  {   232,   443, 1, 1,  2, "Adobe Photoshop CS", "quality 11", -96 },
 
249
  {   649,   853, 1, 1,  2, "Adobe Photoshop 7.0, CS, CS2, Elements 4.0", "quality 8", -91 },
 
250
  {   844,   849, 2, 2,  2, "Adobe Photoshop CS", "quality 5", -90 },
 
251
  {   962,   892, 2, 2,  2, "Adobe Photoshop CS", "?", -89 },
 
252
  {   406,   722, 1, 1,  2, "Adobe Photoshop 7.0", "quality 10", -93 },
 
253
  {   539,   801, 1, 1,  2, "Adobe Photoshop 5.0, 7.0", "quality 9", -92 },
 
254
  {   786,   926, 1, 1,  2, "Adobe Photoshop 7.0, CS2", "quality 7", -90 },
 
255
  {   717,   782, 2, 2,  2, "Adobe Photoshop 5.0", "?", -91 },
 
256
  {  1068,   941, 2, 2,  2, "Adobe Photoshop 4.0", "?", -89 },
 
257
  {   339,   670, 1, 1,  2, "Adobe Photoshop ?", "save for web 85", -94 },
 
258
  {   406,   722, 1, 1,  2, "Adobe Photoshop 6.0", "quality 10", -93 },
 
259
  {   427,   613, 2, 2,  2, "Adobe Photoshop ?", "?", -94 },
 
260
  {   525,   941, 1, 1,  2, "Adobe Photoshop ?", "save for web 75", -92 },
 
261
  {   803,  1428, 1, 1,  2, "Adobe Photoshop ?", "save for web 65", -87 },
 
262
  {  1085,  1996, 1, 1,  2, "Adobe Photoshop ?", "save for web 55", -83 },
 
263
  {  1156,  2116, 1, 1,  2, "Adobe Photoshop ?", "save for web 52", -82 },
 
264
  {  1175,  2169, 1, 1,  2, "Adobe Photoshop ?", "save for web 51", -81 },
 
265
  {  2272,  2522, 2, 2,  2, "Adobe Photoshop ?", "save for web 29", -73 },
 
266
  {  4028,  4174, 2, 2,  2, "Adobe Photoshop ?", "save for web 3", -55 },
 
267
  {   513,     0, 1, 1,  1, "Adobe Photoshop ?", "?", -93 },
 
268
  {  2515,  2831, 2, 2,  2, "Adobe ImageReady", "save for web 22", -70 },
 
269
  {  3822,  3975, 2, 2,  2, "Adobe ImageReady", "save for web 6", -57 },
 
270
  {   255,   393, 2, 1,  2, "Apple Quicktime 7.1 or 7.2", "?", -96 },
 
271
  {   513,   775, 2, 2,  2, "Apple Quicktime 7.2", "?", -93 },
 
272
  {   543,   784, 2, 1, -2, "Apple Quicktime 7.1", "?", -92 },
 
273
  {   361,   506, 2, 1,  2, "Apple ?", "?", -95 },
 
274
  {  1511,  2229, 2, 2,  2, "Apple ?", "?", -79 },
 
275
  {   188,   276, 2, 1, -2, "Canon EOS 300D, 350D or 400D", "Fine", -97 },
 
276
  {   708,  1057, 2, 1, -2, "Canon EOS 10D", "Normal", -90 },
 
277
  {   533,  1325, 2, 1, -2, "Canon PowerShot A95, S1, S2, SD400 or SD630", "Fine", -89 },
 
278
  {   192,   556, 2, 1, -2, "Canon PowerShot S5 IS, A300, A430, S200, SD500, SD700, Ixus 700 or 800", "Superfine", -95 },
 
279
  {   533,  1325, 1, 2, -2, "Canon Digital Ixus 400", "Fine", -89 },
 
280
  {   288,   443, 2, 1, -3, "FujiFilm MX-2700", "?", -96 },
 
281
  {   389,   560, 2, 1, -3, "FujiFilm FinePix S700", "Fine", -94 },
 
282
  {   515,   774, 2, 1, -3, "FujiFilm FinePix 2600 Zoom", "Fine", -93 },
 
283
  {   167,   240, 2, 2, -3, "HP PhotoSmart C850, C935", "?", -97 },
 
284
  {   167,   240, 2, 2, -3, "HP PhotoSmart C850, C935", "?", -97 },
 
285
  {  1970,  1970, 2, 2, -3, "HP PhotoSmart C812", "?", -78 },
 
286
  {   369,   558, 2, 1, -3, "Kodak P880", "?", 95 },
 
287
  {   566,   583, 2, 2, -2, "Kodak V610", "Fine", -93 },
 
288
  {   736,  1110, 2, 2, -2, "Kodak DC240", "?", 90 },
 
289
  {   736,  1110, 1, 1, -2, "Kodak Imaging", "High (high res.)", 90 },
 
290
  {   736,  1110, 2, 1, -2, "Kodak Imaging", "High (medium res.)", 90 },
 
291
  {   736,  1110, 4, 1, -2, "Kodak Imaging", "High (low res.)", 90 },
 
292
  {   736,     0, 1, 1,  1, "Kodak Imaging", "High (grayscale)", 90 },
 
293
  {  3688,  5505, 1, 1, -2, "Kodak Imaging", "Medium (high res.)", 50 },
 
294
  {  3688,  5505, 2, 1, -2, "Kodak Imaging", "Medium (medium res.)", 50 },
 
295
  {  3688,  5505, 4, 1, -2, "Kodak Imaging", "Medium (low res.)", 50 },
 
296
  {  3688,     0, 1, 1,  1, "Kodak Imaging", "Medium (grayscale)", 50 },
 
297
  {  9056, 13790, 1, 1, -2, "Kodak Imaging", "Low (high res.)", 20 },
 
298
  {  9056, 13790, 2, 1, -2, "Kodak Imaging", "Low (medium res.)", 20 },
 
299
  {  9056, 13790, 4, 1, -2, "Kodak Imaging", "Low (low res.)", 20 },
 
300
  {  9056,     0, 1, 1,  1, "Kodak Imaging", "Low (grayscale)", 20 },
 
301
  {   161,   179, 1, 1, -2, "Lead ?", "?", -98 },
 
302
  {   711,  1055, 1, 1, -2, "Lead ?", "?", -90 },
 
303
  {  1079,  1610, 1, 1, -2, "Lead ?", "?", -85 },
 
304
  {  2031,  3054, 1, 1, -2, "Lead ?", "?", -72 },
 
305
  {  4835,  7226, 1, 1, -2, "Lead ?", "?", -37 },
 
306
  {  8199, 12287, 1, 1, -2, "Lead ?", "?", -22 },
 
307
  {    96,   117, 2, 1, -2, "Leica Digilux 3", "?", -98 },
 
308
  {   221,   333, 2, 1, -2, "Leica M8", "?", 97 },
 
309
  {   582,   836, 2, 1, -2, "Medion ?", "?", -92 },
 
310
  {   433,   667, 2, 1, -2, "Medion ?", "?", -94 },
 
311
  {  1858,  2780, 2, 2,  2, "Microsoft Office", "Default", 75 },
 
312
  {   116,   169, 2, 1, -2, "Nikon D50, D70, D70s, D80", "Fine", -98 },
 
313
  {   218,   333, 2, 1, -2, "Nikon D70 or D70s", "Normal", -97 },
 
314
  {   616,   941, 2, 1, -2, "Nikon D70 or D70s", "Basic", -91 },
 
315
  {   671,   999, 2, 1, -2, "Nikon D70 or D70s", "Basic + raw", -90 },
 
316
  {   127,   169, 2, 1, -2, "Nikon D70 v1.0", "Fine", -98 },
 
317
  {   302,   444, 2, 1, -2, "Nikon D70 v1.0", "Fine", -95 },
 
318
  {   315,   499, 2, 1, -2, "Nikon D70 v1.0", "Fine", -95 },
 
319
  {   329,   500, 2, 1, -2, "Nikon D70 v1.0", "Fine", -95 },
 
320
  {   346,   500, 2, 1, -2, "Nikon D70 v1.0", "Fine", -95 },
 
321
  {   372,   558, 2, 1, -2, "Nikon D70 v1.0", "Fine", -94 },
 
322
  {   389,   560, 2, 1, -2, "Nikon D70 v1.0", "Fine", -94 },
 
323
  {   419,   611, 2, 1, -2, "Nikon D70 v1.0", "Fine", -94 },
 
324
  {   449,   668, 2, 1, -2, "Nikon D70 v1.0", "Fine", -93 },
 
325
  {   506,   775, 2, 1, -2, "Nikon D70 v1.0", "Fine", -93 },
 
326
  {   529,   781, 2, 1, -2, "Nikon D70 v1.0", "Fine", -92 },
 
327
  {   261,   389, 2, 1, -2, "Nikon D50", "Normal", -96 },
 
328
  {   345,   499, 2, 1, -2, "Nikon D50", "Normal", -95 },
 
329
  {   855,  1279, 2, 1, -2, "Nikon D40", "?", -88 },
 
330
  {   667,   999, 2, 1, -3, "Nikon E4300", "Normal", 91 },
 
331
  {   736,  1110, 2, 1, -3, "Nikon E4300", "Normal", 90 },
 
332
  {   884,  1332, 2, 1, -3, "Nikon E4300", "Normal", 88 },
 
333
  {    64,    64, 1, 1, -2, "Nikon Browser 6", "High quality", 100 },
 
334
  {   779,  1164, 1, 1, -2, "Nikon Browser 6 or PictureProject 1.6", "Standard quality", -89 },
 
335
  {  1697,  2554, 2, 1, -2, "Nikon Browser 6", "Standard eq", -76 },
 
336
  {  2746,  5112, 2, 2, -2, "Nikon Browser 6", "Standard compression", -57 },
 
337
  {  8024, 12006, 2, 2, -2, "Nikon Browser 6", "Maximum compression", -22 },
 
338
  {   736,  1110, 2, 2, -2, "Olympus Camedia Master", "High quality?", 90 },
 
339
  {  1477,  2221, 2, 2, -2, "Olympus u710,S710", "Super high quality?", 80 },
 
340
  {   437,   617, 2, 1, -2, "Olympus u30D,S410D,u410D", "High quality", -94 },
 
341
  {   447,   670, 2, 1, -2, "Olympus u30D,S410D,u410D", "High quality", -93 },
 
342
  {   447,   670, 2, 1, -2, "Olympus u30D,S410D,u410D", "High quality", -93 },
 
343
  {   814,  1223, 2, 1, -3, "Olympus C960Z,D460Z", "Standard quality", 89 },
 
344
  {   884,  1332, 2, 1, -3, "Olympus C211Z", "Standard quality", 88 },
 
345
  {  1552,  2336, 2, 1, -3, "Olympus C990Z,D490Z", "High quality", 79 },
 
346
  {   261,   392, 2, 1, -2, "Panasonic DMC-FZ5", "High", -96 },
 
347
  {   251,   392, 2, 1, -2, "Panasonic DMC-FZ30", "High", -96 },
 
348
  {   280,   445, 2, 1, -2, "Panasonic DMC-FZ30", "High", -96 },
 
349
  {   304,   448, 2, 1, -2, "Panasonic DMC-FZ30", "High", -95 },
 
350
  {   316,   499, 2, 1, -2, "Panasonic DMC-FZ30", "High", -95 },
 
351
  {   332,   550, 2, 1, -2, "Panasonic DMC-FZ30", "High", -95 },
 
352
  {   355,   555, 2, 1, -2, "Panasonic DMC-FZ30", "High", -95 },
 
353
  {   375,   606, 2, 1, -2, "Panasonic DMC-FZ30", "High", -94 },
 
354
  {   400,   615, 2, 1, -2, "Panasonic DMC-FZ30", "High", -94 },
 
355
  {   420,   667, 2, 1, -2, "Panasonic DMC-FZ30", "High", -94 },
 
356
  {   501,   775, 2, 1, -2, "Panasonic DMC-FZ30", "High", -93 },
 
357
  {   577,   891, 2, 1, -2, "Panasonic DMC-FZ30", "High", -92 },
 
358
  {   324,   499, 2, 1,  2, "Ricoh Caplio R1V", "?", -95 },
 
359
  {   274,   443, 2, 1,  2, "Roxio PhotoSuite", "?", -96 },
 
360
  {   634,   943, 2, 1, -2, "Samsung Digimax V3", "?", -91 },
 
361
  {  1313,  1997, 2, 1, -2, "Samsung Digimax V3", "?", -82 },
 
362
  {   218,   331, 2, 1, -2, "Samsung Digimax S600", "?", -97 },
 
363
  {   258,   389, 2, 1, -2, "Sony Cybershot", "?", -96 },
 
364
  {    86,   115, 2, 1, -2, "Sony DSC-W55", "Fine", 99 },
 
365
  {   122,   169, 2, 1, -2, "Sony DSC-F828, DSC-F88", "?", -98 },
 
366
  {   221,   333, 2, 1, -2, "Sony DSC-W30, DSC-W50, DSC-H2, DSC-H5", "?", 97 },
 
367
  {   518,   779, 2, 1, -2, "Sony DSC-W70", "?", 93 },
 
368
  {  1477,  2221, 2, 2, -2, "Sony DSC-W30, DSC-P43, DSC-S600", "?", 80 },
 
369
  {   324,   682, 2, 1, -2, "Sony DSLR-A100", "?", -94 },
 
370
  {   736,  1110, 2, 1, -2, "SonyEricsson K750i", "Fine", 90 },
 
371
  {  1858,  2780, 2, 1, -2, "SonyEricsson K750i or W200i", "Normal", 75 },
 
372
  {   836,  1094, 2, 2, -2, "SonyEricsson K750i", "Panorama fine", -89 },
 
373
  {  1672,  2188, 2, 2, -2, "SonyEricsson K750i", "Panorama normal", -79 },
 
374
  {   361,   555, 2, 1, -2, "SonyEricsson K750i", "?", -95 },
 
375
  {   433,   667, 2, 1, -2, "SonyEricsson K750i", "?", -94 },
 
376
  {   954,  1443, 2, 1, -2, "SonyEricsson K750i", "?", -87 },
 
377
  {  1024,  1504, 2, 1, -2, "SonyEricsson K750i", "?", -86 },
 
378
  {  1097,  1615, 2, 1, -2, "SonyEricsson K750i", "?", -85 },
 
379
  {  1168,  1727, 2, 1, -2, "SonyEricsson K750i", "?", -84 },
 
380
  {  1324,  2000, 2, 1, -2, "SonyEricsson K750i", "?", -82 },
 
381
  {  1473,  2170, 2, 1, -2, "SonyEricsson K750i", "?", -80 },
 
382
  {  1615,  2394, 2, 1, -2, "SonyEricsson K750i", "?", -78 },
 
383
  {  1759,  2612, 2, 1, -2, "SonyEricsson K750i", "?", -76 },
 
384
  {  1491,  1491, 2, 1, -2, "SonyEricsson Z600", "Default", -83 },
 
385
  {  2211,  3284, 2, 1, -2, "Trust 760 Powerc@m", "?", 70 },
 
386
  {  2211,  3284, 1, 2, -2, "Trust 760 Powerc@m", "?", 70 },
 
387
  {  1830,  2725, 1, 1,  2, "Xing VT-Compress", "?", -75 }
 
388
};
 
389
 
 
390
typedef struct
 
391
{
 
392
  guint32  hashval;
 
393
  gint     subsmp_h;
 
394
  gint     subsmp_v;
 
395
  gint     num_quant_tables;
 
396
  gint     ijg_qual;
 
397
  GSList  *files;
 
398
  guint16  luminance[DCTSIZE2];
 
399
  guint16  chrominance[DCTSIZE2];
 
400
} QuantTableData;
 
401
 
 
402
static GSList *found_tables = NULL;
 
403
 
 
404
#if 0 /* FIXME ---v-v-v---------------------------------------------v-v-v--- */
 
405
 
80
406
static guint16 **ijg_luminance       = NULL; /* luminance, baseline */
81
407
static guint16 **ijg_chrominance     = NULL; /* chrominance, baseline */
82
408
static guint16 **ijg_luminance_nb    = NULL; /* luminance, not baseline */
83
409
static guint16 **ijg_chrominance_nb  = NULL; /* chrominance, not baseline */
84
 
#endif
85
 
 
86
 
typedef struct
87
 
{
88
 
  const gint   lum_sum;
89
 
  const gint   chrom_sum;
90
 
  const gint   subsmp_h;
91
 
  const gint   subsmp_v;
92
 
  const gchar *source_name;
93
 
  const gchar *setting_name;
94
 
  const gint   ijg_qual;
95
 
} QuantInfo;
96
 
 
97
 
static const QuantInfo quant_info[] =
98
 
{
99
 
  {    64,    64, 0, 0, "IJG JPEG Library", "quality 100", 100 },
100
 
  {    86,   115, 0, 0, "IJG JPEG Library", "quality 99", 99 },
101
 
  {   151,   224, 0, 0, "IJG JPEG Library", "quality 98", 98 },
102
 
  {   221,   333, 0, 0, "IJG JPEG Library", "quality 97", 97 },
103
 
  {   292,   443, 0, 0, "IJG JPEG Library", "quality 96", 96 },
104
 
  {   369,   558, 0, 0, "IJG JPEG Library", "quality 95", 95 },
105
 
  {   441,   668, 0, 0, "IJG JPEG Library", "quality 94", 94 },
106
 
  {   518,   779, 0, 0, "IJG JPEG Library", "quality 93", 93 },
107
 
  {   592,   891, 0, 0, "IJG JPEG Library", "quality 92", 92 },
108
 
  {   667,   999, 0, 0, "IJG JPEG Library", "quality 91", 91 },
109
 
  {   736,  1110, 0, 0, "IJG JPEG Library", "quality 90", 90 },
110
 
  {   814,  1223, 0, 0, "IJG JPEG Library", "quality 89", 89 },
111
 
  {   884,  1332, 0, 0, "IJG JPEG Library", "quality 88", 88 },
112
 
  {   961,  1444, 0, 0, "IJG JPEG Library", "quality 87", 87 },
113
 
  {  1031,  1555, 0, 0, "IJG JPEG Library", "quality 86", 86 },
114
 
  {  1109,  1666, 0, 0, "IJG JPEG Library", "quality 85", 85 },
115
 
  {  1179,  1778, 0, 0, "IJG JPEG Library", "quality 84", 84 },
116
 
  {  1251,  1888, 0, 0, "IJG JPEG Library", "quality 83", 83 },
117
 
  {  1326,  2000, 0, 0, "IJG JPEG Library", "quality 82", 82 },
118
 
  {  1398,  2111, 0, 0, "IJG JPEG Library", "quality 81", 81 },
119
 
  {  1477,  2221, 0, 0, "IJG JPEG Library", "quality 80", 80 },
120
 
  {  1552,  2336, 0, 0, "IJG JPEG Library", "quality 79", 79 },
121
 
  {  1620,  2445, 0, 0, "IJG JPEG Library", "quality 78", 78 },
122
 
  {  1692,  2556, 0, 0, "IJG JPEG Library", "quality 77", 77 },
123
 
  {  1773,  2669, 0, 0, "IJG JPEG Library", "quality 76", 76 },
124
 
  {  1858,  2780, 0, 0, "IJG JPEG Library", "quality 75", 75 },
125
 
  {  1915,  2836, 0, 0, "IJG JPEG Library", "quality 74", 74 },
126
 
  {  1996,  2949, 0, 0, "IJG JPEG Library", "quality 73", 73 },
127
 
  {  2068,  3060, 0, 0, "IJG JPEG Library", "quality 72", 72 },
128
 
  {  2136,  3169, 0, 0, "IJG JPEG Library", "quality 71", 71 },
129
 
  {  2211,  3284, 0, 0, "IJG JPEG Library", "quality 70", 70 },
130
 
  {  2290,  3394, 0, 0, "IJG JPEG Library", "quality 69", 69 },
131
 
  {  2362,  3505, 0, 0, "IJG JPEG Library", "quality 68", 68 },
132
 
  {  2437,  3617, 0, 0, "IJG JPEG Library", "quality 67", 67 },
133
 
  {  2509,  3727, 0, 0, "IJG JPEG Library", "quality 66", 66 },
134
 
  {  2583,  3839, 0, 0, "IJG JPEG Library", "quality 65", 65 },
135
 
  {  2657,  3950, 0, 0, "IJG JPEG Library", "quality 64", 64 },
136
 
  {  2727,  4061, 0, 0, "IJG JPEG Library", "quality 63", 63 },
137
 
  {  2804,  4173, 0, 0, "IJG JPEG Library", "quality 62", 62 },
138
 
  {  2874,  4282, 0, 0, "IJG JPEG Library", "quality 61", 61 },
139
 
  {  2952,  4395, 0, 0, "IJG JPEG Library", "quality 60", 60 },
140
 
  {  3021,  4506, 0, 0, "IJG JPEG Library", "quality 59", 59 },
141
 
  {  3096,  4614, 0, 0, "IJG JPEG Library", "quality 58", 58 },
142
 
  {  3170,  4726, 0, 0, "IJG JPEG Library", "quality 57", 57 },
143
 
  {  3247,  4837, 0, 0, "IJG JPEG Library", "quality 56", 56 },
144
 
  {  3323,  4947, 0, 0, "IJG JPEG Library", "quality 55", 55 },
145
 
  {  3396,  5062, 0, 0, "IJG JPEG Library", "quality 54", 54 },
146
 
  {  3467,  5172, 0, 0, "IJG JPEG Library", "quality 53", 53 },
147
 
  {  3541,  5281, 0, 0, "IJG JPEG Library", "quality 52", 52 },
148
 
  {  3621,  5396, 0, 0, "IJG JPEG Library", "quality 51", 51 },
149
 
  {  3688,  5505, 0, 0, "IJG JPEG Library", "quality 50", 50 },
150
 
  {  3755,  5614, 0, 0, "IJG JPEG Library", "quality 49", 49 },
151
 
  {  3835,  5729, 0, 0, "IJG JPEG Library", "quality 48", 48 },
152
 
  {  3909,  5838, 0, 0, "IJG JPEG Library", "quality 47", 47 },
153
 
  {  3980,  5948, 0, 0, "IJG JPEG Library", "quality 46", 46 },
154
 
  {  4092,  6116, 0, 0, "IJG JPEG Library", "quality 45", 45 },
155
 
  {  4166,  6226, 0, 0, "IJG JPEG Library", "quality 44", 44 },
156
 
  {  4280,  6396, 0, 0, "IJG JPEG Library", "quality 43", 43 },
157
 
  {  4393,  6562, 0, 0, "IJG JPEG Library", "quality 42", 42 },
158
 
  {  4463,  6672, 0, 0, "IJG JPEG Library", "quality 41", 41 },
159
 
  {  4616,  6897, 0, 0, "IJG JPEG Library", "quality 40", 40 },
160
 
  {  4719,  7060, 0, 0, "IJG JPEG Library", "quality 39", 39 },
161
 
  {  4829,  7227, 0, 0, "IJG JPEG Library", "quality 38", 38 },
162
 
  {  4976,  7447, 0, 0, "IJG JPEG Library", "quality 37", 37 },
163
 
  {  5086,  7616, 0, 0, "IJG JPEG Library", "quality 36", 36 },
164
 
  {  5240,  7841, 0, 0, "IJG JPEG Library", "quality 35", 35 },
165
 
  {  5421,  8114, 0, 0, "IJG JPEG Library", "quality 34", 34 },
166
 
  {  5571,  8288, 0, 0, "IJG JPEG Library", "quality 33", 33 },
167
 
  {  5756,  8565, 0, 0, "IJG JPEG Library", "quality 32", 32 },
168
 
  {  5939,  8844, 0, 0, "IJG JPEG Library", "quality 31", 31 },
169
 
  {  6125,  9122, 0, 0, "IJG JPEG Library", "quality 30", 30 },
170
 
  {  6345,  9455, 0, 0, "IJG JPEG Library", "quality 29", 29 },
171
 
  {  6562,  9787, 0, 0, "IJG JPEG Library", "quality 28", 28 },
172
 
  {  6823, 10175, 0, 0, "IJG JPEG Library", "quality 27", 27 },
173
 
  {  7084, 10567, 0, 0, "IJG JPEG Library", "quality 26", 26 },
174
 
  {  7376, 11010, 0, 0, "IJG JPEG Library", "quality 25", 25 },
175
 
  {  7668, 11453, 0, 0, "IJG JPEG Library", "quality 24", 24 },
176
 
  {  7995, 11954, 0, 0, "IJG JPEG Library", "quality 23", 23 },
177
 
  {  8331, 12511, 0, 0, "IJG JPEG Library", "quality 22", 22 },
178
 
  {  8680, 13121, 0, 0, "IJG JPEG Library", "quality 21", 21 },
179
 
  {  9056, 13790, 0, 0, "IJG JPEG Library", "quality 20", 20 },
180
 
  {  9368, 14204, 0, 0, "IJG JPEG Library", "quality 19", 19 },
181
 
  {  9679, 14267, 0, 0, "IJG JPEG Library", "quality 18", 18 },
182
 
  { 10027, 14346, 0, 0, "IJG JPEG Library", "quality 17", 17 },
183
 
  { 10360, 14429, 0, 0, "IJG JPEG Library", "quality 16", 16 },
184
 
  { 10714, 14526, 0, 0, "IJG JPEG Library", "quality 15", 15 },
185
 
  { 11081, 14635, 0, 0, "IJG JPEG Library", "quality 14", 14 },
186
 
  { 11456, 14754, 0, 0, "IJG JPEG Library", "quality 13", 13 },
187
 
  { 11861, 14864, 0, 0, "IJG JPEG Library", "quality 12", 12 },
188
 
  { 12240, 14985, 0, 0, "IJG JPEG Library", "quality 11", 11 },
189
 
  { 12560, 15110, 0, 0, "IJG JPEG Library", "quality 10", 10 },
190
 
  { 12859, 15245, 0, 0, "IJG JPEG Library", "quality 9", 9 },
191
 
  { 13230, 15369, 0, 0, "IJG JPEG Library", "quality 8", 8 },
192
 
  { 13623, 15523, 0, 0, "IJG JPEG Library", "quality 7", 7 },
193
 
  { 14073, 15731, 0, 0, "IJG JPEG Library", "quality 6", 6 },
194
 
  { 14655, 16010, 0, 0, "IJG JPEG Library", "quality 5", 5 },
195
 
  { 15277, 16218, 0, 0, "IJG JPEG Library", "quality 4", 4 },
196
 
  { 15946, 16320, 0, 0, "IJG JPEG Library", "quality 3", 3 },
197
 
  { 16315, 16320, 0, 0, "IJG JPEG Library", "quality 2", 2 },
198
 
  { 16320, 16320, 0, 0, "IJG JPEG Library", "quality 1", 1 },
199
 
  { 16320, 16320, 0, 0, "IJG JPEG Library", "quality 0", 1 },
200
 
  {  8008, 11954, 0, 0, "IJG JPEG Library", "not baseline 23", -22 },
201
 
  {  8370, 12511, 0, 0, "IJG JPEG Library", "not baseline 22", -21 },
202
 
  {  8774, 13121, 0, 0, "IJG JPEG Library", "not baseline 21", -20 },
203
 
  {  9234, 13790, 0, 0, "IJG JPEG Library", "not baseline 20", -19 },
204
 
  {  9700, 14459, 0, 0, "IJG JPEG Library", "not baseline 19", -17 },
205
 
  { 10209, 15236, 0, 0, "IJG JPEG Library", "not baseline 18", -14 },
206
 
  { 10843, 16182, 0, 0, "IJG JPEG Library", "not baseline 17", -11 },
207
 
  { 11505, 17183, 0, 0, "IJG JPEG Library", "not baseline 16", -7 },
208
 
  { 12279, 18351, 0, 0, "IJG JPEG Library", "not baseline 15", -5 },
209
 
  { 13166, 19633, 0, 0, "IJG JPEG Library", "not baseline 14", 0 },
210
 
  { 14160, 21129, 0, 0, "IJG JPEG Library", "not baseline 13", 0 },
211
 
  { 15344, 22911, 0, 0, "IJG JPEG Library", "not baseline 12", 0 },
212
 
  { 16748, 24969, 0, 0, "IJG JPEG Library", "not baseline 11", 0 },
213
 
  { 18440, 27525, 0, 0, "IJG JPEG Library", "not baseline 10", 0 },
214
 
  { 20471, 30529, 0, 0, "IJG JPEG Library", "not baseline 9", 0 },
215
 
  { 23056, 34422, 0, 0, "IJG JPEG Library", "not baseline 8", 0 },
216
 
  { 26334, 39314, 0, 0, "IJG JPEG Library", "not baseline 7", 0 },
217
 
  { 30719, 45876, 0, 0, "IJG JPEG Library", "not baseline 6", 0 },
218
 
  { 36880, 55050, 0, 0, "IJG JPEG Library", "not baseline 5", 0 },
219
 
  { 46114, 68840, 0, 0, "IJG JPEG Library", "not baseline 4", 0 },
220
 
  { 61445, 91697, 0, 0, "IJG JPEG Library", "not baseline 3", 0 },
221
 
  { 92200, 137625, 0, 0, "IJG JPEG Library", "not baseline 2", 0 },
222
 
  { 184400, 275250, 0, 0, "IJG JPEG Library", "not baseline 1", 0 },
223
 
  { 184400, 275250, 0, 0, "IJG JPEG Library", "not baseline 0", 0 },
224
 
  {   319,   665, 2, 1, "ACD ?", "?", -94 },
225
 
  {   436,   996, 2, 1, "ACD ?", "?", -92 },
226
 
  {   664,  1499, 2, 1, "ACD ?", "?", -88 },
227
 
  {  1590,  3556, 2, 2, "ACD ?", "?", -71 },
228
 
  {   284,   443, 2, 2, "Adobe Photoshop CS3", "?", -96 },
229
 
  {   109,   171, 1, 1, "Adobe Photoshop CS or CS2", "quality 12", -98 },
230
 
  {   303,   466, 1, 1, "Adobe Photoshop CS2", "quality 11", -95 },
231
 
  {   535,   750, 1, 1, "Adobe Photoshop CS2", "quality 10", -93 },
232
 
  {   668,   830, 1, 1, "Adobe Photoshop CS2", "quality 9", -91 },
233
 
  {   794,   895, 1, 1, "Adobe Photoshop CS2", "quality 8", -90 },
234
 
  {   971,   950, 1, 1, "Adobe Photoshop CS2", "quality 7", -89 },
235
 
  {   884,   831, 2, 2, "Adobe Photoshop CS2", "quality 6", -90 },
236
 
  {  1032,   889, 2, 2, "Adobe Photoshop CS2", "quality 5", -89 },
237
 
  {  1126,   940, 2, 2, "Adobe Photoshop CS2", "quality 4", -88 },
238
 
  {  1216,   977, 2, 2, "Adobe Photoshop CS2", "quality 3", -88 },
239
 
  {  1281,   998, 2, 2, "Adobe Photoshop CS2", "quality 2", -87 },
240
 
  {  1484,  1083, 2, 2, "Adobe Photoshop CS2", "quality 1", -86 },
241
 
  {  1582,  1108, 2, 2, "Adobe Photoshop CS2", "quality 0", -85 },
242
 
  {    95,   168, 1, 1, "Adobe Photoshop CS2", "save for web 100", -98 },
243
 
  {   234,   445, 1, 1, "Adobe Photoshop CS2", "save for web 90", -96 },
244
 
  {   406,   724, 1, 1, "Adobe Photoshop CS2", "save for web 80", -93 },
245
 
  {   646,  1149, 1, 1, "Adobe Photoshop CS2", "save for web 70", -90 },
246
 
  {   974,  1769, 1, 1, "Adobe Photoshop CS2", "save for web 60", -85 },
247
 
  {  1221,  1348, 2, 2, "Adobe Photoshop CS2", "save for web 50", -86 },
248
 
  {  1821,  1997, 2, 2, "Adobe Photoshop CS2", "save for web 40", -79 },
249
 
  {  2223,  2464, 2, 2, "Adobe Photoshop CS2", "save for web 30", -74 },
250
 
  {  2575,  2903, 2, 2, "Adobe Photoshop CS2", "save for web 20", -70 },
251
 
  {  3514,  3738, 2, 2, "Adobe Photoshop CS2", "save for web 10", -60 },
252
 
  {    95,   166, 1, 1, "Adobe Photoshop CS or Lightroom", "save for web 100?", -98 },
253
 
  {   232,   443, 1, 1, "Adobe Photoshop CS", "?", -96 },
254
 
  {   649,   853, 1, 1, "Adobe Photoshop CS or Elements 4.0", "?", -91 },
255
 
  {   844,   849, 2, 2, "Adobe Photoshop CS", "?", -90 },
256
 
  {   962,   892, 2, 2, "Adobe Photoshop CS", "?", -89 },
257
 
  {   406,   722, 1, 1, "Adobe Photoshop 7.0", "?", -93 },
258
 
  {   539,   801, 1, 1, "Adobe Photoshop 7.0 CE", "?", -92 },
259
 
  {   786,   926, 1, 1, "Adobe Photoshop 7.0", "?", -90 },
260
 
  {   539,   801, 1, 1, "Adobe Photoshop 5.0", "?", -92 },
261
 
  {   717,   782, 2, 2, "Adobe Photoshop 5.0", "?", -91 },
262
 
  {  1068,   941, 2, 2, "Adobe Photoshop 4.0", "?", -89 },
263
 
  {   339,   670, 1, 1, "Adobe Photoshop ?", "?", -94 },
264
 
  {   406,   722, 1, 1, "Adobe Photoshop ?", "?", -93 },
265
 
  {   427,   613, 2, 2, "Adobe Photoshop ?", "?", -94 },
266
 
  {   525,   941, 1, 1, "Adobe Photoshop ?", "?", -92 },
267
 
  {   803,  1428, 1, 1, "Adobe Photoshop ?", "?", -87 },
268
 
  {  1085,  1996, 1, 1, "Adobe Photoshop ?", "?", -83 },
269
 
  {  1156,  2116, 1, 1, "Adobe Photoshop ?", "?", -82 },
270
 
  {  1175,  2169, 1, 1, "Adobe Photoshop ?", "?", -81 },
271
 
  {  2272,  2522, 2, 2, "Adobe Photoshop ?", "?", -73 },
272
 
  {   513,     0, 1, 1, "Adobe Photoshop ?", "?", -97 },
273
 
  {  2515,  2831, 2, 2, "Adobe ImageReady", "?", -70 },
274
 
  {  3822,  3975, 2, 2, "Adobe ImageReady", "?", -57 },
275
 
  {   255,   393, 2, 1, "Apple Quicktime 7", "?", -96 },
276
 
  {   513,   775, 2, 2, "Apple Quicktime 7", "?", -93 },
277
 
  {   543,   784, 2, 1, "Apple Quicktime 7", "?", -92 },
278
 
  {   361,   506, 2, 1, "Apple ?", "?", -95 },
279
 
  {  1511,  2229, 2, 2, "Apple ?", "?", -79 },
280
 
  {   188,   276, 2, 1, "Canon EOS 300D, 350D or 400D", "Fine", -97 },
281
 
  {   708,  1057, 2, 1, "Canon EOS 10D", "?", -90 },
282
 
  {   533,  1925, 2, 1, "Canon Digital Ixus", "Fine", -86 },
283
 
  {   533,  1325, 2, 1, "Canon PowerShot A95, S1, S2, SD400 or SD630", "Fine", -89 },
284
 
  {   192,   556, 1, 2, "Canon PowerShot A430", "Superfine", -95 },
285
 
  {   192,   556, 2, 1, "Canon PowerShot S200 or Ixus 800", "Superfine", -95 },
286
 
  {    64,    64, 2, 2, "Casio EX-Z600", "Fine", 100 },
287
 
  {   288,   443, 2, 1, "FujiFilm MX-2700", "?", -96 },
288
 
  {  2056,  3102, 2, 1, "FujiFilm DX-10", "?", -71 },
289
 
  {  1254,  1888, 2, 1, "FujiFilm MX-1700 Zoom", "?", -82 },
290
 
  {   515,   774, 2, 1, "FujiFilm FinePix 2600 Zoom", "Fine", -93 },
291
 
  {  1375,  1131, 2, 2, "Kodak DC210", "?", -86 },
292
 
  {   736,  1110, 2, 2, "Kodak DC240", "?", 90 },
293
 
  {   161,   179, 1, 1, "Lead ?", "?", -98 },
294
 
  {   711,  1055, 1, 1, "Lead ?", "?", -90 },
295
 
  {  1079,  1610, 1, 1, "Lead ?", "?", -85 },
296
 
  {  2031,  3054, 1, 1, "Lead ?", "?", -72 },
297
 
  {  4835,  7226, 1, 1, "Lead ?", "?", -37 },
298
 
  {  8199, 12287, 1, 1, "Lead ?", "?", -22 },
299
 
  {   582,   836, 2, 1, "Medion ?", "?", -92 },
300
 
  {   116,   169, 2, 1, "Nikon D50, D70, D70s, D80", "Fine", -98 },
301
 
  {   218,   333, 2, 1, "Nikon D70 or D70s", "Normal", -97 },
302
 
  {   616,   941, 2, 1, "Nikon D70 or D70s", "Basic", -91 },
303
 
  {   671,   999, 2, 1, "Nikon D70 or D70s", "Basic + raw", -90 },
304
 
  {   127,   169, 2, 1, "Nikon D70 v1.0", "Fine", -98 },
305
 
  {   302,   444, 2, 1, "Nikon D70 v1.0", "Fine", -95 },
306
 
  {   315,   499, 2, 1, "Nikon D70 v1.0", "Fine", -95 },
307
 
  {   329,   500, 2, 1, "Nikon D70 v1.0", "Fine", -95 },
308
 
  {   346,   500, 2, 1, "Nikon D70 v1.0", "Fine", -95 },
309
 
  {   372,   558, 2, 1, "Nikon D70 v1.0", "Fine", -94 },
310
 
  {   389,   560, 2, 1, "Nikon D70 v1.0", "Fine", -94 },
311
 
  {   419,   611, 2, 1, "Nikon D70 v1.0", "Fine", -94 },
312
 
  {   449,   668, 2, 1, "Nikon D70 v1.0", "Fine", -93 },
313
 
  {   506,   775, 2, 1, "Nikon D70 v1.0", "Fine", -93 },
314
 
  {   529,   781, 2, 1, "Nikon D70 v1.0", "Fine", -92 },
315
 
  {   855,  1279, 2, 1, "Nikon D40", "?", -88 },
316
 
  {    64,    64, 1, 1, "Nikon Browser 6", "High quality", 100 },
317
 
  {   779,  1164, 1, 1, "Nikon Browser 6", "Standard quality", -89 },
318
 
  {  1697,  2554, 2, 1, "Nikon Browser 6", "Standard eq", -76 },
319
 
  {  2746,  5112, 2, 2, "Nikon Browser 6", "Standard compression", -57 },
320
 
  {  8024, 12006, 2, 2, "Nikon Browser 6", "Maximum compression", -22 },
321
 
  {   736,  1110, 2, 2, "Olympus Camedia Master", "High quality?", 90 },
322
 
  {  1057,  1561, 2, 1, "Olympus u770SW,S770SW", "?", -85 },
323
 
  {   275,   395, 2, 1, "Olympus u750,S750", "Raw?", -96 },
324
 
  {  1477,  2221, 2, 2, "Olympus U710,S710", "Super high quality?", 80 },
325
 
  {   251,   392, 2, 1, "Panasonic DMC-FZ30", "High", -96 },
326
 
  {   280,   445, 2, 1, "Panasonic DMC-FZ30", "High", -96 },
327
 
  {   304,   448, 2, 1, "Panasonic DMC-FZ30", "High", -95 },
328
 
  {   316,   499, 2, 1, "Panasonic DMC-FZ30", "High", -95 },
329
 
  {   332,   550, 2, 1, "Panasonic DMC-FZ30", "High", -95 },
330
 
  {   355,   555, 2, 1, "Panasonic DMC-FZ30", "High", -95 },
331
 
  {   375,   606, 2, 1, "Panasonic DMC-FZ30", "High", -94 },
332
 
  {   400,   615, 2, 1, "Panasonic DMC-FZ30", "High", -94 },
333
 
  {   420,   667, 2, 1, "Panasonic DMC-FZ30", "High", -94 },
334
 
  {   501,   775, 2, 1, "Panasonic DMC-FZ30", "High", -93 },
335
 
  {   577,   891, 2, 1, "Panasonic DMC-FZ30", "High", -92 },
336
 
  {   324,   499, 2, 1, "Ricoh Caplio R1V", "?", -95 },
337
 
  {   634,   943, 2, 1, "Samsung Digimax V3", "?", -91 },
338
 
  {  1313,  1997, 2, 1, "Samsung Digimax V3", "?", -82 },
339
 
  {  1075,  1612, 2, 1, "Sanyo SR6", "?", -85 },
340
 
  {   785,  1168, 2, 1, "Sanyo SX113", "?", -89 },
341
 
  {   258,   389, 2, 1, "Sony Cybershot", "?", -96 },
342
 
  {  2782,  4259, 2, 1, "Sony Cybershot", "?", -61 },
343
 
  {    86,   115, 2, 1, "Sony DSC-W55", "?", 99 },
344
 
  {   221,   333, 2, 1, "Sony DSC-W50", "?", 97 },
345
 
  {  1477,  2221, 2, 2, "Sony DSC-W30, DSC-P43, DSC-S600", "?", 80 },
346
 
  {   736,  1110, 2, 1, "SonyEricsson K750i", "Fine", 90 },
347
 
  {  1858,  2780, 2, 1, "SonyEricsson K750i", "Normal", 75 },
348
 
  {   836,  1094, 2, 2, "SonyEricsson K750i", "Panorama fine", -89 },
349
 
  {  1672,  2188, 2, 2, "SonyEricsson K750i", "Panorama normal", -79 },
350
 
  {   361,   555, 2, 1, "SonyEricsson K750i", "?", -95 },
351
 
  {   433,   667, 2, 1, "SonyEricsson K750i", "?", -94 },
352
 
  {   954,  1443, 2, 1, "SonyEricsson K750i", "?", -87 },
353
 
  {  1024,  1504, 2, 1, "SonyEricsson K750i", "?", -86 },
354
 
  {  1097,  1615, 2, 1, "SonyEricsson K750i", "?", -85 },
355
 
  {  1168,  1727, 2, 1, "SonyEricsson K750i", "?", -84 },
356
 
  {  1324,  2000, 2, 1, "SonyEricsson K750i", "?", -82 },
357
 
  {  1473,  2170, 2, 1, "SonyEricsson K750i", "?", -80 },
358
 
  {  1615,  2394, 2, 1, "SonyEricsson K750i", "?", -78 },
359
 
  {  1759,  2612, 2, 1, "SonyEricsson K750i", "?", -76 },
360
 
  {  1491,  1491, 2, 1, "SonyEricsson Z600", "Default", -83 },
361
 
  {  1830,  2725, 1, 1, "Xing VT-Compress", "?", -75 }
362
 
};
363
 
 
364
 
#if 0 /* FIXME */
365
410
 
366
411
/*
367
412
 * Initialize the IJG quantization tables for each quality setting.
421
466
  return TRUE;
422
467
}
423
468
 
424
 
#endif /* FIXME */
425
 
 
 
469
#endif /* FIXME ---^-^-^--------------------------------------------^-^-^--- */
 
470
 
 
471
/*
 
472
 * Trivial hash function (simple, but good enough for 1 to 4 * 64 short ints).
 
473
 */
 
474
static guint32
 
475
hash_quant_tables (struct jpeg_decompress_struct *cinfo)
 
476
{
 
477
  guint32 hashval;
 
478
  gint    t;
 
479
  gint    i;
 
480
 
 
481
  hashval = 11;
 
482
  for (t = 0; t < 4; t++)
 
483
    if (cinfo->quant_tbl_ptrs[t])
 
484
      for (i = 0; i < DCTSIZE2; i++)
 
485
        hashval = hashval * 4177 + cinfo->quant_tbl_ptrs[t]->quantval[i];
 
486
  return hashval;
 
487
}
 
488
 
 
489
static void
 
490
add_unknown_table (struct jpeg_decompress_struct *cinfo,
 
491
                   gchar                         *filename)
 
492
{
 
493
  guint32         hashval;
 
494
  GSList         *list;
 
495
  QuantTableData *table_data;
 
496
  gint            num_quant_tables;
 
497
  gint            t;
 
498
  gint            i;
 
499
 
 
500
  hashval = hash_quant_tables (cinfo);
 
501
 
 
502
  /* linear search - the number of unknown tables is usually very small */
 
503
  for (list = found_tables; list; list = list->next)
 
504
    {
 
505
      table_data = list->data;
 
506
      if (table_data->hashval == hashval
 
507
          && table_data->subsmp_h == cinfo->comp_info[0].h_samp_factor
 
508
          && table_data->subsmp_v == cinfo->comp_info[0].v_samp_factor)
 
509
        {
 
510
          /* this unknown table has already been seen in previous files */
 
511
          table_data->files = g_slist_prepend (table_data->files, filename);
 
512
          return;
 
513
        }
 
514
    }
 
515
 
 
516
  /* not found => new table */
 
517
  table_data = g_new (QuantTableData, 1);
 
518
  table_data->hashval = hashval;
 
519
  table_data->subsmp_h = cinfo->comp_info[0].h_samp_factor;
 
520
  table_data->subsmp_v = cinfo->comp_info[0].v_samp_factor;
 
521
  num_quant_tables = 0;
 
522
  for (t = 0; t < 4; t++)
 
523
    if (cinfo->quant_tbl_ptrs[t])
 
524
      num_quant_tables++;
 
525
  table_data->num_quant_tables = num_quant_tables;
 
526
  table_data->ijg_qual = jpeg_detect_quality (cinfo);
 
527
  table_data->files = g_slist_prepend (NULL, filename);
 
528
  if (cinfo->quant_tbl_ptrs[0])
 
529
    {
 
530
      for (i = 0; i < DCTSIZE2; i++)
 
531
        table_data->luminance[i] = cinfo->quant_tbl_ptrs[0]->quantval[i];
 
532
    }
 
533
  else
 
534
    {
 
535
      for (i = 0; i < DCTSIZE2; i++)
 
536
        table_data->luminance[i] = 0;
 
537
    }
 
538
  if (cinfo->quant_tbl_ptrs[1])
 
539
    {
 
540
      for (i = 0; i < DCTSIZE2; i++)
 
541
        table_data->chrominance[i] = cinfo->quant_tbl_ptrs[1]->quantval[i];
 
542
    }
 
543
  else
 
544
    {
 
545
      for (i = 0; i < DCTSIZE2; i++)
 
546
        table_data->chrominance[i] = 0;
 
547
    }
 
548
  found_tables = g_slist_prepend (found_tables, table_data);
 
549
}
 
550
 
 
551
/*
 
552
 * Analyze the JPEG quantization tables and return a list of devices or
 
553
 * software that can generate the same tables and subsampling factors.
 
554
 */
426
555
static GSList *
427
 
detect_source (struct jpeg_decompress_struct *cinfo)
 
556
detect_source (struct jpeg_decompress_struct *cinfo,
 
557
               gint                           num_quant_tables)
428
558
{
429
 
  guint   lum_sum;
430
 
  guint   chrom_sum;
431
 
  gint    i;
432
 
  GSList *source_list;
 
559
  guint    lum_sum;
 
560
  guint    chrom_sum;
 
561
  gint     i;
 
562
  GSList  *source_list;
433
563
 
434
564
  /* compute sum of luminance and chrominance quantization tables */
435
565
  lum_sum = 0;
436
566
  chrom_sum = 0;
437
 
  for (i = 0; i < DCTSIZE2; i++)
438
 
    lum_sum += cinfo->quant_tbl_ptrs[0]->quantval[i];
439
 
 
 
567
  if (cinfo->quant_tbl_ptrs[0])
 
568
    {
 
569
      for (i = 0; i < DCTSIZE2; i++)
 
570
        lum_sum += cinfo->quant_tbl_ptrs[0]->quantval[i];
 
571
    }
440
572
  if (cinfo->quant_tbl_ptrs[1])
441
573
    {
442
574
      for (i = 0; i < DCTSIZE2; i++)
445
577
 
446
578
  /* there can be more than one match (if sampling factors are compatible) */
447
579
  source_list = NULL;
448
 
  if (chrom_sum == 0)
 
580
  if (chrom_sum == 0 && num_quant_tables == 1)
449
581
    {
450
582
      /* grayscale */
451
583
      for (i = 0; i < G_N_ELEMENTS (quant_info); i++)
456
588
                  == cinfo->comp_info[0].h_samp_factor)
457
589
              && (quant_info[i].subsmp_v == 0
458
590
                  || quant_info[i].subsmp_v
459
 
                  == cinfo->comp_info[0].v_samp_factor))
 
591
                  == cinfo->comp_info[0].v_samp_factor)
 
592
              && quant_info[i].num_quant_tables > 0)
460
593
            {
461
594
              source_list = g_slist_append (source_list,
462
595
                                            (gpointer) (quant_info + i));
475
608
                  == cinfo->comp_info[0].h_samp_factor)
476
609
              && (quant_info[i].subsmp_v == 0
477
610
                  || quant_info[i].subsmp_v
478
 
                  == cinfo->comp_info[0].v_samp_factor))
 
611
                  == cinfo->comp_info[0].v_samp_factor)
 
612
              && (quant_info[i].num_quant_tables == num_quant_tables
 
613
                  || quant_info[i].num_quant_tables == -num_quant_tables))
479
614
            {
480
615
              source_list = g_slist_append (source_list,
481
616
                                            (gpointer) (quant_info + i));
486
621
  return source_list;
487
622
}
488
623
 
 
624
/*
 
625
 * ... FIXME: docs
 
626
 */
489
627
static void
490
 
print_summary (struct jpeg_decompress_struct *cinfo)
 
628
print_summary (struct jpeg_decompress_struct *cinfo,
 
629
               gint                           num_quant_tables)
491
630
{
492
631
  gint       quality;
493
632
  gint       i;
520
659
    }
521
660
  g_print ("\n");
522
661
 
523
 
  source_list = detect_source (cinfo);
 
662
  /* Number of quantization tables */
 
663
  g_print ("\tQ.tables: %d\n", num_quant_tables);
 
664
 
 
665
  source_list = detect_source (cinfo, num_quant_tables);
524
666
  if (source_list)
525
667
    {
526
668
      GSList *l;
549
691
  gint i;
550
692
 
551
693
  g_return_if_fail (quant_table != NULL);
552
 
  g_print ("    {  /* table %d */\n      ", table_id);
 
694
  if (table_id >= 0)
 
695
    g_print ("    {  /* table %d */\n      ", table_id);
 
696
  else
 
697
    g_print ("    {\n      ");
553
698
  for (i = 0; i < DCTSIZE2; i++)
554
699
    {
555
700
      if (i == DCTSIZE2 - 1)
621
766
}
622
767
 
623
768
/*
 
769
 * Error handling as in the IJG libjpeg example.
 
770
 */
 
771
typedef struct my_error_mgr
 
772
{
 
773
  struct jpeg_error_mgr pub;            /* "public" fields */
 
774
#ifdef __ia64__
 
775
  long double           dummy;          /* bug #138357 */
 
776
#endif
 
777
  jmp_buf               setjmp_buffer;  /* for return to caller */
 
778
} *my_error_ptr;
 
779
 
 
780
static void
 
781
my_error_exit (j_common_ptr cinfo)
 
782
{
 
783
  my_error_ptr myerr = (my_error_ptr) cinfo->err;
 
784
  (*cinfo->err->output_message) (cinfo);
 
785
  longjmp (myerr->setjmp_buffer, 1);
 
786
}
 
787
 
 
788
/*
624
789
 * Analyze a JPEG file according to the command-line options.
625
790
 */
626
791
static gboolean
627
 
analyze_file (const gchar *filename)
 
792
analyze_file (gchar *filename)
628
793
{
629
794
  struct jpeg_decompress_struct  cinfo;
630
 
  struct jpeg_error_mgr          jerr;
 
795
  struct my_error_mgr            jerr;
631
796
  FILE                          *f;
632
797
  gint                           i;
 
798
  gint                           num_quant_tables;
633
799
  GSList                        *source_list;
634
800
 
635
801
  if ((f = fopen (filename, "rb")) == NULL)
636
802
    {
637
 
      g_print ("Cannot open '%s'\n", filename);
 
803
      g_printerr ("Cannot open '%s'\n", filename);
638
804
      return FALSE;
639
805
    }
640
806
 
641
807
  if (option_summary)
642
808
    g_print ("%s:\n", filename);
643
809
 
644
 
  cinfo.err = jpeg_std_error (&jerr);
 
810
  cinfo.err = jpeg_std_error (&jerr.pub);
 
811
  jerr.pub.error_exit = my_error_exit;
 
812
  if (setjmp (jerr.setjmp_buffer))
 
813
    {
 
814
      /* if we get here, the JPEG code has signaled an error. */
 
815
      jpeg_destroy_decompress (&cinfo);
 
816
      fclose (f);
 
817
      return FALSE;
 
818
    }
645
819
  jpeg_create_decompress (&cinfo);
646
820
 
647
821
  jpeg_stdio_src (&cinfo, f);
648
822
 
649
823
  jpeg_read_header (&cinfo, TRUE);
650
824
 
651
 
  source_list = detect_source (&cinfo);
652
 
  if (!source_list || !option_unknown)
 
825
  num_quant_tables = 0;
 
826
  for (i = 0; i < 4; i++)
 
827
    if (cinfo.quant_tbl_ptrs[i])
 
828
      num_quant_tables++;
 
829
 
 
830
  source_list = detect_source (&cinfo, num_quant_tables);
 
831
  add_unknown_table (&cinfo, filename); /* FIXME */
 
832
  /*
 
833
  if (!source_list)
 
834
    {
 
835
      add_unknown_table (&cinfo, filename);
 
836
    }
 
837
  */
 
838
  if (! option_unknown)
653
839
    {
654
840
      if (option_summary)
655
 
        print_summary (&cinfo);
 
841
        print_summary (&cinfo, num_quant_tables);
656
842
 
657
843
      if (option_ctable)
658
844
        {
659
 
          g_print ("  {\n    /* %s */\n    \"%s\", \"?\",\n    %hd, %hd,\n",
 
845
          g_print ("  {\n    /* %s */\n    \"?\", \"?\",\n    %hd, %hd,\n    %d,\n",
660
846
                   filename,
661
 
                   (option_name ? option_name : filename),
662
847
                   cinfo.comp_info[0].h_samp_factor,
663
 
                   cinfo.comp_info[0].v_samp_factor);
 
848
                   cinfo.comp_info[0].v_samp_factor,
 
849
                   num_quant_tables);
664
850
          for (i = 0; i < 4; i++)
665
851
            if (cinfo.quant_tbl_ptrs[i])
666
852
              print_ctable (i, cinfo.quant_tbl_ptrs[i]->quantval,
688
874
}
689
875
 
690
876
/*
691
 
 * Help?
 
877
 * ... FIXME: docs
692
878
 */
693
879
static void
694
 
usage (void)
 
880
print_unknown_tables (void)
695
881
{
696
 
  const OptionDesc *opt;
697
 
 
698
 
  g_print ("This program analyzes the quantization tables of the JPEG files given on the\n"
699
 
           "command line and displays their quality settings.\n"
700
 
           "\n");
701
 
  g_print ("Usage:\n"
702
 
           "  jpegqual [options] file [[options] file [...]]\n"
703
 
           "\n");
704
 
  g_print ("Options:\n");
705
 
  for (opt = options_desc; opt->option; opt++)
706
 
    g_print ("  %-20s %s.\n", opt->option, opt->description);
707
 
  g_print ("\n");
708
 
  g_print ("Options may be given before any file.  Long boolean options can be negated\n"
709
 
           "by prefixing them with --no.  For example: --no-summary.\n");
 
882
  GSList         *list;
 
883
  GSList         *flist;
 
884
  QuantTableData *table_data;
 
885
  gint            num_files;
 
886
  gint            total_files = 0;
 
887
 
 
888
  for (list = found_tables; list; list = list->next)
 
889
    {
 
890
      table_data = list->data;
 
891
 
 
892
      if (option_ctable)
 
893
        {
 
894
          g_print ("  {\n");
 
895
          num_files = 0;
 
896
          for (flist = table_data->files; flist; flist = flist->next)
 
897
            {
 
898
              g_print("    /* %s */\n", (gchar *)(flist->data));
 
899
              num_files++;
 
900
            }
 
901
 
 
902
          { /* FIXME */
 
903
            guint    lum_sum;
 
904
            guint    chrom_sum;
 
905
            gint     i;
 
906
 
 
907
            total_files += num_files;
 
908
            lum_sum = 0;
 
909
            chrom_sum = 0;
 
910
            for (i = 0; i < DCTSIZE2; i++)
 
911
              lum_sum += table_data->luminance[i];
 
912
            for (i = 0; i < DCTSIZE2; i++)
 
913
              chrom_sum += table_data->chrominance[i];
 
914
            g_print ("    /* hash 0x%x, IJG %d, lum %d, chrom %d, files: %d */\n",
 
915
                     table_data->hashval,
 
916
                     table_data->ijg_qual,
 
917
                     lum_sum, chrom_sum,
 
918
                     num_files);
 
919
 
 
920
            if (chrom_sum == 0 && table_data->num_quant_tables == 1)
 
921
              {
 
922
                /* grayscale */
 
923
                for (i = 0; i < G_N_ELEMENTS (quant_info); i++)
 
924
                  {
 
925
                    if (quant_info[i].lum_sum == lum_sum
 
926
                        && (quant_info[i].subsmp_h == 0
 
927
                            || quant_info[i].subsmp_h
 
928
                            == table_data->subsmp_h)
 
929
                        && (quant_info[i].subsmp_v == 0
 
930
                            || quant_info[i].subsmp_v
 
931
                            == table_data->subsmp_v)
 
932
                        && quant_info[i].num_quant_tables > 0)
 
933
                      {
 
934
                        g_print("    XXX \"%s\", \"%s\",\n",
 
935
                                quant_info[i].source_name,
 
936
                                quant_info[i].setting_name);
 
937
                      }
 
938
                  }
 
939
              }
 
940
            else
 
941
              {
 
942
                /* RGB and other color spaces */
 
943
                for (i = 0; i < G_N_ELEMENTS (quant_info); i++)
 
944
                  {
 
945
                    if (quant_info[i].lum_sum == lum_sum
 
946
                        && quant_info[i].chrom_sum == chrom_sum
 
947
                        && (quant_info[i].subsmp_h == 0
 
948
                            || quant_info[i].subsmp_h
 
949
                            == table_data->subsmp_h)
 
950
                        && (quant_info[i].subsmp_v == 0
 
951
                            || quant_info[i].subsmp_v
 
952
                            == table_data->subsmp_v)
 
953
                        && (quant_info[i].num_quant_tables == table_data->num_quant_tables
 
954
                            || quant_info[i].num_quant_tables == -table_data->num_quant_tables))
 
955
                      {
 
956
                        g_print("    XXX \"%s\", \"%s\",\n",
 
957
                                quant_info[i].source_name,
 
958
                                quant_info[i].setting_name);
 
959
                      }
 
960
                  }
 
961
              }
 
962
          } /* FIXME */
 
963
 
 
964
          g_print ("    \"?\", \"? (hash %x)\",\n"
 
965
                   "    %hd, %hd,\n    %d,\n",
 
966
                   table_data->hashval,
 
967
                   table_data->subsmp_h,
 
968
                   table_data->subsmp_v,
 
969
                   -table_data->num_quant_tables);
 
970
          print_ctable (-1, table_data->luminance, TRUE);
 
971
          print_ctable (-1, table_data->chrominance, FALSE);
 
972
          g_print ("  },\n");
 
973
        }
 
974
    }
 
975
  g_print ("/* TOTAL FILES: %d */\n", total_files);
710
976
}
711
977
 
712
978
/*
716
982
main (int   argc,
717
983
      char *argv[])
718
984
{
719
 
  gboolean parse_options = TRUE;
 
985
  GError         *error = NULL;
 
986
  GOptionContext *context;
720
987
 
721
988
  g_set_prgname ("jpegqual");
722
 
  if (argc > 1)
723
 
    {
724
 
      for (argv++, argc--; argc; argv++, argc--)
725
 
        {
726
 
          if (parse_options && **argv == '-')
727
 
            {
728
 
              if (! strcmp (*argv, "--"))
729
 
                parse_options = FALSE;
730
 
              else if (! strcmp (*argv, "-s") || ! strcmp (*argv, "--summary"))
731
 
                option_summary = TRUE;
732
 
              else if (! strcmp (*argv, "--no-summary"))
733
 
                option_summary = FALSE;
734
 
              else if (! strcmp (*argv, "-c") || ! strcmp (*argv, "--c-tables"))
735
 
                option_ctable = TRUE;
736
 
              else if (! strcmp (*argv, "--no-c-tables"))
737
 
                option_ctable = FALSE;
738
 
              else if (! strcmp (*argv, "-t") || ! strcmp (*argv, "--tables"))
739
 
                option_table_2cols = TRUE;
740
 
              else if (! strcmp (*argv, "--no-tables"))
741
 
                option_table_2cols = FALSE;
742
 
              else if ((! strcmp (*argv, "-n") || ! strcmp (*argv, "--name"))
743
 
                        && argc > 1)
744
 
                {
745
 
                  argv++;
746
 
                  argc--;
747
 
                  option_name = *argv;
748
 
                }
749
 
              else if (! strcmp (*argv, "-u") || ! strcmp (*argv, "--unknown"))
750
 
                option_unknown = TRUE;
751
 
              else if (! strcmp (*argv, "--no-unkown"))
752
 
                option_unknown = FALSE;
753
 
              else if (! strcmp (*argv, "-h") || ! strcmp (*argv, "--help")
754
 
                       || ! strcmp (*argv, "-?"))
755
 
                {
756
 
                  usage ();
757
 
                  return 0;
758
 
                }
759
 
              else
760
 
                {
761
 
                  g_print ("Unknown option or missing argument: '%s'.  "
762
 
                           "Try '--help' for help.\n", *argv);
763
 
                  return 1;
764
 
                }
765
 
            }
766
 
          else
767
 
            {
768
 
              if (! analyze_file (*argv))
769
 
                return 1;
770
 
            }
771
 
        }
772
 
      return 0;
773
 
    }
774
 
  else
775
 
    {
776
 
      usage ();
 
989
 
 
990
  context = g_option_context_new ("FILE [...] - analyzes JPEG quantization tables");
 
991
  g_option_context_add_main_entries (context, option_entries,
 
992
                                     NULL /* skip i18n? */);
 
993
  g_option_context_parse (context, &argc, &argv, &error);
 
994
  if (argc <= 1)
 
995
    {
 
996
      g_printerr ("Missing file name.  Try the option --help for help\n");
777
997
      return 1;
778
998
    }
 
999
  if (!option_summary && !option_ctable && !option_table_2cols)
 
1000
    {
 
1001
      g_printerr ("Missing output option.  Assuming that you wanted --summary.\n");
 
1002
      option_summary = TRUE;
 
1003
    }
 
1004
 
 
1005
  for (argv++, argc--; *argv; argv++, argc--)
 
1006
    {
 
1007
      if (! analyze_file (*argv) && ! option_ignore_err)
 
1008
        return 1;
 
1009
    }
 
1010
  if (option_unknown && found_tables)
 
1011
    {
 
1012
      print_unknown_tables ();
 
1013
    }
 
1014
  return 0;
779
1015
}