Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pcl/pcl/pcbiptrn.c
Line
Count
Source
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
/* pcbiptrn.c - code for PCL built-in patterns */
18
19
#include "math_.h"
20
#include "string_.h"
21
#include "gstypes.h"            /* for gsstate.h */
22
#include "gsmatrix.h"           /* for gsstate.h */
23
#include "gsmemory.h"           /* for gsstate.h */
24
#include "gsstate.h"
25
#include "gscoord.h"
26
#include "pcpatrn.h"
27
#include "pcuptrn.h"
28
#include "pcbiptrn.h"
29
#include "pcstate.h"
30
31
/*
32
 * 16x16 bitmap arrays for the built-in patterns.
33
 */
34
static const byte
35
    bi_data_array[(PCL_NUM_SHADE_PATTERNS +
36
                   PCL_NUM_CROSSHATCH_PATTERNS) * 2 * 16] = {
37
38
    /* shade 1% to 2% */
39
    0x80, 0x80,
40
    0x00, 0x00,
41
    0x00, 0x00,
42
    0x00, 0x00,
43
    0x00, 0x00,
44
    0x00, 0x00,
45
    0x00, 0x00,
46
    0x00, 0x00,
47
    0x08, 0x08,
48
    0x00, 0x00,
49
    0x00, 0x00,
50
    0x00, 0x00,
51
    0x00, 0x00,
52
    0x00, 0x00,
53
    0x00, 0x00,
54
    0x00, 0x00,
55
56
    /* shade 3% to 10% */
57
    0x80, 0x80,
58
    0x00, 0x00,
59
    0x00, 0x00,
60
    0x00, 0x00,
61
    0x08, 0x08,
62
    0x00, 0x00,
63
    0x00, 0x00,
64
    0x00, 0x00,
65
    0x80, 0x80,
66
    0x00, 0x00,
67
    0x00, 0x00,
68
    0x00, 0x00,
69
    0x08, 0x08,
70
    0x00, 0x00,
71
    0x00, 0x00,
72
    0x00, 0x00,
73
74
    /* shade 11% to 20% */
75
    0xc0, 0xc0,
76
    0xc0, 0xc0,
77
    0x00, 0x00,
78
    0x00, 0x00,
79
80
    0x0c, 0x0c,
81
    0x0c, 0x0c,
82
    0x00, 0x00,
83
    0x00, 0x00,
84
85
    0xc0, 0xc0,
86
    0xc0, 0xc0,
87
    0x00, 0x00,
88
    0x00, 0x00,
89
90
    0x0c, 0x0c,
91
    0x0c, 0x0c,
92
    0x00, 0x00,
93
    0x00, 0x00,
94
95
96
    /* shade 21% to 35% */
97
    0xc1, 0xc1,
98
    0xc1, 0xc1,
99
    0x80, 0x80,
100
    0x08, 0x08,
101
102
    0x1c, 0x1c,
103
    0x1c, 0x1c,
104
    0x08, 0x08,
105
    0x80, 0x80,
106
107
    0xc1, 0xc1,
108
    0xc1, 0xc1,
109
    0x80, 0x80,
110
    0x08, 0x08,
111
112
    0x1c, 0x1c,
113
    0x1c, 0x1c,
114
    0x08, 0x08,
115
    0x80, 0x80,
116
117
118
    /* shade 36% to 55% */
119
    0xc1, 0xc1,
120
    0xeb, 0xeb,
121
    0xc1, 0xc1,
122
    0x88, 0x88,
123
124
    0x1c, 0x1c,
125
    0xbe, 0xbe,
126
    0x1c, 0x1c,
127
    0x88, 0x88,
128
129
    0xc1, 0xc1,
130
    0xeb, 0xeb,
131
    0xc1, 0xc1,
132
    0x88, 0x88,
133
134
    0x1c, 0x1c,
135
    0xbe, 0xbe,
136
    0x1c, 0x1c,
137
    0x88, 0x88,
138
139
140
    /* shade 56% to 80% */
141
    0xe3, 0xe3,
142
    0xe3, 0xe3,
143
    0xe3, 0xe3,
144
    0xdd, 0xdd,
145
146
    0x3e, 0x3e,
147
    0x3e, 0x3e,
148
    0x3e, 0x3e,
149
    0xdd, 0xdd,
150
151
    0xe3, 0xe3,
152
    0xe3, 0xe3,
153
    0xe3, 0xe3,
154
    0xdd, 0xdd,
155
156
    0x3e, 0x3e,
157
    0x3e, 0x3e,
158
    0x3e, 0x3e,
159
    0xdd, 0xdd,
160
161
162
    /* shade 81% to 99% */
163
    0xf7, 0xf7,
164
    0xe3, 0xe3,
165
    0xf7, 0xf7,
166
    0xff, 0xff,
167
168
    0x7f, 0x7f,
169
    0x3e, 0x3e,
170
    0x7f, 0x7f,
171
    0xff, 0xff,
172
173
    0xf7, 0xf7,
174
    0xe3, 0xe3,
175
    0xf7, 0xf7,
176
    0xff, 0xff,
177
178
    0x7f, 0x7f,
179
    0x3e, 0x3e,
180
    0x7f, 0x7f,
181
    0xff, 0xff,
182
183
184
    /* cross-hatch 1 (horizontal stripes) */
185
    0x00, 0x00,
186
    0x00, 0x00,
187
    0x00, 0x00,
188
    0x00, 0x00,
189
190
    0x00, 0x00,
191
    0x00, 0x00,
192
    0x00, 0x00,
193
    0xff, 0xff,
194
195
    0xff, 0xff,
196
    0x00, 0x00,
197
    0x00, 0x00,
198
    0x00, 0x00,
199
200
    0x00, 0x00,
201
    0x00, 0x00,
202
    0x00, 0x00,
203
    0x00, 0x00,
204
205
206
    /* cross-hatch 2 (vertical stripes) */
207
    0x01, 0x80,
208
    0x01, 0x80,
209
    0x01, 0x80,
210
    0x01, 0x80,
211
212
    0x01, 0x80,
213
    0x01, 0x80,
214
    0x01, 0x80,
215
    0x01, 0x80,
216
217
    0x01, 0x80,
218
    0x01, 0x80,
219
    0x01, 0x80,
220
    0x01, 0x80,
221
222
    0x01, 0x80,
223
    0x01, 0x80,
224
    0x01, 0x80,
225
    0x01, 0x80,
226
227
228
    /* cross-hatch 3 (upper right/lower left diagonal stripes) */
229
    0x80, 0x03,
230
    0x00, 0x07,
231
    0x00, 0x0e,
232
    0x00, 0x1c,
233
234
    0x00, 0x38,
235
    0x00, 0x70,
236
    0x00, 0xe0,
237
    0x01, 0xc0,
238
239
    0x03, 0x80,
240
    0x07, 0x00,
241
    0x0e, 0x00,
242
    0x1c, 0x00,
243
244
    0x38, 0x00,
245
    0x70, 0x00,
246
    0xe0, 0x00,
247
    0xc0, 0x01,
248
249
250
    /* cross-hatch 4 (upper left/lower right diagonal stripes) */
251
    0xc0, 0x01,
252
    0xe0, 0x00,
253
    0x70, 0x00,
254
    0x38, 0x00,
255
256
    0x1c, 0x00,
257
    0x0e, 0x00,
258
    0x07, 0x00,
259
    0x03, 0x80,
260
261
    0x01, 0xc0,
262
    0x00, 0xe0,
263
    0x00, 0x70,
264
    0x00, 0x38,
265
266
    0x00, 0x1c,
267
    0x00, 0x0e,
268
    0x00, 0x07,
269
    0x80, 0x03,
270
271
272
    /* cross-hatch 5 (aligned cross-hatch) */
273
    0x01, 0x80,
274
    0x01, 0x80,
275
    0x01, 0x80,
276
    0x01, 0x80,
277
278
    0x01, 0x80,
279
    0x01, 0x80,
280
    0x01, 0x80,
281
    0xff, 0xff,
282
283
    0xff, 0xff,
284
    0x01, 0x80,
285
    0x01, 0x80,
286
    0x01, 0x80,
287
288
    0x01, 0x80,
289
    0x01, 0x80,
290
    0x01, 0x80,
291
    0x01, 0x80,
292
293
294
    /* cross-hatch 6 (diagnoal cross-hatch) */
295
    0xc0, 0x03,
296
    0xe0, 0x07,
297
    0x70, 0x0e,
298
    0x38, 0x1c,
299
300
    0x1c, 0x38,
301
    0x0e, 0x70,
302
    0x07, 0xe0,
303
    0x03, 0xc0,
304
305
    0x03, 0xc0,
306
    0x07, 0xe0,
307
    0x0e, 0x70,
308
    0x1c, 0x38,
309
310
    0x38, 0x1c,
311
    0x70, 0x0e,
312
    0xe0, 0x07,
313
    0xc0, 0x03,
314
};
315
316
#define make_pixmap(indx)                                           \
317
    { (byte *)(bi_data_array + indx * 2 * 16), 2, {16, 16}, 0, 1, 1 }
