Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pcl/pcl/pcdither.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 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
/* pcdither.c - PCL user-defined dither object implementation */
18
19
#include "pcommand.h"
20
#include "pcpalet.h"
21
#include "pcdither.h"
22
23
/* GC Routines */
24
gs_private_st_simple(st_udither_t, pcl_udither_t,
25
                     "pcl user defined dither matrix");
26
27
/*
28
 * Return a pointer to the thershold array appropriate for one color plane.
29
 */
30
const byte *
31
pcl_udither_get_threshold(const pcl_udither_t * pdither, int indx)
32
0
{
33
0
    uint nplanes = pdither->ptbl->nplanes;
34
35
0
    if (nplanes == 1)
36
0
        return pdither->ptbl->data;
37
0
    else
38
0
        return pdither->ptbl->data + indx * pcl_udither_get_size(pdither);
39
0
}
40
41
/*
42
 * Free a dither matrix structure.
43
 */
44
static void
45
free_dither_matrix(gs_memory_t * pmem, void *pvdither, client_name_t cname)
46
0
{
47
0
    pcl_udither_t *pdither = (pcl_udither_t *) pvdither;
48
49
0
    if (pdither->ptbl != 0)
50
0
        gs_free_object(pmem, (void *)pdither->ptbl, cname);
51
0
    gs_free_object(pmem, pvdither, cname);
52
0
}
53
54
/*
55
 * ESC * m <nbytes> W
56
 *
57
 * Download dither matrix.
58
 */
59
static int
60
download_dither_matrix(pcl_args_t * pargs, pcl_state_t * pcs)
61
16
{
62
16
    uint len = uint_arg(pargs);
63
16
    pcl_udither_t *pdither = 0;
64
65
16
    const pcl__udither_t *ptbl = (pcl__udither_t *) arg_data(pargs);
66
16
    uint nplanes, h, w;
67
16
    size_t rlen;
68
16
    int code = 0;
69
16
    byte *bp;
70
71
#ifdef DEBUG
72
    if (gs_debug_c('i')) {
73
        pcl_debug_dump_data(pcs->memory, arg_data(pargs), uint_arg(pargs));
74
    }
75
#endif
76
77
16
    if (pcs->raster_state.graphics_mode)
78
12
        return 0;
79
    /* check for legitimate parameter values */
80
4
    if (len < 7)
81
3
        return 0;
82
1
    nplanes = ptbl->nplanes;
83
1
    h = (ptbl->height[0] << 8) + ptbl->height[1];
84
1
    w = (ptbl->width[0] << 8) + ptbl->width[1];
85
1
    rlen = nplanes * h * w + 6;
86
1
    if (((nplanes != 1) && (nplanes != 3)) ||
87
0
        (h == 0) || (w == 0) || (len < rlen))
88
1
        return e_Range;
89
90
0
    rc_alloc_struct_1(pdither,
91
0
                      pcl_udither_t,
92
0
                      &st_udither_t,
93
0
                      pcs->memory, return e_Memory, "download dither matrix");
94
0
    pdither->rc.free = free_dither_matrix;
95
0
    pdither->ptbl = 0;
96
97
    /* either take possession of buffer, or allocate a new one */
98
0
    if (pargs->data_on_heap)
99
0
        arg_data(pargs) = 0;
100
0
    else {
101
0
        pcl__udither_t *ptmp = 0;
102
103
0
        ptmp = (pcl__udither_t *) gs_alloc_bytes(pcs->memory,
104
0
                                                 rlen,
105
0
                                                 "donwload dither matrix");
106
0
        if (ptmp == 0) {
107
0
            free_dither_matrix(pdither->rc.memory,
108
0
                               pdither, "download dither matrix");
109
0
            return e_Memory;
110
0
        }
111
0
        memcpy(ptmp, ptbl, rlen);
112
0
        ptbl = ptmp;
113
0
    }
114
0
    pdither->height = h;
115
0
    pdither->width = w;
116
0
    pdither->ptbl = ptbl;
117
118
    /* do not allow the value 0 in the array - black must be black */
119
0
    bp = (byte *) ptbl->data;
120
0
    rlen -= 6;
121
0
    while (rlen-- > 0) {
122
0
        byte b = *bp;
123
124
0
        *bp++ = (b == 0 ? 1 : b);
125
0
    }
126
127
    /* update the dither matrix; release our reference */
128
0
    code = pcl_palette_set_udither(pcs, pdither);
129
0
    pcl_udither_release(pdither);
130
0
    return code;
131
0
}
132
133
/*
134
 * There is no reset or copy procedure for this module, as both functions are
135
 * handled at the palette level.
136
 */
137
static int
138
udither_do_registration(pcl_parser_state_t * pcl_parser_state,
139
                        gs_memory_t * pmem)
140
16.0k
{
141
16.0k
    DEFINE_CLASS('*') {
142
16.0k
        'm', 'W',
143
16.0k
            PCL_COMMAND("Download Dither Matrix", download_dither_matrix,
144
16.0k
                        pca_bytes | pca_raster_graphics)
145
16.0k
    }, END_CLASS return 0;
146
16.0k
}
147
148
const pcl_init_t pcl_udither_init = { udither_do_registration, 0, 0 };