Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gdevmr2n.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
/* RasterOp implementation for 2- and 4-bit memory devices */
17
#include "memory_.h"
18
#include "gx.h"
19
#include "gsbittab.h"
20
#include "gserrors.h"
21
#include "gsropt.h"
22
#include "gxcindex.h"
23
#include "gxdcolor.h"
24
#include "gxdevice.h"
25
#include "gxdevmem.h"
26
#include "gdevmem.h"
27
#include "gdevmrop.h"
28
29
/* Calculate the X offset for a given Y value, */
30
/* taking shift into account if necessary. */
31
#define x_offset(px, ty, textures)\
32
  ((textures)->shift == 0 ? (px) :\
33
   (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
34
35
/* ---------------- Fake RasterOp for 2- and 4-bit devices ---------------- */
36
37
/*
38
 * Define patched versions of the driver procedures that may be called
39
 * by mem_mono_strip_copy_rop (see below).  Currently we just punt to
40
 * the slow, general case; we could do a lot better.
41
 */
42
static int
43
mem_gray_rop_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
44
                            gx_color_index color)
45
0
{
46
0
    return -1;
47
0
}
48
static int
49
mem_gray_rop_copy_mono(gx_device * dev, const byte * data,
50
                       int dx, int raster, gx_bitmap_id id,
51
                       int x, int y, int w, int h,
52
                       gx_color_index zero, gx_color_index one)
53
0
{
54
0
    return -1;
55
0
}
56
static int
57
mem_gray_rop_strip_tile_rectangle(gx_device * dev,
58
                                  const gx_strip_bitmap * tiles,
59
                                  int x, int y, int w, int h,
60
                                  gx_color_index color0, gx_color_index color1,
61
                                  int px, int py)
62
0
{
63
0
    return -1;
64
0
}
65
66
int
67
mem_gray_strip_copy_rop2(gx_device * dev,
68
             const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
69
                        const gx_color_index * scolors,
70
           const gx_strip_bitmap * textures, const gx_color_index * tcolors,
71
                        int x, int y, int width, int height,
72
                        int phase_x, int phase_y, gs_logical_operation_t lop,
73
                        uint planar_height)
74
0
{
75
0
    gx_color_index scolors2[2];
76
0
    const gx_color_index *real_scolors = scolors;
77
0
    gx_color_index tcolors2[2];
78
0
    const gx_color_index *real_tcolors = tcolors;
79
0
    gx_strip_bitmap texture2;
80
0
    const gx_strip_bitmap *real_texture = textures;
81
0
    long tdata;
82
0
    int depth = dev->color_info.depth;
83
0
    int log2_depth = depth >> 1;  /* works for 2, 4 */
84
0
    gx_color_index max_pixel = ((gx_color_index)1 << depth) - 1;
85
0
    int code;
86
87
    /* assert(planar_height == 0); */
88
89
#ifdef DEBUG
90
    if (gs_debug_c('b'))
91
        trace_copy_rop("mem_gray_strip_copy_rop",
92
                       dev, sdata, sourcex, sraster,
93
                       id, scolors, textures, tcolors,
94
                       x, y, width, height, phase_x, phase_y, lop);
95
#endif
96
0
    lop = lop_sanitize(lop);
97
0
    if (gx_device_has_color(dev) ||
98
0
        (scolors &&   /* must be (0,0) or (max,max) */
99
0
         ((scolors[0] | scolors[1]) != 0) &&
100
0
         ((scolors[0] & scolors[1]) != max_pixel)) ||
101
0
        (tcolors && (tcolors[0] != tcolors[1]))
102
0
        ) {
103
        /* We can't fake it: do it the slow, painful way. */
104
0
        return mem_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id,
105
0
                                           scolors, textures, tcolors,
106
0
                                           x, y, width, height,
107
0
                                           phase_x, phase_y, lop, 0);
108
0
    }
109
0
    if (scolors) {   /* Must be a solid color: see above. */
110
0
        scolors2[0] = scolors2[1] = scolors[0] & 1;
111
0
        real_scolors = scolors2;
112
0
    }
113
0
    if (textures) {
114
0
        texture2 = *textures;
115
0
        texture2.size.x <<= log2_depth;
116
0
        texture2.rep_width <<= log2_depth;
117
0
        texture2.shift <<= log2_depth;
118
0
        texture2.rep_shift <<= log2_depth;
119
0
        texture2.num_planes = 1;
120
0
        real_texture = &texture2;
121
0
    }
122
0
    if (tcolors) {
123
        /* For polybit textures with colors other than */
124
        /* all 0s or all 1s, fabricate the data. */
125
0
        if (tcolors[0] != 0 && tcolors[0] != max_pixel) {
126
0
            real_tcolors = 0;
127
0
            *(byte *) & tdata = (byte) tcolors[0] << (8 - depth);
128
0
            texture2.data = (byte *) & tdata;
129
0
            texture2.raster = align_bitmap_mod;
130
0
            texture2.size.x = texture2.rep_width = depth;
131
0
            texture2.size.y = texture2.rep_height = 1;
132
0
            texture2.id = gx_no_bitmap_id;
133
0
            texture2.shift = texture2.rep_shift = 0;
134
0
            real_texture = &texture2;
135
0
        } else {
136
0
            tcolors2[0] = tcolors2[1] = tcolors[0] & 1;
137
0
            real_tcolors = tcolors2;
138
0
        }
139
0
    }
140
    /*
141
     * mem_mono_strip_copy_rop may call fill_rectangle, copy_mono, or
142
     * strip_tile_rectangle for special cases.  Patch those procedures
143
     * temporarily so they will either do the right thing or return
144
     * an error.
145
     */
146
0
    {
147
0
        dev_proc_fill_rectangle((*fill_rectangle)) =
148
0
            dev_proc(dev, fill_rectangle);
149
0
        dev_proc_copy_mono((*copy_mono)) =
150
0
            dev_proc(dev, copy_mono);
151
0
        dev_proc_strip_tile_rectangle((*strip_tile_rectangle)) =
152
0
            dev_proc(dev, strip_tile_rectangle);
153
154
0
        set_dev_proc(dev, fill_rectangle, mem_gray_rop_fill_rectangle);
155
0
        set_dev_proc(dev, copy_mono, mem_gray_rop_copy_mono);
156
0
        set_dev_proc(dev, strip_tile_rectangle,
157
0
                     mem_gray_rop_strip_tile_rectangle);
158
0
        dev->width <<= log2_depth;
159
0
        code = mem_mono_strip_copy_rop2(dev, sdata,
160
0
                                        (real_scolors == NULL ?
161
0
                                         sourcex << log2_depth : sourcex),
162
0
                                        sraster, id, real_scolors,
163
0
                                        real_texture, real_tcolors,
164
0
                                        x << log2_depth, y,
165
0
                                        width << log2_depth, height,
166
0
                                        phase_x << log2_depth, phase_y,
167
0
                                        lop, 0);
168
0
        set_dev_proc(dev, fill_rectangle, fill_rectangle);
169
0
        set_dev_proc(dev, copy_mono, copy_mono);
170
0
        set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle);
171
0
        dev->width >>= log2_depth;
172
0
    }
173
    /* If we punted, use the general procedure. */
174
0
    if (code < 0)
175
0
        return mem_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id,
176
0
                                           scolors, textures, tcolors,
177
0
                                           x, y, width, height,
178
0
                                           phase_x, phase_y, lop, 0);
179
0
    return code;
180
0
}