Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gxdhtserial.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
/* Serialization and de-serialization for (traditional) halftones */
18
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gscdefs.h"
22
#include "gserrors.h"
23
#include "gsstruct.h"
24
#include "gsutil.h"             /* for gs_next_ids */
25
#include "gzstate.h"
26
#include "gxdevice.h"           /* for gzht.h */
27
#include "gzht.h"
28
#include "gxdhtres.h"
29
#include "gsserial.h"
30
#include "gxdhtserial.h"
31
32
/*
33
 * Declare the set of procedures that return resident halftones. This
34
 * declares both the array of procedures and their type. It is used
35
 * only to check if a transmitted halftone order matches one in ROM.
36
 */
37
extern_gx_device_halftone_list();
38
39
/*
40
 * An enumeration of halftone transfer functions. These must distinguish
41
 * between cases in which no transfer function is present, and when one
42
 * is present but provides the identity transformation (an empty
43
 * PostScript array).
44
 */
45
typedef enum {
46
    gx_ht_tf_none = 0,
47
    gx_ht_tf_identity,
48
    gx_ht_tf_complete
49
} gx_ht_tf_type_t;
50
51
/*
52
 * Serialize a transfer function. These will occupy one byte if they are
53
 * not present or provide an identity mapping,
54
 * 1 + transfer_map_size * sizeof(frac) otherwise.
55
 *
56
 * Returns:
57
 *
58
 *    0, with *psize set the the amount of space required, if successful
59
 *
60
 *    gs_error_rangecheck, with *psize set to the size required, if the
61
 *        original *psize was not large enough
62
 */
63
static int
64
gx_ht_write_tf(
65
    const gx_transfer_map * pmap,
66
    byte *                  data,
67
    uint *                  psize )
68
263k
{
69
263k
    int                     req_size = 1;   /* minimum of one byte */
70
71
    /* check for sufficient space */
72
263k
    if ( pmap != 0 && pmap->proc != gs_identity_transfer)
73
0
        req_size += sizeof(pmap->values);
74
263k
    if (req_size > *psize) {
75
197k
        *psize = req_size;
76
197k
        return_error(gs_error_rangecheck);
77
197k
    }
78
79
65.9k
    if (req_size == 1)
80
65.9k
        *data = (byte)(pmap == 0 ? gx_ht_tf_none : gx_ht_tf_identity);
81
0
    else {
82
0
        *data++ = (byte)gx_ht_tf_complete;
83
0
        memcpy(data, pmap->values, sizeof(pmap->values));
84
0
    }
85
86
65.9k
    *psize = req_size;
87
65.9k
    return 0;
88
263k
}
89
90
/*
91
 * Reconstruct a transfer function from its serial representation. The
92
 * buffer provided is expected to be large enough to hold the entire
93
 * transfer function.
94
 *
95
 * Returns the number of bytes read, or < 0 in the event of an error.
96
 */
97
static int
98
gx_ht_read_tf(
99
    gx_transfer_map **  ppmap,
100
    const byte *        data,
101
    uint                size,
102
    gs_memory_t *       mem )
