/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 | } |