Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/sdcparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* DCT filter parameter setting and reading */
18
#include "memory_.h"
19
#include "jpeglib_.h"
20
#include "gserrors.h"
21
#include "gstypes.h"
22
#include "gsmemory.h"
23
#include "gsparam.h"
24
#include "strimpl.h"    /* sdct.h requires this */
25
#include "sdct.h"
26
#include "sdcparam.h"
27
#include "sjpeg.h"
28
29
/* Define the DCT parameters. */
30
#define dctp(key, type, stype, memb) { key, type, offset_of(stype, memb) }
31
static const gs_param_item_t s_DCT_param_items[] =
32
{
33
dctp("ColorTransform", gs_param_type_int, stream_DCT_state, ColorTransform),
34
    dctp("QFactor", gs_param_type_float, stream_DCT_state, QFactor),
35
    gs_param_item_end
36
};
37
static const gs_param_item_t jsd_param_items[] =
38
{
39
    dctp("Picky", gs_param_type_int, jpeg_stream_data, Picky),
40
    dctp("Relax", gs_param_type_int, jpeg_stream_data, Relax),
41
    dctp("Height", gs_param_type_int, jpeg_stream_data, Height),
42
    gs_param_item_end
43
};
44
45
#undef dctp
46
47
/*
48
 * Adobe specifies the values to be supplied in zigzag order.
49
 * For IJG versions newer than v6, we need to convert this order
50
 * to natural array order.  Older IJG versions want zigzag order.
51
 */
52
#if JPEG_LIB_VERSION >= 61
53
        /* natural array position of n'th element of JPEG zigzag order */
54
static const byte natural_order[DCTSIZE2] =
55
{
56
    0, 1, 8, 16, 9, 2, 3, 10,
57
    17, 24, 32, 25, 18, 11, 4, 5,
58
    12, 19, 26, 33, 40, 48, 41, 34,
59
    27, 20, 13, 6, 7, 14, 21, 28,
60
    35, 42, 49, 56, 57, 50, 43, 36,
61
    29, 22, 15, 23, 30, 37, 44, 51,
62
    58, 59, 52, 45, 38, 31, 39, 46,
63
    53, 60, 61, 54, 47, 55, 62, 63
64
};
65
66
0
#define jpeg_order(x)  natural_order[x]
67
        /* invert natural_order for getting parameters */
68
static const byte inverse_natural_order[DCTSIZE2] =
69
{
70
    0, 1, 5, 6, 14, 15, 27, 28,
71
    2, 4, 7, 13, 16, 26, 29, 42,
72
    3, 8, 12, 17, 25, 30, 41, 43,
73
    9, 11, 18, 24, 31, 40, 44, 53,
74
    10, 19, 23, 32, 39, 45, 52, 54,
75
    20, 22, 33, 38, 46, 51, 55, 60,
76
    21, 34, 37, 47, 50, 56, 59, 61,
77
    35, 36, 48, 49, 57, 58, 62, 63
78
};
79
80
0
#define jpeg_inverse_order(x)  inverse_natural_order[x]
81
#else
82
#define jpeg_order(x)  (x)
83
#define jpeg_inverse_order(x) (x)
84
#endif
85
86
/* ================ Get parameters ================ */
87
88
static int
89
quant_param_string(gs_param_string * pstr, int count, const UINT16 * pvals,
90
                   double QFactor, gs_memory_t * mem)
91
0
{
92
0
    byte *data;
93
0
    int code = 0;
94
0
    int i;
95
96
0
    data = gs_alloc_string(mem, count, "quant_param_string");
97
0
    if (data == 0)
98
0
        return_error(gs_error_VMerror);
99
0
    for (i = 0; i < count; ++i) {
100
0
        double val = pvals[jpeg_inverse_order(i)] / QFactor;
101
102
0
        data[i] =
103
0
            (val < 1 ? (code = 1) : val > 255 ? (code = 255) : (byte) val);
104
0
    }
105
0
    pstr->data = data;
106
0
    pstr->size = count;
107
0
    pstr->persistent = true;
108
0
    return code & 1;
109
0
}
110
111
static int
112
quant_param_array(gs_param_float_array * pfa, int count, const UINT16 * pvals,
113
                  double QFactor, gs_memory_t * mem)
