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