Coverage Report

Created: 2025-04-22 06:20

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