Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gdevmr8n.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 8N-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
/* Use the RUN_ROP code. */
30
#define USE_RUN_ROP
31
#undef COMPARE_AND_CONTRAST
32
33
/*
34
 * NOTE: The 16- and 32-bit cases aren't implemented: they just fall back to
35
 * the default implementation.  This is very slow and will be fixed someday.
36
 */
37
38
#define chunk byte
39
40
/* Calculate the X offset for a given Y value, */
41
/* taking shift into account if necessary. */
42
#define x_offset(px, ty, textures)\
43
0
  ((textures)->shift == 0 ? (px) :\
44
0
   (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
45
46
/* ---------------- RasterOp with 8-bit gray / 24-bit RGB ---------------- */
47
48
int
49
mem_gray8_rgb24_strip_copy_rop2(gx_device * dev,
50
             const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
51
                               const gx_color_index * scolors,
52
           const gx_strip_bitmap * textures, const gx_color_index * tcolors,
53
                               int x, int y, int width, int height,
54
                       int phase_x, int phase_y,
55
                       gs_logical_operation_t dirty_lop, uint planar_height)
56
0
{
57
0
    gx_device_memory *mdev = (gx_device_memory *) dev;
58
0
    gs_logical_operation_t lop = lop_sanitize(dirty_lop);
59
0
    gs_rop3_t rop;
60
0
    gx_color_index const_source = gx_no_color_index;
61
0
    gx_color_index const_texture = gx_no_color_index;
62
0
    uint draster = mdev->raster;
63
0
    int line_count;
64
0
    byte *drow, *base;
65
0
    int depth = dev->color_info.depth;
66
0
    int bpp = depth >> 3;       /* bytes per pixel, 1 or 3 */
67
0
    gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1;
68
0
    gx_color_index local_scolors[2];
69
0
    gx_color_index local_tcolors[2];
70
71
0
#ifdef USE_RUN_ROP
72
0
    rop_run_op ropper;
73
#ifdef COMPARE_AND_CONTRAST
74
    static byte testbuffer[4096];
75
    static byte *start;
76
    static int bytelen;
77
#endif
78
0
#endif
79
80
    /* assert(planar_height == 0); */
81
82
    /* Check for constant source. */
83
0
    if (!rop3_uses_S(lop)) {
84
0
        const_source = 0;       /* arbitrary */
85
0
    } else if (scolors != 0 && scolors[0] == scolors[1]) {
86
        /* Constant source */
87
0
        const_source = scolors[0];
88
0
        if (const_source == gx_device_black(dev))
89
0
            lop = lop_know_S_0(lop);
90
0
        else if (const_source == gx_device_white(dev)) {
91
0
            lop = lop_know_S_1(lop);
92
0
        }
93
0
    }
94
95
    /* Check for constant texture. */
96
0
    if (!rop3_uses_T(lop))
97
0
        const_texture = 0;      /* arbitrary */
98
0
    else if (tcolors != 0 && tcolors[0] == tcolors[1]) {
99
        /* Constant texture */
100
0
        const_texture = tcolors[0];
101
0
        if (const_texture == gx_device_black(dev))
102
0
            lop = lop_know_T_0(lop);
103
0
        else if (const_texture == gx_device_white(dev)) {
104
0
            lop = lop_know_T_1(lop);
105
0
        }
106
0
    }
107
108
0
    rop = lop_rop(lop);
109
110
0
    if (bpp == 1 &&
111
0
        (gx_device_has_color(dev) ||
112
0
         (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones))
113
0
        ) {
114
        /*
115
         * This is an 8-bit device but not gray-scale.  Except in a few
116
         * simple cases, we have to use the slow algorithm that converts
117
         * values to and from RGB.
118
         */
119
0
        gx_color_index bw_pixel;
120
121
0
        switch (rop) {
122
0
        case rop3_0:
123
0
            bw_pixel = gx_device_black(dev);
124
0
            goto bw;
125
0
        case rop3_1:
126
0
            bw_pixel = gx_device_white(dev);
127
0
bw:         if (bw_pixel == 0x00)
128
0
                rop = rop3_0;
129
0
            else if (bw_pixel == 0xff)
130
0
                rop = rop3_1;
131
0
            else
132
0
                goto df;
133
0
            break;
134
0
        case rop3_D:
135
0
            break;
136
0
        case rop3_S:
137
0
            break;
138
0
        case rop3_T:
139
0
            break;
140
0
        default:
141
0
df:         return mem_default_strip_copy_rop2(dev,
142
0
                                               sdata, sourcex, sraster, id,
143
0
                                               scolors, textures, tcolors,
144
0
                                               x, y, width, height,
145
0
                                               phase_x, phase_y, lop, 0);
146
0
        }
147
        /* Put the updated rop back into the lop */
148
0
        lop = rop;
149
0
    }
150
151
    /* Adjust coordinates to be in bounds. */
152
0
    if (const_source == gx_no_color_index) {
153
0
        fit_copy(dev, sdata, sourcex, sraster, id,
154
0
                 x, y, width, height);
155
0
    } else {
156
0
        fit_fill(dev, x, y, width, height);
157
0
    }
158
159
    /* Set up transfer parameters. */
160
0
    line_count = height;
161
0
    base = scan_line_base(mdev, y);
162
0
    drow = base + x * bpp;
163
164
    /* Allow for colors being passed in with tags in the top bits.
165
     * This confuses transparency code.
166
     */
167
0
    {
168
0
        gx_color_index color_mask = (bpp == 1 ? 0xff : 0xffffff);
169
0
        if (scolors)
170
0
        {
171
0
            local_scolors[0] = scolors[0] & color_mask;
172
0
            local_scolors[1] = scolors[1] & color_mask;
173
0
            scolors = local_scolors;
174
0
        }
175
0
        if (tcolors)
176
0
        {
177
0
            local_tcolors[0] = tcolors[0] & color_mask;
178
0
            local_tcolors[1] = tcolors[1] & color_mask;
179
0
            tcolors = local_tcolors;
180
0
        }
181
0
    }
182
183
    /*
184
     * There are 18 cases depending on whether each of the source and
185
     * texture is constant, 1-bit, or multi-bit, and on whether the
186
     * depth is 8 or 24 bits.  We divide first according to constant
187
     * vs. non-constant, and then according to 1- vs. multi-bit, and
188
     * finally according to pixel depth.  This minimizes source code,
189
     * but not necessarily time, since we do some of the divisions
190
     * within 1 or 2 levels of loop.
191
     */
192
193
0
#ifdef USE_RUN_ROP
194
0
#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
195
/* 8-bit */
196
0
#define cbit8(base, i, colors)\
197
0
  (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
198
#ifdef COMPARE_AND_CONTRAST
199
#define rop_body_8(s_pixel, t_pixel)\
200
  *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
201
#endif
202
/* 24-bit */
203
0
#define get24(ptr)\
204
0
  (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
205
0
#define put24(ptr, pixel)\
206
0
  (ptr)[0] = (byte)((pixel) >> 16),\
207
0
  (ptr)[1] = (byte)((uint)(pixel) >> 8),\
208
0
  (ptr)[2] = (byte)(pixel)
209
0
#define cbit24(base, i, colors)\
210
0
  (dbit(base, i) ? colors[1] : colors[0])
211
#ifdef COMPARE_AND_CONTRAST
212
#define rop_body_24(s_pixel, t_pixel)\
213
  { gx_color_index d_pixel = get24(dptr);\
214
    d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
215
    put24(dptr, d_pixel);\
216
  }
217
#endif
218
0
    if (const_texture != gx_no_color_index) {
219
/**** Constant texture ****/
220
0
        if (const_source != gx_no_color_index) {
221
/**** Constant source & texture ****/
222
0
            rop_set_s_constant(&ropper, const_source);
223
0
            rop_set_t_constant(&ropper, const_texture);
224
0
            if (rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_constant)) {
225
0
                for (; line_count-- > 0; drow += draster) {
226
#ifdef COMPARE_AND_CONTRAST
227
                    byte *dptr = drow;
228
                    int left = width;
229
230
                    bytelen = left*bpp; start = dptr;
231
                    memcpy(testbuffer, dptr, bytelen);
232
                    rop_run(&ropper, testbuffer, left);
233
234
                    if (bpp == 1)
235
/**** 8-bit destination ****/
236
                        for (; left > 0; ++dptr, --left) {
237
                            rop_body_8((byte)const_source, (byte)const_texture);
238
                        }
239
                    else
240
/**** 24-bit destination ****/
241
                        for (; left > 0; dptr += 3, --left) {
242
                            rop_body_24(const_source, const_texture);
243
                        }
244
                    if (memcmp(testbuffer, start, bytelen) != 0) {
245
                        emprintf(dev->memory, "Failed!\n");
246
                    }
247
#else
248
0
                    rop_run(&ropper, drow, width);
249
0
#endif
250
0
                }
251
0
                rop_release_run_op(&ropper);
252
0
            }
253
0
        } else {
254
/**** Data source, const texture ****/
255
0
            if (scolors) {
256
0
                const byte *srow = sdata;
257
258
0
                rop_set_t_constant(&ropper, const_texture);
259
0
                rop_set_s_colors(&ropper, scolors);
260
0
                if (rop_get_run_op(&ropper, lop, depth, rop_t_constant | rop_s_1bit)) {
261
262
0
                    for (; line_count-- > 0; drow += draster, srow += sraster) {
263
#ifdef COMPARE_AND_CONTRAST
264
                        byte *dptr = drow;
265
                        int left = width;
266
/**** 1-bit source ****/
267
                        int sx = sourcex;
268
269
                        rop_set_s_bitmap_subbyte(&ropper, srow, sourcex);
270
                        bytelen = left*bpp; start = dptr;
271
                        memcpy(testbuffer, dptr, bytelen);
272
                        rop_run(&ropper, testbuffer, width);
273
                        if (bpp == 1)
274
/**** 8-bit destination ****/
275
                            for (; left > 0; ++dptr, ++sx, --left) {
276
                                byte s_pixel = cbit8(srow, sx, scolors);
277
278
                                rop_body_8(s_pixel, (byte)const_texture);
279
                            }
280
                        else
281
/**** 24-bit destination ****/
282
                            for (; left > 0; dptr += 3, ++sx, --left) {
283
                                bits32 s_pixel = cbit24(srow, sx, scolors);
284
285
                                rop_body_24(s_pixel, const_texture);
286
                            }
287
                        if (memcmp(testbuffer, start, bytelen) != 0) {
288
                            emprintf(dev->memory, "Failed!\n");
289
                        }
290
#else
291
/**** 1-bit source ****/
292
/**** 8-bit destination ****/
293
/**** 24-bit destination ****/
294
0
                        rop_set_s_bitmap_subbyte(&ropper, srow, sourcex);
295
0
                        rop_run(&ropper, drow, width);
296
0
#endif
297
0
                    }
298
0
                    rop_release_run_op(&ropper);
299
0
                }
300
0
            } else {
301
0
                const byte *srow = sdata;
302
0
                rop_set_t_constant(&ropper, const_texture);
303
0
                if (rop_get_run_op(&ropper, lop, depth, rop_t_constant)) {
304
0
                    for (; line_count-- > 0; drow += draster, srow += sraster) {
305
#ifdef COMPARE_AND_CONTRAST
306
                        byte *dptr = drow;
307
                        int left = width;
308
309
                        bytelen = left*bpp; start = dptr;
310
                        memcpy(testbuffer, dptr, bytelen);
311
312
                        rop_set_s_bitmap(&ropper, srow + sourcex * bpp);
313
                        rop_run(&ropper, testbuffer, left);
314
/**** 8-bit source & dest ****/
315
                        if (bpp == 1) {
316
                            const byte *sptr = srow + sourcex;
317
318
                            for (; left > 0; ++dptr, ++sptr, --left) {
319
                                byte s_pixel = *sptr;
320
321
                                rop_body_8(s_pixel, (byte)const_texture);
322
                            }
323
                        } else {
324
/**** 24-bit source & dest ****/
325
                            const byte *sptr = srow + sourcex * 3;
326
327
                            bytelen = left*bpp; start = dptr;
328
                            memcpy(testbuffer, dptr, bytelen);
329
330
                            for (; left > 0; dptr += 3, sptr += 3, --left) {
331
                                bits32 s_pixel = get24(sptr);
332
333
                                rop_body_24(s_pixel, const_texture);
334
                            }
335
                        }
336
                        if (memcmp(testbuffer, start, bytelen) != 0) {
337
                            emprintf(dev->memory, "Failed!\n");
338
                        }
339
#else
340
/**** 8-bit source & dest ****/
341
/**** 24-bit source & dest ****/
342
0
                        rop_set_s_bitmap(&ropper, srow + sourcex * bpp);
343
0
                        rop_run(&ropper, drow, width);
344
0
#endif
345
0
                    }
346
0
                    rop_release_run_op(&ropper);
347
0
                }
348
0
            }
349
0
        }
350
0
    } else if (const_source != gx_no_color_index) {
351
/**** Const source, data texture ****/
352
0
        if (tcolors) {
353
0
            uint traster = textures->raster;
354
0
            int ty = y + phase_y;
355
356
0
            rop_set_s_constant(&ropper, const_source);
357
0
            rop_set_t_colors(&ropper, tcolors);
358
0
            if (rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit)) {
359
0
                for (; line_count-- > 0; drow += draster, ++ty) {   /* Loop over copies of the tile. */
360
0
                    int dx = x, w = width, nw;
361
0
                    byte *dptr = drow;
362
0
                    const byte *trow =
363
0
                    textures->data + (ty % textures->size.y) * traster;
364
0
                    int xoff = x_offset(phase_x, ty, textures);
365
366
0
                    for (; w > 0; dx += nw, w -= nw) {
367
0
                        int tx = (dx + xoff) % textures->rep_width;
368
0
                        int left = nw = min(w, textures->size.x - tx);
369
#ifdef COMPARE_AND_CONTRAST
370
                        const byte *tptr = trow;
371
#endif
372
373
0
                        rop_set_t_bitmap_subbyte(&ropper, trow, tx);
374
#ifdef COMPARE_AND_CONTRAST
375
                        bytelen = left*bpp; start = dptr;
376
                        memcpy(testbuffer, dptr, bytelen);
377
                        rop_run(&ropper, testbuffer, left);
378
/**** 1-bit texture ****/
379
                        if (bpp == 1)
380
/**** 8-bit dest ****/
381
                            for (; left > 0; ++dptr, ++tx, --left) {
382
                                byte t_pixel = cbit8(tptr, tx, tcolors);
383
384
                                rop_body_8((byte)const_source, t_pixel);
385
                            }
386
                        else
387
/**** 24-bit dest ****/
388
                            for (; left > 0; dptr += 3, ++tx, --left) {
389
                                bits32 t_pixel = cbit24(tptr, tx, tcolors);
390
391
                                rop_body_24(const_source, t_pixel);
392
                            }
393
                        if (memcmp(testbuffer, start, bytelen) != 0) {
394
                            emprintf(dev->memory, "Failed!\n");
395
                        }
396
#else
397
0
                        rop_run(&ropper, dptr, left);
398
0
                        dptr += left;
399
0
#endif
400
0
                    }
401
0
                }
402
0
            }
403
0
        } else {
404
0
            uint traster = textures->raster;
405
0
            int ty = y + phase_y;
406
407
0
            rop_set_s_constant(&ropper, const_source);
408
0
            if (rop_get_run_op(&ropper, lop, depth, rop_s_constant)) {
409
410
0
                for (; line_count-- > 0; drow += draster, ++ty) {   /* Loop over copies of the tile. */
411
0
                    int dx = x, w = width, nw;
412
0
                    byte *dptr = drow;
413
0
                    const byte *trow =
414
0
                    textures->data + (ty % textures->size.y) * traster;
415
0
                    int xoff = x_offset(phase_x, ty, textures);
416
417
0
                    for (; w > 0; dx += nw, w -= nw) {
418
0
                        int tx = (dx + xoff) % textures->rep_width;
419
0
                        int left = nw = min(w, textures->size.x - tx);
420
0
                        const byte *tptr = trow + tx*bpp;
421
0
                        rop_set_t_bitmap(&ropper, tptr);
422
#ifdef COMPARE_AND_CONTRAST
423
                        bytelen = left*bpp; start = dptr;
424
                        memcpy(testbuffer, dptr, bytelen);
425
                        rop_run(&ropper, testbuffer, left);
426
/**** 8-bit T & D ****/
427
                        if (bpp == 1) {
428
                            for (; left > 0; ++dptr, ++tptr, --left) {
429
                                byte t_pixel = *tptr;
430
431
                                rop_body_8((byte)const_source, t_pixel);
432
                            }
433
                        } else {
434
/**** 24-bit T & D ****/
435
                            for (; left > 0; dptr += 3, tptr += 3, --left) {
436
                                bits32 t_pixel = get24(tptr);
437
438
                                rop_body_24(const_source, t_pixel);
439
                            }
440
                        }
441
                        if (memcmp(testbuffer, start, bytelen) != 0) {
442
                            emprintf(dev->memory, "Failed!\n");
443
                        }
444
#else
445
/**** 8-bit T & D ****/
446
/**** 24-bit T & D ****/
447
0
                        rop_run(&ropper, dptr, left);
448
0
                        dptr += left * bpp;
449
0
#endif
450
0
                    }
451
0
                }
452
0
                rop_release_run_op(&ropper);
453
0
            }
454
0
        }
455
0
    } else {
456
/**** Data source & texture ****/
457
0
        if (scolors != NULL || tcolors != NULL) {
458
0
            uint traster = textures->raster;
459
0
            int ty = y + phase_y;
460
0
            const byte *srow = sdata;
461
462
0
            if (scolors)
463
0
                rop_set_s_colors(&ropper, scolors);
464
0
            if (tcolors)
465
0
                rop_set_s_colors(&ropper, tcolors);
466
0
            if (rop_get_run_op(&ropper, lop, depth,
467
0
                               ((scolors == NULL ? 0 : rop_s_1bit) |
468
0
                                (tcolors == NULL ? 0 : rop_t_1bit)))) {
469
                /* Loop over scan lines. */
470
0
                for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {  /* Loop over copies of the tile. */
471
0
                    int sx = sourcex;
472
0
                    int dx = x;
473
0
                    int w = width;
474
0
                    int nw;
475
0
                    byte *dptr = drow;
476
0
                    const byte *trow =
477
0
                    textures->data + (ty % textures->size.y) * traster;
478
0
                    int xoff = x_offset(phase_x, ty, textures);
479
480
0
                    for (; w > 0; dx += nw, w -= nw) {      /* Loop over individual pixels. */
481
0
                        int tx = (dx + xoff) % textures->rep_width;
482
0
                        int left = nw = min(w, textures->size.x - tx);
483
0
                        const byte *sptr = srow + sx*bpp;
484
0
                        const byte *tptr = trow + tx*bpp;
485
486
                        /*
487
                         * For maximum speed, we should split this loop
488
                         * into 7 cases depending on source & texture
489
                         * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
490
                         * (24,1), (24,24).  But since we expect these
491
                         * cases to be relatively uncommon, we just
492
                         * divide on the destination depth.
493
                         */
494
0
                        if (scolors)
495
0
                            rop_set_s_bitmap_subbyte(&ropper, srow, sx);
496
0
                        else
497
0
                            rop_set_s_bitmap(&ropper, sptr);
498
0
                        if (tcolors)
499
0
                            rop_set_t_bitmap_subbyte(&ropper, trow, tx);
500
0
                        else
501
0
                            rop_set_t_bitmap(&ropper, tptr);
502
503
#ifdef COMPARE_AND_CONTRAST
504
                        bytelen = left*bpp; start = dptr;
505
                        memcpy(testbuffer, dptr, bytelen);
506
                        rop_run(&ropper, testbuffer, left);
507
                        if (bpp == 1) {
508
/**** 8-bit destination ****/
509
                            for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
510
                                byte s_pixel =
511
                                    (scolors ? cbit8(srow, sx, scolors) : *sptr);
512
                                byte t_pixel =
513
                                    (tcolors ? cbit8(trow, tx, tcolors) : *tptr);
514
515
                                rop_body_8(s_pixel, t_pixel);
516
                            }
517
                        } else {
518
/**** 24-bit destination ****/
519
                            for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
520
                                bits32 s_pixel =
521
                                    (scolors ? cbit24(srow, sx, scolors) :
522
                                     get24(sptr));
523
                                bits32 t_pixel =
524
                                    (tcolors ? cbit24(tptr, tx, tcolors) :
525
                                     get24(tptr));
526
527
                                rop_body_24(s_pixel, t_pixel);
528
                            }
529
                        }
530
                        if (memcmp(testbuffer, start, bytelen) != 0) {
531
                            emprintf(dev->memory, "Failed!\n");
532
                        }
533
#else
534
0
                        rop_run(&ropper, dptr, left);
535
0
                        dptr += left * bpp;
536
0
#endif
537
0
                    }
538
0
                }
539
0
            }
540
0
        } else {
541
0
            uint traster = textures->raster;
542
0
            int ty = y + phase_y;
543
0
            const byte *srow = sdata;
544
545
            /* Loop over scan lines. */
546
0
            if (rop_get_run_op(&ropper, lop, depth, 0)) {
547
0
                for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {  /* Loop over copies of the tile. */
548
0
                    int sx = sourcex;
549
0
                    int dx = x;
550
0
                    int w = width;
551
0
                    int nw;
552
0
                    byte *dptr = drow;
553
0
                    const byte *trow =
554
0
                    textures->data + (ty % textures->size.y) * traster;
555
0
                    int xoff = x_offset(phase_x, ty, textures);
556
557
0
                    for (; w > 0; sx += nw, dx += nw, w -= nw) {      /* Loop over individual pixels. */
558
0
                        int tx = (dx + xoff) % textures->rep_width;
559
0
                        int left = nw = min(w, textures->size.x - tx);
560
0
                        const byte *tptr = trow + tx * bpp;
561
0
                        const byte *sptr = srow + sx * bpp;
562
563
0
                        rop_set_s_bitmap(&ropper, sptr);
564
0
                        rop_set_t_bitmap(&ropper, tptr);
565
#ifdef COMPARE_AND_CONTRAST
566
                        if (bpp == 1) {
567
                            rop_run(&ropper, testbuffer, left);
568
/**** 8-bit destination ****/
569
570
                            for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
571
                                rop_body_8(*sptr, *tptr);
572
                            }
573
                        } else {
574
/**** 24-bit destination ****/
575
                            for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
576
                                bits32 s_pixel = get24(sptr);
577
                                bits32 t_pixel = get24(tptr);
578
579
                                rop_body_24(s_pixel, t_pixel);
580
                            }
581
                        }
582
                        if (memcmp(testbuffer, start, bytelen) != 0) {
583
                            emprintf(dev->memory, "Failed!\n");
584
                        }
585
#else
586
/**** 8-bit destination ****/
587
/**** 24-bit destination ****/
588
0
                        rop_run(&ropper, dptr, left);
589
0
                        dptr += left * bpp;
590
0
#endif
591
0
                    }
592
0
                }
593
0
                rop_release_run_op(&ropper);
594
0
            }
595
0
        }
