Coverage Report

Created: 2025-06-10 07:15

/src/ghostpdl/base/sdcparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2024 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, 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_array(gs_param_float_array * pfa, int count, const UINT16 * pvals,
90
                  double QFactor, gs_memory_t * mem)
91
0
{
92
0
    float *data;
93
0
    int i;
94
95
0
    data = (float *)gs_alloc_byte_array(mem, count, sizeof(float),
96
0
                                        "quant_param_array");
97
98
0
    if (data == 0)
99
0
        return_error(gs_error_VMerror);
100
0
    for (i = 0; i < count; ++i)
101
0
        data[i] = pvals[jpeg_inverse_order(i)] / QFactor;
102
0
    pfa->data = data;
103
0
    pfa->size = count;
104
0
    pfa->persistent = true;
105
0
    return 0;
106
0
}
107
108
int
109
s_DCT_get_quantization_tables(gs_param_list * plist,
110
           const stream_DCT_state * pdct, const stream_DCT_state * defaults,
111
                              bool is_encode)
112
0
{
113
0
    gs_memory_t *mem = pdct->memory;
114
0
    jpeg_component_info d_comp_info[4];
115
0
    int num_in_tables;
116
0
    const jpeg_component_info *comp_info;
117
0
    const jpeg_component_info *default_comp_info;
118
0
    JQUANT_TBL **table_ptrs;
119
0
    JQUANT_TBL **default_table_ptrs;
120
0
    gs_param_array quant_tables;
121
0
    double QFactor = pdct->QFactor;
122
0
    int i;
123
0
    int code;
124
125
0
    if (is_encode) {
126
0
        num_in_tables = pdct->data.compress->cinfo.num_components;
127
0
        comp_info = pdct->data.compress->cinfo.comp_info;
128
0
        table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
129
0
        if (defaults) {
130
0
            default_comp_info = defaults->data.compress->cinfo.comp_info;
131
0
            default_table_ptrs = defaults->data.compress->cinfo.quant_tbl_ptrs;
132
0
        }
133
0
    } else {
134
0
        quant_tables.size = count_of(d_comp_info);
135
0
        num_in_tables = quant_tables.size;
136
0
        for (i = 0; i < num_in_tables; ++i)
137
0
            d_comp_info[i].quant_tbl_no = i;
138
0
        comp_info = d_comp_info;
139
0
        table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
140
0
        if (defaults) {
141
0
            default_comp_info = d_comp_info;
142
0
            default_table_ptrs =
143
0
                defaults->data.decompress->dinfo.quant_tbl_ptrs;
144
0
        }
145
0
    }
146
147
    /* Check whether all tables match defaults. */
148
0
    if (defaults) {
149
0
        bool match = true;
150
151
0
        for (i = 0; i < num_in_tables; ++i) {
152
0
            JQUANT_TBL *tbl = table_ptrs[comp_info[i].quant_tbl_no];
153
0
            JQUANT_TBL *default_tbl =
154
0
            (default_comp_info == 0 || default_table_ptrs == 0 ? 0 :
155
0
             default_table_ptrs[default_comp_info[i].quant_tbl_no]);
156
157
0
            if (tbl == default_tbl)
158
0
                continue;
159
0
            if (tbl == 0 || default_tbl == 0 ||
160
0
                memcmp(tbl->quantval, default_tbl->quantval,
161
0
                       DCTSIZE2 * sizeof(UINT16))
162
0
                ) {
163
0
                match = false;
164
0
                break;
165
0
            }
166
0
        }
167
0
        if (match)
168
0
            return 0;
169
0
    }
170
0
    quant_tables.size = num_in_tables;
171
0
    code = param_begin_write_collection(plist, "QuantTables",
172
0
                                        &quant_tables,
173
0
                                        gs_param_collection_array);
174
0
    if (code < 0)
175
0
        return code;
176
0
    for (i = 0; i < num_in_tables; ++i) {
177
0
        char key[3];
178
0
        gs_param_float_array fa;
179
180
0
        gs_snprintf(key, sizeof(key), "%d", i);
181
0
        code = quant_param_array(&fa, DCTSIZE2,
182
0
                            table_ptrs[comp_info[i].quant_tbl_no]->quantval,
183
0
                                 QFactor, mem);
184
0
        if (code < 0)
185
0
            return code; /* should dealloc */
186
0
        code = param_write_float_array(quant_tables.list, key, &fa);
187
0
        if (code < 0)
188
0
            return code; /* should dealloc */
189
0
    }
190
0
    return param_end_write_dict(plist, "QuantTables", &quant_tables);
191
0
}
192
193
static int
194
pack_huff_table(gs_param_string * pstr, const JHUFF_TBL * table,
195
                gs_memory_t * mem)