318
319
static const gs_depth_bitmap bi_pixmap_array[PCL_NUM_CROSSHATCH_PATTERNS +
320
                                             PCL_NUM_SHADE_PATTERNS] = {
321
    make_pixmap(0),
322
    make_pixmap(1),
323
    make_pixmap(2),
324
    make_pixmap(3),
325
    make_pixmap(4),
326
    make_pixmap(5),
327
    make_pixmap(6),
328
    make_pixmap(7),
329
    make_pixmap(8),
330
    make_pixmap(9),
331
    make_pixmap(10),
332
    make_pixmap(11),
333
    make_pixmap(12)
334
};
335
336
1.55k
#define bi_cross_offset 7
337
338
/*
339
 * A special pattern, used for rendering images that interact with solid
340
 * foregrounds.
341
 *
342
 * Handling the interaction of rasters and foregrounds in PCL is tricky. PCL
343
 * foregounds carry a full set of rendering information, including color
344
 * correction and halftoning information. These may differe from the color
345
 * correction information and halftone mechanism used to process the raster
346
 * itself (which is always taken from the current palette at the time the
347
 * raster is output). The graphic library can accommodate only a single
348
 * color rendering dictionary and halftone mechanism at one time, hence the
349
 * problem.
350
 *
351
 * The solution is to invoke a second graphic state. Patterns in the graphic
352
 * library are provided with their own graphic state, so method for handling
353
 * solid foreground colors is to create a solid, uncolored pattern that is
354
 * is "on" (assumes the foreground color) everywhere.
355
 *
356
 * The following 1x1 pixel texture is used for this prupose. As with the
357
 * pattern above, two copies of this structure are required: a prototype
358
 * (qualified as const) and the pattern actually used.
359
 */