103
2.40M
{
104
2.40M
    gx_ht_tf_type_t     tf_type;
105
2.40M
    gx_transfer_map *   pmap;
106
107
    /* read the type byte */
108
2.40M
    if (size == 0)
109
0
        return_error(gs_error_rangecheck);
110
2.40M
    --size;
111
2.40M
    tf_type = (gx_ht_tf_type_t)*data++;
112
113
    /* If no transfer function or identity set to NULL */
114
2.40M
    if (tf_type == gx_ht_tf_none || tf_type == gx_ht_tf_identity) {
115
2.40M
        *ppmap = NULL;
116
2.40M
        return 1;
117
2.40M
    }
118
119
    /* If something strange then exit. Likely clist issue */
120
0
    if (tf_type != gx_ht_tf_complete || size < sizeof(pmap->values))
121
0
        return_error(gs_error_rangecheck);
122
123
    /* Otherwise we have a real map. Allocate a transfer map */
124
0
    rc_alloc_struct_1( pmap,
125
0
                       gx_transfer_map,
126
0
                       &st_transfer_map,
127
0
                       mem,
128
0
                       return_error(gs_error_VMerror),
129
0
                       "gx_ht_read_tf" );
130
0
    pmap->id = gs_next_ids(mem, 1);
131
0
    pmap->closure.proc = 0;
132
0
    pmap->closure.data = 0;
133
0
    memcpy(pmap->values, data, sizeof(pmap->values));
134
0
    pmap->proc = gs_mapped_transfer;
135
0
    *ppmap = pmap;
136
0
    return 1 + sizeof(pmap->values);
137
0
}
138
139
/*
140
 * Serialize a halftone component. The only part that is serialized is the
141
 * halftone order; the other two components are only required during
142
 * halftone construction.
143
 *
144
 * Returns:
145
 *
146
 *    0, with *psize set the the amount of space required, if successful
147
 *
148
 *    gs_error_rangecheck, with *psize set to the size required, if the
149
 *        original *psize was not large enough
150
 *
151
 *    some other error code, with *psize unchanged, in the event of an
152
 *        error other than lack of space
153
 */
154
static int
155
gx_ht_write_component(
156
    const gx_ht_order_component *   pcomp,
157
    byte *                          data,
158
    uint *                          psize )
159
197k
{
160
197k
    const gx_ht_order *             porder = &pcomp->corder;
161
197k
    byte *                          data0 = data;
162
197k
    int                             code, levels_size, bits_size;
163
197k
    uint          tmp_size = 0;
164
197k
    int                             req_size;
165
166
    /*
167
     * There is no need to transmit the comp_number field, as this must be
168
     * the same as the index in the component array (see gx_ht_write).
169
     *
170
     * There is also no reason to transmit the colorant name (cname), as
171
     * this is only used by some high-level devices that would not be targets
172
     * of the command list device (and even those devices should be able to
173
     * get the information from their color models).
174
     *
175
     * This leaves the order itself.
176
     */
177
178
    /*
179
     * The following order fields are not transmitted:
180
     *
181
     *  params          Only required during halftone cell construction
182
     *
183
     *  raster          Can be re-calculated by the renderer from the width
184
     *
185
     *  orig_height,    The only potential use for these parameters is in
186
     *  orig_shift      this routine; they are not useful to the renderer.
187
     *
188
     *  full_height     Can be re-calculated by the renderer from the
189
     *                  height, width, and shift values.
190
     *
191
     *  data_memory     Must be provided by the renderer.
192
     *
193
     *  cache           Must be provided by the renderer.
194
     *
195
     *  screen_params   Ony required during halftone cell construction
196
     *
197
     * In addition, the procs parameter is passed as an index into the
198
     * ht_order_procs_table, as the renderer may not be in the same address
199
     * space as the writer.
200
     *
201
     * Calculate the size required.
202
     */
203
197k
    levels_size = porder->num_levels * sizeof(porder->levels[0]);
204
197k
    bits_size = porder->num_bits * porder->procs->bit_data_elt_size;
205
197k
    req_size =  enc_u_sizew(porder->width)
206
197k
               + enc_u_sizew(porder->height)
207
197k
               + enc_u_sizew(porder->shift)
208
197k
               + enc_u_sizew(porder->num_levels)
209
197k
               + enc_u_sizew(porder->num_bits)
210
197k
               + 1          /* order procs, as index into table */
211
197k
               + levels_size
212
197k
               + bits_size;
213
197k
    code = gx_ht_write_tf(porder->transfer, data, &tmp_size);
214
197k
    if (code < 0 && code != gs_error_rangecheck)
215
0
        return code;
216
197k
    req_size += tmp_size;
217
197k
    if (req_size > *psize) {
218
131k
        *psize = req_size;
219
131k
        return_error(gs_error_rangecheck);
220
131k
    }
221
222
    /* write out the dimensional data */
223
197k
    enc_u_putw(porder->width, data);
224
65.9k
    enc_u_putw(porder->height, data);
225
65.9k
    enc_u_putw(porder->shift, data);
226
65.9k
    enc_u_putw(porder->num_levels, data);
227
65.9k
    enc_u_putw(porder->num_bits, data);
228
229
    /* white out the procs index */
230
65.9k
    *data++ = porder->procs - ht_order_procs_table;
231
232
    /* copy the levels array and whitening order array */
233
65.9k
    memcpy(data, porder->levels, levels_size);
234
65.9k
    data += levels_size;
235
65.9k
    memcpy(data, porder->bit_data, bits_size);
236
65.9k
    data += bits_size;
237
238
    /* write out the transfer function */
239
65.9k
    tmp_size = *psize - (data - data0);
240
65.9k
    if ((code = gx_ht_write_tf(porder->transfer, data, &tmp_size)) == 0)
241
65.9k
        *psize = tmp_size + (data - data0);
242
65.9k
    return code;
243
197k
}
244
245
/*
246
 * Reconstruct a halftone component from its serial representation. The
247
 * buffer provided is expected to be large enough to hold the entire
248
 * halftone component.
249
 *
250
 * Because halftone components are allocated in arrays (an unfortunate
251
 * arrangement, as it prevents component sharing), a pointer to an
252
 * already allocated component structure is passed as an operand, as
253
 * opposed to the more normal mechanism that would have a read routine
254
 * allocate the component. The memory pointer is still passed, however,
255
 * as the levels and bit_data arrays must be allocated.
256
 *
257
 * Returns the number of bytes read, or < 0 in the event of an error.
258
 */