596
0
    }
597
0
#undef rop_body_8
598
0
#undef rop_body_24
599
0
#undef dbit
600
0
#undef cbit8
601
0
#undef cbit24
602
#else
603
604
#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
605
/* 8-bit */
606
#define cbit8(base, i, colors)\
607
  (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
608
#define rop_body_8(s_pixel, t_pixel)\
609
  *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
610
/* 24-bit */
611
#define get24(ptr)\
612
  (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
613
#define put24(ptr, pixel)\
614
  (ptr)[0] = (byte)((pixel) >> 16),\
615
  (ptr)[1] = (byte)((uint)(pixel) >> 8),\
616
  (ptr)[2] = (byte)(pixel)
617
#define cbit24(base, i, colors)\
618
  (dbit(base, i) ? colors[1] : colors[0])
619
#define rop_body_24(s_pixel, t_pixel)\
620
  { gx_color_index d_pixel = get24(dptr);\
621
    d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
622
    put24(dptr, d_pixel);\
623
  }
624
625
    if (const_texture != gx_no_color_index) {
626
/**** Constant texture ****/
627
        if (const_source != gx_no_color_index) {
628
/**** Constant source & texture ****/
629
            for (; line_count-- > 0; drow += draster) {
630
                byte *dptr = drow;
631
                int left = width;
632
633
                if (bpp == 1)
634
/**** 8-bit destination ****/
635
                    for (; left > 0; ++dptr, --left) {
636
                        rop_body_8((byte)const_source, (byte)const_texture);
637
                    }
638
                else
639
/**** 24-bit destination ****/
640
                    for (; left > 0; dptr += 3, --left) {
641
                        rop_body_24(const_source, const_texture);
642
                    }
643
            }
644
        } else {
645
/**** Data source, const texture ****/
646
            const byte *srow = sdata;
647
648
            for (; line_count-- > 0; drow += draster, srow += sraster) {
649
                byte *dptr = drow;
650
                int left = width;
651
652
                if (scolors) {
653
/**** 1-bit source ****/
654
                    int sx = sourcex;
655
656
                    if (bpp == 1)
657
/**** 8-bit destination ****/
658
                        for (; left > 0; ++dptr, ++sx, --left) {
659
                            byte s_pixel = cbit8(srow, sx, scolors);
660
661
                            rop_body_8(s_pixel, (byte)const_texture);
662
                        }
663
                    else
664
/**** 24-bit destination ****/
665
                        for (; left > 0; dptr += 3, ++sx, --left) {
666
                            bits32 s_pixel = cbit24(srow, sx, scolors);
667
668
                            rop_body_24(s_pixel, const_texture);
669
                        }
670
                } else if (bpp == 1) {
671
/**** 8-bit source & dest ****/
672
                    const byte *sptr = srow + sourcex;
673
674
                    for (; left > 0; ++dptr, ++sptr, --left) {
675
                        byte s_pixel = *sptr;
676
677
                        rop_body_8(s_pixel, (byte)const_texture);
678
                    }
679
                } else {
680
/**** 24-bit source & dest ****/
681
                    const byte *sptr = srow + sourcex * 3;
682
683
                    for (; left > 0; dptr += 3, sptr += 3, --left) {
684
                        bits32 s_pixel = get24(sptr);
685
686
                        rop_body_24(s_pixel, const_texture);
687
                    }
688
                }
689
            }
690
        }
691
    } else if (const_source != gx_no_color_index) {
692
/**** Const source, data texture ****/
693
        uint traster = textures->raster;
694
        int ty = y + phase_y;
695
696
        for (; line_count-- > 0; drow += draster, ++ty) {       /* Loop over copies of the tile. */
697
            int dx = x, w = width, nw;
698
            byte *dptr = drow;
699
            const byte *trow =
700
            textures->data + (ty % textures->size.y) * traster;
701
            int xoff = x_offset(phase_x, ty, textures);
702
703
            for (; w > 0; dx += nw, w -= nw) {
704
                int tx = (dx + xoff) % textures->rep_width;
705
                int left = nw = min(w, textures->size.x - tx);
706
                const byte *tptr = trow;
707
708
                if (tcolors) {
709
/**** 1-bit texture ****/
710
                    if (bpp == 1)
711
/**** 8-bit dest ****/
712
                        for (; left > 0; ++dptr, ++tx, --left) {
713
                            byte t_pixel = cbit8(tptr, tx, tcolors);
714
715
                            rop_body_8((byte)const_source, t_pixel);
716
                        }
717
                    else
718
/**** 24-bit dest ****/
719
                        for (; left > 0; dptr += 3, ++tx, --left) {
720
                            bits32 t_pixel = cbit24(tptr, tx, tcolors);
721
722
                            rop_body_24(const_source, t_pixel);
723
                        }
724
                } else if (bpp == 1) {
725
/**** 8-bit T & D ****/
726
                    tptr += tx;
727
                    for (; left > 0; ++dptr, ++tptr, --left) {
728
                        byte t_pixel = *tptr;
729
730
                        rop_body_8((byte)const_source, t_pixel);
731
                    }
732
                } else {
733
/**** 24-bit T & D ****/
734
                    tptr += tx * 3;
735
                    for (; left > 0; dptr += 3, tptr += 3, --left) {
736
                        bits32 t_pixel = get24(tptr);
737
738
                        rop_body_24(const_source, t_pixel);
739
                    }
740
                }
741
            }
742
        }
743
    } else {
744
/**** Data source & texture ****/
745
        uint traster = textures->raster;
746
        int ty = y + phase_y;
747
        const byte *srow = sdata;
748
749
        /* Loop over scan lines. */
750
        for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {      /* Loop over copies of the tile. */
751
            int sx = sourcex;
752
            int dx = x;
753
            int w = width;
754
            int nw;
755
            byte *dptr = drow;
756
            const byte *trow =
757
            textures->data + (ty % textures->size.y) * traster;
758
            int xoff = x_offset(phase_x, ty, textures);
759
760
            for (; w > 0; dx += nw, w -= nw) {  /* Loop over individual pixels. */
761
                int tx = (dx + xoff) % textures->rep_width;
762
                int left = nw = min(w, textures->size.x - tx);
763
                const byte *tptr = trow;
764
765
                /*
766
                 * For maximum speed, we should split this loop
767
                 * into 7 cases depending on source & texture
768
                 * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
769
                 * (24,1), (24,24).  But since we expect these
770
                 * cases to be relatively uncommon, we just
771
                 * divide on the destination depth.
772
                 */
773
                if (bpp == 1) {
774
/**** 8-bit destination ****/
775
                    const byte *sptr = srow + sx;
776
777
                    tptr += tx;
778
                    for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
779
                        byte s_pixel =
780
                            (scolors ? cbit8(srow, sx, scolors) : *sptr);
781
                        byte t_pixel =
782
                            (tcolors ? cbit8(tptr, tx, tcolors) : *tptr);
783
784
                        rop_body_8(s_pixel, t_pixel);
785
                    }
786
                } else {
787
/**** 24-bit destination ****/
788
                    const byte *sptr = srow + sx * 3;
789
790
                    tptr += tx * 3;
791
                    for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
792
                        bits32 s_pixel =
793
                            (scolors ? cbit24(srow, sx, scolors) :
794
                             get24(sptr));
795
                        bits32 t_pixel =
796
                            (tcolors ? cbit24(tptr, tx, tcolors) :
797
                             get24(tptr));
798
799
                        rop_body_24(s_pixel, t_pixel);
800
                    }
801
                }
802
            }
803
        }
804
    }
805
#undef rop_body_8
806
#undef rop_body_24
807
#undef dbit
808
#undef cbit8
809
#undef cbit24
810
#endif
811
0
    return 0;
812
0
}