114
0
{
115
0
    float *data;
116
0
    int i;
117
118
0
    data = (float *)gs_alloc_byte_array(mem, count, sizeof(float),
119
0
                                        "quant_param_array");
120
121
0
    if (data == 0)
122
0
        return_error(gs_error_VMerror);
123
0
    for (i = 0; i < count; ++i)
124
0
        data[i] = pvals[jpeg_inverse_order(i)] / QFactor;
125
0
    pfa->data = data;
126
0
    pfa->size = count;
127
0
    pfa->persistent = true;
128
0
    return 0;
129
0
}
130
131
int
132
s_DCT_get_quantization_tables(gs_param_list * plist,
133
           const stream_DCT_state * pdct, const stream_DCT_state * defaults,
134
                              bool is_encode)
135
0
{
136
0
    gs_memory_t *mem = pdct->memory;
137
0
    jpeg_component_info d_comp_info[4];
138
0
    int num_in_tables;
139
0
    const jpeg_component_info *comp_info;
140
0
    const jpeg_component_info *default_comp_info;
141
0
    JQUANT_TBL **table_ptrs;
142
0
    JQUANT_TBL **default_table_ptrs;
143
0
    gs_param_array quant_tables;
144
0
    double QFactor = pdct->QFactor;
145
0
    int i;
146
0
    int code;
147
148
0
    if (is_encode) {
149
0
        num_in_tables = pdct->data.compress->cinfo.num_components;
150
0
        comp_info = pdct->data.compress->cinfo.comp_info;
151
0
        table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
152
0
        if (defaults) {
153
0
            default_comp_info = defaults->data.compress->cinfo.comp_info;
154
0
            default_table_ptrs = defaults->data.compress->cinfo.quant_tbl_ptrs;
155
0
        }
156
0
    } else {
157
0
        quant_tables.size = count_of(d_comp_info);
158
0
        num_in_tables = quant_tables.size;
159
0
        for (i = 0; i < num_in_tables; ++i)
160
0
            d_comp_info[i].quant_tbl_no = i;
161
0
        comp_info = d_comp_info;
162
0
        table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
163
0
        if (defaults) {
164
0
            default_comp_info = d_comp_info;
165
0
            default_table_ptrs =
166
0
                defaults->data.decompress->dinfo.quant_tbl_ptrs;
167
0
        }
168
0
    }
169
170
    /* Check whether all tables match defaults. */
171
0
    if (defaults) {
172
0
        bool match = true;
173
174
0
        for (i = 0; i < num_in_tables; ++i) {
175
0
            JQUANT_TBL *tbl = table_ptrs[comp_info[i].quant_tbl_no];
176
0
            JQUANT_TBL *default_tbl =
177
0
            (default_comp_info == 0 || default_table_ptrs == 0 ? 0 :
178
0
             default_table_ptrs[default_comp_info[i].quant_tbl_no]);
179
180
0
            if (tbl == default_tbl)
181
0
                continue;
182
0
            if (tbl == 0 || default_tbl == 0 ||
183
0
                memcmp(tbl->quantval, default_tbl->quantval,
184
0
                       DCTSIZE2 * sizeof(UINT16))
185
0
                ) {
186
0
                match = false;
187
0
                break;
188
0
            }
189
0
        }
190
0
        if (match)
191
0
            return 0;
192
0
    }
193
0
    quant_tables.size = num_in_tables;
194
0
    code = param_begin_write_collection(plist, "QuantTables",
195
0
                                        &quant_tables,
196
0
                                        gs_param_collection_array);
197
0
    if (code < 0)
198
0
        return code;
199
0
    for (i = 0; i < num_in_tables; ++i) {
200
0
        char key[3];
201
0
        gs_param_string str;
202
0
        gs_param_float_array fa;
203
204
0
        gs_snprintf(key, sizeof(key), "%d", i);
205
0
        if (QFactor == 1.0) {
206
0
            code = quant_param_string(&str, DCTSIZE2,
207
0
                            table_ptrs[comp_info[i].quant_tbl_no]->quantval,
208
0
                                      QFactor, mem);
209
0
            switch (code) {
210
0
                case 0:
211
0
                    code = param_write_string(quant_tables.list, key, &str);
212
0
                    if (code < 0)
213
0
                        return code; /* should dealloc */
214
0
                    continue;
215
0
                default:
216
0
                    return code; /* should dealloc */
217
0
                case 1:
218
0
                    break;
219
0
            }
220
0
            gs_free_const_string(mem, str.data, str.size,
221
0
                                 "quant_param_string");
222
0
        }
223
0
        code = quant_param_array(&fa, DCTSIZE2,
224
0
                            table_ptrs[comp_info[i].quant_tbl_no]->quantval,
225
0
                                 QFactor, mem);
226
0
        if (code < 0)
227
0
            return code; /* should dealloc */
228
0
        code = param_write_float_array(quant_tables.list, key, &fa);
229
0
        if (code < 0)
230
0
            return code; /* should dealloc */
231
0
    }
232
0
    return param_end_write_dict(plist, "QuantTables", &quant_tables);
233
0
}
234
235
static int
236
pack_huff_table(gs_param_string * pstr, const JHUFF_TBL * table,
237
                gs_memory_t * mem)