196
0
{
197
0
    int total;
198
0
    int i;
199
0
    byte *data;
200
201
0
    for (i = 1, total = 0; i <= 16; ++i)
202
0
        total += table->bits[i];
203
0
    data = gs_alloc_string(mem, 16 + total, "pack_huff_table");
204
0
    if (data == 0)
205
0
        return_error(gs_error_VMerror);
206
0
    memcpy(data, table->bits + 1, 16);
207
0
    memcpy(data + 16, table->huffval, total);
208
0
    pstr->data = data;
209
0
    pstr->size = 16 + total;
210
0
    pstr->persistent = true;
211
0
    return 0;
212
0
}
213
214
int
215
s_DCT_get_huffman_tables(gs_param_list * plist,
216
           const stream_DCT_state * pdct, const stream_DCT_state * defaults,
217
                         bool is_encode)
218
0
{
219
0
    gs_memory_t *mem = pdct->memory;
220
0
    gs_param_string *huff_data;
221
0
    gs_param_string_array hta;
222
0
    int num_in_tables;
223
0
    JHUFF_TBL **dc_table_ptrs;
224
0
    JHUFF_TBL **ac_table_ptrs;
225
0
    int i;
226
0
    int code = 0;
227
228
0
    if (is_encode) {
229
0
        dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
230
0
        ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
231
0
        num_in_tables = pdct->data.compress->cinfo.input_components * 2;
232
0
    } else {
233
0
        dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
234
0
        ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
235
0
        for (i = 2; i > 0; --i)
236
0
            if (dc_table_ptrs[i - 1] || ac_table_ptrs[i - 1])
237
0
                break;
238
0
        num_in_tables = i * 2;
239
0
    }
240
/****** byte_array IS WRONG ******/
241
0
    huff_data = (gs_param_string *)
242
0
        gs_alloc_byte_array(mem, num_in_tables, sizeof(gs_param_string),
243
0
                            "get huffman tables");
244
0
    if (huff_data == 0)
245
0
        return_error(gs_error_VMerror);
246
0
    for (i = 0; i < num_in_tables; i += 2) {
247
0
        if ((code = pack_huff_table(huff_data + i, ac_table_ptrs[i >> 1], mem)) < 0 ||
248
0
            (code = pack_huff_table(huff_data + i + 1, dc_table_ptrs[i >> 1], mem))
249
0
            )
250
0
            break;
251
0
    }
252
0
    if (code < 0)
253
0
        return code;
254
0
    hta.data = huff_data;
255
0
    hta.size = num_in_tables;
256
0
    hta.persistent = true;
257
0
    return param_write_string_array(plist, "HuffTables", &hta);
258
0
}
259
260
int
261
s_DCT_get_params(gs_param_list * plist, const stream_DCT_state * ss,
262
                 const stream_DCT_state * defaults)
263
0
{
264
0
    int code =
265
0
    gs_param_write_items(plist, ss, defaults, s_DCT_param_items);
266
267
0
    if (code >= 0)
268
0
        code = gs_param_write_items(plist, ss->data.common,
269
0
                                    (defaults ? defaults->data.common :
270
0
                                     NULL),
271
0
                                    jsd_param_items);
272
0
    return code;
273
0
}
274
275
/* ================ Put parameters ================ */
276
277
stream_state_proc_put_params(s_DCT_put_params, stream_DCT_state); /* check */
278
279
/* ---------------- Utilities ---------------- */
280
281
/*
282
 * Get N byte-size values from an array or a string.
283
 * Used for HuffTables, HSamples, VSamples.
284
 */