360
/* Although only a byte is used, the 1bpp rendering code expects at least
361
 * a short.
362
 */
363
static const byte solid_pattern_data[2] = { 0xff, 0xff };
364
365
static const gs_depth_bitmap solid_pattern_pixmap = {
366
    (byte *) & solid_pattern_data[0], 1, {1, 1}, 0, 1, 1
367
};
368
369
/*
370
 * An "un-solid" pattern, similar to the solid pattern described above, but
371
 * with only background. This is used primarily to handle the case of an
372
 * uncolored patter with a white foreground color in GL/2, which such patterns
373
 * are completely transparent (if pattern transparency is on; note that what
374
 * the GL/2 documentation describes as source transparency is actually pattern
375
 * transparency).
376
 */
377
/* This only actually needs to be a single byte, but we
378
 * allocate it to be 2 as this stops address sanitizer
379
 * reporting (intentional, safe) overreads by
380
 * mem_copy_color_mono. See bug 696603. */
381
static const byte unsolid_pattern_data[2] = { 0, 0 };
382
383
static const gs_depth_bitmap unsolid_pattern_pixmap = {
384
    (byte *) & unsolid_pattern_data[0], 1, {1, 1}, 0, 1, 1
385
};
386
387
/*
388
 * Initialize the built-in patterns
389
 */