238
0
{
239
0
    int total;
240
0
    int i;
241
0
    byte *data;
242
243
0
    for (i = 1, total = 0; i <= 16; ++i)
244
0
        total += table->bits[i];
245
0
    data = gs_alloc_string(mem, 16 + total, "pack_huff_table");
246
0
    if (data == 0)
247
0
        return_error(gs_error_VMerror);
248
0
    memcpy(data, table->bits + 1, 16);
249
0
    memcpy(data + 16, table->huffval, total);
250
0
    pstr->data = data;
251
0
    pstr->size = 16 + total;
252
0
    pstr->persistent = true;
253
0
    return 0;
254
0
}
255
256
int
257
s_DCT_get_huffman_tables(gs_param_list * plist,
258
           const stream_DCT_state * pdct, const stream_DCT_state * defaults,
259
                         bool is_encode)
260
0
{
261
0
    gs_memory_t *mem = pdct->memory;
262
0
    gs_param_string *huff_data;
263
0
    gs_param_string_array hta;
264
0
    int num_in_tables;
265
0
    JHUFF_TBL **dc_table_ptrs;
266
0
    JHUFF_TBL **ac_table_ptrs;
267
0
    int i;
268
0
    int code = 0;
269
270
0
    if (is_encode) {
271
0
        dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
272
0
        ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
273
0
        num_in_tables = pdct->data.compress->cinfo.input_components * 2;
274
0
    } else {
275
0
        dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
276
0
        ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
277
0
        for (i = 2; i > 0; --i)
278
0
            if (dc_table_ptrs[i - 1] || ac_table_ptrs[i - 1])
279
0
                break;
280
0
        num_in_tables = i * 2;
281
0
    }
282
/****** byte_array IS WRONG ******/
283
0
    huff_data = (gs_param_string *)
284
0
        gs_alloc_byte_array(mem, num_in_tables, sizeof(gs_param_string),
285
0
                            "get huffman tables");
286
0
    if (huff_data == 0)
287
0
        return_error(gs_error_VMerror);
288
0
    for (i = 0; i < num_in_tables; i += 2) {
289
0
        if ((code = pack_huff_table(huff_data + i, ac_table_ptrs[i >> 1], mem)) < 0 ||
290
0
            (code = pack_huff_table(huff_data + i + 1, dc_table_ptrs[i >> 1], mem))
291
0
            )
292
0
            break;
293
0
    }
294
0
    if (code < 0)
295
0
        return code;
296
0
    hta.data = huff_data;
297
0
    hta.size = num_in_tables;
298
0
    hta.persistent = true;
299
0
    return param_write_string_array(plist, "HuffTables", &hta);
300
0
}
301
302
int
303
s_DCT_get_params(gs_param_list * plist, const stream_DCT_state * ss,
304
                 const stream_DCT_state * defaults)
305
0
{
306
0
    int code =
307
0
    gs_param_write_items(plist, ss, defaults, s_DCT_param_items);
308
309
0
    if (code >= 0)
310
0
        code = gs_param_write_items(plist, ss->data.common,
311
0
                                    (defaults ? defaults->data.common :
312
0
                                     NULL),
313
0
                                    jsd_param_items);
314
0
    return code;
315
0
}
316
317
/* ================ Put parameters ================ */
318
319
stream_state_proc_put_params(s_DCT_put_params, stream_DCT_state); /* check */
320
321
/* ---------------- Utilities ---------------- */
322
323
/*
324
 * Get N byte-size values from an array or a string.
325
 * Used for HuffTables, HSamples, VSamples.
326
 */