259
static int
260
gx_ht_read_component(
261
    gx_ht_order_component * pcomp,
262
    const byte *            data,
263
    uint                    size,
264
    gs_memory_t *           mem )
265
2.40M
{
266
2.40M
    gx_ht_order             new_order;
267
2.40M
    const byte *            data0 = data;
268
2.40M
    const byte *            data_lim = data + size;
269
2.40M
    int                     i, code, levels_size, bits_size;
270
2.40M
    const gx_dht_proc *     phtrp = gx_device_halftone_list;
271
272
    /* check the order type */
273
2.40M
    if (size == 0)
274
0
        return_error(gs_error_rangecheck);
275
276
    /*
277
     * For performance reasons, the number encoding macros do not
278
     * support full buffer size verification. The code below verifies
279
     * that a minimum number of bytes is available, then converts
280
     * blindly and does not check again until the various integers are
281
     * read. Obviously this can be hazardous, but should not be a
282
     * problem in practice, as the calling code should have verified
283
     * that the data provided holds the entire halftone.
284
     */
285
2.40M
    if (size < 7)
286
0
        return_error(gs_error_rangecheck);
287
2.40M
    enc_u_getw(new_order.width, data);
288
2.40M
    enc_u_getw(new_order.height, data);
289
2.40M
    enc_u_getw(new_order.shift, data);
290
2.40M
    enc_u_getw(new_order.num_levels, data);
291
2.40M
    enc_u_getw(new_order.num_bits, data);
292
2.40M
    if (data >= data_lim)
293
0
        return_error(gs_error_rangecheck);
294
2.40M
    new_order.procs = &ht_order_procs_table[*data++];
295
2.40M
    new_order.threshold_inverted = 0;
296
297
    /* calculate the space required for levels and bit data */
298
2.40M
    levels_size = new_order.num_levels * sizeof(new_order.levels[0]);
299
2.40M
    bits_size = new_order.num_bits * new_order.procs->bit_data_elt_size;
300
301
    /* + 1 below is for the minimal transfer function */
302
2.40M
    if (data + bits_size + levels_size + 1 > data_lim)
303
0
        return_error(gs_error_rangecheck);
304
305
    /*
306
     * Allocate the levels and bit data structures. The gx_ht_alloc_ht_order
307
     * has a name that is both strange and misleading. The routine does
308
     * not allocate a halftone order. Rather, it initializes the order,
309
     * and allocates the levels and bit data arrays. In particular, it
310
     * sets all of the following fields:
311
     *
312
     *    width = operand width
313
     *    height = operand height
314
     *    raster = bitmap_raster(operand width)
315
     *    shift = operand shift
316
     *    orig_height = operand height
317
     *    orig_shift = operand strip_shift
318
     *    num_levels = operand num_levels
319
     *    num_bits = operand num_bits
320
     *    procs = operand procs
321
     *    levels = newly allocated array
322
     *    bit_data = new allocated array
323
     *    cache = 0
324
     *    transfer = 0
325
     *
326
     * Since several of the list fields are already set, this call
327
     * effectively sets them to the values they already have. This is a
328
     * bit peculiar but not otherwise harmful.
329
     *
330
     * For reasons that are not known and are probably historical, the
331
     * procedure does not initialize the params or screen_params fields.
332
     * In the unlikely event that these fields are ever contain pointers,
333
     * we initialize them explicitly here. Wse, params, and scrren_params
334
     * probably should not occur in the device halftone at all; they are
335
     * themselves historical artifacts.
336
     */
337
2.40M
    code = gx_ht_alloc_ht_order( &new_order,
338
2.40M
                                 new_order.width,
339
2.40M
                                 new_order.height,
340
2.40M
                                 new_order.num_levels,
341
2.40M
                                 new_order.num_bits,
342
2.40M
                                 new_order.shift,
343
2.40M
                                 new_order.procs,
344
2.40M
                                 mem );
345
2.40M
    if (code < 0)
346
0
        return code;
347
2.40M
    memset(&new_order.params, 0, sizeof(new_order.params));
348
2.40M
    memset(&new_order.screen_params, 0, sizeof(new_order.screen_params));
349
350
    /* fill in the levels and bit_data arrays */
351
2.40M
    memcpy(new_order.levels, data, levels_size);
352
2.40M
    data += levels_size;
353
2.40M
    memcpy(new_order.bit_data, data, bits_size);
354
2.40M
    data += bits_size;
355
356
    /* process the transfer function */
357
2.40M
    code = gx_ht_read_tf(&new_order.transfer, data, data_lim - data, mem);
358
2.40M
    if (code < 0) {
359
0
        gx_ht_order_release(&new_order, mem, false);
360
0
        return code;
361
0
    }
362
2.40M
    data += code;
363
364
    /*
365
     * Check to see if the order is in ROM. Since it is possible (if not
366
     * particularly likely) that the command list writer and renderer do
367
     * not have the same set of ROM-based halftones, the full halftone
368
     * order is transmitted and compared against the set ROM set provided
369
     * by the renderer. If there is a match, the transmitted version is
370
     * discarded and the ROM version used.
371
     *
372
     * It is not clear which, if any or the currently used devices
373
     * provide a ROM-based halftone order set.
374
     */
375
2.40M
    for (i = 0; phtrp[i] != 0; i++) {
376
0
        const gx_device_halftone_resource_t *const *    pphtr = phtrp[i]();
377
0
        const gx_device_halftone_resource_t *           phtr;
378
379
0
        while ((phtr = *pphtr++) != 0) {
380
            /*
381
             * This test does not check for strict equality of the order,
382
             * nor is strict equality necessary. The ROM data will replace
383
             * just the levels and bit_data arrays of the transmitted
384
             * order, so only these must be the same. We don't even care
385
             * if the ROM's levels and bit_data arrays are larger; we
386
             * will never check values beyond the range required by the
387
             * current order.
388
             */
389
0
            if ( phtr->num_levels * sizeof(phtr->levels[0]) >= levels_size &&
390
0
                 phtr->Width * phtr->Height * phtr->elt_size >= bits_size  &&
391
0
                 memcmp(phtr->levels, new_order.levels, levels_size) == 0  &&
392
0
                 memcmp(phtr->bit_data, new_order.bit_data, bits_size) == 0  ) {
393
                /* the casts below are required to discard const qualifiers */
394
0
                gs_free_object(mem, new_order.bit_data, "gx_ht_read_component");
395
0
                new_order.bit_data = (void *)phtr->bit_data;
396
0
                gs_free_object(mem, new_order.levels, "gx_ht_read_component");
397
0
                new_order.levels = (uint *)phtr->levels;
398
0
                goto done;
399
0
            }
400
0
        }
401
0
    }
402
403
2.40M
  done:
404
    /* everything OK, save the order and return the # of bytes read */
405
2.40M
    pcomp->corder = new_order;
406
2.40M
    pcomp->cname = 0;
407
2.40M
    return data - data0;
408
2.40M
}
409
410
/*
411
 * Serialize a halftone. The essential step is the serialization of the
412
 * halftone orders; beyond this only the halftone type must be
413
 * transmitted.
414
 *
415
 * Returns:
416
 *
417
 *    0, with *psize set the the amount of space required, if successful
418
 *
419
 *    gs_error_rangecheck, with *psize set to the size required, if the
420
 *        original *psize was not large enough
421
 *
422
 *    some other error code, with *psize unchange, in the event of an
423
 *        error other than lack of space
424
 */