390
void
391
pcl_pattern_init_bi_patterns(pcl_state_t * pcs)
392
8.09k
{
393
8.09k
    memset(pcs->bi_pattern_array, 0, sizeof(pcs->bi_pattern_array));
394
8.09k
    pcs->psolid_pattern = 0;
395
8.09k
    pcs->punsolid_pattern = 0;
396
8.09k
}
397
398
/*
399
 * Clear all built-in patterns. This is normally called during a reset, to
400
 * conserve memory.
401
 */
402
void
403
pcl_pattern_clear_bi_patterns(pcl_state_t * pcs)
404
24.9k
{
405
24.9k
    int i;
406
407
349k
    for (i = 0; i < countof(pcs->bi_pattern_array); i++) {
408
324k
        if (pcs->bi_pattern_array[i] != 0) {
409
492
            pcl_pattern_free_pattern(pcs->memory,
410
492
                                     pcs->bi_pattern_array[i],
411
492
                                     "clear PCL built-in patterns");
412
492
            pcs->bi_pattern_array[i] = 0;
413
492
        }
414
324k
    }
415
416
24.9k
    if (pcs->psolid_pattern != 0) {
417
0
        pcl_pattern_free_pattern(pcs->memory,
418
0
                                 pcs->psolid_pattern,
419
0
                                 "clear PCL built-in patterns");
420
421
0
        pcs->psolid_pattern = 0;
422
0
    }
423
24.9k
    if (pcs->punsolid_pattern != 0) {
424
62
        pcl_pattern_free_pattern(pcs->memory,
425
62
                                 pcs->punsolid_pattern,
426
62
                                 "clear PCL built-in patterns");
427
428
62
        pcs->punsolid_pattern = 0;
429
62
    }
430
24.9k
}
431
432
/*
433
 * pcl patterns are always always 300 dpi but we use the device
434
 * resolution on devices lower than 300 dpi so we can at least see the
435
 * patterns on screen resolution devices.  We also provide a #define
436
 * here for customers that wish to have better patterns at higher
437
 * resolutions.
438
 */
439
440
/* #define DEVICE_RES_PATTERNS */
441
442
static int
443
pcl_get_pattern_resolution(pcl_state_t * pcs, gs_point * pattern_res)
444
1.04k
{
445
    /* default is 300 */
446
1.04k
    pattern_res->x = 300;
447
1.04k
    pattern_res->y = 300;
448
    /* get the current resolutions based on the device. */
449
1.04k
    {
450
1.04k
        gs_point device_res;
451
1.04k
        gx_device *pdev = gs_currentdevice(pcs->pgs);
452
453
1.04k
        device_res.x = pdev->HWResolution[0];
454
1.04k
        device_res.y = pdev->HWResolution[1];
455
#ifdef DEVICE_RES_PATTERNS
456
        pattern_res->x = device_res.x;
457
        pattern_res->y = device_res.y;
458
#else
459
        /* if both are less than 300 dpi override the 300 dpi default. */
460
1.04k
        if ((device_res.x < 300) && (device_res.y < 300)) {
461
1.04k
            pattern_res->x = device_res.x;
462
1.04k
            pattern_res->y = device_res.y;
463
1.04k
        }
464
1.04k
#endif
465
1.04k
    }
466
1.04k
    return 0;
467
1.04k
}
468
#undef DEVICE_RES_PATTERNS
469
/*
470
 * Return the pointer to a built-in pattern, building it if necessary.
471
 */
472
static pcl_pattern_t *
473
get_bi_pattern(pcl_state_t * pcs, int indx)
474
73.8k
{
475
73.8k
    if (pcs->bi_pattern_array[indx] == 0) {
476
881
        gs_point pattern_res;
477
881
        int code;
478
479
881
        pcl_get_pattern_resolution(pcs, &pattern_res);
480
881
        code = pcl_pattern_build_pattern(&(pcs->bi_pattern_array[indx]),
481
881
                                        &(bi_pixmap_array[indx]),
482
881
                                        pcl_pattern_uncolored,
483
881
                                        (int)pattern_res.x,
484
881
                                        (int)pattern_res.y, pcs->memory);
485
881
        if (code < 0) return NULL;
486
881
        pcs->bi_pattern_array[indx]->ppat_data->storage = pcds_internal;
487
881
    }
488
73.8k
    return pcs->bi_pattern_array[indx];
489
73.8k
}
490
491
/*
492
 * For a given intensity value, return the corresponding shade pattern. A
493
 * null return indicates that a solid pattern should be used - the caller
494
 * must look at the intensity to determine if it is black or white.
495
 */