327
int
328
s_DCT_byte_params(gs_param_list * plist, gs_param_name key, int start,
329
                  int count, UINT8 * pvals)
330
756k
{
331
756k
    int i;
332
756k
    gs_param_string bytes;
333
756k
    gs_param_float_array floats;
334
756k
    gs_param_int_array ints;
335
756k
    int code = param_read_string(plist, key, &bytes);
336
337
756k
    switch (code) {
338
0
        case 0:
339
0
            if (bytes.size < start + count) {
340
0
                code = gs_note_error(gs_error_rangecheck);
341
0
            } else {
342
0
                for (i = 0; i < count; ++i)
343
0
                    pvals[i] = (UINT8) bytes.data[start + i];
344
0
                code = 0;
345
0
            }
346
0
            break;
347
756k
        default:    /* might be a float array */
348
756k
            code = param_read_int_array(plist, key, &ints);
349
756k
            if (!code) {
350
756k
                if (ints.size < start + count) {
351
0
                    code = gs_note_error(gs_error_rangecheck);
352
756k
                } else {
353
3.02M
                    for (i = 0; i < count; ++i) {
354
2.26M
                        pvals[i] = ints.data[start + i];
355
2.26M
                    }
356
756k
                    code = 0;
357
756k
                }
358
756k
            } else {
359
0
                code = param_read_float_array(plist, key, &floats);
360
0
                if (!code) {
361
0
                    if (floats.size < start + count) {
362
0
                        code = gs_note_error(gs_error_rangecheck);
363
0
                    } else {
364
0
                        for (i = 0; i < count; ++i) {
365
0
                            float v = floats.data[start + i];
366
367
0
                            if (v < 0 || v > 255) {
368
0
                                code = gs_note_error(gs_error_rangecheck);
369
0
                                break;
370
0
                            }
371
0
                            pvals[i] = (UINT8) (v + 0.5);
372
0
                        }
373
0
                    }
374
0
                    if (code >= 0)
375
0
                        code = 0;
376
0
                } else
377
0
                    code = 1;
378
0
            }
379
756k
            break;
380
756k
    }
381
756k
    if (code < 0)
382
0
        param_signal_error(plist, key, code);
383
756k
    return code;
384
756k
}
385
386
/* Get N quantization values from an array or a string. */
387
static int
388
quant_params(gs_param_list * plist, gs_param_name key, int count,
389
             UINT16 * pvals, double QFactor)
