1 /* Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /* Default and device-independent RasterOp algorithms */
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 "gxgetbit.h"
28 #include "gdevmem.h" /* for mem_default_strip_copy_rop prototype */
29 #include "gdevmpla.h"
30 #include "gdevmrop.h"
31 #include "gxdevsop.h"
32
33 /*
34 * Define the maximum amount of space we are willing to allocate for a
35 * multiple-row RasterOp buffer. (We are always willing to allocate
36 * one row, no matter how wide.)
37 */
38 static const uint max_rop_bitmap = 1000;
39
40 /* ---------------- Debugging aids ---------------- */
41
42 #ifdef DEBUG
43
44 void
trace_copy_rop(const char * cname,gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)45 trace_copy_rop(const char *cname, gx_device * dev,
46 const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
47 const gx_color_index * scolors,
48 const gx_strip_bitmap * textures,
49 const gx_color_index * tcolors,
50 int x, int y, int width, int height,
51 int phase_x, int phase_y, gs_logical_operation_t lop)
52 {
53 dlprintf4("%s: dev=0x%lx(%s) depth=%d\n",
54 cname, (ulong) dev, dev->dname, dev->color_info.depth);
55 dlprintf4(" source data=0x%lx x=%d raster=%u id=%lu colors=",
56 (ulong) sdata, sourcex, sraster, (ulong) id);
57 if (scolors)
58 dprintf2("(%lu,%lu);\n", scolors[0], scolors[1]);
59 else
60 dputs("none;\n");
61 if (textures)
62 dlprintf8(" textures=0x%lx size=%dx%d(%dx%d) raster=%u shift=%d(%d)",
63 (ulong) textures, textures->size.x, textures->size.y,
64 textures->rep_width, textures->rep_height,
65 textures->raster, textures->shift, textures->rep_shift);
66 else
67 dlputs(" textures=none");
68 if (tcolors)
69 dprintf2(" colors=(%lu,%lu)\n", tcolors[0], tcolors[1]);
70 else
71 dputs(" colors=none\n");
72 dlprintf7(" rect=(%d,%d),(%d,%d) phase=(%d,%d) op=0x%x\n",
73 x, y, x + width, y + height, phase_x, phase_y,
74 (uint) lop);
75 if (gs_debug_c('B')) {
76 if (sdata)
77 debug_dump_bitmap(sdata, sraster, height, "source bits");
78 if (textures && textures->data)
79 debug_dump_bitmap(textures->data, textures->raster,
80 textures->size.y, "textures bits");
81 }
82 }
83
84 #endif
85
86 /* ---------------- Default copy_rop implementations ---------------- */
87
88 /*
89 * The default implementation for non-memory devices uses get_bits_rectangle
90 * to read out the pixels, the memory device implementation to do the
91 * operation, and copy_color to write the pixels back.
92 */
93 int
gx_default_strip_copy_rop(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)94 gx_default_strip_copy_rop(gx_device * dev,
95 const byte * sdata, int sourcex,
96 uint sraster, gx_bitmap_id id,
97 const gx_color_index * scolors,
98 const gx_strip_bitmap * textures,
99 const gx_color_index * tcolors,
100 int x, int y, int width, int height,
101 int phase_x, int phase_y,
102 gs_logical_operation_t lop)
103 {
104 return gx_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id,
105 scolors, textures, tcolors,
106 x, y, width, height,
107 phase_x, phase_y, lop, 0);
108 }
109
110 int
gx_default_strip_copy_rop2(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop,uint planar_height)111 gx_default_strip_copy_rop2(gx_device * dev,
112 const byte * sdata, int sourcex,
113 uint sraster, gx_bitmap_id id,
114 const gx_color_index * scolors,
115 const gx_strip_bitmap * textures,
116 const gx_color_index * tcolors,
117 int x, int y, int width, int height,
118 int phase_x, int phase_y,
119 gs_logical_operation_t lop,
120 uint planar_height)
121 {
122 int depth = dev->color_info.depth;
123 gs_memory_t *mem = dev->memory;
124 const gx_device_memory *mdproto = gdev_mem_device_for_bits(depth);
125 gx_device_memory *pmdev;
126 uint draster;
127 byte *row = 0;
128 gs_int_rect rect;
129 int max_height;
130 int block_height;
131 int code;
132 int py;
133 int is_planar = 0;
134
135 #ifdef DEBUG
136 if (gs_debug_c('b'))
137 trace_copy_rop("gx_default_strip_copy_rop",
138 dev, sdata, sourcex, sraster,
139 id, scolors, textures, tcolors,
140 x, y, width, height, phase_x, phase_y, lop);
141 #endif
142 if (mdproto == 0)
143 return_error(gs_error_rangecheck);
144 if (sdata == 0) {
145 fit_fill(dev, x, y, width, height);
146 } else {
147 fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
148 }
149 draster = bitmap_raster(width * depth);
150 max_height = max_rop_bitmap / draster;
151 if (max_height == 0)
152 max_height = 1;
153 block_height = min(height, max_height);
154 if (planar_height > 0)
155 block_height = planar_height;
156 gs_make_mem_device_with_copydevice(&pmdev, mdproto, mem, -1, dev);
157 pmdev->width = width;
158 pmdev->height = block_height;
159 pmdev->bitmap_memory = mem;
160 pmdev->color_info = dev->color_info;
161 if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0))
162 {
163 gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];
164 int num_comp = dev->color_info.num_components;
165 int depth = dev->color_info.depth/num_comp;
166 int i;
167 for (i = 0; i < num_comp; i++)
168 {
169 planes[i].shift = depth * (num_comp - 1 - i);
170 planes[i].depth = depth;
171 planes[i].index = i;
172 }
173 /* RJW: This code, like most of ghostscripts planar support,
174 * will only work if every plane has the same depth. */
175 draster = bitmap_raster(width * planes[0].depth);
176 code = gdev_mem_set_planar(pmdev, num_comp, planes);
177 if (code < 0)
178 return code;
179 is_planar = 1;
180 }
181 code = (*dev_proc(pmdev, open_device))((gx_device *)pmdev);
182 pmdev->is_open = true; /* not sure why we need this, but we do. */
183 if (code < 0)
184 return code;
185 if (rop3_uses_D(gs_transparent_rop(lop))) {
186 row = gs_alloc_bytes(mem, draster * block_height, "copy_rop row");
187 if (row == 0) {
188 code = gs_note_error(gs_error_VMerror);
189 goto out;
190 }
191 }
192 rect.p.x = x;
193 rect.q.x = x + width;
194 for (py = y; py < y + height; py += block_height) {
195 if (block_height > y + height - py)
196 block_height = y + height - py;
197 rect.p.y = py;
198 rect.q.y = py + block_height;
199 if (row /*uses_d*/) {
200 gs_get_bits_params_t bit_params;
201
202 bit_params.options =
203 GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL |
204 GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD |
205 GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD;
206 bit_params.data[0] = row;
207 bit_params.x_offset = 0;
208 code = (*dev_proc(dev, get_bits_rectangle))
209 (dev, &rect, &bit_params, NULL);
210 if (code < 0)
211 break;
212 code = (*dev_proc(pmdev, copy_color))
213 ((gx_device *)pmdev, bit_params.data[0], bit_params.x_offset,
214 draster, gx_no_bitmap_id, 0, 0, width,
215 block_height);
216 if (code < 0)
217 return code;
218 }
219 if (planar_height == 0) {
220 code = (*dev_proc(pmdev, strip_copy_rop))
221 ((gx_device *)pmdev,
222 sdata + (py - y) * sraster, sourcex, sraster,
223 gx_no_bitmap_id, scolors, textures, tcolors,
224 0, 0, width, block_height,
225 phase_x + x, phase_y + py,
226 lop);
227 } else {
228 code = (*dev_proc(pmdev, strip_copy_rop2))
229 ((gx_device *)pmdev,
230 sdata + (py - y) * sraster, sourcex, sraster,
231 gx_no_bitmap_id, scolors, textures, tcolors,
232 0, 0, width, block_height,
233 phase_x + x, phase_y + py,
234 lop, planar_height);
235 }
236 if (code < 0)
237 break;
238 if (is_planar) {
239 code = (*dev_proc(dev, copy_planes))
240 (dev, scan_line_base(pmdev, 0), 0,
241 draster, gx_no_bitmap_id,
242 x, py, width, block_height, block_height);
243 } else {
244 code = (*dev_proc(dev, copy_color))
245 (dev, scan_line_base(pmdev, 0), 0,
246 draster, gx_no_bitmap_id,
247 x, py, width, block_height);
248 }
249 if (code < 0)
250 break;
251 }
252 out:
253 gs_free_object(mem, row, "copy_rop row");
254 gx_device_retain((gx_device *)pmdev, false);
255 return code;
256 }
257
258 /* ---------------- Default memory device copy_rop ---------------- */
259
260 /* Convert color constants to standard RGB representation. */
261 static void
unpack_colors_to_standard(gx_device * dev,gx_color_index real_colors[2],const gx_color_index * colors,int depth)262 unpack_colors_to_standard(gx_device * dev, gx_color_index real_colors[2],
263 const gx_color_index * colors, int depth)
264 {
265 int i;
266
267 for (i = 0; i < 2; ++i) {
268 gx_color_value rgb[3];
269 gx_color_index pixel;
270
271 (*dev_proc(dev, map_color_rgb)) (dev, colors[i], rgb);
272 pixel = gx_color_value_to_byte(rgb[0]);
273 if (depth > 8) {
274 pixel = (pixel << 16) +
275 (gx_color_value_to_byte(rgb[1]) << 8) +
276 gx_color_value_to_byte(rgb[2]);
277 }
278 real_colors[i] = pixel;
279 }
280 }
281
282 /*
283 * Convert RGB to the device's native format. We special-case this for
284 * 1-bit CMYK devices.
285 */
286 static void
pack_cmyk_1bit_from_standard(gx_device_memory * dev,int y,int destx,const byte * src,int width,int depth,int src_depth)287 pack_cmyk_1bit_from_standard(gx_device_memory * dev, int y, int destx,
288 const byte * src, int width, int depth,
289 int src_depth)
290 {
291 /*
292 * This routine is only called if dev_proc(dev, map_cmyk_color) ==
293 * cmyk_1bit_map_cmyk_color (implying depth == 4) and src_depth == 24.
294 */
295 byte *dest = scan_line_base(dev, y);
296 int bit_x = destx * 4;
297 byte *dp = dest + (bit_x >> 3);
298 bool hi = (bit_x & 4) != 0; /* true if last nibble filled was hi */
299 byte buf = (hi ? *dp & 0xf0 : 0);
300 const byte *sp = src;
301 int x;
302
303 for (x = width; --x >= 0; sp += 3) {
304 byte r = sp[0], g = sp[1], b = sp[2];
305 byte pixel =
306 (r | g | b ?
307 (((r >> 4) & 8) | ((g >> 5) & 4) | ((b >> 6) & 2)) ^ 0xe : 1);
308
309 if ((hi = !hi))
310 buf = pixel << 4;
311 else
312 *dp++ = buf | pixel;
313 }
314 if (hi && width > 0)
315 *dp = buf | (*dp & 0xf);
316
317 }
318
319 static void
pack_planar_cmyk_1bit_from_standard(gx_device_memory * dev,int y,int destx,const byte * src,int width,int depth,int src_depth)320 pack_planar_cmyk_1bit_from_standard(gx_device_memory * dev, int y, int destx,
321 const byte * src, int width, int depth,
322 int src_depth)
323 {
324 /*
325 * This routine is only called if dev_proc(dev, map_cmyk_color) ==
326 * cmyk_1bit_map_cmyk_color (implying depth == 4) and src_depth == 24.
327 */
328 byte *dp[GX_DEVICE_COLOR_MAX_COMPONENTS];
329 int shift = destx & 7;
330 byte buf[GX_DEVICE_COLOR_MAX_COMPONENTS];
331 const byte *sp = src;
332 int x, plane;
333
334 for (plane = 0; plane < 4; plane++) {
335 byte *dest = scan_line_base(dev, y + plane * dev->height);
336 dp[plane] = dest + (destx >> 3);
337 buf[plane] = (shift == 0 ? 0 : *dp[plane] & (0xff00 >> shift));
338 }
339
340 shift = (0x80>>shift);
341 for (x = width; --x >= 0;) {
342 byte vr, vg, vb;
343
344 vr = *sp++;
345 vg = *sp++;
346 vb = *sp++;
347 if ((vr | vg | vb) == 0)
348 buf[3] += shift;
349 else {
350 if ((vr & 0x80) == 0)
351 buf[0] += shift;
352 if ((vg & 0x80) == 0)
353 buf[1] += shift;
354 if ((vb & 0x80) == 0)
355 buf[2] += shift;
356 }
357 shift >>= 1;
358 if (shift == 0) {
359 *dp[0]++ = buf[0]; buf[0] = 0;
360 *dp[1]++ = buf[1]; buf[1] = 0;
361 *dp[2]++ = buf[2]; buf[2] = 0;
362 *dp[3]++ = buf[3]; buf[3] = 0;
363 shift = 0x80;
364 }
365 }
366 if (shift != 0x80) {
367 shift += shift-1;
368 *dp[0] = (*dp[0] & shift) + buf[0];
369 *dp[1] = (*dp[1] & shift) + buf[1];
370 *dp[2] = (*dp[2] & shift) + buf[2];
371 *dp[3] = (*dp[3] & shift) + buf[3];
372 }
373 }
374
375 static gx_color_index
map_rgb_to_color_via_cmyk(gx_device * dev,const gx_color_value rgbcv[])376 map_rgb_to_color_via_cmyk(gx_device * dev, const gx_color_value rgbcv[])
377 {
378 gx_color_value cmykcv[4];
379
380 cmykcv[0] = gx_max_color_value - rgbcv[0];
381 cmykcv[1] = gx_max_color_value - rgbcv[1];
382 cmykcv[2] = gx_max_color_value - rgbcv[2];
383 cmykcv[3] = (cmykcv[0] < cmykcv[1] ? min(cmykcv[0], cmykcv[2]) : min(cmykcv[1], cmykcv[2]));
384
385 cmykcv[0] -= cmykcv[3];
386 cmykcv[1] -= cmykcv[3];
387 cmykcv[2] -= cmykcv[3];
388
389 return (*dev_proc(dev, map_cmyk_color)) (dev, cmykcv);
390 }
391 static void
pack_from_standard(gx_device_memory * dev,int y,int destx,const byte * src,int width,int depth,int src_depth)392 pack_from_standard(gx_device_memory * dev, int y, int destx, const byte * src,
393 int width, int depth, int src_depth)
394 {
395 byte *dest = scan_line_base(dev, y);
396 dev_proc_map_rgb_color((*map)) =
397 (dev->color_info.num_components == 4 ?
398 map_rgb_to_color_via_cmyk : dev_proc(dev, map_rgb_color));
399 int bit_x = destx * depth;
400 byte *dp = dest + (bit_x >> 3);
401 /* RJW: I'm suspicious of this; see how shift = bit_x & 7 in the planar
402 * 1bit version above? Has anything ever used the <8 bit code here? */
403 int shift = (~bit_x & 7) + 1;
404 byte buf = (shift == 8 ? 0 : *dp & (0xff00 >> shift));
405 const byte *sp = src;
406 int x;
407
408 for (x = width; --x >= 0;) {
409 byte vr, vg, vb;
410 gx_color_index pixel;
411 byte chop = 0x1;
412
413 vr = *sp++;
414 if (src_depth > 8) {
415 vg = *sp++;
416 vb = *sp++;
417 } else
418 vb = vg = vr;
419 /*
420 * We have to map back to some pixel value, even if the color
421 * isn't accurate.
422 */
423 for (;;) {
424 gx_color_value cv[3];
425 cv[0] = gx_color_value_from_byte(vr);
426 cv[1] = gx_color_value_from_byte(vg);
427 cv[2] = gx_color_value_from_byte(vb);
428 pixel = (*map) ((gx_device *)dev, cv);
429 if (pixel != gx_no_color_index)
430 break;
431 /* Reduce the color accuracy and try again. */
432 vr = (vr >= 0x80 ? vr | chop : vr & ~chop);
433 vg = (vg >= 0x80 ? vg | chop : vg & ~chop);
434 vb = (vb >= 0x80 ? vb | chop : vb & ~chop);
435 chop <<= 1;
436 }
437 if ((shift -= depth) >= 0)
438 buf += (byte)(pixel << shift);
439 else {
440 switch (depth) {
441 default: /* 1, 2, 4, 8 */
442 *dp++ = buf;
443 shift += 8;
444 buf = (byte)(pixel << shift);
445 break;
446 case 32:
447 *dp++ = (byte)(pixel >> 24);
448 *dp++ = (byte)(pixel >> 16);
449 case 16:
450 *dp++ = (byte)(pixel >> 8);
451 *dp++ = (byte)pixel;
452 shift = 0;
453 }
454 }
455 }
456 if (width > 0 && depth <= 8)
457 *dp = (shift == 0 ? buf : buf + (*dp & ((1 << shift) - 1)));
458 }
459
460 static void
pack_planar_from_standard(gx_device_memory * dev,int y,int destx,const byte * src,int width,int depth,int src_depth)461 pack_planar_from_standard(gx_device_memory * dev, int y, int destx,
462 const byte * src, int width, int depth, int src_depth)
463 {
464 /* This code assumes that all planar planes have the same depth */
465 dev_proc_map_rgb_color((*map)) =
466 (dev->color_info.num_components == 4 ?
467 map_rgb_to_color_via_cmyk : dev_proc(dev, map_rgb_color));
468 int pdepth = dev->plane_depth;
469 int bit_x = destx * pdepth;
470 byte *dp[GX_DEVICE_COLOR_MAX_COMPONENTS];
471 int shift = (~bit_x & 7) + 1;
472 byte buf[GX_DEVICE_COLOR_MAX_COMPONENTS];
473 const byte *sp = src;
474 int x, plane;
475
476 if (pdepth == 1 && dev->color_info.num_components == 4) {
477 pack_planar_cmyk_1bit_from_standard(dev, y, destx, src, width,
478 depth, src_depth);
479 return;
480 }
481
482 for (plane = 0; plane < dev->num_planes; plane++) {
483 byte *dest = scan_line_base(dev, y + plane * dev->height);
484 dp[plane] = dest + (bit_x >> 3);
485 buf[plane] = (shift == 8 ? 0 : *dp[plane] & (0xff00 >> shift));
486 }
487
488 for (x = width; --x >= 0;) {
489 byte vr, vg, vb;
490 gx_color_index pixel;
491 byte chop = 0x1;
492
493 vr = *sp++;
494 if (src_depth > 8) {
495 vg = *sp++;
496 vb = *sp++;
497 } else
498 vb = vg = vr;
499 /*
500 * We have to map back to some pixel value, even if the color
501 * isn't accurate.
502 */
503 for (;;) {
504 gx_color_value cv[3];
505 cv[0] = gx_color_value_from_byte(vr);
506 cv[1] = gx_color_value_from_byte(vg);
507 cv[2] = gx_color_value_from_byte(vb);
508 pixel = (*map) ((gx_device *)dev, cv);
509 if (pixel != gx_no_color_index)
510 break;
511 /* Reduce the color accuracy and try again. */
512 vr = (vr >= 0x80 ? vr | chop : vr & ~chop);
513 vg = (vg >= 0x80 ? vg | chop : vg & ~chop);
514 vb = (vb >= 0x80 ? vb | chop : vb & ~chop);
515 chop <<= 1;
516 }
517 switch (depth) {
518 case 32:
519 *dp[0]++ = (byte)(pixel >> 24);
520 *dp[1]++ = (byte)(pixel >> 16);
521 *dp[2]++ = (byte)(pixel >> 8);
522 *dp[3]++ = (byte)pixel;
523 shift = 0;
524 break;
525 case 24:
526 *dp[0]++ = (byte)(pixel >> 16);
527 *dp[1]++ = (byte)(pixel >> 8);
528 *dp[2]++ = (byte)pixel;
529 shift = 0;
530 break;
531 case 16:
532 *dp[0]++ = (byte)(pixel >> 8);
533 *dp[1]++ = (byte)pixel;
534 shift = 0;
535 break;
536 default: /* 1, 2, 4, 8 */
537 {
538 int pmask = (1<<pdepth)-1;
539
540 #ifdef ORIGINAL_CODE_KEPT_FOR_REFERENCE
541 /* Original code, kept for reference. I believe this copies
542 * bits in the wrong order (i.e. the 0th component comes from
543 * the lowest bits in pixel, rather than the highest), and
544 * gets them from the wrong place (8 bits apart rather than
545 * pdepth), but as I have no examples that actually tickle
546 * this code, currently, I don't want to throw it away. */
547 int pshift = 8-pdepth;
548 #else
549 /* We have pdepth*num_planes bits in 'pixel'. We need to copy
550 * them (topmost bits first) into the buffer, packing them at
551 * shift position. */
552 int pshift = pdepth*(dev->num_planes-1);
553 #endif
554 /* Can we fit another pdepth bits into our buffer? */
555 shift -= pdepth;
556 if (shift < 0) {
557 /* No, so flush the buffer to the planes. */
558 for (plane = 0; plane < dev->num_planes; plane++)
559 *dp[plane]++ = buf[plane];
560 shift += 8;
561 }
562 /* Copy the next pdepth bits into each planes buffer */
563 #ifdef ORIGINAL_CODE_KEPT_FOR_REFERENCE
564 for (plane = 0; plane < dev->num_planes; pshift+=8,plane++)
565 buf[plane] += (byte)(((pixel>>pshift) & pmask)<<shift);
566 #else
567 for (plane = 0; plane < dev->num_planes; pshift-=pdepth,plane++)
568 buf[plane] += (byte)(((pixel>>pshift) & pmask)<<shift);
569 #endif
570 break;
571 }
572 }
573 }
574 if (width > 0 && depth <= 8) {
575 if (shift == 0)
576 for (plane = 0; plane < dev->num_planes; plane++)
577 *dp[plane] = buf[plane];
578 else {
579 int mask = (1<<shift)-1;
580 for (plane = 0; plane < dev->num_planes; plane++)
581 *dp[plane] = (*dp[plane] & mask) + buf[plane];
582 }
583 }
584 }
585
586 /*
587 * The default implementation for memory devices uses get_bits_rectangle to
588 * read out the pixels and convert them to standard (8-bit gray or 24-bit
589 * RGB) representation, the standard memory device implementation to do the
590 * operation, pack_from_standard to convert them back to the device
591 * representation, and copy_color to write the pixels back.
592 */
593 int
mem_default_strip_copy_rop2(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop,uint planar_height)594 mem_default_strip_copy_rop2(gx_device * dev,
595 const byte * sdata, int sourcex,
596 uint sraster, gx_bitmap_id id,
597 const gx_color_index * scolors,
598 const gx_strip_bitmap * textures,
599 const gx_color_index * tcolors,
600 int x, int y, int width, int height,
601 int phase_x, int phase_y,
602 gs_logical_operation_t lop,
603 uint planar_height)
604 {
605 dlprintf("mem_default_strip_copy_rop2 should never be called!\n");
606 return gs_error_Fatal;
607 }
608
609 int
mem_default_strip_copy_rop(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)610 mem_default_strip_copy_rop(gx_device * dev,
611 const byte * sdata, int sourcex,
612 uint sraster, gx_bitmap_id id,
613 const gx_color_index * scolors,
614 const gx_strip_bitmap * textures,
615 const gx_color_index * tcolors,
616 int x, int y, int width, int height,
617 int phase_x, int phase_y,
618 gs_logical_operation_t lop)
619 {
620 int depth = dev->color_info.depth;
621 int rop_depth = (gx_device_has_color(dev) ? 24 : 8);
622 void (*pack)(gx_device_memory *, int, int, const byte *, int, int, int);
623 const gx_bitmap_format_t no_expand_options =
624 GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL |
625 GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD |
626 GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD;
627 const gx_bitmap_format_t no_expand_t_options =
628 GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL |
629 GB_RETURN_ALL | GB_ALIGN_STANDARD |
630 GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD |
631 ((textures && textures->num_planes > 1) ? GB_PACKING_PLANAR : GB_PACKING_CHUNKY);
632 const gx_bitmap_format_t expand_options =
633 (rop_depth > 8 ? GB_COLORS_RGB : GB_COLORS_GRAY) |
634 GB_ALPHA_NONE | GB_DEPTH_8 |
635 GB_PACKING_CHUNKY | GB_RETURN_COPY | GB_ALIGN_STANDARD |
636 GB_OFFSET_0 | GB_RASTER_STANDARD;
637 gs_memory_t *mem = dev->memory;
638 const gx_device_memory *mdproto = gdev_mem_device_for_bits(rop_depth);
639 gx_device_memory mdev;
640 union { long l; void *p; } mdev_storage[20];
641 uint row_raster = bitmap_raster(width * depth);
642 ulong size_from_mem_device;
643 gs_rop3_t trans_rop = gs_transparent_rop(lop);
644 bool uses_d = rop3_uses_D(trans_rop);
645 bool uses_s = rop3_uses_S(trans_rop);
646 bool uses_t = rop3_uses_T(trans_rop);
647 bool expand_s, expand_t;
648 byte *row = 0;
649 union { long l; void *p; } dest_buffer[16];
650 byte *source_row = 0;
651 uint source_row_raster;
652 union { long l; void *p; } source_buffer[16];
653 byte *texture_row = 0;
654 uint texture_row_raster;
655 union { long l; void *p; } texture_buffer[16];
656 gx_color_index source_colors[2];
657 const gx_color_index *real_scolors = scolors;
658 gx_color_index texture_colors[2];
659 const gx_color_index *real_tcolors = tcolors;
660 gx_strip_bitmap rop_texture;
661 const gx_strip_bitmap *real_texture = textures;
662 gs_int_rect rect;
663 gs_get_bits_params_t bit_params;
664 gs_get_bits_params_t expand_params;
665 gs_get_bits_params_t no_expand_params;
666 gs_get_bits_params_t no_expand_t_params;
667 int max_height;
668 int block_height, loop_height;
669 int code;
670 int py;
671 gx_device_memory *tdev = (gx_device_memory *)dev;
672
673 /*
674 * Allocate a temporary row buffer. Free variables: mem, block_height.
675 * Labels used: out.
676 */
677 #define ALLOC_BUF(buf, prebuf, size, cname)\
678 BEGIN\
679 uint num_bytes = (size) * block_height;\
680 \
681 if (num_bytes <= sizeof(prebuf))\
682 buf = (byte *)prebuf;\
683 else {\
684 buf = gs_alloc_bytes(mem, num_bytes, cname);\
685 if (buf == 0) {\
686 code = gs_note_error(gs_error_VMerror);\
687 goto out;\
688 }\
689 }\
690 END
691
692 /* We know the device is a memory device, so we can store the
693 * result directly into its scan lines, unless it is planar. */
694 if (tdev->num_planes <= 1) {
695 if ((rop_depth == 24) && (dev_proc(dev, dev_spec_op)(dev,
696 gxdso_is_std_cmyk_1bit, NULL, 0) > 0)) {
697 pack = pack_cmyk_1bit_from_standard;
698 } else {
699 pack = pack_from_standard;
700 }
701 } else {
702 pack = pack_planar_from_standard;
703 }
704 #ifdef DEBUG
705 if (gs_debug_c('b'))
706 trace_copy_rop("mem_default_strip_copy_rop",
707 dev, sdata, sourcex, sraster,
708 id, scolors, textures, tcolors,
709 x, y, width, height, phase_x, phase_y, lop);
710 #endif
711 if (mdproto == 0)
712 return_error(gs_error_rangecheck);
713 if (sdata == 0) {
714 fit_fill(dev, x, y, width, height);
715 } else {
716 fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
717 }
718 /* Compute max_height conservatively. */
719 max_height = max_rop_bitmap / (width * rop_depth);
720 if (max_height == 0)
721 max_height = 1;
722 block_height = min(height, max_height);
723 expand_s = scolors == 0 && uses_s;
724 expand_t = tcolors == 0 && uses_t;
725 no_expand_params.options = no_expand_options;
726 no_expand_t_params.options = no_expand_t_options;
727 if (expand_t) {
728 /*
729 * We don't want to wrap around more than once in Y when
730 * copying the texture to the intermediate buffer.
731 */
732 if (textures->size.y < block_height)
733 block_height = textures->size.y;
734 }
735 gs_make_mem_device(&mdev, mdproto, mem, -1, NULL);
736 gx_device_retain((gx_device *)&mdev, true); /* prevent freeing */
737 mdev.width = width;
738 mdev.height = block_height;
739 mdev.color_info.num_components = rop_depth >> 3;
740 if (gdev_mem_data_size(&mdev, width, block_height, &size_from_mem_device) >= 0 &&
741 size_from_mem_device <= sizeof(mdev_storage)) {
742 /* Use the locally allocated storage. */
743 mdev.base = (byte *)mdev_storage;
744 if ((code = gdev_mem_bits_size(&mdev, mdev.width, mdev.height, &size_from_mem_device)) < 0)
745 return code;
746 mdev.line_ptrs = (byte **) (mdev.base + size_from_mem_device);
747 } else {
748 mdev.bitmap_memory = mem;
749 }
750 code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev);
751 if (code < 0)
752 return code;
753 ALLOC_BUF(row, dest_buffer, row_raster, "copy_rop row");
754 /* We may need intermediate buffers for all 3 operands. */
755 if (expand_s) {
756 source_row_raster = bitmap_raster(width * rop_depth);
757 ALLOC_BUF(source_row, source_buffer, source_row_raster,
758 "copy_rop source_row");
759 }
760 if (scolors && uses_s) {
761 unpack_colors_to_standard(dev, source_colors, scolors, rop_depth);
762 real_scolors = source_colors;
763 }
764 if (expand_t) {
765 texture_row_raster = bitmap_raster(textures->rep_width * rop_depth);
766 ALLOC_BUF(texture_row, texture_buffer, texture_row_raster,
767 "copy_rop texture_row");
768 rop_texture = *textures;
769 rop_texture.data = texture_row;
770 rop_texture.raster = texture_row_raster;
771 rop_texture.size.x = rop_texture.rep_width;
772 rop_texture.id = gs_no_bitmap_id;
773 real_texture = &rop_texture;
774 if (rop_texture.size.y > rop_texture.rep_height)
775 rop_texture.size.y = rop_texture.rep_height; /* we only allocated one row_raster, no reps */
776 }
777 if (tcolors && uses_t) {
778 unpack_colors_to_standard(dev, texture_colors, tcolors, rop_depth);
779 real_tcolors = texture_colors;
780 }
781 expand_params.options = expand_options;
782 expand_params.x_offset = 0;
783 rect.p.x = x;
784 rect.q.x = x + width;
785 for (py = y; py < y + height; py += loop_height) {
786 int sx = sourcex;
787 const byte *source_data = sdata + (py - y) * sraster;
788 uint source_raster = sraster;
789
790 if (block_height > y + height - py)
791 block_height = y + height - py;
792 rect.p.y = py;
793 if (expand_t) {
794 int rep_y = (phase_y + py) % rop_texture.rep_height;
795
796 loop_height = min(block_height, rop_texture.size.y - rep_y);
797 rect.q.y = py + loop_height;
798 expand_params.data[0] = texture_row;
799 gx_get_bits_copy(dev, 0, textures->rep_width, loop_height,
800 &expand_params, &no_expand_t_params,
801 textures->data + rep_y * textures->raster,
802 textures->raster);
803 /*
804 * Compensate for the addition of rep_y * raster
805 * in the subsidiary strip_copy_rop call.
806 */
807 rop_texture.data = texture_row - rep_y * rop_texture.raster;
808 } else {
809 loop_height = block_height;
810 rect.q.y = py + block_height;
811 }
812 if (uses_d) {
813 bit_params.options = expand_options;
814 bit_params.data[0] = scan_line_base(&mdev, 0);
815 bit_params.x_offset = 0;
816 bit_params.raster = mdev.raster;
817 code = (*dev_proc(dev, get_bits_rectangle))
818 (dev, &rect, &bit_params, NULL);
819 if (code < 0)
820 break;
821 }
822 /* Convert the source and texture to standard format. */
823 if (expand_s) {
824 expand_params.data[0] = source_row;
825 gx_get_bits_copy(dev, sx, width, loop_height, &expand_params,
826 &no_expand_params, source_data, sraster);
827 sx = 0;
828 source_data = source_row;
829 source_raster = source_row_raster;
830 }
831 code = (*dev_proc(&mdev, strip_copy_rop))
832 ((gx_device *)&mdev, source_data, sx, source_raster,
833 gx_no_bitmap_id, real_scolors, real_texture, real_tcolors,
834 0, 0, width, loop_height, phase_x + x, phase_y + py, lop);
835 if (code < 0)
836 break;
837 /* Convert the result back to the device's format. */
838 {
839 int i;
840 const byte *unpacked = scan_line_base(&mdev, 0);
841
842 for (i = 0; i < loop_height; unpacked += mdev.raster, ++i) {
843 pack(tdev, py + i, x, unpacked, width, depth, rop_depth);
844 }
845 }
846 }
847 out:
848 if (texture_row != 0 && texture_row != (byte *)texture_buffer)
849 gs_free_object(mem, texture_row, "copy_rop texture_row");
850 if (source_row != 0 && source_row != (byte *)source_buffer)
851 gs_free_object(mem, source_row, "copy_rop source_row");
852 if (row != 0 && row != (byte *)dest_buffer)
853 gs_free_object(mem, row, "copy_rop row");
854 (*dev_proc(&mdev, close_device)) ((gx_device *) & mdev);
855 return code;
856 }
857
858 /* ------ Implementation of related functions ------ */
859
860 int
gx_default_copy_rop(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_tile_bitmap * texture,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)861 gx_default_copy_rop(gx_device * dev,
862 const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
863 const gx_color_index * scolors,
864 const gx_tile_bitmap * texture, const gx_color_index * tcolors,
865 int x, int y, int width, int height,
866 int phase_x, int phase_y, gs_logical_operation_t lop)
867 {
868 const gx_strip_bitmap *textures;
869 gx_strip_bitmap tiles;
870
871 if (texture == 0)
872 textures = 0;
873 else {
874 *(gx_tile_bitmap *) & tiles = *texture;
875 tiles.rep_shift = tiles.shift = 0;
876 tiles.num_planes = 1;
877 textures = &tiles;
878 }
879 return (*dev_proc(dev, strip_copy_rop))
880 (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors,
881 x, y, width, height, phase_x, phase_y, lop);
882 }
883
884 int
gx_copy_rop_unaligned(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_tile_bitmap * texture,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)885 gx_copy_rop_unaligned(gx_device * dev,
886 const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
887 const gx_color_index * scolors,
888 const gx_tile_bitmap * texture, const gx_color_index * tcolors,
889 int x, int y, int width, int height,
890 int phase_x, int phase_y, gs_logical_operation_t lop)
891 {
892 const gx_strip_bitmap *textures;
893 gx_strip_bitmap tiles;
894
895 if (texture == 0)
896 textures = 0;
897 else {
898 *(gx_tile_bitmap *) & tiles = *texture;
899 tiles.rep_shift = tiles.shift = 0;
900 tiles.num_planes = 1;
901 textures = &tiles;
902 }
903 return gx_strip_copy_rop_unaligned
904 (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors,
905 x, y, width, height, phase_x, phase_y, lop);
906 }
907
908 int
gx_strip_copy_rop_unaligned(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)909 gx_strip_copy_rop_unaligned(gx_device * dev,
910 const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
911 const gx_color_index * scolors,
912 const gx_strip_bitmap * textures, const gx_color_index * tcolors,
913 int x, int y, int width, int height,
914 int phase_x, int phase_y, gs_logical_operation_t lop)
915 {
916 dev_proc_strip_copy_rop((*copy_rop)) = dev_proc(dev, strip_copy_rop);
917 int depth = (scolors == 0 ? dev->color_info.depth : 1);
918 int step = sraster & (align_bitmap_mod - 1);
919
920 /* Adjust the origin. */
921 if (sdata != 0) {
922 uint offset =
923 (uint) (sdata - (const byte *)0) & (align_bitmap_mod - 1);
924
925 /* See copy_color above re the following statement. */
926 if (depth == 24)
927 offset += (offset % 3) *
928 (align_bitmap_mod * (3 - (align_bitmap_mod % 3)));
929 sdata -= offset;
930 sourcex += (offset << 3) / depth;
931 }
932 /* Adjust the raster. */
933 if (!step || sdata == 0 ||
934 (scolors != 0 && scolors[0] == scolors[1])
935 ) { /* No adjustment needed. */
936 return (*copy_rop) (dev, sdata, sourcex, sraster, id, scolors,
937 textures, tcolors, x, y, width, height,
938 phase_x, phase_y, lop);
939 }
940 /* Do the transfer one scan line at a time. */
941 {
942 const byte *p = sdata;
943 int d = sourcex;
944 int dstep = (step << 3) / depth;
945 int code = 0;
946 int i;
947
948 for (i = 0; i < height && code >= 0;
949 ++i, p += sraster - step, d += dstep
950 )
951 code = (*copy_rop) (dev, p, d, sraster, gx_no_bitmap_id, scolors,
952 textures, tcolors, x, y + i, width, 1,
953 phase_x, phase_y, lop);
954 return code;
955 }
956 }
957
958 /* ---------------- Internal routines ---------------- */
959
960 /* Compute the effective RasterOp for the 1-bit case, */
961 /* taking transparency into account. */
962 gs_rop3_t
gs_transparent_rop(gs_logical_operation_t lop)963 gs_transparent_rop(gs_logical_operation_t lop)
964 {
965 gs_rop3_t rop = lop_rop(lop);
966
967 /*
968 * The algorithm for computing an effective RasterOp is presented,
969 * albeit obfuscated, in the H-P PCL5 technical documentation.
970 * Define So ("source opaque") and Po ("pattern opaque") as masks
971 * that have 1-bits precisely where the source or pattern
972 * respectively are not white (transparent).
973 * One applies the original RasterOp to compute an intermediate
974 * result R, and then computes the final result as
975 * (R & M) | (D & ~M) where M depends on transparencies as follows:
976 * s_tr p_tr M
977 * 0 0 1
978 * 0 1 ~So | Po (? Po ?)
979 * 1 0 So
980 * 1 1 So & Po
981 * The s_tr = 0, p_tr = 1 case seems wrong, but it's clearly
982 * specified that way in the "PCL 5 Color Technical Reference
983 * Manual."
984 *
985 * In the 1-bit case, So = ~S and Po = ~P, so we can apply the
986 * above table directly.
987 */
988 #define So rop3_not(rop3_S)
989 #define Po rop3_not(rop3_T)
990 #ifdef TRANSPARENCY_PER_H_P
991 /*
992 * Believe it or not, MPo depends on S in this case even if the original
993 * RasterOp didn't depend on S.
994 */
995 # define MPo (rop3_not(So) | Po)
996 #else
997 # define MPo Po
998 #endif
999 /*
1000 * If the operation doesn't use S or T, we must disregard the
1001 * corresponding transparency flag.
1002 */
1003 #define source_transparent ((lop & lop_S_transparent) && rop3_uses_S(rop))
1004 #define pattern_transparent ((lop & lop_T_transparent) && rop3_uses_T(rop))
1005 gs_rop3_t mask =
1006 (source_transparent ?
1007 (pattern_transparent ? So & Po : So) :
1008 (pattern_transparent ? MPo : rop3_1));
1009
1010 #undef MPo
1011 return (rop & mask) | (rop3_D & ~mask);
1012 }
1013