496
pcl_pattern_t *
497
pcl_pattern_get_shade(pcl_state_t * pcs, int inten)
498
90.3k
{
499
90.3k
    pcl_pattern_t *shade = 0;
500
501
90.3k
    if (inten <= 0)
502
3
        shade = 0;
503
90.3k
    else if (inten <= 2)
504
71.4k
        shade = get_bi_pattern(pcs, 0);
505
18.8k
    else if (inten <= 10)
506
486
        shade = get_bi_pattern(pcs, 1);
507
18.4k
    else if (inten <= 20)
508
200
        shade = get_bi_pattern(pcs, 2);
509
18.2k
    else if (inten <= 35)
510
0
        shade = get_bi_pattern(pcs, 3);
511
18.2k
    else if (inten <= 55)
512
138
        shade = get_bi_pattern(pcs, 4);
513
18.0k
    else if (inten <= 80)
514
0
        shade = get_bi_pattern(pcs, 5);
515
18.0k
    else if (inten <= 99)
516
0
        shade = get_bi_pattern(pcs, 6);
517
90.3k
    return shade;
518
90.3k
}
519
520
/*
521
 * For a given index value, return the corresponding cross-hatch pattern. A
522
 * null return indicates that the pattern is out of range. The caller must
523
 * determine what to do in this case.
524
 */
525
pcl_pattern_t *
526
pcl_pattern_get_cross(pcl_state_t * pcs, int indx)
527
2.49k
{
528
2.49k
    if ((indx < 1) || (indx > 6))
529
940
        return 0;
530
1.55k
    else
531
1.55k
        return get_bi_pattern(pcs, indx + bi_cross_offset - 1);
532
2.49k
}
533
534
/*
535
 * Return the solid uncolored pattern, to be used with rasters (see above).
536
 */
537
pcl_pattern_t *
538
pcl_pattern_get_solid_pattern(pcl_state_t * pcs)
539
0
{
540
0
    if (pcs->psolid_pattern == 0) {
541
0
        gs_point pattern_res;
542
0
        int code;
543
544
0
        pcl_get_pattern_resolution(pcs, &pattern_res);
545
0
        code = pcl_pattern_build_pattern(&(pcs->psolid_pattern),
546
0
                                        &solid_pattern_pixmap,
547
0
                                        pcl_pattern_uncolored,
548
0
                                        (int)pattern_res.x,
549
0
                                        (int)pattern_res.y, pcs->memory);
550
0
        if (code < 0) return NULL;
551
0
        pcs->psolid_pattern->ppat_data->storage = pcds_internal;
552
0
    }
553
0
    return pcs->psolid_pattern;
554
0
}
555
556
/*
557
 * Return the "unsolid" uncolored patterns, to be used with GL/2.
558
 */
559
pcl_pattern_t *
560
pcl_pattern_get_unsolid_pattern(pcl_state_t * pcs)
561
71.4k
{
562
71.4k
    if (pcs->punsolid_pattern == 0) {
563
165
        gs_point pattern_res;
564
165
        int code;
565
566
165
        pcl_get_pattern_resolution(pcs, &pattern_res);
567
165
        code = pcl_pattern_build_pattern(&(pcs->punsolid_pattern),
568
165
                                        &unsolid_pattern_pixmap,
569
165
                                        pcl_pattern_uncolored,
570
165
                                        (int)pattern_res.x,
571
165
                                        (int)pattern_res.y, pcs->memory);
572
165
        if (code < 0) return NULL;
573
165
        pcs->punsolid_pattern->ppat_data->storage = pcds_internal;
574
165
    }
575
71.4k
    return pcs->punsolid_pattern;
576
71.4k
}