285
int
286
s_DCT_byte_params(gs_param_list * plist, gs_param_name key, int start,
287
                  int count, UINT8 * pvals)
288
12
{
289
12
    int i;
290
12
    gs_param_string bytes;
291
12
    gs_param_float_array floats;
292
12
    gs_param_int_array ints;
293
12
    int code = param_read_string(plist, key, &bytes);
294
295
12
    switch (code) {
296
0
        case 0:
297
0
            if (bytes.size < start + count) {
298
0
                code = gs_note_error(gs_error_rangecheck);
299
0
            } else {
300
0
                for (i = 0; i < count; ++i)
301
0
                    pvals[i] = (UINT8) bytes.data[start + i];
302
0
                code = 0;
303
0
            }
304
0
            break;
305
12
        default:    /* might be a float array */
306
12
            code = param_read_int_array(plist, key, &ints);
307
12
            if (!code) {
308
12
                if (ints.size < start + count) {
309
0
                    code = gs_note_error(gs_error_rangecheck);
310
12
                } else {
311
48
                    for (i = 0; i < count; ++i) {
312
36
                        pvals[i] = ints.data[start + i];
313
36
                    }
314
12
                    code = 0;
315
12
                }
316
12
            } else {
317
0
                code = param_read_float_array(plist, key, &floats);
318
0
                if (!code) {
319
0
                    if (floats.size < start + count) {
320
0
                        code = gs_note_error(gs_error_rangecheck);
321
0
                    } else {
322
0
                        for (i = 0; i < count; ++i) {
323
0
                            float v = floats.data[start + i];
324
325
0
                            if (v < 0 || v > 255) {
326
0
                                code = gs_note_error(gs_error_rangecheck);
327
0
                                break;
328
0
                            }
329
0
                            pvals[i] = (UINT8) (v + 0.5);
330
0
                        }
331
0
                    }
332
0
                    if (code >= 0)
333
0
                        code = 0;
334
0
                } else
335
0
                    code = 1;
336
0
            }
337
12
            break;
338
12
    }
339
12
    if (code < 0)
340
0
        param_signal_error(plist, key, code);
341
12
    return code;
342
12
}
343
344
/* Get N quantization values from an array or a string. */
345
static int
346
quant_params(gs_param_list * plist, gs_param_name key, int count,
347
             UINT16 * pvals, double QFactor)
