]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/gxiinit.c
Import cups.org releases
[thirdparty/cups.git] / pstoraster / gxiinit.c
1 /* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
2
3 This file is part of GNU Ghostscript.
4
5 GNU Ghostscript is distributed in the hope that it will be useful, but
6 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 to anyone for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing. Refer
9 to the GNU General Public License for full details.
10
11 Everyone is granted permission to copy, modify and redistribute GNU
12 Ghostscript, but only under the conditions described in the GNU General
13 Public License. A copy of this license is supposed to have been given
14 to you along with GNU Ghostscript so you can know your rights and
15 responsibilities. It should be in a file named COPYING. Among other
16 things, the copyright notice and this notice must be preserved on all
17 copies.
18
19 Aladdin Enterprises supports the work of the GNU Project, but is not
20 affiliated with the Free Software Foundation or the GNU Project. GNU
21 Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 GNU software to build or run it.
23 */
24
25 /*$Id$ */
26 /* Image setup procedures for Ghostscript library */
27 #include "gx.h"
28 #include "math_.h"
29 #include "memory_.h"
30 #include "gpcheck.h"
31 #include "gserrors.h"
32 #include "gsstruct.h"
33 #include "gsutil.h"
34 #include "gxfixed.h"
35 #include "gxfrac.h"
36 #include "gxarith.h"
37 #include "gxmatrix.h"
38 #include "gsccolor.h"
39 #include "gspaint.h"
40 #include "gzstate.h"
41 #include "gxdevice.h"
42 #include "gzpath.h"
43 #include "gzcpath.h"
44 #include "gxdevmem.h"
45 #include "gximage.h"
46 #include "gxiparam.h"
47 #include "gdevmrop.h"
48
49 /* ---------------- Generic image support ---------------- */
50
51 /* Initialize the common parts of image structures. */
52 void
53 gs_image_common_t_init(gs_image_common_t * pic)
54 {
55 gs_make_identity(&pic->ImageMatrix);
56 }
57 void
58 gs_data_image_t_init(gs_data_image_t * pim, int num_components)
59 {
60 int i;
61
62 gs_image_common_t_init((gs_image_common_t *) pim);
63 pim->Width = pim->Height = 0;
64 pim->BitsPerComponent = 1;
65 if (num_components >= 0) {
66 for (i = 0; i < num_components * 2; i += 2)
67 pim->Decode[i] = 0, pim->Decode[i + 1] = 1;
68 } else {
69 for (i = 0; i < num_components * -2; i += 2)
70 pim->Decode[i] = 1, pim->Decode[i + 1] = 0;
71 }
72 pim->Interpolate = false;
73 }
74 void
75 gs_pixel_image_t_init(gs_pixel_image_t * pim, const gs_color_space * color_space)
76 {
77 int num_components;
78
79 if (color_space == 0 ||
80 (num_components =
81 gs_color_space_num_components(color_space)) < 0
82 )
83 num_components = 0;
84 gs_data_image_t_init((gs_data_image_t *) pim, num_components);
85 pim->format = gs_image_format_chunky;
86 pim->ColorSpace = color_space;
87 pim->CombineWithColor = false;
88 }
89
90 /* Initialize the common part of an image-processing enumerator. */
91 int
92 gx_image_enum_common_init(gx_image_enum_common_t * piec,
93 const gs_image_common_t * pic, const gx_image_enum_procs_t * piep,
94 gx_device * dev, int bits_per_component, int num_components,
95 gs_image_format_t format)
96 {
97 piec->image_type = pic->type;
98 piec->procs = piep;
99 piec->dev = dev;
100 piec->id = gs_next_ids(1);
101 switch (format) {
102 case gs_image_format_chunky:
103 piec->num_planes = 1;
104 piec->plane_depths[0] = bits_per_component * num_components;
105 break;
106 case gs_image_format_component_planar:
107 piec->num_planes = num_components;
108 {
109 int i;
110
111 for (i = 0; i < num_components; ++i)
112 piec->plane_depths[i] = bits_per_component;
113 }
114 break;
115 case gs_image_format_bit_planar:
116 piec->num_planes = bits_per_component * num_components;
117 {
118 int i;
119
120 for (i = 0; i < piec->num_planes; ++i)
121 piec->plane_depths[i] = 1;
122 }
123 #if 0 /* **************** */
124 break;
125 #endif /* **************** */
126 default:
127 return_error(gs_error_rangecheck);
128 }
129 return 0;
130 }
131
132 /* ---------------- ImageType 1 images ---------------- */
133
134 /* Structure descriptors */
135 private_st_gx_image_enum();
136 public_st_gs_image_common();
137 public_st_gs_data_image();
138 public_st_gs_pixel_image();
139
140 /* Strategy procedures */
141 gx_image_strategies_t image_strategies;
142
143 /* Define the image type for ImageType 1 images. */
144 private const gx_image_type_t image1_type = {
145 gx_begin_image1, gx_data_image_source_size, 1
146 };
147 private const gx_image_enum_procs_t image1_enum_procs = {
148 gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
149 };
150
151 /* Define the procedures for initializing gs_image_ts to default values. */
152 void
153 gs_image_t_init(gs_image_t * pim, const gs_color_space * color_space)
154 {
155 gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
156 pim->type = &image1_type;
157 pim->ImageMask = pim->adjust = (color_space == NULL);
158 pim->Alpha = gs_image_alpha_none;
159 }
160 void
161 gs_image_t_init_mask(gs_image_t * pim, bool write_1s)
162 {
163 gs_image_t_init(pim, NULL);
164 if (write_1s)
165 pim->Decode[0] = 1, pim->Decode[1] = 0;
166 else
167 pim->Decode[0] = 0, pim->Decode[1] = 1;
168 }
169
170 /* Compute the source size of an ordinary image with explicit data. */
171 int
172 gx_data_image_source_size(const gs_imager_state * pis,
173 const gs_image_common_t * pim, gs_int_point * psize)
174 {
175 const gs_data_image_t *pdi = (const gs_data_image_t *)pim;
176
177 psize->x = pdi->Width;
178 psize->y = pdi->Height;
179 return 0;
180 }
181
182 /* Process the next piece of an image with no source data. */
183 /* This procedure should never be called. */
184 int
185 gx_no_image_plane_data(gx_device * dev,
186 gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height)
187 {
188 return_error(gs_error_Fatal);
189 }
190
191 /* Clean up after processing an image with no source data. */
192 /* This procedure may be called, but should do nothing. */
193 int
194 gx_ignore_end_image(gx_device * dev, gx_image_enum_common_t * info,
195 bool draw_last)
196 {
197 return 0;
198 }
199
200 /* GC procedures */
201 #define eptr ((gx_image_enum *)vptr)
202 private
203 ENUM_PTRS_BEGIN(image_enum_enum_ptrs)
204 {
205 int bps;
206 gs_ptr_type_t ret;
207
208 /* Enumerate the used members of clues.dev_color. */
209 index -= gx_image_enum_num_ptrs;
210 bps = eptr->unpack_bps;
211 if (eptr->spp != 1)
212 bps = 8;
213 else if (bps > 8 || eptr->unpack == sample_unpack_copy)
214 bps = 1;
215 if (index >= (1 << bps) * st_device_color_max_ptrs) /* done */
216 return 0;
217 ret = ENUM_USING(st_device_color,
218 &eptr->clues[(index / st_device_color_max_ptrs) *
219 (255 / ((1 << bps) - 1))].dev_color,
220 sizeof(eptr->clues[0].dev_color),
221 index % st_device_color_max_ptrs);
222 if (ret == 0) /* don't stop early */
223 ENUM_RETURN(0);
224 return ret;
225 }
226 #define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
227 gx_image_enum_do_ptrs(e1)
228 #undef e1
229 ENUM_PTRS_END
230 private RELOC_PTRS_BEGIN(image_enum_reloc_ptrs)
231 {
232 int i;
233
234 #define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
235 gx_image_enum_do_ptrs(r1)
236 #undef r1
237 {
238 int bps = eptr->unpack_bps;
239
240 if (eptr->spp != 1)
241 bps = 8;
242 else if (bps > 8 || eptr->unpack == sample_unpack_copy)
243 bps = 1;
244 for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
245 RELOC_USING(st_device_color,
246 &eptr->clues[i].dev_color, sizeof(gx_device_color));
247 }
248 }
249 RELOC_PTRS_END
250 #undef eptr
251
252 /* Forward declarations */
253 private int color_draws_b_w(P2(gx_device * dev,
254 const gx_drawing_color * pdcolor));
255 private void image_init_map(P3(byte * map, int map_size, const float *decode));
256 private void image_init_colors(P9(gx_image_enum * penum, int bps, int spp,
257 bool multi, const float *decode,
258 const gs_imager_state * pis, gx_device * dev,
259 const gs_color_space * pcs, bool * pdcb));
260
261 /* Procedures for unpacking the input data into bytes or fracs. */
262 /*extern sample_unpack_proc(sample_unpack_copy); *//* declared above */
263 extern sample_unpack_proc(sample_unpack_1);
264 extern sample_unpack_proc(sample_unpack_2);
265 extern sample_unpack_proc(sample_unpack_4);
266 extern sample_unpack_proc(sample_unpack_8);
267
268 sample_unpack_proc((*sample_unpack_12_proc)); /* optional */
269
270 /* Start processing an ImageType 1 image. */
271 /* Note that since this is actually a begin_typed_image procedure, */
272 /* the type of pim is the more abstract one. */
273 int
274 gx_begin_image1(gx_device * dev,
275 const gs_imager_state * pis, const gs_matrix * pmat,
276 const gs_image_common_t * pic, const gs_int_rect * prect,
277 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
278 gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
279 {
280 const gs_image_t *pim = (const gs_image_t *)pic;
281 gs_image_format_t format = pim->format;
282 gx_image_enum *penum;
283 const int width = pim->Width;
284 const int height = pim->Height;
285 const int bps = pim->BitsPerComponent;
286 bool masked = pim->ImageMask;
287 const float *decode = pim->Decode;
288 bool multi;
289 int index_bps;
290 const gs_color_space *pcs = pim->ColorSpace;
291 gs_logical_operation_t lop = (pis ? pis->log_op : lop_default);
292 int code;
293 gs_matrix mat;
294 int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
295 int spp, nplanes, spread;
296 uint bsize;
297 byte *buffer;
298 fixed mtx, mty;
299 gs_fixed_point row_extent, col_extent, x_extent, y_extent;
300 bool device_color;
301 gs_fixed_rect obox, cbox;
302 fixed adjust;
303
304 if (width < 0 || height < 0)
305 return_error(gs_error_rangecheck);
306 switch (format) {
307 case gs_image_format_chunky:
308 multi = false;
309 break;
310 case gs_image_format_component_planar:
311 multi = true;
312 break;
313 default:
314 return_error(gs_error_rangecheck);
315 }
316 switch (bps) {
317 case 1:
318 index_bps = 0;
319 break;
320 case 2:
321 index_bps = 1;
322 break;
323 case 4:
324 index_bps = 2;
325 break;
326 case 8:
327 index_bps = 3;
328 break;
329 case 12:
330 index_bps = 4;
331 break;
332 default:
333 return_error(gs_error_rangecheck);
334 }
335 if (prect) {
336 if (prect->p.x < 0 || prect->p.y < 0 ||
337 prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
338 prect->q.x > width || prect->q.y > height
339 )
340 return_error(gs_error_rangecheck);
341 }
342 if (pmat == 0)
343 pmat = &ctm_only(pis);
344 if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
345 (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0 ||
346 (code =
347 gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
348 (floatp) width, (floatp) 0,
349 &row_extent)) < 0 ||
350 (code =
351 gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
352 (floatp) 0, (floatp) height,
353 &col_extent)) < 0
354 )
355 return code;
356 penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
357 "gx_default_begin_image");
358 if (penum == 0)
359 return_error(gs_error_VMerror);
360 gx_image_enum_common_init((gx_image_enum_common_t *) penum, pic,
361 &image1_enum_procs, dev, bps,
362 (masked ? 1 : cs_num_components(pcs)),
363 format);
364 if (prect) {
365 penum->rect.x = prect->p.x, penum->rect.y = prect->p.y;
366 penum->rect.w = prect->q.x - prect->p.x,
367 penum->rect.h = prect->q.y - prect->p.y;
368 if ((code =
369 gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
370 (floatp) penum->rect.w, (floatp) 0,
371 &x_extent)) < 0 ||
372 (code =
373 gs_distance_transform2fixed((const gs_matrix_fixed *)&mat,
374 (floatp) 0, (floatp) penum->rect.h,
375 &y_extent)) < 0
376 ) {
377 gs_free_object(mem, penum, "gx_default_begin_image");
378 return code;
379 }
380 } else {
381 penum->rect.x = 0, penum->rect.y = 0;
382 penum->rect.w = width, penum->rect.h = height;
383 x_extent = row_extent;
384 y_extent = col_extent;
385 }
386 if ((penum->masked = masked)) { /* This is imagemask. */
387 if (bps != 1 || multi || pcs != NULL || pim->Alpha ||
388 !((decode[0] == 0.0 && decode[1] == 1.0) ||
389 (decode[0] == 1.0 && decode[1] == 0.0))
390 ) {
391 gs_free_object(mem, penum, "gx_default_begin_image");
392 return_error(gs_error_rangecheck);
393 }
394 /* Initialize color entries 0 and 255. */
395 color_set_pure(&penum->icolor0, gx_no_color_index);
396 penum->icolor1 = *pdcolor;
397 memcpy(&penum->map[0].table.lookup4x1to32[0],
398 (decode[0] == 0 ? lookup4x1to32_inverted :
399 lookup4x1to32_identity),
400 16 * 4);
401 penum->map[0].decoding = sd_none;
402 spp = 1;
403 adjust = (pim->adjust ? float2fixed(0.25) : fixed_0);
404 lop = rop3_know_S_0(lop);
405 } else { /* This is image, not imagemask. */
406 const gs_color_space_type *pcst = pcs->type;
407 int b_w_color;
408
409 spp = cs_num_components(pcs);
410 if (spp < 0) { /* Pattern not allowed */
411 gs_free_object(mem, penum, "gx_default_begin_image");
412 return_error(gs_error_rangecheck);
413 }
414 if (pim->Alpha)
415 ++spp;
416 if (spp == 1)
417 multi = false;
418 device_color = (*pcst->concrete_space) (pcs, pis) == pcs;
419 image_init_colors(penum, bps, spp, multi, decode, pis, dev,
420 pcs, &device_color);
421 adjust = fixed_0;
422 /* Try to transform non-default RasterOps to something */
423 /* that we implement less expensively. */
424 if (!pim->CombineWithColor)
425 lop = rop3_know_T_0(lop) & ~lop_T_transparent;
426 else {
427 if (rop3_uses_T(lop))
428 switch (color_draws_b_w(dev, pdcolor)) {
429 case 0:
430 lop = rop3_know_T_0(lop);
431 break;
432 case 1:
433 lop = rop3_know_T_1(lop);
434 break;
435 default:
436 ;
437 }
438 }
439 if (lop != rop3_S && /* if best case, no more work needed */
440 !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
441 (b_w_color =
442 color_draws_b_w(dev, &penum->icolor0)) >= 0 &&
443 color_draws_b_w(dev, &penum->icolor1) == (b_w_color ^ 1)
444 ) {
445 if (b_w_color) { /* Swap the colors and invert the RasterOp source. */
446 gx_device_color dcolor;
447
448 dcolor = penum->icolor0;
449 penum->icolor0 = penum->icolor1;
450 penum->icolor1 = dcolor;
451 lop = rop3_invert_S(lop);
452 }
453 /*
454 * At this point, we know that the source pixels
455 * correspond directly to the S input for the raster op,
456 * i.e., icolor0 is black and icolor1 is white.
457 */
458 switch (lop) {
459 case rop3_D & rop3_S:
460 /* Implement this as an inverted mask writing 0s. */
461 penum->icolor1 = penum->icolor0;
462 /* (falls through) */
463 case rop3_D | rop3_not(rop3_S):
464 /* Implement this as an inverted mask writing 1s. */
465 memcpy(&penum->map[0].table.lookup4x1to32[0],
466 lookup4x1to32_inverted, 16 * 4);
467 rmask: /* Fill in the remaining parameters for a mask. */
468 penum->masked = masked = true;
469 color_set_pure(&penum->icolor0, gx_no_color_index);
470 penum->map[0].decoding = sd_none;
471 lop = rop3_T;
472 break;
473 case rop3_D & rop3_not(rop3_S):
474 /* Implement this as a mask writing 0s. */
475 penum->icolor1 = penum->icolor0;
476 /* (falls through) */
477 case rop3_D | rop3_S:
478 /* Implement this as a mask writing 1s. */
479 memcpy(&penum->map[0].table.lookup4x1to32[0],
480 lookup4x1to32_identity, 16 * 4);
481 goto rmask;
482 default:
483 ;
484 }
485 }
486 }
487 penum->device_color = device_color;
488 /*
489 * Adjust width upward for unpacking up to 7 trailing bits in
490 * the row, plus 1 byte for end-of-run, plus up to 7 leading
491 * bits for data_x offset within a packed byte.
492 */
493 bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
494 buffer = gs_alloc_bytes(mem, bsize, "image buffer");
495 if (buffer == 0) {
496 gs_free_object(mem, penum, "gx_default_begin_image");
497 return_error(gs_error_VMerror);
498 }
499 penum->bps = bps;
500 penum->unpack_bps = bps;
501 penum->log2_xbytes = log2_xbytes;
502 penum->spp = spp;
503 penum->alpha = pim->Alpha;
504 nplanes = (multi ? spp : 1);
505 penum->num_planes = nplanes;
506 spread = nplanes << log2_xbytes;
507 penum->spread = spread;
508 penum->matrix = mat;
509 penum->x_extent = x_extent;
510 penum->y_extent = y_extent;
511 penum->posture =
512 ((x_extent.y | y_extent.x) == 0 ? image_portrait :
513 (x_extent.x | y_extent.y) == 0 ? image_landscape :
514 image_skewed);
515 mtx = float2fixed(mat.tx);
516 mty = float2fixed(mat.ty);
517 penum->pis = pis;
518 penum->pcs = pcs;
519 penum->memory = mem;
520 penum->buffer = buffer;
521 penum->buffer_size = bsize;
522 penum->line = 0;
523 penum->line_size = 0;
524 /*
525 * If we're asked to interpolate in a partial image, we have to
526 * assume that the client either really only is interested in
527 * the given sub-image, or else is constructing output out of
528 * overlapping pieces.
529 */
530 penum->interpolate = pim->Interpolate;
531 penum->use_rop = lop != (masked ? rop3_T : rop3_S);
532 #ifdef DEBUG
533 if (gs_debug_c('*')) {
534 if (penum->use_rop)
535 dprintf1("[%03x]", lop);
536 dprintf5("%c%d%c%dx%d ",
537 (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
538 bps,
539 (penum->posture == image_portrait ? ' ' :
540 penum->posture == image_landscape ? 'L' : 'T'),
541 width, height);
542 }
543 #endif
544 penum->slow_loop = 0;
545 if (pcpath == 0) {
546 (*dev_proc(dev, get_clipping_box)) (dev, &obox);
547 cbox = obox;
548 penum->clip_image = 0;
549 } else
550 penum->clip_image =
551 (gx_cpath_outer_box(pcpath, &obox) | /* not || */
552 gx_cpath_inner_box(pcpath, &cbox) ?
553 0 : image_clip_region);
554 penum->clip_outer = obox;
555 penum->clip_inner = cbox;
556 penum->log_op = rop3_T; /* rop device takes care of this */
557 penum->clip_dev = 0; /* in case we bail out */
558 penum->rop_dev = 0; /* ditto */
559 penum->scaler = 0; /* ditto */
560 /*
561 * If all four extrema of the image fall within the clipping
562 * rectangle, clipping is never required. When making this check,
563 * we must carefully take into account the fact that we only care
564 * about pixel centers.
565 */
566 {
567 fixed
568 epx = min(row_extent.x, 0) + min(col_extent.x, 0),
569 eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
570 epy = min(row_extent.y, 0) + min(col_extent.y, 0),
571 eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
572
573 {
574 int hwx, hwy;
575
576 switch (penum->posture) {
577 case image_portrait:
578 hwx = width, hwy = height;
579 break;
580 case image_landscape:
581 hwx = height, hwy = width;
582 break;
583 default:
584 hwx = hwy = 0;
585 }
586 /*
587 * If the image is only 1 sample wide or high,
588 * and is less than 1 device pixel wide or high,
589 * move it slightly so that it covers pixel centers.
590 * This is a hack to work around a bug in some old
591 * versions of TeX/dvips, which use 1-bit-high images
592 * to draw horizontal and vertical lines without
593 * positioning them properly.
594 */
595 if (hwx == 1 && eqx - epx < fixed_1) {
596 fixed diff =
597 arith_rshift_1(row_extent.x + col_extent.x);
598
599 mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
600 }
601 if (hwy == 1 && eqy - epy < fixed_1) {
602 fixed diff =
603 arith_rshift_1(row_extent.y + col_extent.y);
604
605 mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
606 }
607 }
608 if_debug5('b', "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
609 (masked? "masked, " : ""), spp, bps,
610 fixed2float(mtx), fixed2float(mty));
611 if_debug9('b',
612 "[b] cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
613 fixed2float(cbox.p.x), fixed2float(cbox.p.y),
614 fixed2float(cbox.q.x), fixed2float(cbox.q.y),
615 fixed2float(obox.p.x), fixed2float(obox.p.y),
616 fixed2float(obox.q.x), fixed2float(obox.q.y),
617 penum->clip_image);
618 dda_init(penum->dda.row.x, mtx, col_extent.x, height);
619 dda_init(penum->dda.row.y, mty, col_extent.y, height);
620 if (penum->rect.y) {
621 dda_advance(penum->dda.row.x, penum->rect.y);
622 dda_advance(penum->dda.row.y, penum->rect.y);
623 }
624 penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
625 penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
626 dda_init(penum->dda.pixel0.x, penum->cur.x, row_extent.x,
627 width);
628 dda_init(penum->dda.pixel0.y, penum->cur.y, row_extent.y,
629 width);
630 if (penum->rect.x) {
631 dda_advance(penum->dda.pixel0.x, penum->rect.x);
632 dda_advance(penum->dda.pixel0.y, penum->rect.x);
633 } {
634 fixed ox = dda_current(penum->dda.pixel0.x);
635 fixed oy = dda_current(penum->dda.pixel0.y);
636
637 if (!penum->clip_image) /* i.e., not clip region */
638 penum->clip_image =
639 (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
640 image_clip_xmin : 0) +
641 (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
642 image_clip_xmax : 0) +
643 (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
644 image_clip_ymin : 0) +
645 (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
646 image_clip_ymax : 0);
647 }
648 }
649 penum->y = 0;
650 penum->adjust = adjust;
651 {
652 static const sample_unpack_proc_t procs[4] =
653 {
654 sample_unpack_1, sample_unpack_2,
655 sample_unpack_4, sample_unpack_8
656 };
657
658 if (index_bps == 4) {
659 if ((penum->unpack = sample_unpack_12_proc) == 0) { /* 12-bit samples are not supported. */
660 gx_default_end_image(dev,
661 (gx_image_enum_common_t *) penum,
662 false);
663 return_error(gs_error_rangecheck);
664 }
665 } else {
666 penum->unpack = procs[index_bps];
667 if_debug1('b', "[b]unpack=%d\n", bps);
668 }
669 #define use_strategy(sp)\
670 (image_strategies.sp != 0 &&\
671 (penum->render = (*image_strategies.sp)(penum)) != 0)
672 if (
673 use_strategy(interpolate) ||
674 use_strategy(simple) ||
675 use_strategy(fracs) ||
676 use_strategy(mono) ||
677 use_strategy(color)
678 )
679 DO_NOTHING;
680 #undef use_strategy
681 else { /* No available strategy can handle this image. */
682 gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
683 false);
684 return_error(gs_error_rangecheck);
685 }
686 }
687 if (penum->clip_image && pcpath) { /* Set up the clipping device. */
688 gx_device_clip *cdev =
689 gs_alloc_struct(mem, gx_device_clip,
690 &st_device_clip, "image clipper");
691
692 if (cdev == 0) {
693 gx_default_end_image(dev,
694 (gx_image_enum_common_t *) penum,
695 false);
696 return_error(gs_error_VMerror);
697 }
698 gx_make_clip_device(cdev, cdev, gx_cpath_list(pcpath));
699 cdev->target = dev;
700 (*dev_proc(cdev, open_device)) ((gx_device *) cdev);
701 penum->clip_dev = cdev;
702 }
703 if (penum->use_rop) { /* Set up the RasterOp source device. */
704 gx_device_rop_texture *rtdev;
705
706 code = gx_alloc_rop_texture_device(&rtdev, mem,
707 "image RasterOp");
708 if (code < 0) {
709 gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
710 false);
711 return code;
712 }
713 gx_make_rop_texture_device(rtdev,
714 (penum->clip_dev != 0 ?
715 (gx_device *) penum->clip_dev :
716 dev), lop, pdcolor);
717 penum->rop_dev = rtdev;
718 }
719 #ifdef DEBUG
720 if (gs_debug_c('b')) {
721 dlprintf2("[b]Image: w=%d h=%d", width, height);
722 if (prect)
723 dprintf4(" ((%d,%d),(%d,%d))",
724 prect->p.x, prect->p.y, prect->q.x, prect->q.y);
725 dprintf6(" [%g %g %g %g %g %g]\n",
726 mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
727 }
728 #endif
729 *pinfo = (gx_image_enum_common_t *) penum;
730 return 0;
731 }
732
733 /* If a drawing color is black or white, return 0 or 1 respectively, */
734 /* otherwise return -1. */
735 private int
736 color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
737 {
738 if (color_is_pure(pdcolor)) {
739 gx_color_value rgb[3];
740
741 (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
742 rgb);
743 if (!(rgb[0] | rgb[1] | rgb[2]))
744 return 0;
745 if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
746 return 1;
747 }
748 return -1;
749 }
750
751 /* Initialize the color mapping tables for a non-mask image. */
752 private void
753 image_init_colors(gx_image_enum * penum, int bps, int spp, bool multi,
754 const float *decode /*[spp*2] */ , const gs_imager_state * pis, gx_device * dev,
755 const gs_color_space * pcs, bool * pdcb)
756 {
757 int ci;
758 static const float default_decode[] =
759 {
760 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
761 };
762
763 /* Initialize the color table */
764
765 #define ictype(i)\
766 penum->clues[i].dev_color.type
767 switch ((spp == 1 ? bps : 8)) {
768 case 8: /* includes all color images */
769 {
770 register gx_image_clue *pcht = &penum->clues[0];
771 register int n = 64;
772
773 do {
774 pcht[0].dev_color.type =
775 pcht[1].dev_color.type =
776 pcht[2].dev_color.type =
777 pcht[3].dev_color.type =
778 gx_dc_type_none;
779 pcht[0].key = pcht[1].key =
780 pcht[2].key = pcht[3].key = 0;
781 pcht += 4;
782 }
783 while (--n > 0);
784 penum->clues[0].key = 1; /* guarantee no hit */
785 break;
786 }
787 case 4:
788 ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
789 ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
790 ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
791 ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
792 gx_dc_type_none;
793 /* falls through */
794 case 2:
795 ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
796 #undef ictype
797 }
798
799 /* Initialize the maps from samples to intensities. */
800
801 for (ci = 0; ci < spp; ci++) {
802 sample_map *pmap = &penum->map[ci];
803
804 /* If the decoding is [0 1] or [1 0], we can fold it */
805 /* into the expansion of the sample values; */
806 /* otherwise, we have to use the floating point method. */
807
808 const float *this_decode = &decode[ci * 2];
809 const float *map_decode; /* decoding used to */
810
811 /* construct the expansion map */
812
813 const float *real_decode; /* decoding for */
814
815 /* expanded samples */
816
817 bool no_decode;
818
819 map_decode = real_decode = this_decode;
820 if (map_decode[0] == 0.0 && map_decode[1] == 1.0)
821 no_decode = true;
822 else if (map_decode[0] == 1.0 && map_decode[1] == 0.0)
823 no_decode = true,
824 real_decode = default_decode;
825 else
826 no_decode = false,
827 *pdcb = false,
828 map_decode = default_decode;
829 if (bps > 2 || multi) {
830 if (bps <= 8)
831 image_init_map(&pmap->table.lookup8[0], 1 << bps,
832 map_decode);
833 } else { /* The map index encompasses more than one pixel. */
834 byte map[4];
835 register int i;
836
837 image_init_map(&map[0], 1 << bps, map_decode);
838 switch (bps) {
839 case 1:
840 {
841 register bits32 *p = &pmap->table.lookup4x1to32[0];
842
843 if (map[0] == 0 && map[1] == 0xff)
844 memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
845 else if (map[0] == 0xff && map[1] == 0)
846 memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
847 else
848 for (i = 0; i < 16; i++, p++)
849 ((byte *) p)[0] = map[i >> 3],
850 ((byte *) p)[1] = map[(i >> 2) & 1],
851 ((byte *) p)[2] = map[(i >> 1) & 1],
852 ((byte *) p)[3] = map[i & 1];
853 }
854 break;
855 case 2:
856 {
857 register bits16 *p = &pmap->table.lookup2x2to16[0];
858
859 for (i = 0; i < 16; i++, p++)
860 ((byte *) p)[0] = map[i >> 2],
861 ((byte *) p)[1] = map[i & 3];
862 }
863 break;
864 }
865 }
866 pmap->decode_base /* = decode_lookup[0] */ = real_decode[0];
867 pmap->decode_factor =
868 (real_decode[1] - real_decode[0]) /
869 (bps <= 8 ? 255.0 : (float)frac_1);
870 pmap->decode_max /* = decode_lookup[15] */ = real_decode[1];
871 if (no_decode)
872 pmap->decoding = sd_none;
873 else if (bps <= 4) {
874 int step = 15 / ((1 << bps) - 1);
875 int i;
876
877 pmap->decoding = sd_lookup;
878 for (i = 15 - step; i > 0; i -= step)
879 pmap->decode_lookup[i] = pmap->decode_base +
880 i * (255.0 / 15) * pmap->decode_factor;
881 } else
882 pmap->decoding = sd_compute;
883 if (spp == 1) { /* and ci == 0 *//* Pre-map entries 0 and 255. */
884 gs_client_color cc;
885
886 cc.paint.values[0] = real_decode[0];
887 (*pcs->type->remap_color) (&cc, pcs, &penum->icolor0,
888 pis, dev, gs_color_select_source);
889 cc.paint.values[0] = real_decode[1];
890 (*pcs->type->remap_color) (&cc, pcs, &penum->icolor1,
891 pis, dev, gs_color_select_source);
892 }
893 }
894
895 }
896 /* Construct a mapping table for sample values. */
897 /* map_size is 2, 4, 16, or 256. Note that 255 % (map_size - 1) == 0, */
898 /* so the division 0xffffL / (map_size - 1) is always exact. */
899 private void
900 image_init_map(byte * map, int map_size, const float *decode)
901 {
902 float min_v = decode[0];
903 float diff_v = decode[1] - min_v;
904
905 if (diff_v == 1 || diff_v == -1) { /* We can do the stepping with integers, without overflow. */
906 byte *limit = map + map_size;
907 uint value = min_v * 0xffffL;
908 int diff = diff_v * (0xffffL / (map_size - 1));
909
910 for (; map != limit; map++, value += diff)
911 *map = value >> 8;
912 } else { /* Step in floating point, with clamping. */
913 int i;
914
915 for (i = 0; i < map_size; ++i) {
916 int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
917
918 map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
919 }
920 }
921 }