425
int
426
gx_ht_write(
427
    const gx_device_halftone *  pdht,
428
    const gx_device *           dev,
429
    byte *                      data,
430
    uint *                      psize )
431
52.9k
{
432
52.9k
    int                         num_dev_comps;
433
52.9k
    int                         i, code;
434
52.9k
    uint                        req_size = 2, used_size = 2;
435
                                /* 1 for halftone type, 1 for num_dev_comps */
436
437
    /*
438
     * With the introduction of color models, there should never be a
439
     * halftone that includes just one component. Enforce this
440
     * restriction, even though it is not present in much of the rest
441
     * of the code.
442
     *
443
     * NB: the pdht->order field is ignored by this code.
444
     */
445
52.9k
    if (pdht == 0 || pdht->components == 0)
446
0
        return_error(gs_error_unregistered); /* Must not happen. */
447
52.9k
    num_dev_comps = pdht->num_dev_comp;
448
449
    /*
450
     * The following fields do not need to be transmitted:
451
     *
452
     *  order       Ignored by this code (see above).
453
     *
454
     *  rc, id      Recreated by the allocation code on the renderer.
455
     *
456
     *  lcm_width,  Can be recreated by the de-serialization code on the
457
     *  lcm_height  the renderer. Since halftones are transmitted
458
     *              infrequently (for normal jobs), the time required
459
     *              for re-calculation is not significant.
460
     *
461
     * Hence, the only fields that must be serialized are the type,and
462
     * the number of components.  (The number of components for the halftone
463
     * may not match the device's if we are compositing with a process color
464
     * model which does not match the output device.
465
     *
466
     * Several halftone components may be identical, but there is
467
     * currently no simple way to determine this. Halftones are normally
468
     * transmitted only once per page, so it is not clear that use of
469
     * such information would significantly reduce command list size.
470
     */
471
472
    /* calculate the required data space */
473
52.9k
    for ( i = 0, code = gs_error_rangecheck;
474
184k
          i < num_dev_comps && code == gs_error_rangecheck;
475
131k
          i++) {
476
131k
        uint     tmp_size = 0;
477
478
        /* sanity check */
479
131k
        if (i != pdht->components[i].comp_number)
480
0
            return_error(gs_error_unregistered); /* Must not happen. */
481
482
131k
        code = gx_ht_write_component( &pdht->components[i],
483
131k
                                      data,
484
131k
                                      &tmp_size );
485
131k
        req_size += tmp_size;
486
131k
    }
487
52.9k
    if (code < 0 && code != gs_error_rangecheck)
488
0
        return code;
489
52.9k
    else if (*psize < req_size) {
490
26.4k
        *psize = req_size;
491
26.4k
        return 0;
492
26.4k
    }
493
26.4k
    req_size = *psize;
494
495
    /* the halftone type is known to fit in a byte */
496
26.4k
    *data++ = (byte)pdht->type;
497
    /* the number of components is known to fit in a byte */
498
26.4k
    *data++ = (byte)num_dev_comps;
499
500
    /* serialize the halftone components */
501
92.3k
    for (i = 0, code = 0; i < num_dev_comps && code == 0; i++) {
502
65.9k
        uint    tmp_size = req_size - used_size;
503
504
65.9k
        code = gx_ht_write_component( &pdht->components[i],
505
65.9k
                                      data,
506
65.9k
                                      &tmp_size );
507
65.9k
        used_size += tmp_size;
508
65.9k
        data += tmp_size;
509
65.9k
    }
510
511
26.4k
    if (code < 0) {
512
0
        if (code == gs_error_rangecheck)
513
0
            code = gs_error_unknownerror;
514
0
        return code;
515
0
    }
516
517
26.4k
    *psize = used_size;
518
26.4k
    return 0;
519
26.4k
}
520
521
/*
522
 * Reconstruct a halftone from its serial representation, and install it
523
 * as the current halftone. The buffer provided is expected to be large
524
 * enough to hold the entire halftone.
525
 *
526
 * The reading and installation phases are combined in this routine so as
527
 * to avoid unnecessarily allocating a device halftone and its component
528
 * array, just to release them immediately after installation is complete.
529
 * There is also not much reason to reconstuct a halftone except to make
530
 * it the current halftone.
531
 *
532
 * Returns the number of bytes read, or <0 in the event of an error.
533
 */
