1 /* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /*$Id: gxclimag.c,v 1.13 2005/10/10 18:58:18 leonardo Exp $ */
18 /* Higher-level image operations for band lists */
19 #include "math_.h"
20 #include "memory_.h"
21 #include "gx.h"
22 #include "gserrors.h"
23 #include "gscspace.h"
24 #include "gscdefs.h" /* for image type table */
25 #include "gxarith.h"
26 #include "gxcspace.h"
27 #include "gxdevice.h"
28 #include "gxdevmem.h" /* must precede gxcldev.h */
29 #include "gxcldev.h"
30 #include "gxclpath.h"
31 #include "gxfmap.h"
32 #include "gxiparam.h"
33 #include "gxpath.h"
34 #include "stream.h"
35 #include "strimpl.h" /* for sisparam.h */
36 #include "sisparam.h"
37 #include "gxcomp.h"
38 #include "gsserial.h"
39 #include "gxdhtserial.h"
40
41 extern_gx_image_type_table();
42
43 /* Define whether we should use high-level images. */
44 /* (See below for additional restrictions.) */
45 static const bool USE_HL_IMAGES = true;
46
47 /* Forward references */
48 private int cmd_put_set_data_x(gx_device_clist_writer * cldev,
49 gx_clist_state * pcls, int data_x);
50 private bool check_rect_for_trivial_clip(
51 const gx_clip_path *pcpath, /* May be NULL, clip to evaluate */
52 int px, int py, int qx, int qy /* corners of box to test */
53 );
54
55 /* ------ Driver procedures ------ */
56
57 int
clist_fill_mask(gx_device * dev,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int width,int height,const gx_drawing_color * pdcolor,int depth,gs_logical_operation_t lop,const gx_clip_path * pcpath)58 clist_fill_mask(gx_device * dev,
59 const byte * data, int data_x, int raster, gx_bitmap_id id,
60 int x, int y, int width, int height,
61 const gx_drawing_color * pdcolor, int depth,
62 gs_logical_operation_t lop, const gx_clip_path * pcpath)
63 {
64 gx_device_clist_writer * const cdev =
65 &((gx_device_clist *)dev)->writer;
66 const byte *orig_data = data; /* for writing tile */
67 int orig_data_x = data_x; /* ditto */
68 int orig_x = x; /* ditto */
69 int orig_width = width; /* ditto */
70 int orig_height = height; /* ditto */
71 int log2_depth = ilog2(depth);
72 int y0;
73 int data_x_bit;
74 byte copy_op =
75 (depth > 1 ? cmd_op_copy_color_alpha :
76 cmd_op_copy_mono + cmd_copy_ht_color);
77 bool slow_rop =
78 cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor) ||
79 cmd_slow_rop(dev, lop_know_S_1(lop), pdcolor);
80
81 /* If depth > 1, this call will be translated to a copy_alpha call. */
82 /* if the target device can't perform copy_alpha, exit now. */
83 if (depth > 1 && (cdev->disable_mask & clist_disable_copy_alpha) != 0)
84 return_error(gs_error_unknownerror);
85
86 fit_copy(dev, data, data_x, raster, id, x, y, width, height);
87 y0 = y; /* must do after fit_copy */
88
89 /* If non-trivial clipping & complex clipping disabled, default */
90 /* Also default for uncached bitmap or non-defaul lop; */
91 /* We could handle more RasterOp cases here directly, but it */
92 /* doesn't seem worth the trouble right now. */
93 /* Lastly, the command list will translate calls with depth > 1 to */
94 /* copy_alpha calls, so the device color must be pure */
95 if (((cdev->disable_mask & clist_disable_complex_clip) &&
96 !check_rect_for_trivial_clip(pcpath, x, y, x + width, y + height)) ||
97 gs_debug_c('`') || id == gx_no_bitmap_id || lop != lop_default ||
98 (depth > 1 && !color_writes_pure(pdcolor, lop))
99 )
100 copy:
101 return gx_default_fill_mask(dev, data, data_x, raster, id,
102 x, y, width, height, pdcolor, depth,
103 lop, pcpath);
104
105 if (cmd_check_clip_path(cdev, pcpath))
106 cmd_clear_known(cdev, clip_path_known);
107 data_x_bit = data_x << log2_depth;
108 FOR_RECTS {
109 int code;
110 ulong offset_temp;
111
112 TRY_RECT {
113 code = cmd_update_lop(cdev, pcls, lop);
114 } HANDLE_RECT(code);
115 if (depth > 1 && !pcls->color_is_alpha) {
116 byte *dp;
117
118 TRY_RECT {
119 code =
120 set_cmd_put_op(dp, cdev, pcls, cmd_opv_set_copy_alpha, 1);
121 } HANDLE_RECT(code);
122 pcls->color_is_alpha = 1;
123 }
124 TRY_RECT {
125 code = cmd_do_write_unknown(cdev, pcls, clip_path_known);
126 if (code >= 0)
127 code = cmd_do_enable_clip(cdev, pcls, pcpath != NULL);
128 } HANDLE_RECT(code);
129 TRY_RECT {
130 code = cmd_put_drawing_color(cdev, pcls, pdcolor);
131 if (depth > 1 && code >= 0)
132 code = cmd_set_color1(cdev, pcls, pdcolor->colors.pure);
133 } HANDLE_RECT(code);
134 pcls->colors_used.slow_rop |= slow_rop;
135
136 /* Put it in the cache if possible. */
137 if (!cls_has_tile_id(cdev, pcls, id, offset_temp)) {
138 gx_strip_bitmap tile;
139
140 tile.data = (byte *) orig_data; /* actually const */
141 tile.raster = raster;
142 tile.size.x = tile.rep_width = orig_width;
143 tile.size.y = tile.rep_height = orig_height;
144 tile.rep_shift = tile.shift = 0;
145 tile.id = id;
146 TRY_RECT {
147 code = clist_change_bits(cdev, pcls, &tile, depth);
148 } HANDLE_RECT_UNLESS(code,
149 (code != gs_error_VMerror || !cdev->error_is_retryable) );
150 if (code < 0) {
151 /* Something went wrong; just copy the bits. */
152 goto copy;
153 }
154 }
155 {
156 gx_cmd_rect rect;
157 int rsize;
158 byte op = copy_op + cmd_copy_use_tile;
159
160 /* Output a command to copy the entire character. */
161 /* It will be truncated properly per band. */
162 rect.x = orig_x, rect.y = y0;
163 rect.width = orig_width, rect.height = yend - y0;
164 rsize = 1 + cmd_sizexy(rect);
165 TRY_RECT {
166 code = (orig_data_x ?
167 cmd_put_set_data_x(cdev, pcls, orig_data_x) : 0);
168 if (code >= 0) {
169 byte *dp;
170
171 code = set_cmd_put_op(dp, cdev, pcls, op, rsize);
172 /*
173 * The following conditional is unnecessary: the two
174 * statements inside it should go outside the
175 * HANDLE_RECT. They are here solely to pacify
176 * stupid compilers that don't understand that dp
177 * will always be set if control gets past the
178 * HANDLE_RECT.
179 */
180 if (code >= 0) {
181 dp++;
182 cmd_putxy(rect, dp);
183 }
184 }
185 } HANDLE_RECT(code);
186 pcls->rect = rect;
187 goto end;
188 }
189 end:
190 ;
191 } END_RECTS;
192 return 0;
193 }
194
195 /* ------ Bitmap image driver procedures ------ */
196
197 /* Define the structure for keeping track of progress through an image. */
198 typedef struct clist_image_enum_s {
199 gx_image_enum_common;
200 /* Arguments of begin_image */
201 gs_memory_t *memory;
202 gs_pixel_image_t image; /* only uses Width, Height, Interpolate */
203 gx_drawing_color dcolor; /* only pure right now */
204 gs_int_rect rect;
205 const gs_imager_state *pis;
206 const gx_clip_path *pcpath;
207 /* Set at creation time */
208 gs_image_format_t format;
209 gs_int_point support; /* extra source pixels for interpolation */
210 int bits_per_plane; /* bits per pixel per plane */
211 gs_matrix matrix; /* image space -> device space */
212 bool uses_color;
213 clist_color_space_t color_space;
214 int ymin, ymax;
215 gx_colors_used_t colors_used;
216 /* begin_image command prepared & ready to output */
217 /****** SIZE COMPUTATION IS WRONG, TIED TO gximage.c, gsmatrix.c ******/
218 byte begin_image_command[3 +
219 /* Width, Height */
220 2 * cmd_sizew_max +
221 /* ImageMatrix */
222 1 + 6 * sizeof(float) +
223 /* Decode */
224 (GS_IMAGE_MAX_COMPONENTS + 3) / 4 +
225 GS_IMAGE_MAX_COMPONENTS * 2 * sizeof(float) +
226 /* MaskColors */
227 GS_IMAGE_MAX_COMPONENTS * cmd_sizew_max +
228 /* rect */
229 4 * cmd_sizew_max];
230 int begin_image_command_length;
231 /* Updated dynamically */
232 int y;
233 bool color_map_is_known;
234 } clist_image_enum;
235 gs_private_st_suffix_add3(st_clist_image_enum, clist_image_enum,
236 "clist_image_enum", clist_image_enum_enum_ptrs,
237 clist_image_enum_reloc_ptrs, st_gx_image_enum_common,
238 pis, pcpath, color_space.space);
239
240 private image_enum_proc_plane_data(clist_image_plane_data);
241 private image_enum_proc_end_image(clist_image_end_image);
242 private const gx_image_enum_procs_t clist_image_enum_procs =
243 {
244 clist_image_plane_data, clist_image_end_image
245 };
246
247 /* Forward declarations */
248 private bool image_band_box(gx_device * dev, const clist_image_enum * pie,
249 int y, int h, gs_int_rect * pbox);
250 private int begin_image_command(byte *buf, uint buf_size,
251 const gs_image_common_t *pic);
252 private int cmd_image_plane_data(gx_device_clist_writer * cldev,
253 gx_clist_state * pcls,
254 const gx_image_plane_t * planes,
255 const gx_image_enum_common_t * pie,
256 uint bytes_per_plane,
257 const uint * offsets, int dx, int h);
258 private uint clist_image_unknowns(gx_device *dev,
259 const clist_image_enum *pie);
260 private int write_image_end_all(gx_device *dev,
261 const clist_image_enum *pie);
262
263 /*
264 * Since currently we are limited to writing a single subrectangle of the
265 * image for each band, images that are rotated by angles other than
266 * multiples of 90 degrees may wind up writing many copies of the data.
267 * Eventually we will fix this by breaking up the image into multiple
268 * subrectangles, but for now, don't use the high-level approach if it would
269 * cause the data to explode because of this.
270 */
271 private bool
image_matrix_ok_to_band(const gs_matrix * pmat)272 image_matrix_ok_to_band(const gs_matrix * pmat)
273 {
274 double t;
275
276 /* Don't band if the matrix is (nearly) singular. */
277 if (fabs(pmat->xx * pmat->yy - pmat->xy * pmat->yx) < 0.001)
278 return false;
279 if (is_xxyy(pmat) || is_xyyx(pmat))
280 return true;
281 t = (fabs(pmat->xx) + fabs(pmat->yy)) /
282 (fabs(pmat->xy) + fabs(pmat->yx));
283 return (t < 0.2 || t > 5);
284 }
285
286 /* Start processing an image. */
287 int
clist_begin_typed_image(gx_device * dev,const gs_imager_state * pis,const gs_matrix * pmat,const gs_image_common_t * pic,const gs_int_rect * prect,const gx_drawing_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * mem,gx_image_enum_common_t ** pinfo)288 clist_begin_typed_image(gx_device * dev,
289 const gs_imager_state * pis, const gs_matrix * pmat,
290 const gs_image_common_t * pic, const gs_int_rect * prect,
291 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
292 gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
293 {
294 const gs_pixel_image_t * const pim = (const gs_pixel_image_t *)pic;
295 gx_device_clist_writer * const cdev =
296 &((gx_device_clist *)dev)->writer;
297 clist_image_enum *pie = 0;
298 int base_index;
299 bool indexed;
300 bool masked = false;
301 bool has_alpha = false;
302 int num_components;
303 int bits_per_pixel;
304 bool uses_color;
305 bool varying_depths = false;
306 gs_matrix mat;
307 gs_rect sbox, dbox;
308 gs_image_format_t format;
309 gx_color_index colors_used = 0;
310 int code;
311
312 /* We can only handle a limited set of image types. */
313 switch ((gs_debug_c('`') ? -1 : pic->type->index)) {
314 case 1:
315 masked = ((const gs_image1_t *)pim)->ImageMask;
316 has_alpha = ((const gs_image1_t *)pim)->Alpha != 0;
317 case 4:
318 if (pmat == 0)
319 break;
320 default:
321 goto use_default;
322 }
323 format = pim->format;
324 /* See above for why we allocate the enumerator as immovable. */
325 pie = gs_alloc_struct_immovable(mem, clist_image_enum,
326 &st_clist_image_enum,
327 "clist_begin_typed_image");
328 if (pie == 0)
329 return_error(gs_error_VMerror);
330 pie->memory = mem;
331 *pinfo = (gx_image_enum_common_t *) pie;
332 /* num_planes and plane_depths[] are set later, */
333 /* by gx_image_enum_common_init. */
334 if (masked) {
335 base_index = gs_color_space_index_DeviceGray; /* arbitrary */
336 indexed = false;
337 num_components = 1;
338 uses_color = true;
339 /* cmd_put_drawing_color handles colors_used */
340 } else {
341 const gs_color_space *pcs = pim->ColorSpace;
342
343 base_index = gs_color_space_get_index(pcs);
344 if (base_index == gs_color_space_index_Indexed) {
345 const gs_color_space *pbcs =
346 gs_color_space_indexed_base_space(pcs);
347
348 indexed = true;
349 base_index = gs_color_space_get_index(pbcs);
350 num_components = 1;
351 } else {
352 indexed = false;
353 num_components = gs_color_space_num_components(pcs);
354 }
355 uses_color = pim->CombineWithColor && rop3_uses_T(pis->log_op);
356 }
357 code = gx_image_enum_common_init((gx_image_enum_common_t *) pie,
358 (const gs_data_image_t *) pim,
359 &clist_image_enum_procs, dev,
360 num_components, format);
361 {
362 int i;
363
364 for (i = 1; i < pie->num_planes; ++i)
365 varying_depths |= pie->plane_depths[i] != pie->plane_depths[0];
366 }
367 if (code < 0 ||
368 !USE_HL_IMAGES || /* Always use the default. */
369 (cdev->disable_mask & clist_disable_hl_image) ||
370 cdev->image_enum_id != gs_no_id || /* Can't handle nested images */
371 /****** CAN'T HANDLE CIE COLOR YET ******/
372 base_index > gs_color_space_index_DeviceCMYK ||
373 /****** CAN'T HANDLE NON-PURE COLORS YET ******/
374 (uses_color && !gx_dc_is_pure(pdcolor)) ||
375 /****** CAN'T HANDLE IMAGES WITH ALPHA YET ******/
376 has_alpha ||
377 /****** CAN'T HANDLE IMAGES WITH IRREGULAR DEPTHS ******/
378 varying_depths ||
379 (code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
380 (code = gs_matrix_multiply(&mat, &ctm_only(pis), &mat)) < 0 ||
381 !(cdev->disable_mask & clist_disable_nonrect_hl_image ?
382 (is_xxyy(&mat) || is_xyyx(&mat)) :
383 image_matrix_ok_to_band(&mat))
384 )
385 goto use_default;
386 {
387 int bytes_per_plane, bytes_per_row;
388
389 bits_per_pixel = pim->BitsPerComponent * num_components;
390 pie->image = *pim;
391 pie->dcolor = *pdcolor;
392 if (prect)
393 pie->rect = *prect;
394 else {
395 pie->rect.p.x = 0, pie->rect.p.y = 0;
396 pie->rect.q.x = pim->Width, pie->rect.q.y = pim->Height;
397 }
398 pie->pis = pis;
399 pie->pcpath = pcpath;
400 pie->format = format;
401 pie->bits_per_plane = bits_per_pixel / pie->num_planes;
402 pie->matrix = mat;
403 pie->uses_color = uses_color;
404 if (masked) {
405 pie->color_space.byte1 = 0; /* arbitrary */
406 pie->color_space.space = 0;
407 pie->color_space.id = gs_no_id;
408 } else {
409 pie->color_space.byte1 = (base_index << 4) |
410 (indexed ? (pim->ColorSpace->params.indexed.use_proc ? 12 : 8) : 0);
411 pie->color_space.id =
412 (pie->color_space.space = pim->ColorSpace)->id;
413 }
414 pie->y = pie->rect.p.y;
415
416 /* Image row has to fit in cmd writer's buffer */
417 bytes_per_plane =
418 (pim->Width * pie->bits_per_plane + 7) >> 3;
419 bytes_per_row = bytes_per_plane * pie->num_planes;
420 bytes_per_row = max(bytes_per_row, 1);
421 if (cmd_largest_size + bytes_per_row > cdev->cend - cdev->cbuf)
422 goto use_default;
423 }
424 if (pim->Interpolate)
425 pie->support.x = pie->support.y = MAX_ISCALE_SUPPORT + 1;
426 else
427 pie->support.x = pie->support.y = 0;
428 sbox.p.x = pie->rect.p.x - pie->support.x;
429 sbox.p.y = pie->rect.p.y - pie->support.y;
430 sbox.q.x = pie->rect.q.x + pie->support.x;
431 sbox.q.y = pie->rect.q.y + pie->support.y;
432 gs_bbox_transform(&sbox, &mat, &dbox);
433
434 if (cdev->disable_mask & clist_disable_complex_clip)
435 if (!check_rect_for_trivial_clip(pcpath,
436 (int)floor(dbox.p.x), (int)floor(dbox.p.y),
437 (int)ceil(dbox.q.x), (int)ceil(dbox.q.y)))
438 goto use_default;
439 /* Create the begin_image command. */
440 if ((pie->begin_image_command_length =
441 begin_image_command(pie->begin_image_command,
442 sizeof(pie->begin_image_command), pic)) < 0)
443 goto use_default;
444 if (!masked) {
445 /*
446 * Calculate (conservatively) the set of colors that this image
447 * might generate. For single-component images with up to 4 bits
448 * per pixel, standard Decode values, and no Interpolate, we
449 * generate all the possible colors now; otherwise, we assume that
450 * any color might be generated. It is possible to do better than
451 * this, but we won't bother unless there's evidence that it's
452 * worthwhile.
453 */
454 gx_color_index all =
455 ((gx_color_index)1 << dev->color_info.depth) - 1;
456
457 if (bits_per_pixel > 4 || pim->Interpolate || num_components > 1)
458 colors_used = all;
459 else {
460 int max_value = (1 << bits_per_pixel) - 1;
461 float dmin = pim->Decode[0], dmax = pim->Decode[1];
462 float dtemp;
463
464 if (dmax < dmin)
465 dtemp = dmax, dmax = dmin, dmin = dtemp;
466 if (dmin != 0 ||
467 dmax != (indexed ? max_value : 1)
468 ) {
469 colors_used = all;
470 } else {
471 /* Enumerate the possible pixel values. */
472 const gs_color_space *pcs = pim->ColorSpace;
473 cs_proc_remap_color((*remap_color)) = pcs->type->remap_color;
474 gs_client_color cc;
475 gx_drawing_color dcolor;
476 int i;
477 double denom = (indexed ? 1 : max_value);
478
479 for (i = 0; i <= max_value; ++i) {
480 cc.paint.values[0] = (double)i / denom;
481 remap_color(&cc, pcs, &dcolor, pis, dev,
482 gs_color_select_source);
483 colors_used |= cmd_drawing_colors_used(cdev, &dcolor);
484 }
485 }
486 }
487 }
488
489 pie->colors_used.or = colors_used;
490 pie->colors_used.slow_rop =
491 cmd_slow_rop(dev, pis->log_op, (uses_color ? pdcolor : NULL));
492 pie->color_map_is_known = false;
493 /*
494 * Calculate a (slightly conservative) Y bounding interval for the image
495 * in device space.
496 */
497 {
498 int y0 = (int)floor(dbox.p.y - 0.51); /* adjust + rounding slop */
499 int y1 = (int)ceil(dbox.q.y + 0.51); /* ditto */
500
501 pie->ymin = max(y0, 0);
502 pie->ymax = min(y1, dev->height);
503 }
504
505 /*
506 * Make sure the CTM, color space, and clipping region (and, for
507 * masked images or images with CombineWithColor, the current color)
508 * are known at the time of the begin_image command.
509 */
510 cmd_clear_known(cdev, clist_image_unknowns(dev, pie) | begin_image_known);
511
512 cdev->image_enum_id = pie->id;
513 return 0;
514
515 /*
516 * We couldn't handle the image. Use the default algorithms, which
517 * break the image up into rectangles or small pixmaps.
518 */
519 use_default:
520 gs_free_object(mem, pie, "clist_begin_typed_image");
521 return gx_default_begin_typed_image(dev, pis, pmat, pic, prect,
522 pdcolor, pcpath, mem, pinfo);
523 }
524
525 /* Process the next piece of an image. */
526 private int
clist_image_plane_data(gx_image_enum_common_t * info,const gx_image_plane_t * planes,int yh,int * rows_used)527 clist_image_plane_data(gx_image_enum_common_t * info,
528 const gx_image_plane_t * planes, int yh,
529 int *rows_used)
530 {
531 gx_device *dev = info->dev;
532 gx_device_clist_writer * const cdev =
533 &((gx_device_clist *)dev)->writer;
534 clist_image_enum *pie = (clist_image_enum *) info;
535 gs_rect sbox, dbox;
536 int y_orig = pie->y;
537 int yh_used = min(yh, pie->rect.q.y - y_orig);
538 int y0, y1;
539 int y, height; /* for BEGIN/END_RECT */
540 int code;
541
542 #ifdef DEBUG
543 if (pie->id != cdev->image_enum_id) {
544 lprintf2("end_image id = %lu != clist image id = %lu!\n",
545 (ulong) pie->id, (ulong) cdev->image_enum_id);
546 *rows_used = 0;
547 return_error(gs_error_Fatal);
548 }
549 #endif
550 /****** CAN'T HANDLE VARYING data_x VALUES YET ******/
551 {
552 int i;
553
554 for (i = 1; i < info->num_planes; ++i)
555 if (planes[i].data_x != planes[0].data_x) {
556 *rows_used = 0;
557 return_error(gs_error_rangecheck);
558 }
559 }
560 sbox.p.x = pie->rect.p.x - pie->support.x;
561 sbox.p.y = (y0 = y_orig) - pie->support.y;
562 sbox.q.x = pie->rect.q.x + pie->support.x;
563 sbox.q.y = (y1 = pie->y += yh_used) + pie->support.y;
564 gs_bbox_transform(&sbox, &pie->matrix, &dbox);
565 /*
566 * In order to keep the band list consistent, we must write out
567 * the image data in precisely those bands whose begin_image
568 * Y range includes the respective image scan lines. Because of
569 * rounding, we must expand the dbox by a little extra, and then
570 * use image_band_box to calculate the precise range for each band.
571 * This is slow, but we don't see any faster way to do it in the
572 * general case.
573 */
574 {
575 int ry0 = (int)floor(dbox.p.y) - 2;
576 int ry1 = (int)ceil(dbox.q.y) + 2;
577 int band_height = cdev->page_band_height;
578
579 /*
580 * Make sure we don't go into any bands beyond the Y range
581 * determined at begin_image time.
582 */
583 if (ry0 < pie->ymin)
584 ry0 = pie->ymin;
585 if (ry1 > pie->ymax)
586 ry1 = pie->ymax;
587 /*
588 * If the image extends off the page in the Y direction,
589 * we may have ry0 > ry1. Check for this here.
590 */
591 if (ry0 >= ry1)
592 goto done;
593 /* Expand the range out to band boundaries. */
594 y = ry0 / band_height * band_height;
595 height = min(ROUND_UP(ry1, band_height), dev->height) - y;
596 }
597
598 FOR_RECTS {
599 /*
600 * Just transmit the subset of the data that intersects this band.
601 * Note that y and height always define a complete band.
602 */
603 gs_int_rect ibox;
604 gs_int_rect entire_box;
605
606 if (!image_band_box(dev, pie, y, height, &ibox))
607 continue;
608 /*
609 * The transmitted subrectangle has to be computed at the time
610 * we write the begin_image command; this in turn controls how
611 * much of each scan line we write out.
612 */
613 {
614 int band_ymax = min(band_end, pie->ymax);
615 int band_ymin = max(band_end - band_height, pie->ymin);
616
617 if (!image_band_box(dev, pie, band_ymin,
618 band_ymax - band_ymin, &entire_box))
619 continue;
620 }
621
622 pcls->colors_used.or |= pie->colors_used.or;
623 pcls->colors_used.slow_rop |= pie->colors_used.slow_rop;
624
625 /* Write out begin_image & its preamble for this band */
626 if (!(pcls->known & begin_image_known)) {
627 gs_logical_operation_t lop = pie->pis->log_op;
628 byte *dp;
629 byte *bp = pie->begin_image_command +
630 pie->begin_image_command_length;
631 uint len;
632 byte image_op = cmd_opv_begin_image;
633
634 /* Make sure the imager state is up to date. */
635 TRY_RECT {
636 code = (pie->color_map_is_known ? 0 :
637 cmd_put_color_mapping(cdev, pie->pis));
638 pie->color_map_is_known = true;
639 if (code >= 0) {
640 uint want_known = ctm_known | clip_path_known |
641 op_bm_tk_known | opacity_alpha_known |
642 shape_alpha_known | alpha_known |
643 (pie->color_space.id == gs_no_id ? 0 :
644 color_space_known);
645
646 code = cmd_do_write_unknown(cdev, pcls, want_known);
647 }
648 if (code >= 0)
649 code = cmd_do_enable_clip(cdev, pcls, pie->pcpath != NULL);
650 if (code >= 0)
651 code = cmd_update_lop(cdev, pcls, lop);
652 } HANDLE_RECT(code);
653 if (pie->uses_color) {
654 TRY_RECT {
655 code = cmd_put_drawing_color(cdev, pcls, &pie->dcolor);
656 } HANDLE_RECT(code);
657 }
658 if (entire_box.p.x != 0 || entire_box.p.y != 0 ||
659 entire_box.q.x != pie->image.Width ||
660 entire_box.q.y != pie->image.Height
661 ) {
662 image_op = cmd_opv_begin_image_rect;
663 cmd_put2w(entire_box.p.x, entire_box.p.y, bp);
664 cmd_put2w(pie->image.Width - entire_box.q.x,
665 pie->image.Height - entire_box.q.y, bp);
666 }
667 len = bp - pie->begin_image_command;
668 TRY_RECT {
669 code =
670 set_cmd_put_op(dp, cdev, pcls, image_op, 1 + len);
671 } HANDLE_RECT(code);
672 memcpy(dp + 1, pie->begin_image_command, len);
673
674 /* Mark band's begin_image as known */
675 pcls->known |= begin_image_known;
676 }
677
678 /*
679 * The data that we write out must use the X values set by
680 * begin_image, which may cover a larger interval than the ones
681 * actually needed for these particular scan lines if the image is
682 * rotated.
683 */
684 {
685 /*
686 * image_band_box ensures that b{x,y}{0,1} fall within
687 * pie->rect.
688 */
689 int bx0 = entire_box.p.x, bx1 = entire_box.q.x;
690 int by0 = ibox.p.y, by1 = ibox.q.y;
691 int bpp = pie->bits_per_plane;
692 int num_planes = pie->num_planes;
693 uint offsets[gs_image_max_planes];
694 int i, iy, ih, xskip, xoff, nrows;
695 uint bytes_per_plane, bytes_per_row, rows_per_cmd;
696
697 if (by0 < y0)
698 by0 = y0;
699 if (by1 > y1)
700 by1 = y1;
701 /*
702 * Make sure we're skipping an integral number of pixels, by
703 * truncating the initial X coordinate to the next lower
704 * value that is an exact multiple of a byte.
705 */
706 xoff = bx0 - pie->rect.p.x;
707 xskip = xoff & -(int)"\001\010\004\010\002\010\004\010"[bpp & 7];
708 for (i = 0; i < num_planes; ++i)
709 offsets[i] =
710 (by0 - y0) * planes[i].raster + ((xskip * bpp) >> 3);
711 bytes_per_plane = ((bx1 - (pie->rect.p.x + xskip)) * bpp + 7) >> 3;
712 bytes_per_row = bytes_per_plane * pie->num_planes;
713 rows_per_cmd =
714 (cbuf_size - cmd_largest_size) / max(bytes_per_row, 1);
715
716 if (rows_per_cmd == 0) {
717 /* The reader will have to buffer a row separately. */
718 rows_per_cmd = 1;
719 }
720 for (iy = by0, ih = by1 - by0; ih > 0; iy += nrows, ih -= nrows) {
721 nrows = min(ih, rows_per_cmd);
722 TRY_RECT {
723 code = cmd_image_plane_data(cdev, pcls, planes, info,
724 bytes_per_plane, offsets,
725 xoff - xskip, nrows);
726 } HANDLE_RECT(code);
727 for (i = 0; i < num_planes; ++i)
728 offsets[i] += planes[i].raster * nrows;
729 }
730 }
731 } END_RECTS_ON_ERROR(
732 BEGIN
733 ++cdev->ignore_lo_mem_warnings;
734 NEST_RECT {
735 code = write_image_end_all(dev, pie);
736 } UNNEST_RECT;
737 --cdev->ignore_lo_mem_warnings;
738 /* Update sub-rect */
739 if (!pie->image.Interpolate)
740 pie->rect.p.y += yh_used; /* interpolate & mem recovery currently incompat */
741 END,
742 (code < 0 ? (band_code = code) : code) >= 0,
743 (cmd_clear_known(cdev,
744 clist_image_unknowns(dev, pie) | begin_image_known),
745 pie->color_map_is_known = false,
746 cdev->image_enum_id = pie->id, true)
747 );
748 done:
749 *rows_used = pie->y - y_orig;
750 return pie->y >= pie->rect.q.y;
751 }
752
753 /* Clean up by releasing the buffers. */
754 private int
clist_image_end_image(gx_image_enum_common_t * info,bool draw_last)755 clist_image_end_image(gx_image_enum_common_t * info, bool draw_last)
756 {
757 gx_device *dev = info->dev;
758 gx_device_clist_writer * const cdev =
759 &((gx_device_clist *)dev)->writer;
760 clist_image_enum *pie = (clist_image_enum *) info;
761 int code;
762
763 #ifdef DEBUG
764 if (pie->id != cdev->image_enum_id) {
765 lprintf2("end_image id = %lu != clist image id = %lu!\n",
766 (ulong) pie->id, (ulong) cdev->image_enum_id);
767 return_error(gs_error_Fatal);
768 }
769 #endif
770 NEST_RECT {
771 do {
772 code = write_image_end_all(dev, pie);
773 } while (code < 0 && cdev->error_is_retryable &&
774 (code = clist_VMerror_recover(cdev, code)) >= 0
775 );
776 /* if couldn't write successsfully, do a hard flush */
777 if (code < 0 && cdev->error_is_retryable) {
778 int retry_code;
779 ++cdev->ignore_lo_mem_warnings;
780 retry_code = write_image_end_all(dev, pie); /* force it out */
781 --cdev->ignore_lo_mem_warnings;
782 if (retry_code >= 0 && cdev->driver_call_nesting == 0)
783 code = clist_VMerror_recover_flush(cdev, code);
784 }
785 } UNNEST_RECT;
786 cdev->image_enum_id = gs_no_id;
787 gs_free_object(pie->memory, pie, "clist_image_end_image");
788 return code;
789 }
790
791 /* Create a compositor device. */
792 int
clist_create_compositor(gx_device * dev,gx_device ** pcdev,const gs_composite_t * pcte,gs_imager_state * pis,gs_memory_t * mem)793 clist_create_compositor(gx_device * dev,
794 gx_device ** pcdev, const gs_composite_t * pcte,
795 gs_imager_state * pis, gs_memory_t * mem)
796 {
797 byte * dp;
798 uint size = 0;
799 int code = pcte->type->procs.write(pcte, 0, &size);
800
801 /* determine the amount of space required */
802 if (code < 0 && code != gs_error_rangecheck)
803 return code;
804 size += 2 + 1; /* 2 bytes for the command code, one for the id */
805
806 /* Create a compositor device for clist writing (if needed) */
807 code = pcte->type->procs.clist_compositor_write_update(pcte, dev,
808 pcdev, pis, mem);
809 if (code < 0)
810 return code;
811
812 if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
813 gx_device_clist_writer * const cldev =
814 &((gx_device_clist *)dev)->writer;
815 int len = cmd_write_ctm_return_length(cldev, &ctm_only(pis));
816
817 code = set_cmd_put_all_op(dp, (gx_device_clist_writer *)dev,
818 cmd_opv_set_ctm, len + 1);
819 if (code < 0)
820 return code;
821 /* fixme: would like to set pcls->known for covered bands. */
822 code = cmd_write_ctm(&ctm_only(pis), dp, len);
823 if (code < 0)
824 return code;
825 }
826
827 /* overprint applies to all bands */
828 /* fixme: optimize: the pdf14 compositor could be applied
829 only to bands covered by the pcte->params.bbox. */
830 code = set_cmd_put_all_op( dp,
831 (gx_device_clist_writer *)dev,
832 cmd_opv_extend,
833 size );
834 if (code < 0)
835 return code;
836
837 /* insert the command and compositor identifier */
838 dp[1] = cmd_opv_ext_create_compositor;
839 dp[2] = pcte->type->comp_id;
840
841 /* serialize the remainder of the compositor */
842 if ((code = pcte->type->procs.write(pcte, dp + 3, &size)) < 0)
843 ((gx_device_clist_writer *)dev)->cnext = dp;
844 return code;
845 }
846
847 /* ------ Utilities ------ */
848
849 /* Add a command to set data_x. */
850 private int
cmd_put_set_data_x(gx_device_clist_writer * cldev,gx_clist_state * pcls,int data_x)851 cmd_put_set_data_x(gx_device_clist_writer * cldev, gx_clist_state * pcls,
852 int data_x)
853 {
854 byte *dp;
855 int code;
856
857 if (data_x > 0x1f) {
858 int dx_msb = data_x >> 5;
859
860 code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc,
861 2 + cmd_size_w(dx_msb));
862 if (code >= 0) {
863 dp[1] = cmd_set_misc_data_x + 0x20 + (data_x & 0x1f);
864 cmd_put_w(dx_msb, dp + 2);
865 }
866 } else {
867 code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc, 2);
868 if (code >= 0)
869 dp[1] = cmd_set_misc_data_x + data_x;
870 }
871 return code;
872 }
873
874 /* Add commands to represent a full (device) halftone. */
875 int
cmd_put_halftone(gx_device_clist_writer * cldev,const gx_device_halftone * pdht)876 cmd_put_halftone(gx_device_clist_writer * cldev, const gx_device_halftone * pdht)
877 {
878 uint ht_size = 0, req_size;
879 byte * dp;
880 byte * dp0 = 0;
881 byte * pht_buff = 0;
882 int code = gx_ht_write(pdht, (gx_device *)cldev, 0, &ht_size);
883
884 /*
885 * Determine the required size, and if necessary allocate a buffer.
886 *
887 * The full serialized representation consists of:
888 * command code (2 bytes)
889 * length of serialized halftone (enc_u_sizew(ht_size)
890 * one or more halfton segments, which consist of:
891 * command code (2 bytes)
892 * segment size (enc_u_sizew(seg_size) (seg_size < cbuf_ht_seg_max_size)
893 * the serialized halftone segment (seg_size)
894 *
895 * Serialized halftones may be larger than the command buffer, so it
896 * is sent in segments. The cmd_opv_extend/cmd_opv_ext_put_halftone
897 * combination indicates that a device halftone is being sent, and
898 * provides the length of the entire halftone. This is followed by
899 * one or more cmd_opv_extend/cmd_opv_ext_ht_seg commands, which
900 * convey the segments of the serialized hafltone. The reader can
901 * identify the final segment by adding segment lengths.
902 *
903 * This complexity is hidden from the serialization code. If the
904 * halftone is larger than a single halftone buffer, we allocate a
905 * buffer to hold the entire representation, and divided into
906 * segments in this routine.
907 */
908 if (code < 0 && code != gs_error_rangecheck)
909 return code;
910 req_size = 2 + enc_u_sizew(ht_size);
911
912 /* output the "put halftone" command */
913 if ((code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, req_size)) < 0)
914 return code;
915 dp[1] = cmd_opv_ext_put_halftone;
916 dp += 2;
917 enc_u_putw(ht_size, dp);
918
919 /* see if a spearate allocated buffer is required */
920 if (ht_size > cbuf_ht_seg_max_size) {
921 pht_buff = gs_alloc_bytes( cldev->bandlist_memory,
922 ht_size,
923 "cmd_put_halftone" );
924 if (pht_buff == 0)
925 return_error(gs_error_VMerror);
926 } else {
927 /* send the only segment command */
928 req_size += ht_size;
929 code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, req_size);
930 if (code < 0)
931 return code;
932 dp0 = dp;
933 dp[1] = cmd_opv_ext_put_ht_seg;
934 dp += 2;
935 enc_u_putw(ht_size, dp);
936 pht_buff = dp;
937 }
938
939 /* serialize the halftone */
940 code = gx_ht_write(pdht, (gx_device *)cldev, pht_buff, &ht_size);
941 if (code < 0) {
942 if (ht_size > cbuf_ht_seg_max_size)
943 gs_free_object( cldev->bandlist_memory,
944 pht_buff,
945 "cmd_put_halftone" );
946 else
947 cldev->cnext = dp0;
948 return code;
949 }
950
951 /*
952 * If the halftone fit into a single command buffer, we are done.
953 * Otherwise, process the individual segments.
954 *
955 * If bandlist memory is exhausted while processing the segments,
956 * we do not make any attempt to recover the partially submitted
957 * halftone. The reader will discard any partially sent hafltone
958 * when it receives the next cmd_opv_extend/
959 * cmd_opv_ext_put_halftone combination.
960 */
961 if (ht_size > cbuf_ht_seg_max_size) {
962 byte * pbuff = pht_buff;
963
964 while (ht_size > 0 && code >= 0) {
965 int seg_size, tmp_size;
966
967 seg_size = ( ht_size > cbuf_ht_seg_max_size ? cbuf_ht_seg_max_size
968 : ht_size );
969 tmp_size = 2 + enc_u_sizew(seg_size) + seg_size;
970 code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, tmp_size);
971 if (code >= 0) {
972 dp[1] = cmd_opv_ext_put_ht_seg;
973 dp += 2;
974 enc_u_putw(seg_size, dp);
975 memcpy(dp, pbuff, seg_size);
976 ht_size -= seg_size;
977 pbuff += seg_size;
978 }
979 }
980 gs_free_object( cldev->bandlist_memory, pht_buff, "cmd_put_halftone");
981 pht_buff = 0;
982 }
983
984 if (code >= 0)
985 cldev->device_halftone_id = pdht->id;
986
987 return code;
988 }
989
990 /* Write out any necessary color mapping data. */
991 int
cmd_put_color_mapping(gx_device_clist_writer * cldev,const gs_imager_state * pis)992 cmd_put_color_mapping(gx_device_clist_writer * cldev,
993 const gs_imager_state * pis)
994 {
995 int code;
996 const gx_device_halftone *pdht = pis->dev_ht;
997
998 /* Put out the halftone. */
999 if (pdht->id != cldev->device_halftone_id) {
1000 code = cmd_put_halftone(cldev, pdht);
1001 if (code < 0)
1002 return code;
1003 cldev->device_halftone_id = pdht->id;
1004 }
1005 /* Put the under color removal and black generation functions */
1006 code = cmd_put_color_map(cldev, cmd_map_black_generation,
1007 0, pis->black_generation,
1008 &cldev->black_generation_id);
1009 if (code < 0)
1010 return code;
1011 code = cmd_put_color_map(cldev, cmd_map_undercolor_removal,
1012 0, pis->undercolor_removal,
1013 &cldev->undercolor_removal_id);
1014 if (code < 0)
1015 return code;
1016 /* Now put out the transfer functions. */
1017 {
1018 uint which = 0;
1019 bool all_same = true;
1020 bool send_default_comp = false;
1021 int i;
1022 gs_id default_comp_id, xfer_ids[4];
1023
1024 /*
1025 * Determine the ids for the transfer functions that we currently
1026 * have in the set_transfer structure. The halftone xfer funcs
1027 * are sent in cmd_put_halftone.
1028 */
1029 #define get_id(pis, color, color_num) \
1030 ((pis->set_transfer.color != NULL && pis->set_transfer.color_num >= 0) \
1031 ? pis->set_transfer.color->id\
1032 : pis->set_transfer.gray->id)
1033
1034 xfer_ids[0] = get_id(pis, red, red_component_num);
1035 xfer_ids[1] = get_id(pis, green, green_component_num);
1036 xfer_ids[2] = get_id(pis, blue, blue_component_num);
1037 xfer_ids[3] = default_comp_id = pis->set_transfer.gray->id;
1038 #undef get_id
1039
1040 for (i = 0; i < countof(cldev->transfer_ids); ++i) {
1041 if (xfer_ids[i] != cldev->transfer_ids[i])
1042 which |= 1 << i;
1043 if (xfer_ids[i] != default_comp_id)
1044 all_same = false;
1045 if (xfer_ids[i] == default_comp_id &&
1046 cldev->transfer_ids[i] != default_comp_id)
1047 send_default_comp = true;
1048 }
1049 /* There are 3 cases for transfer functions: nothing to write, */
1050 /* a single function, and multiple functions. */
1051 if (which == 0)
1052 return 0;
1053 /*
1054 * Send default transfer function if changed or we need it for a
1055 * component
1056 */
1057 if (send_default_comp || cldev->transfer_ids[0] != default_comp_id) {
1058 gs_id dummy = gs_no_id;
1059
1060 code = cmd_put_color_map(cldev, cmd_map_transfer, 0,
1061 pis->set_transfer.gray, &dummy);
1062 if (code < 0)
1063 return code;
1064 /* Sending a default will force all xfers to default */
1065 for (i = 0; i < countof(cldev->transfer_ids); ++i)
1066 cldev->transfer_ids[i] = default_comp_id;
1067 }
1068 /* Send any transfer functions which have changed */
1069 if (cldev->transfer_ids[0] != xfer_ids[0]) {
1070 code = cmd_put_color_map(cldev, cmd_map_transfer_0,
1071 pis->set_transfer.red_component_num,
1072 pis->set_transfer.red, &cldev->transfer_ids[0]);
1073 if (code < 0)
1074 return code;
1075 }
1076 if (cldev->transfer_ids[1] != xfer_ids[1]) {
1077 code = cmd_put_color_map(cldev, cmd_map_transfer_1,
1078 pis->set_transfer.green_component_num,
1079 pis->set_transfer.green, &cldev->transfer_ids[1]);
1080 if (code < 0)
1081 return code;
1082 }
1083 if (cldev->transfer_ids[2] != xfer_ids[2]) {
1084 code = cmd_put_color_map(cldev, cmd_map_transfer_2,
1085 pis->set_transfer.blue_component_num,
1086 pis->set_transfer.blue, &cldev->transfer_ids[2]);
1087 if (code < 0)
1088 return code;
1089 }
1090 }
1091
1092 return 0;
1093 }
1094
1095 /*
1096 * Compute the subrectangle of an image that intersects a band;
1097 * return false if it is empty.
1098 * It is OK for this to be too large; in fact, with the present
1099 * algorithm, it will be quite a bit too large if the transformation isn't
1100 * well-behaved ("well-behaved" meaning either xy = yx = 0 or xx = yy = 0).
1101 */
1102 #define I_FLOOR(x) ((int)floor(x))
1103 #define I_CEIL(x) ((int)ceil(x))
1104 private void
box_merge_point(gs_int_rect * pbox,floatp x,floatp y)1105 box_merge_point(gs_int_rect * pbox, floatp x, floatp y)
1106 {
1107 int t;
1108
1109 if ((t = I_FLOOR(x)) < pbox->p.x)
1110 pbox->p.x = t;
1111 if ((t = I_CEIL(x)) > pbox->q.x)
1112 pbox->q.x = t;
1113 if ((t = I_FLOOR(y)) < pbox->p.y)
1114 pbox->p.y = t;
1115 if ((t = I_CEIL(y)) > pbox->q.y)
1116 pbox->q.y = t;
1117 }
1118 private bool
image_band_box(gx_device * dev,const clist_image_enum * pie,int y,int h,gs_int_rect * pbox)1119 image_band_box(gx_device * dev, const clist_image_enum * pie, int y, int h,
1120 gs_int_rect * pbox)
1121 {
1122 fixed by0 = int2fixed(y);
1123 fixed by1 = int2fixed(y + h);
1124 int
1125 px = pie->rect.p.x, py = pie->rect.p.y,
1126 qx = pie->rect.q.x, qy = pie->rect.q.y;
1127 gs_fixed_rect cbox; /* device clipping box */
1128 gs_rect bbox; /* cbox intersected with band */
1129
1130 /* Intersect the device clipping box and the band. */
1131 (*dev_proc(dev, get_clipping_box)) (dev, &cbox);
1132 /* The fixed_half here is to allow for adjustment. */
1133 bbox.p.x = fixed2float(cbox.p.x - fixed_half);
1134 bbox.q.x = fixed2float(cbox.q.x + fixed_half);
1135 bbox.p.y = fixed2float(max(cbox.p.y, by0) - fixed_half);
1136 bbox.q.y = fixed2float(min(cbox.q.y, by1) + fixed_half);
1137 #ifdef DEBUG
1138 if (gs_debug_c('b')) {
1139 dlprintf6("[b]band box for (%d,%d),(%d,%d), band (%d,%d) =>\n",
1140 px, py, qx, qy, y, y + h);
1141 dlprintf10(" (%g,%g),(%g,%g), matrix=[%g %g %g %g %g %g]\n",
1142 bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y,
1143 pie->matrix.xx, pie->matrix.xy, pie->matrix.yx,
1144 pie->matrix.yy, pie->matrix.tx, pie->matrix.ty);
1145 }
1146 #endif
1147 if (is_xxyy(&pie->matrix) || is_xyyx(&pie->matrix)) {
1148 /*
1149 * The inverse transform of the band is a rectangle aligned with
1150 * the coordinate axes, so we can just intersect it with the
1151 * image subrectangle.
1152 */
1153 gs_rect ibox; /* bbox transformed back to image space */
1154
1155 if (gs_bbox_transform_inverse(&bbox, &pie->matrix, &ibox) < 0)
1156 return false;
1157 pbox->p.x = max(px, I_FLOOR(ibox.p.x));
1158 pbox->q.x = min(qx, I_CEIL(ibox.q.x));
1159 pbox->p.y = max(py, I_FLOOR(ibox.p.y));
1160 pbox->q.y = min(qy, I_CEIL(ibox.q.y));
1161 } else {
1162 /*
1163 * The inverse transform of the band is not aligned with the
1164 * axes, i.e., is a general parallelogram. To compute an exact
1165 * bounding box, we need to find the intersections of this
1166 * parallelogram with the image subrectangle.
1167 *
1168 * There is probably a much more efficient way to do this
1169 * computation, but we don't know what it is.
1170 */
1171 gs_point rect[4];
1172 gs_point corners[5];
1173 int i;
1174
1175 /* Store the corners of the image rectangle. */
1176 rect[0].x = rect[3].x = px;
1177 rect[1].x = rect[2].x = qx;
1178 rect[0].y = rect[1].y = py;
1179 rect[2].y = rect[3].y = qy;
1180 /*
1181 * Compute the corners of the clipped band in image space. If
1182 * the matrix is singular or an overflow occurs, the result will
1183 * be nonsense: in this case, there isn't anything useful we
1184 * can do, so return an empty intersection.
1185 */
1186 if (gs_point_transform_inverse(bbox.p.x, bbox.p.y, &pie->matrix,
1187 &corners[0]) < 0 ||
1188 gs_point_transform_inverse(bbox.q.x, bbox.p.y, &pie->matrix,
1189 &corners[1]) < 0 ||
1190 gs_point_transform_inverse(bbox.q.x, bbox.q.y, &pie->matrix,
1191 &corners[2]) < 0 ||
1192 gs_point_transform_inverse(bbox.p.x, bbox.q.y, &pie->matrix,
1193 &corners[3]) < 0
1194 ) {
1195 if_debug0('b', "[b]can't inverse-transform a band corner!\n");
1196 return false;
1197 }
1198 corners[4] = corners[0];
1199 pbox->p.x = qx, pbox->p.y = qy;
1200 pbox->q.x = px, pbox->q.y = py;
1201 /*
1202 * We iterate over both the image rectangle and the band
1203 * parallelogram in a single loop for convenience, even though
1204 * there is no coupling between the two.
1205 */
1206 for (i = 0; i < 4; ++i) {
1207 gs_point pa, pt;
1208 double dx, dy;
1209
1210 /* Check the image corner for being inside the band. */
1211 pa = rect[i];
1212 gs_point_transform(pa.x, pa.y, &pie->matrix, &pt);
1213 if (pt.x >= bbox.p.x && pt.x <= bbox.q.x &&
1214 pt.y >= bbox.p.y && pt.y <= bbox.q.y
1215 )
1216 box_merge_point(pbox, pa.x, pa.y);
1217 /* Check the band corner for being inside the image. */
1218 pa = corners[i];
1219 if (pa.x >= px && pa.x <= qx && pa.y >= py && pa.y <= qy)
1220 box_merge_point(pbox, pa.x, pa.y);
1221 /* Check for intersections of band edges with image edges. */
1222 dx = corners[i + 1].x - pa.x;
1223 dy = corners[i + 1].y - pa.y;
1224 #define in_range(t, tc, p, q)\
1225 (0 <= t && t <= 1 && (t = tc) >= p && t <= q)
1226 if (dx != 0) {
1227 double t = (px - pa.x) / dx;
1228
1229 if_debug3('b', " (px) t=%g => (%d,%g)\n",
1230 t, px, pa.y + t * dy);
1231 if (in_range(t, pa.y + t * dy, py, qy))
1232 box_merge_point(pbox, (floatp) px, t);
1233 t = (qx - pa.x) / dx;
1234 if_debug3('b', " (qx) t=%g => (%d,%g)\n",
1235 t, qx, pa.y + t * dy);
1236 if (in_range(t, pa.y + t * dy, py, qy))
1237 box_merge_point(pbox, (floatp) qx, t);
1238 }
1239 if (dy != 0) {
1240 double t = (py - pa.y) / dy;
1241
1242 if_debug3('b', " (py) t=%g => (%g,%d)\n",
1243 t, pa.x + t * dx, py);
1244 if (in_range(t, pa.x + t * dx, px, qx))
1245 box_merge_point(pbox, t, (floatp) py);
1246 t = (qy - pa.y) / dy;
1247 if_debug3('b', " (qy) t=%g => (%g,%d)\n",
1248 t, pa.x + t * dx, qy);
1249 if (in_range(t, pa.x + t * dx, px, qx))
1250 box_merge_point(pbox, t, (floatp) qy);
1251 }
1252 #undef in_range
1253 }
1254 }
1255 if_debug4('b', " => (%d,%d),(%d,%d)\n", pbox->p.x, pbox->p.y,
1256 pbox->q.x, pbox->q.y);
1257 /*
1258 * If necessary, add pixels around the edges so we will have
1259 * enough information to do interpolation.
1260 */
1261 if ((pbox->p.x -= pie->support.x) < pie->rect.p.x)
1262 pbox->p.x = pie->rect.p.x;
1263 if ((pbox->p.y -= pie->support.y) < pie->rect.p.y)
1264 pbox->p.y = pie->rect.p.y;
1265 if ((pbox->q.x += pie->support.x) > pie->rect.q.x)
1266 pbox->q.x = pie->rect.q.x;
1267 if ((pbox->q.y += pie->support.y) > pie->rect.q.y)
1268 pbox->q.y = pie->rect.q.y;
1269 return (pbox->p.x < pbox->q.x && pbox->p.y < pbox->q.y);
1270 }
1271
1272 /* Determine which image-related properties are unknown */
1273 private uint /* mask of unknown properties(see pcls->known) */
clist_image_unknowns(gx_device * dev,const clist_image_enum * pie)1274 clist_image_unknowns(gx_device *dev, const clist_image_enum *pie)
1275 {
1276 gx_device_clist_writer * const cdev =
1277 &((gx_device_clist *)dev)->writer;
1278 const gs_imager_state *const pis = pie->pis;
1279 uint unknown = 0;
1280
1281 /*
1282 * Determine if the CTM, color space, and clipping region (and, for
1283 * masked images or images with CombineWithColor, the current color)
1284 * are unknown. Set the device state in anticipation of the values
1285 * becoming known.
1286 */
1287 if (cdev->imager_state.ctm.xx != pis->ctm.xx ||
1288 cdev->imager_state.ctm.xy != pis->ctm.xy ||
1289 cdev->imager_state.ctm.yx != pis->ctm.yx ||
1290 cdev->imager_state.ctm.yy != pis->ctm.yy ||
1291 cdev->imager_state.ctm.tx != pis->ctm.tx ||
1292 cdev->imager_state.ctm.ty != pis->ctm.ty
1293 ) {
1294 unknown |= ctm_known;
1295 cdev->imager_state.ctm = pis->ctm;
1296 }
1297 if (pie->color_space.id == gs_no_id) { /* masked image */
1298 cdev->color_space.space = 0; /* for GC */
1299 } else { /* not masked */
1300 if (cdev->color_space.id == pie->color_space.id) {
1301 /* The color space pointer might not be valid: update it. */
1302 cdev->color_space.space = pie->color_space.space;
1303 } else {
1304 unknown |= color_space_known;
1305 cdev->color_space = pie->color_space;
1306 }
1307 }
1308 if (cmd_check_clip_path(cdev, pie->pcpath))
1309 unknown |= clip_path_known;
1310 /*
1311 * Note: overprint and overprint_mode are implemented via a compositor
1312 * device, which is passed separately through the command list. Hence,
1313 * though both parameters are passed in the state as well, this usually
1314 * has no effect.
1315 */
1316 if (cdev->imager_state.overprint != pis->overprint ||
1317 cdev->imager_state.overprint_mode != pis->overprint_mode ||
1318 cdev->imager_state.blend_mode != pis->blend_mode ||
1319 cdev->imager_state.text_knockout != pis->text_knockout) {
1320 unknown |= op_bm_tk_known;
1321 cdev->imager_state.overprint = pis->overprint;
1322 cdev->imager_state.overprint_mode = pis->overprint_mode;
1323 cdev->imager_state.blend_mode = pis->blend_mode;
1324 cdev->imager_state.text_knockout = pis->text_knockout;
1325 }
1326 if (cdev->imager_state.opacity.alpha != pis->opacity.alpha) {
1327 unknown |= opacity_alpha_known;
1328 cdev->imager_state.opacity.alpha = pis->opacity.alpha;
1329 }
1330 if (cdev->imager_state.shape.alpha != pis->shape.alpha) {
1331 unknown |= shape_alpha_known;
1332 cdev->imager_state.shape.alpha = pis->shape.alpha;
1333 }
1334 if (cdev->imager_state.alpha != pis->alpha) {
1335 unknown |= alpha_known;
1336 cdev->imager_state.alpha = pis->alpha;
1337 }
1338 return unknown;
1339 }
1340
1341 /* Construct the begin_image command. */
1342 private int
begin_image_command(byte * buf,uint buf_size,const gs_image_common_t * pic)1343 begin_image_command(byte *buf, uint buf_size, const gs_image_common_t *pic)
1344 {
1345 int i;
1346 stream s;
1347 const gs_color_space *ignore_pcs;
1348 int code;
1349
1350 for (i = 0; i < gx_image_type_table_count; ++i)
1351 if (gx_image_type_table[i] == pic->type)
1352 break;
1353 if (i >= gx_image_type_table_count)
1354 return_error(gs_error_rangecheck);
1355 s_init(&s, NULL);
1356 swrite_string(&s, buf, buf_size);
1357 sputc(&s, (byte)i);
1358 code = pic->type->sput(pic, &s, &ignore_pcs);
1359 return (code < 0 ? code : stell(&s));
1360 }
1361
1362 /* Write data for a partial image. */
1363 private int
cmd_image_plane_data(gx_device_clist_writer * cldev,gx_clist_state * pcls,const gx_image_plane_t * planes,const gx_image_enum_common_t * pie,uint bytes_per_plane,const uint * offsets,int dx,int h)1364 cmd_image_plane_data(gx_device_clist_writer * cldev, gx_clist_state * pcls,
1365 const gx_image_plane_t * planes,
1366 const gx_image_enum_common_t * pie,
1367 uint bytes_per_plane, const uint * offsets,
1368 int dx, int h)
1369 {
1370 int data_x = planes[0].data_x + dx;
1371 uint nbytes = bytes_per_plane * pie->num_planes * h;
1372 uint len = 1 + cmd_size2w(h, bytes_per_plane) + nbytes;
1373 byte *dp;
1374 uint offset = 0;
1375 int plane, i;
1376 int code;
1377
1378 if (data_x) {
1379 code = cmd_put_set_data_x(cldev, pcls, data_x);
1380 if (code < 0)
1381 return code;
1382 offset = ((data_x & ~7) * cldev->color_info.depth) >> 3;
1383 }
1384 code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_image_data, len);
1385 if (code < 0)
1386 return code;
1387 dp++;
1388 cmd_put2w(h, bytes_per_plane, dp);
1389 for (plane = 0; plane < pie->num_planes; ++plane)
1390 for (i = 0; i < h; ++i) {
1391 memcpy(dp,
1392 planes[plane].data + i * planes[plane].raster +
1393 offsets[plane] + offset,
1394 bytes_per_plane);
1395 dp += bytes_per_plane;
1396 }
1397 return 0;
1398 }
1399
1400 /* Write image_end commands into all bands */
1401 private int /* ret 0 ok, else -ve error status */
write_image_end_all(gx_device * dev,const clist_image_enum * pie)1402 write_image_end_all(gx_device *dev, const clist_image_enum *pie)
1403 {
1404 gx_device_clist_writer * const cdev =
1405 &((gx_device_clist *)dev)->writer;
1406 int code;
1407 int y = pie->ymin;
1408 int height = pie->ymax - y;
1409
1410 /*
1411 * We need to check specially for images lying entirely outside the
1412 * page, since FOR_RECTS doesn't do this.
1413 */
1414 if (height <= 0)
1415 return 0;
1416 FOR_RECTS {
1417 byte *dp;
1418
1419 if (!(pcls->known & begin_image_known))
1420 continue;
1421 TRY_RECT {
1422 if_debug1('L', "[L]image_end for band %d\n", band);
1423 code = set_cmd_put_op(dp, cdev, pcls, cmd_opv_image_data, 2);
1424 } HANDLE_RECT(code);
1425 dp[1] = 0; /* EOD */
1426 pcls->known ^= begin_image_known;
1427 } END_RECTS;
1428 return 0;
1429 }
1430
1431 /*
1432 * Compare a rectangle vs. clip path. Return true if there is no clipping
1433 * path, if the rectangle is unclipped, or if the clipping path is a
1434 * rectangle and intersects the given rectangle.
1435 */
1436 private bool
check_rect_for_trivial_clip(const gx_clip_path * pcpath,int px,int py,int qx,int qy)1437 check_rect_for_trivial_clip(
1438 const gx_clip_path *pcpath, /* May be NULL, clip to evaluate */
1439 int px, int py, int qx, int qy /* corners of box to test */
1440 )
1441 {
1442 gs_fixed_rect obox;
1443 gs_fixed_rect imgbox;
1444
1445 if (!pcpath)
1446 return true;
1447
1448 imgbox.p.x = int2fixed(px);
1449 imgbox.p.y = int2fixed(py);
1450 imgbox.q.x = int2fixed(qx);
1451 imgbox.q.y = int2fixed(qy);
1452 if (gx_cpath_includes_rectangle(pcpath,
1453 imgbox.p.x, imgbox.p.y,
1454 imgbox.q.x, imgbox.q.y))
1455 return true;
1456
1457 return (gx_cpath_outer_box(pcpath, &obox) /* cpath is rectangle */ &&
1458 obox.p.x <= imgbox.q.x && obox.q.x >= imgbox.p.x &&
1459 obox.p.y <= imgbox.q.y && obox.q.y >= imgbox.p.y );
1460 }
1461