390
0
{
391
0
    int i;
392
0
    gs_param_string bytes;
393
0
    gs_param_float_array floats;
394
0
    int code = param_read_string(plist, key, &bytes);
395
396
0
    switch (code) {
397
0
        case 0:
398
0
            if (bytes.size != count) {
399
0
                code = gs_note_error(gs_error_rangecheck);
400
0
                break;
401
0
            }
402
0
            for (i = 0; i < count; ++i) {
403
0
                double v = bytes.data[i] * QFactor;
404
405
0
                pvals[jpeg_order(i)] =
406
0
                    (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
407
0
            }
408
0
            return 0;
409
0
        default:    /* might be a float array */
410
0
            code = param_read_float_array(plist, key, &floats);
411
0
            if (!code) {
412
0
                if (floats.size != count) {
413
0
                    code = gs_note_error(gs_error_rangecheck);
414
0
                    break;
415
0
                }
416
0
                for (i = 0; i < count; ++i) {
417
0
                    double v = floats.data[i] * QFactor;
418
419
0
                    pvals[jpeg_order(i)] =
420
0
                        (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
421
0
                }
422
0
            }
423
0
    }
424
0
    if (code < 0)
425
0
        param_signal_error(plist, key, code);
426
0
    return code;
427
0
#undef jpeg_order
428
0
}
429
430
/* ---------------- Main procedures ---------------- */
431
432
/* Put common scalars. */
433
int
434
s_DCT_put_params(gs_param_list * plist, stream_DCT_state * pdct)
435
378k
{
436
378k
    int code =
437
378k
    gs_param_read_items(plist, pdct, s_DCT_param_items, NULL);
438
439
378k
    if (code < 0)
440
0
        return code;
441
378k
    code = gs_param_read_items(plist, pdct->data.common, jsd_param_items, NULL);
442
378k
    if (code < 0)
443
0
        return code;
444
378k
    if (pdct->data.common->Picky < 0 || pdct->data.common->Picky > 1 ||
445
378k
        pdct->data.common->Relax < 0 || pdct->data.common->Relax > 1 ||
446
378k
        pdct->ColorTransform < -1 || pdct->ColorTransform > 2 ||
447
378k
        pdct->QFactor < 0.0 || pdct->QFactor > 1000000.0
448
378k
        )
449
0
        return_error(gs_error_rangecheck);
450
378k
    return 0;
451
378k
}
452
453
/* Put quantization tables. */
454
int
455
s_DCT_put_quantization_tables(gs_param_list * plist, stream_DCT_state * pdct,
456
                              bool is_encode)
457
378k
{
458
378k
    int code;
459
378k
    int i, j;
460
378k
    gs_param_array quant_tables;  /* array of strings/arrays */
461
378k
    int num_in_tables;
462
378k
    int num_out_tables;
463
378k
    jpeg_component_info *comp_info;
464
378k
    JQUANT_TBL **table_ptrs;
465
378k
    JQUANT_TBL *this_table;
466
467
378k
    switch ((code = param_begin_read_dict(plist, "QuantTables",
468
378k
                                          &quant_tables, true))
469
378k
        ) {
470
378k
        case 1:
471
378k
            return 1;
472
0
        default:
473
0
            return param_signal_error(plist, "QuantTables", code);
474
0
        case 0:
475
0
            ;
476
378k
    }
477
0
    if (is_encode) {
478
0
        num_in_tables = pdct->data.compress->cinfo.num_components;
479
0
        if (quant_tables.size < num_in_tables)
480
0
            return_error(gs_error_rangecheck);
481
0
        comp_info = pdct->data.compress->cinfo.comp_info;
482
0
        table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
483
0
    } else {
484
0
        num_in_tables = quant_tables.size;
485
0
        comp_info = NULL; /* do not set for decompress case */
486
0
        table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
487
0
    }
488
0
    num_out_tables = 0;
489
0
    for (i = 0; i < num_in_tables; ++i) {
490
0
        char istr[5];   /* i converted to string key */
491
0
        UINT16 values[DCTSIZE2];
492
493
0
        gs_snprintf(istr, sizeof(istr), "%d", i);
494
0
        code = quant_params(quant_tables.list, istr, DCTSIZE2, values,
495
0
                            pdct->QFactor);
496
0
        if (code < 0)
497
0
            return code;
498
        /* Check for duplicate tables. */
499
0
        for (j = 0; j < num_out_tables; j++) {
500
0
            if (!memcmp(table_ptrs[j]->quantval, values, sizeof(values)))
501
0
                break;
502
0
        }
503
0
        if (comp_info != NULL)
504
0
            comp_info[i].quant_tbl_no = j;
505
0
        if (j < num_out_tables) /* found a duplicate */
506
0
            continue;
507
0
        if (++num_out_tables > NUM_QUANT_TBLS)
508
0
            return_error(gs_error_rangecheck);
509
0
        this_table = table_ptrs[j];
510
0
        if (this_table == NULL) {
511
0
            this_table = gs_jpeg_alloc_quant_table(pdct);
512
0
            if (this_table == NULL)
513
0
                return_error(gs_error_VMerror);
514
0
            table_ptrs[j] = this_table;
515
0
        }
516
0
        memcpy(this_table->quantval, values, sizeof(values));
517
0
    }
518
0
    return 0;
519
0
}
520
521
/* Put Huffman tables. */
522
static int
523
find_huff_values(JHUFF_TBL ** table_ptrs, int num_tables,
524
               const UINT8 * counts, const UINT8 * values, int codes_size)
525
0
{
526
0
    int j;
527
528
0
    for (j = 0; j < num_tables; ++j)
529
0
        if (!memcmp(table_ptrs[j]->bits, counts, 16*sizeof(counts[0])) &&
530
0
            !memcmp(table_ptrs[j]->huffval, values,
531
0
                    codes_size * sizeof(values[0])))
532
0
            break;
533
0
    return j;
534
0
}
535
int
536
s_DCT_put_huffman_tables(gs_param_list * plist, stream_DCT_state * pdct,
537
                         bool is_encode)
538
378k
{
539
378k
    int code;
540
378k
    int i, j;
541
378k
    gs_param_array huff_tables;
542
378k
    int num_in_tables;
543
378k
    int ndc, nac;
544
378k
    int codes_size;
545
378k
    jpeg_component_info *comp_info;
546
378k
    JHUFF_TBL **dc_table_ptrs;
547
378k
    JHUFF_TBL **ac_table_ptrs;
548
378k
    JHUFF_TBL **this_table_ptr;
549
378k
    JHUFF_TBL *this_table;
550
378k
    int max_tables = 2;   /* baseline limit */
551
552
378k
    switch ((code = param_begin_read_dict(plist, "HuffTables",
553
378k
                                          &huff_tables, true))
554
378k
        ) {
555
378k
        case 1:
556
378k
            return 0;
557
0
        default:
558
0
            return param_signal_error(plist, "HuffTables", code);
559
0
        case 0:
560
0
            ;
561
378k
    }
562
0
    if (is_encode) {
563
0
        num_in_tables = pdct->data.compress->cinfo.input_components * 2;
564
0
        if (huff_tables.size < num_in_tables)
565
0
            return_error(gs_error_rangecheck);
566
0
        comp_info = pdct->data.compress->cinfo.comp_info;
567
0
        dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
568
0
        ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
569
0
        if (pdct->data.common->Relax)
570
0
            max_tables = max(pdct->data.compress->cinfo.input_components, 2);
571
0
    } else {
572
0
        num_in_tables = huff_tables.size;
573
0
        comp_info = NULL; /* do not set for decompress case */
574
0
        dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
575
0
        ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
576
0
        if (pdct->data.common->Relax)
577
0
            max_tables = NUM_HUFF_TBLS;
578
0
    }
579
0
    ndc = nac = 0;
580
0
    for (i = 0; i < num_in_tables; ++i) {
581
0
        char istr[5];   /* i converted to string key */
582
0
        UINT8 counts[16], values[256];
583
584
        /* Collect the Huffman parameters. */
585
0
        gs_snprintf(istr, sizeof(istr), "%d", i);
586
0
        code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts);
587
0
        if (code < 0)
588
0
            return code;
589
0
        for (codes_size = 0, j = 0; j < 16; j++)
590
0
            codes_size += counts[j];
591
0
        if (codes_size > 256 /*|| r_size(pa) != codes_size+16 */ )
592
0
            return_error(gs_error_rangecheck);
593
0
        code = s_DCT_byte_params(huff_tables.list, istr, 16, codes_size,
594
0
                                 values);
595
0
        if (code < 0)
596
0
            return code;
597
0
        if (i & 1) {
598
0
            j = find_huff_values(ac_table_ptrs, nac, counts, values,
599
0
                                 codes_size);
600
0
            if (comp_info != NULL)
601
0
                comp_info[i >> 1].ac_tbl_no = j;
602
0
            if (j < nac)
603
0
                continue;
604
0
            if (++nac > NUM_HUFF_TBLS)
605
0
                return_error(gs_error_rangecheck);
606
0
            this_table_ptr = ac_table_ptrs + j;
607
0
        } else {
608
0
            j = find_huff_values(dc_table_ptrs, ndc, counts, values,
609
0
                                 codes_size);
610
0
            if (comp_info != NULL)
611
0
                comp_info[i >> 1].dc_tbl_no = j;
612
0
            if (j < ndc)
613
0
                continue;
614
0
            if (++ndc > NUM_HUFF_TBLS)
615
0
                return_error(gs_error_rangecheck);
616
0
            this_table_ptr = dc_table_ptrs + j;
617
0
        }
618
0
        this_table = *this_table_ptr;
619
0
        if (this_table == NULL) {
620
0
            this_table = gs_jpeg_alloc_huff_table(pdct);
621
0
            if (this_table == NULL)
622
0
                return_error(gs_error_VMerror);
623
0
            *this_table_ptr = this_table;
624
0
        }
625
0
        memcpy(this_table->bits, counts, sizeof(counts));
626
0
        memcpy(this_table->huffval, values, codes_size * sizeof(values[0]));
627
0
    }
628
0
    if (nac > max_tables || ndc > max_tables)
629
0
        return_error(gs_error_rangecheck);
630
0
    return 0;
631
0
}