534
int
535
gx_ht_read_and_install(
536
    gs_gstate        *       pgs,
537
    const gx_device *       dev,
538
    const byte *            data,
539
    uint                    size,
540
    gs_memory_t *           mem )
541
963k
{
542
963k
    gx_ht_order_component   components[GX_DEVICE_COLOR_MAX_COMPONENTS];
543
963k
    gx_ht_order_component   components_save[GX_DEVICE_COLOR_MAX_COMPONENTS];
544
963k
    const byte *            data0 = data;
545
963k
    gx_device_halftone      dht;
546
963k
    int                     num_dev_comps;
547
963k
    int                     i, code;
548
549
    /* fill in some fixed fields */
550
963k
    memset(&dht.order, 0, sizeof(dht.order));
551
963k
    memset(&dht.rc, 0, sizeof(dht.rc));
552
963k
    dht.id = gs_no_id;      /* updated during installation */
553
963k
    dht.components = components;
554
963k
    dht.lcm_width = 1;      /* recalculated during installation */
555
963k
    dht.lcm_height = 1;
556
557
    /* clear pointers in the components array in case we need to abort */
558
963k
    memset(components, 0, sizeof(components));
559
560
    /* get the halftone type */
561
963k
    if (size < 2)
562
0
        return_error(gs_error_rangecheck);
563
963k
    dht.type = (gs_halftone_type)(*data++);
564
963k
    num_dev_comps = dht.num_dev_comp = dht.num_comp = *data++;
565
963k
    size -= 2;
566
567
    /* process the component orders */
568
3.37M
    for (i = 0, code = 0; i < num_dev_comps && code >= 0; i++) {
569
2.40M
        components[i].comp_number = i;
570
2.40M
        code = gx_ht_read_component(&components[i], data, size, mem);
571
2.40M
        if (code >= 0) {
572
2.40M
            size -= code;
573
2.40M
            data += code;
574
2.40M
        }
575
2.40M
    }
576
577
    /* if everything is OK, install the halftone */
578
963k
    if (code >= 0) {
579
        /* save since the 'install' copies the order, but then clears the source order  */
580
3.37M
        for (i = 0; i < num_dev_comps; i++)
581
2.40M
            components_save[i] = components[i];
582
963k
        code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev, HT_OBJTYPE_DEFAULT);
583
963k
        if (code >= 0) {
584
3.37M
            for (i = 0; i < num_dev_comps; i++)
585
2.40M
                gx_ht_order_release(&components_save[i].corder, mem, false);
586
963k
        }
587
963k
    }
588
589
    /*
590
     * If installation failed, discard the allocated elements. We can't
591
     * use the gx_device_halftone_release procedure, as the components
592
     * array is on the stack rather than in the heap.
593
     */
594
963k
    if (code < 0) {
595
0
        for (i = 0; i < num_dev_comps; i++)
596
0
            gx_ht_order_release(&components[i].corder, mem, false);
597
0
    }
598
599
963k
    return code < 0 ? code : data - data0;
600
963k
}