348
0
{
349
0
    int i;
350
0
    gs_param_string bytes;
351
0
    gs_param_float_array floats;
352
0
    int code = param_read_string(plist, key, &bytes);
353
354
0
    switch (code) {
355
0
        case 0:
356
0
            if (bytes.size != count) {
357
0
                code = gs_note_error(gs_error_rangecheck);
358
0
                break;
359
0
            }
360
0
            for (i = 0; i < count; ++i) {
361
0
                double v = bytes.data[i] * QFactor;
362
363
0
                pvals[jpeg_order(i)] =
364
0
                    (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
365
0
            }
366
0
            return 0;
367
0
        default:    /* might be a float array */
368
0
            code = param_read_float_array(plist, key, &floats);
369
0
            if (!code) {
370
0
                if (floats.size != count) {
371
0
                    code = gs_note_error(gs_error_rangecheck);
372
0
                    break;
373
0
                }
374
0
                for (i = 0; i < count; ++i) {
375
0
                    double v = floats.data[i] * QFactor;
376
377
0
                    pvals[jpeg_order(i)] =
378
0
                        (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
379
0
                }
380
0
            }
381
0
    }
382
0
    if (code < 0)
383
0
        param_signal_error(plist, key, code);
384
0
    return code;
385
0
#undef jpeg_order
386
0
}
387
388
/* ---------------- Main procedures ---------------- */
389
390
/* Put common scalars. */
391
int
392
s_DCT_put_params(gs_param_list * plist, stream_DCT_state * pdct)
393
6
{
394
6
    int code =
395
6
    gs_param_read_items(plist, pdct, s_DCT_param_items, NULL);
396
397
6
    if (code < 0)
398
0
        return code;
399
6
    code = gs_param_read_items(plist, pdct->data.common, jsd_param_items, NULL);
400
6
    if (code < 0)
401
0
        return code;
402
6
    if (pdct->data.common->Picky < 0 || pdct->data.common->Picky > 1 ||
403
6
        pdct->data.common->Relax < 0 || pdct->data.common->Relax > 1 ||
404
6
        pdct->ColorTransform < -1 || pdct->ColorTransform > 2 ||
405
6
        pdct->QFactor < 0.0 || pdct->QFactor > 1000000.0
406
6
        )
407
0
        return_error(gs_error_rangecheck);
408
6
    return 0;
409
6
}
410
411
/* Put quantization tables. */
412
int
413
s_DCT_put_quantization_tables(gs_param_list * plist, stream_DCT_state * pdct,
414
                              bool is_encode)
415
6
{
416
6
    int code;
417
6
    int i, j;
418
6
    gs_param_array quant_tables;  /* array of strings/arrays */
419
6
    int num_in_tables;
420
6
    int num_out_tables;
421
6
    jpeg_component_info *comp_info;
422
6
    JQUANT_TBL **table_ptrs;
423
6
    JQUANT_TBL *this_table;
424
425
6
    switch ((code = param_begin_read_dict(plist, "QuantTables",
426
6
                                          &quant_tables, true))
427
6
        ) {
428
6
        case 1:
429
6
            return 1;
430
0
        default:
431
0
            return param_signal_error(plist, "QuantTables", code);
432
0
        case 0:
433
0
            ;
434
6
    }
435
0
    if (is_encode) {
436
0
        num_in_tables = pdct->data.compress->cinfo.num_components;
437
0
        if (quant_tables.size < num_in_tables)
438
0
            return_error(gs_error_rangecheck);
439
0
        comp_info = pdct->data.compress->cinfo.comp_info;
440
0
        table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
441
0
    } else {
442
0
        num_in_tables = quant_tables.size;
443
0
        comp_info = NULL; /* do not set for decompress case */
444
0
        table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
445
0
    }
446
0
    num_out_tables = 0;
447
0
    for (i = 0; i < num_in_tables; ++i) {
448
0
        char istr[5];   /* i converted to string key */
449
0
        UINT16 values[DCTSIZE2];
450
451
0
        gs_snprintf(istr, sizeof(istr), "%d", i);
452
0
        code = quant_params(quant_tables.list, istr, DCTSIZE2, values,
453
0
                            pdct->QFactor);
454
0
        if (code < 0)
455
0
            return code;
456
        /* Check for duplicate tables. */
457
0
        for (j = 0; j < num_out_tables; j++) {
458
0
            if (!memcmp(table_ptrs[j]->quantval, values, sizeof(values)))
459
0
                break;
460
0
        }
461
0
        if (comp_info != NULL)
462
0
            comp_info[i].quant_tbl_no = j;
463
0
        if (j < num_out_tables) /* found a duplicate */
464
0
            continue;
465
0
        if (++num_out_tables > NUM_QUANT_TBLS)
466
0
            return_error(gs_error_rangecheck);
467
0
        this_table = table_ptrs[j];
468
0
        if (this_table == NULL) {
469
0
            this_table = gs_jpeg_alloc_quant_table(pdct);
470
0
            if (this_table == NULL)
471
0
                return_error(gs_error_VMerror);
472
0
            table_ptrs[j] = this_table;
473
0
        }
474
0
        memcpy(this_table->quantval, values, sizeof(values));
475
0
    }
476
0
    return 0;
477
0
}
478
479
/* Put Huffman tables. */
480
static int
481
find_huff_values(JHUFF_TBL ** table_ptrs, int num_tables,
482
               const UINT8 * counts, const UINT8 * values, int codes_size)
483
0
{
484
0
    int j;
485
486
0
    for (j = 0; j < num_tables; ++j)
487
0
        if (!memcmp(table_ptrs[j]->bits, counts, 16*sizeof(counts[0])) &&
488
0
            !memcmp(table_ptrs[j]->huffval, values,
489
0
                    codes_size * sizeof(values[0])))
490
0
            break;
491
0
    return j;
492
0
}
493
int
494
s_DCT_put_huffman_tables(gs_param_list * plist, stream_DCT_state * pdct,
495
                         bool is_encode)
496
6
{
497
6
    int code;
498
6
    int i, j;
499
6
    gs_param_array huff_tables;
500
6
    int num_in_tables;
501
6
    int ndc, nac;
502
6
    int codes_size;
503
6
    jpeg_component_info *comp_info;
504
6
    JHUFF_TBL **dc_table_ptrs;
505
6
    JHUFF_TBL **ac_table_ptrs;
506
6
    JHUFF_TBL **this_table_ptr;
507
6
    JHUFF_TBL *this_table;
508
6
    int max_tables = 2;   /* baseline limit */
509
510
6
    switch ((code = param_begin_read_dict(plist, "HuffTables",
511
6
                                          &huff_tables, true))
512
6
        ) {
513
6
        case 1:
514
6
            return 0;
515
0
        default:
516
0
            return param_signal_error(plist, "HuffTables", code);
517
0
        case 0:
518
0
            ;
519
6
    }
520
0
    if (is_encode) {
521
0
        num_in_tables = pdct->data.compress->cinfo.input_components * 2;
522
0
        if (huff_tables.size < num_in_tables)
523
0
            return_error(gs_error_rangecheck);
524
0
        comp_info = pdct->data.compress->cinfo.comp_info;
525
0
        dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
526
0
        ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
527
0
        if (pdct->data.common->Relax)
528
0
            max_tables = max(pdct->data.compress->cinfo.input_components, 2);
529
0
    } else {
530
0
        num_in_tables = huff_tables.size;
531
0
        comp_info = NULL; /* do not set for decompress case */
532
0
        dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
533
0
        ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
534
0
        if (pdct->data.common->Relax)
535
0
            max_tables = NUM_HUFF_TBLS;
536
0
    }
537
0
    ndc = nac = 0;
538
0
    for (i = 0; i < num_in_tables; ++i) {
539
0
        char istr[5];   /* i converted to string key */
540
0
        UINT8 counts[16], values[256];
541
542
        /* Collect the Huffman parameters. */
543
0
        gs_snprintf(istr, sizeof(istr), "%d", i);
544
0
        code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts);
545
0
        if (code < 0)
546
0
            return code;
547
0
        for (codes_size = 0, j = 0; j < 16; j++)
548
0
            codes_size += counts[j];
549
0
        if (codes_size > 256 /*|| r_size(pa) != codes_size+16 */ )
550
0
            return_error(gs_error_rangecheck);
551
0
        code = s_DCT_byte_params(huff_tables.list, istr, 16, codes_size,
552
0
                                 values);
553
0
        if (code < 0)
554
0
            return code;
555
0
        if (i & 1) {
556
0
            j = find_huff_values(ac_table_ptrs, nac, counts, values,
557
0
                                 codes_size);
558
0
            if (comp_info != NULL)
559
0
                comp_info[i >> 1].ac_tbl_no = j;
560
0
            if (j < nac)
561
0
                continue;
562
0
            if (++nac > NUM_HUFF_TBLS)
563
0
                return_error(gs_error_rangecheck);
564
0
            this_table_ptr = ac_table_ptrs + j;
565
0
        } else {
566
0
            j = find_huff_values(dc_table_ptrs, ndc, counts, values,
567
0
                                 codes_size);
568
0
            if (comp_info != NULL)
569
0
                comp_info[i >> 1].dc_tbl_no = j;
570
0
            if (j < ndc)
571
0
                continue;
572
0
            if (++ndc > NUM_HUFF_TBLS)
573
0
                return_error(gs_error_rangecheck);
574
0
            this_table_ptr = dc_table_ptrs + j;
575
0
        }
576
0
        this_table = *this_table_ptr;
577
0
        if (this_table == NULL) {
578
0
            this_table = gs_jpeg_alloc_huff_table(pdct);
579
0
            if (this_table == NULL)
580
0
                return_error(gs_error_VMerror);
581
0
            *this_table_ptr = this_table;
582
0
        }
583
0
        memcpy(this_table->bits, counts, sizeof(counts));
584
0
        memcpy(this_table->huffval, values, codes_size * sizeof(values[0]));
585
0
    }
586
0
    if (nac > max_tables || ndc > max_tables)
587
0
        return_error(gs_error_rangecheck);
588
0
    return 0;
589
0
}