1 /* Copyright (C) 2001-2019 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., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Common code for ImageType 1 and 4 initialization */
18 #include "gx.h"
19 #include "math_.h"
20 #include "memory_.h"
21 #include "gpcheck.h"
22 #include "gscdefs.h" /* for image class table */
23 #include "gserrors.h"
24 #include "gsstruct.h"
25 #include "gsutil.h"
26 #include "gxfixed.h"
27 #include "gxfrac.h"
28 #include "gxarith.h"
29 #include "gxmatrix.h"
30 #include "gsccolor.h"
31 #include "gspaint.h"
32 #include "gzstate.h"
33 #include "gxdevice.h"
34 #include "gzpath.h"
35 #include "gzcpath.h"
36 #include "gxdevmem.h"
37 #include "gximage.h"
38 #include "gxiparam.h"
39 #include "gdevmrop.h"
40 #include "gscspace.h"
41 #include "gscindex.h"
42 #include "gsicc_cache.h"
43 #include "gsicc_cms.h"
44 #include "gsicc_manage.h"
45 #include "gxdevsop.h"
46
47 /* Structure descriptors */
48 private_st_gx_image_enum();
49
50 /* Image class procedures */
51 extern_gx_image_class_table();
52
53 /* Enumerator procedures */
54 static const gx_image_enum_procs_t image1_enum_procs = {
55 gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
56 };
57
58 /* GC procedures */
59 gs_private_st_ptrs2(st_color_cache, gx_image_color_cache_t, "gx_image_color_cache",
60 color_cache_enum_ptrs, color_cache_reloc_ptrs,
61 is_transparent, device_contone);
62 static
ENUM_PTRS_WITH(image_enum_enum_ptrs,gx_image_enum * eptr)63 ENUM_PTRS_WITH(image_enum_enum_ptrs, gx_image_enum *eptr)
64 {
65 int bps;
66 gs_ptr_type_t ret;
67
68 /* Enumerate the used members of clues.dev_color. */
69 index -= gx_image_enum_num_ptrs;
70 bps = eptr->unpack_bps;
71 if (eptr->spp != 1)
72 bps = 8;
73 else if (bps > 8 || eptr->unpack == sample_unpack_copy)
74 bps = 1;
75 if (index >= (1 << bps) * st_device_color_max_ptrs) /* done */
76 return 0;
77 /* the clues may have been cleared by gx_image_free_enum, but not freed in that */
78 /* function due to being at a different save level. Only trace if dev_color.type != 0. */
79 if (eptr->spp == 1) {
80 if (eptr->clues != NULL) {
81 if (eptr->clues[(index/st_device_color_max_ptrs) *
82 (255 / ((1 << bps) - 1))].dev_color.type != 0) {
83 ret = ENUM_USING(st_device_color,
84 &eptr->clues[(index / st_device_color_max_ptrs) *
85 (255 / ((1 << bps) - 1))].dev_color,
86 sizeof(eptr->clues[0].dev_color),
87 index % st_device_color_max_ptrs);
88 } else {
89 ret = 0;
90 }
91 } else {
92 ret = 0;
93 }
94 } else {
95 ret = 0;
96 }
97 if (ret == 0) /* don't stop early */
98 ENUM_RETURN(0);
99 return ret;
100 }
101
102 #define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
gx_image_enum_do_ptrs(e1)103 gx_image_enum_do_ptrs(e1)
104 #undef e1
105 ENUM_PTRS_END
106
107 static RELOC_PTRS_WITH(image_enum_reloc_ptrs, gx_image_enum *eptr)
108 {
109 int i;
110
111 #define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
112 gx_image_enum_do_ptrs(r1)
113 #undef r1
114 {
115 int bps = eptr->unpack_bps;
116
117 if (eptr->spp != 1)
118 bps = 8;
119 else if (bps > 8 || eptr->unpack == sample_unpack_copy)
120 bps = 1;
121 if (eptr->spp == 1) {
122 for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
123 RELOC_USING(st_device_color,
124 &eptr->clues[i].dev_color, sizeof(gx_device_color));
125 }
126 }
127 }
128 RELOC_PTRS_END
129
130 /* Forward declarations */
131 static int color_draws_b_w(gx_device * dev,
132 const gx_drawing_color * pdcolor);
133 static int image_init_colors(gx_image_enum * penum, int bps, int spp,
134 gs_image_format_t format,
135 const float *decode,
136 const gs_gstate * pgs, gx_device * dev,
137 const gs_color_space * pcs, bool * pdcb);
138
139 /* Procedures for unpacking the input data into bytes or fracs. */
140 /*extern SAMPLE_UNPACK_PROC(sample_unpack_copy); *//* declared above */
141
142 /*
143 * Do common initialization for processing an ImageType 1 or 4 image.
144 * Allocate the enumerator and fill in the following members:
145 * rect
146 */
147 int
gx_image_enum_alloc(const gs_image_common_t * pic,const gs_int_rect * prect,gs_memory_t * mem,gx_image_enum ** ppenum)148 gx_image_enum_alloc(const gs_image_common_t * pic,
149 const gs_int_rect * prect, gs_memory_t * mem,
150 gx_image_enum **ppenum)
151 {
152 const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
153 int width = pim->Width, height = pim->Height;
154 int bpc = pim->BitsPerComponent;
155 gx_image_enum *penum;
156
157 if (width < 0 || height < 0)
158 return_error(gs_error_rangecheck);
159 switch (pim->format) {
160 case gs_image_format_chunky:
161 case gs_image_format_component_planar:
162 switch (bpc) {
163 case 1: case 2: case 4: case 8: case 12: case 16: break;
164 default: return_error(gs_error_rangecheck);
165 }
166 break;
167 case gs_image_format_bit_planar:
168 if (bpc < 1 || bpc > 8)
169 return_error(gs_error_rangecheck);
170 }
171 if (prect) {
172 if (prect->p.x < 0 || prect->p.y < 0 ||
173 prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
174 prect->q.x > width || prect->q.y > height
175 )
176 return_error(gs_error_rangecheck);
177 }
178 *ppenum = NULL; /* in case alloc fails and caller doesn't check code */
179 penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
180 "gx_default_begin_image");
181 if (penum == 0)
182 return_error(gs_error_VMerror);
183 memset(penum, 0, sizeof(gx_image_enum)); /* in case of failure, no dangling pointers */
184 if (prect) {
185 penum->rect.x = prect->p.x;
186 penum->rect.y = prect->p.y;
187 penum->rect.w = prect->q.x - prect->p.x;
188 penum->rect.h = prect->q.y - prect->p.y;
189 } else {
190 penum->rect.x = 0, penum->rect.y = 0;
191 penum->rect.w = width, penum->rect.h = height;
192 }
193 penum->rrect.x = penum->rect.x;
194 penum->rrect.y = penum->rect.y;
195 penum->rrect.w = penum->rect.w;
196 penum->rrect.h = penum->rect.h;
197 penum->drect.x = penum->rect.x;
198 penum->drect.y = penum->rect.y;
199 penum->drect.w = penum->rect.w;
200 penum->drect.h = penum->rect.h;
201 #ifdef DEBUG
202 if (gs_debug_c('b')) {
203 dmlprintf2(mem, "[b]Image: w=%d h=%d", width, height);
204 if (prect)
205 dmprintf4(mem, " ((%d,%d),(%d,%d))",
206 prect->p.x, prect->p.y, prect->q.x, prect->q.y);
207 }
208 #endif
209 *ppenum = penum;
210 return 0;
211 }
212
213 /* Convert and restrict to a valid range. */
float2fixed_rounded_boxed(double src)214 static inline fixed float2fixed_rounded_boxed(double src) {
215 float v = floor(src*fixed_scale + 0.5);
216
217 if (v <= min_fixed)
218 return min_fixed;
219 else if (v >= max_fixed)
220 return max_fixed;
221 else
222 return (fixed)v;
223 }
224
225 /* Compute the image matrix combining the ImageMatrix with either the pmat or the pgs ctm */
226 int
gx_image_compute_mat(const gs_gstate * pgs,const gs_matrix * pmat,const gs_matrix * ImageMatrix,gs_matrix_double * rmat)227 gx_image_compute_mat(const gs_gstate *pgs, const gs_matrix *pmat, const gs_matrix *ImageMatrix,
228 gs_matrix_double *rmat)
229 {
230 int code = 0;
231
232 if (pmat == 0)
233 pmat = &ctm_only(pgs);
234 if (ImageMatrix->xx == pmat->xx && ImageMatrix->xy == pmat->xy &&
235 ImageMatrix->yx == pmat->yx && ImageMatrix->yy == pmat->yy) {
236 /* Process common special case separately to accept singular matrix. */
237 rmat->xx = rmat->yy = 1.;
238 rmat->xy = rmat->yx = 0.;
239 rmat->tx = pmat->tx - ImageMatrix->tx;
240 rmat->ty = pmat->ty - ImageMatrix->ty;
241 } else {
242 if ((code = gs_matrix_invert_to_double(ImageMatrix, rmat)) < 0 ||
243 (code = gs_matrix_multiply_double(rmat, pmat, rmat)) < 0
244 ) {
245 return code;
246 }
247 }
248 return code;
249 }
250
251 /*
252 * Finish initialization for processing an ImageType 1 or 4 image.
253 * Assumes the following members of *penum are set in addition to those
254 * set by gx_image_enum_alloc:
255 * alpha, use_mask_color, mask_color (if use_mask_color is true),
256 * masked, adjust
257 */
258 int
gx_image_enum_begin(gx_device * dev,const gs_gstate * pgs,const gs_matrix * pmat,const gs_image_common_t * pic,const gx_drawing_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * mem,gx_image_enum * penum)259 gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs,
260 const gs_matrix *pmat, const gs_image_common_t * pic,
261 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
262 gs_memory_t * mem, gx_image_enum *penum)
263 {
264 const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
265 gs_image_format_t format = pim->format;
266 const int width = pim->Width;
267 const int height = pim->Height;
268 const int bps = pim->BitsPerComponent;
269 bool masked = penum->masked;
270 const float *decode = pim->Decode;
271 gs_matrix_double mat;
272 int index_bps;
273 const gs_color_space *pcs = pim->ColorSpace;
274 gs_logical_operation_t lop = (pgs ? pgs->log_op : lop_default);
275 int code;
276 int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
277 int spp, nplanes, spread;
278 uint bsize;
279 byte *buffer = NULL;
280 fixed mtx, mty;
281 gs_fixed_point row_extent, col_extent, x_extent, y_extent;
282 bool device_color = true;
283 gs_fixed_rect obox, cbox;
284 bool gridfitimages = 0;
285 bool in_pattern_accumulator;
286 bool in_smask;
287 int orthogonal;
288 int force_interpolation = 0;
289
290 penum->clues = NULL;
291 penum->icc_setup.has_transfer = false;
292 penum->icc_setup.is_lab = false;
293 penum->icc_setup.must_halftone = false;
294 penum->icc_setup.need_decode = false;
295 penum->Width = width;
296 penum->Height = height;
297
298 if ((code = gx_image_compute_mat(pgs, pmat, &(pim->ImageMatrix), &mat)) < 0) {
299 return code;
300 }
301 lop = lop_sanitize(lop);
302 /* Grid fit: A common construction in postscript/PDF files is for images
303 * to be constructed as a series of 'stacked' 1 pixel high images.
304 * Furthermore, many of these are implemented as an imagemask plotted on
305 * top of thin rectangles. The different fill rules for images and line
306 * art produces problems; line art fills a pixel if any part of it is
307 * touched - images only fill a pixel if the centre of the pixel is
308 * covered. Bug 692666 is such a problem.
309 *
310 * As a workaround for this problem, the code below was introduced. The
311 * concept is that orthogonal images can be 'grid fitted' (or 'stretch')
312 * to entirely cover pixels that they touch. Initially I had this working
313 * for all images regardless of type, but as testing has proceeded, this
314 * showed more and more regressions, so I've cut the cases back in which
315 * this code is used until it now only triggers on imagemasks that are
316 * either 1 pixel high, or wide, and then not if we are rendering a
317 * glyph (such as from a type3 font).
318 */
319
320 /* Ask the device if we are in a pattern accumulator */
321 in_pattern_accumulator = (dev_proc(dev, dev_spec_op)(dev, gxdso_in_pattern_accumulator, NULL, 0));
322 if (in_pattern_accumulator < 0)
323 in_pattern_accumulator = 0;
324
325 /* Figure out if we are orthogonal */
326 if (mat.xy == 0 && mat.yx == 0)
327 orthogonal = 1;
328 else if (mat.xx == 0 && mat.yy == 0)
329 orthogonal = 2;
330 else
331 orthogonal = 0;
332
333 /* If we are in a pattern accumulator, we choose to always grid fit
334 * orthogonal images. We do this by asking the device whether we
335 * should grid fit. This allows us to avoid nasty blank lines around
336 * the edges of cells. Similarly, for smasks.
337 */
338 in_smask = (pim->override_in_smask ||
339 (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0);
340 gridfitimages = (in_smask || in_pattern_accumulator) && orthogonal;
341
342 if (pgs != NULL && pgs->show_gstate != NULL) {
343 /* If we're a graphics state, and we're in a text object, then we
344 * must be in a type3 font. Don't fiddle with it. */
345 } else if (!gridfitimages &&
346 (!penum->masked || penum->image_parent_type != 0)) {
347 /* Other than for images we are specifically looking to grid fit (such as
348 * ones in a pattern device), we only grid fit imagemasks */
349 } else if (gridfitimages && (penum->masked && penum->image_parent_type == 0)) {
350 /* We don't gridfit imagemasks in a pattern accumulator */
351 } else if (pgs != NULL && pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0) {
352 /* If fill adjust is disabled, so is grid fitting */
353 } else if (orthogonal == 1) {
354 if (width == 1 || gridfitimages) {
355 if (mat.xx > 0) {
356 fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx)));
357 double x1 = mat.tx + mat.xx * width;
358 fixed ix1 = int2fixed(fixed2int_ceiling(float2fixed(x1)));
359 mat.tx = (double)fixed2float(ix0);
360 mat.xx = (double)(fixed2float(ix1 - ix0)/width);
361 } else if (mat.xx < 0) {
362 fixed ix0 = int2fixed(fixed2int_ceiling(float2fixed(mat.tx)));
363 double x1 = mat.tx + mat.xx * width;
364 fixed ix1 = int2fixed(fixed2int(float2fixed(x1)));
365 mat.tx = (double)fixed2float(ix0);
366 mat.xx = (double)(fixed2float(ix1 - ix0)/width);
367 }
368 }
369 if (height == 1 || gridfitimages) {
370 if (mat.yy > 0) {
371 fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty)));
372 double y1 = mat.ty + mat.yy * height;
373 fixed iy1 = int2fixed(fixed2int_ceiling(float2fixed(y1)));
374 mat.ty = (double)fixed2float(iy0);
375 mat.yy = (double)(fixed2float(iy1 - iy0)/height);
376 } else if (mat.yy < 0) {
377 fixed iy0 = int2fixed(fixed2int_ceiling(float2fixed(mat.ty)));
378 double y1 = mat.ty + mat.yy * height;
379 fixed iy1 = int2fixed(fixed2int(float2fixed(y1)));
380 mat.ty = (double)fixed2float(iy0);
381 mat.yy = ((double)fixed2float(iy1 - iy0)/height);
382 }
383 }
384 } else if (orthogonal == 2) {
385 if (height == 1 || gridfitimages) {
386 if (mat.yx > 0) {
387 fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx)));
388 double x1 = mat.tx + mat.yx * height;
389 fixed ix1 = int2fixed(fixed2int_ceiling(float2fixed(x1)));
390 mat.tx = (double)fixed2float(ix0);
391 mat.yx = (double)(fixed2float(ix1 - ix0)/height);
392 } else if (mat.yx < 0) {
393 fixed ix0 = int2fixed(fixed2int_ceiling(float2fixed(mat.tx)));
394 double x1 = mat.tx + mat.yx * height;
395 fixed ix1 = int2fixed(fixed2int(float2fixed(x1)));
396 mat.tx = (double)fixed2float(ix0);
397 mat.yx = (double)(fixed2float(ix1 - ix0)/height);
398 }
399 }
400 if (width == 1 || gridfitimages) {
401 if (mat.xy > 0) {
402 fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty)));
403 double y1 = mat.ty + mat.xy * width;
404 fixed iy1 = int2fixed(fixed2int_ceiling(float2fixed(y1)));
405 mat.ty = (double)fixed2float(iy0);
406 mat.xy = (double)(fixed2float(iy1 - iy0)/width);
407 } else if (mat.xy < 0) {
408 fixed iy0 = int2fixed(fixed2int_ceiling(float2fixed(mat.ty)));
409 double y1 = mat.ty + mat.xy * width;
410 fixed iy1 = int2fixed(fixed2int(float2fixed(y1)));
411 mat.ty = (double)fixed2float(iy0);
412 mat.xy = ((double)fixed2float(iy1 - iy0)/width);
413 }
414 }
415 }
416
417 /* When rendering to a pattern accumulator, if we are downscaling
418 * then enable interpolation, as otherwise dropouts can cause
419 * serious problems. */
420 if (in_pattern_accumulator) {
421 double ome = ((double)(fixed_1 - fixed_epsilon)) / (double)fixed_1; /* One Minus Epsilon */
422
423 if (orthogonal == 1) {
424 if ((mat.xx > -ome && mat.xx < ome) || (mat.yy > -ome && mat.yy < ome)) {
425 force_interpolation = true;
426 }
427 } else if (orthogonal == 2) {
428 if ((mat.xy > -ome && mat.xy < ome) || (mat.yx > -ome && mat.yx < ome)) {
429 force_interpolation = true;
430 }
431 }
432 }
433
434 /* Can we restrict the amount of image we need? */
435 while (pcpath) /* So we can break out of it */
436 {
437 gs_rect rect, rect_out;
438 gs_matrix mi;
439 const gs_matrix *m = pgs != NULL ? &ctm_only(pgs) : NULL;
440 gs_fixed_rect obox;
441 gs_int_rect irect;
442 if (m == NULL || (code = gs_matrix_invert(m, &mi)) < 0 ||
443 (code = gs_matrix_multiply(&mi, &pic->ImageMatrix, &mi)) < 0) {
444 /* Give up trying to shrink the render box, but continue processing */
445 break;
446 }
447 gx_cpath_outer_box(pcpath, &obox);
448 rect.p.x = fixed2float(obox.p.x);
449 rect.p.y = fixed2float(obox.p.y);
450 rect.q.x = fixed2float(obox.q.x);
451 rect.q.y = fixed2float(obox.q.y);
452 code = gs_bbox_transform(&rect, &mi, &rect_out);
453 if (code < 0) {
454 /* Give up trying to shrink the render/decode boxes, but continue processing */
455 break;
456 }
457 irect.p.x = (int)(rect_out.p.x-1.0);
458 irect.p.y = (int)(rect_out.p.y-1.0);
459 irect.q.x = (int)(rect_out.q.x+1.0);
460 irect.q.y = (int)(rect_out.q.y+1.0);
461 /* We therefore only need to render within irect. Restrict rrect to this. */
462 if (penum->rrect.x < irect.p.x) {
463 penum->rrect.w -= irect.p.x - penum->rrect.x;
464 if (penum->rrect.w < 0)
465 penum->rrect.w = 0;
466 penum->rrect.x = irect.p.x;
467 }
468 if (penum->rrect.x + penum->rrect.w > irect.q.x) {
469 penum->rrect.w = irect.q.x - penum->rrect.x;
470 if (penum->rrect.w < 0)
471 penum->rrect.w = 0;
472 }
473 if (penum->rrect.y < irect.p.y) {
474 penum->rrect.h -= irect.p.y - penum->rrect.y;
475 if (penum->rrect.h < 0)
476 penum->rrect.h = 0;
477 penum->rrect.y = irect.p.y;
478 }
479 if (penum->rrect.y + penum->rrect.h > irect.q.y) {
480 penum->rrect.h = irect.q.y - penum->rrect.y;
481 if (penum->rrect.h < 0)
482 penum->rrect.h = 0;
483 }
484 /* Need to expand the region to allow for the fact that the mitchell
485 * scaler reads multiple pixels in. */
486 /* If mi.{xx,yy} > 1 then we are downscaling. During downscaling,
487 * the support increases to ensure that we don't lose pixels contributions
488 * entirely. */
489 /* I do not understand the need for the +/- 1 fudge factors,
490 * but they seem to be required. Increasing the decode rectangle can
491 * never be bad at least... RJW */
492 {
493 float support = any_abs(mi.xx);
494 int isupport;
495 if (any_abs(mi.yy) > support)
496 support = any_abs(mi.yy);
497 if (any_abs(mi.xy) > support)
498 support = any_abs(mi.xy);
499 if (any_abs(mi.yx) > support)
500 support = any_abs(mi.yx);
501 isupport = (int)(MAX_ISCALE_SUPPORT * (support+1)) + 1;
502 irect.p.x -= isupport;
503 irect.p.y -= isupport;
504 irect.q.x += isupport;
505 irect.q.y += isupport;
506 }
507 if (penum->drect.x < irect.p.x) {
508 penum->drect.w -= irect.p.x - penum->drect.x;
509 if (penum->drect.w < 0)
510 penum->drect.w = 0;
511 penum->drect.x = irect.p.x;
512 }
513 if (penum->drect.x + penum->drect.w > irect.q.x) {
514 penum->drect.w = irect.q.x - penum->drect.x;
515 if (penum->drect.w < 0)
516 penum->drect.w = 0;
517 }
518 if (penum->drect.y < irect.p.y) {
519 penum->drect.h -= irect.p.y - penum->drect.y;
520 if (penum->drect.h < 0)
521 penum->drect.h = 0;
522 penum->drect.y = irect.p.y;
523 }
524 if (penum->drect.y + penum->drect.h > irect.q.y) {
525 penum->drect.h = irect.q.y - penum->drect.y;
526 if (penum->drect.h < 0)
527 penum->drect.h = 0;
528 }
529 break; /* Out of the while */
530 }
531 /* Check for the intersection being null */
532 if (penum->drect.x + penum->drect.w <= penum->rect.x ||
533 penum->rect.x + penum->rect.w <= penum->drect.x ||
534 penum->drect.y + penum->drect.h <= penum->rect.y ||
535 penum->rect.y + penum->rect.h <= penum->drect.y)
536 {
537 /* Something may have gone wrong with the floating point above.
538 * set the region to something sane. */
539 penum->drect.x = penum->rect.x;
540 penum->drect.y = penum->rect.y;
541 penum->drect.w = 0;
542 penum->drect.h = 0;
543 }
544 if (penum->rrect.x + penum->rrect.w <= penum->drect.x ||
545 penum->drect.x + penum->drect.w <= penum->rrect.x ||
546 penum->rrect.y + penum->rrect.h <= penum->drect.y ||
547 penum->drect.y + penum->drect.h <= penum->rrect.y)
548 {
549 /* Something may have gone wrong with the floating point above.
550 * set the region to something sane. */
551 penum->rrect.x = penum->drect.x;
552 penum->rrect.y = penum->drect.y;
553 penum->rrect.w = 0;
554 penum->rrect.h = 0;
555 }
556
557 /*penum->matrix = mat;*/
558 penum->matrix.xx = mat.xx;
559 penum->matrix.xy = mat.xy;
560 penum->matrix.yx = mat.yx;
561 penum->matrix.yy = mat.yy;
562 penum->matrix.tx = mat.tx;
563 penum->matrix.ty = mat.ty;
564 if_debug6m('b', mem, " [%g %g %g %g %g %g]\n",
565 mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
566 /* following works for 1, 2, 4, 8, 12, 16 */
567 index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
568 /*
569 * Compute extents with distance transformation.
570 */
571 if (mat.tx > 0)
572 mtx = float2fixed(mat.tx);
573 else { /* Use positive values to ensure round down. */
574 int f = (int)-mat.tx + 1;
575
576 mtx = float2fixed(mat.tx + f) - int2fixed(f);
577 }
578 if (mat.ty > 0)
579 mty = float2fixed(mat.ty);
580 else { /* Use positive values to ensure round down. */
581 int f = (int)-mat.ty + 1;
582
583 mty = float2fixed(mat.ty + f) - int2fixed(f);
584 }
585
586 row_extent.x = float2fixed_rounded_boxed(width * mat.xx);
587 row_extent.y =
588 (is_fzero(mat.xy) ? fixed_0 :
589 float2fixed_rounded_boxed(width * mat.xy));
590 col_extent.x =
591 (is_fzero(mat.yx) ? fixed_0 :
592 float2fixed_rounded_boxed(height * mat.yx));
593 col_extent.y = float2fixed_rounded_boxed(height * mat.yy);
594 gx_image_enum_common_init((gx_image_enum_common_t *)penum,
595 (const gs_data_image_t *)pim,
596 &image1_enum_procs, dev,
597 (masked ? 1 : (penum->alpha ? cs_num_components(pcs)+1 : cs_num_components(pcs))),
598 format);
599 if (penum->rect.w == width && penum->rect.h == height) {
600 x_extent = row_extent;
601 y_extent = col_extent;
602 } else {
603 int rw = penum->rect.w, rh = penum->rect.h;
604
605 x_extent.x = float2fixed_rounded_boxed(rw * mat.xx);
606 x_extent.y =
607 (is_fzero(mat.xy) ? fixed_0 :
608 float2fixed_rounded_boxed(rw * mat.xy));
609 y_extent.x =
610 (is_fzero(mat.yx) ? fixed_0 :
611 float2fixed_rounded_boxed(rh * mat.yx));
612 y_extent.y = float2fixed_rounded_boxed(rh * mat.yy);
613 }
614 /* Set icolor0 and icolor1 to point to image clues locations if we have
615 1spp or an imagemask, otherwise image clues is not used and
616 we have these values point to other member variables */
617 if (masked || cs_num_components(pcs) == 1) {
618 /* Go ahead and allocate now if not already done. For a mask
619 we really should only do 2 values. For now, the goal is to
620 eliminate the 256 bytes for the >8bpp image enumerator */
621 penum->clues = (gx_image_clue*) gs_alloc_bytes(mem, sizeof(gx_image_clue)*256,
622 "gx_image_enum_begin");
623 if (penum->clues == NULL) {
624 code = gs_error_VMerror;
625 goto fail;
626 }
627 penum->icolor0 = &(penum->clues[0].dev_color);
628 penum->icolor1 = &(penum->clues[255].dev_color);
629 } else {
630 penum->icolor0 = &(penum->icolor0_val);
631 penum->icolor1 = &(penum->icolor1_val);
632 }
633 if (masked) { /* This is imagemask. */
634 if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
635 code = gs_error_rangecheck;
636 goto fail;
637 }
638 /* Initialize color entries 0 and 255. */
639 set_nonclient_dev_color(penum->icolor0, gx_no_color_index);
640 set_nonclient_dev_color(penum->icolor1, gx_no_color_index);
641 *(penum->icolor1) = *pdcolor;
642 memcpy(&penum->map[0].table.lookup4x1to32[0],
643 (decode[0] < decode[1] ? lookup4x1to32_inverted :
644 lookup4x1to32_identity),
645 16 * 4);
646 penum->map[0].decoding = sd_none;
647 spp = 1;
648 lop = rop3_know_S_0(lop);
649 } else { /* This is image, not imagemask. */
650 const gs_color_space_type *pcst = pcs->type;
651 int b_w_color;
652
653 spp = cs_num_components(pcs);
654 if (spp < 0) { /* Pattern not allowed */
655 code = gs_error_rangecheck;
656 goto fail;
657 }
658 if (penum->alpha)
659 ++spp;
660 /* Use a less expensive format if possible. */
661 switch (format) {
662 case gs_image_format_bit_planar:
663 if (bps > 1)
664 break;
665 format = gs_image_format_component_planar;
666 case gs_image_format_component_planar:
667 if (spp == 1)
668 format = gs_image_format_chunky;
669 default: /* chunky */
670 break;
671 }
672
673 if (pcs->cmm_icc_profile_data != NULL) {
674 device_color = false;
675 } else {
676 device_color = (*pcst->concrete_space) (pcs, pgs) == pcs;
677 }
678
679 code = image_init_colors(penum, bps, spp, format, decode, pgs, dev,
680 pcs, &device_color);
681 if (code < 0) {
682 gs_free_object(mem, penum->clues, "gx_image_enum_begin");
683 gs_free_object(mem, penum, "gx_default_begin_image");
684 return gs_throw(code, "Image colors initialization failed");
685 }
686 /* If we have a CIE based color space and the icc equivalent profile
687 is not yet set, go ahead and handle that now. It may already
688 be done due to the above init_colors which may go through remap. */
689 if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent == NULL) {
690 code = gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(penum->icc_setup.is_lab),
691 pgs->memory);
692 if (code < 0)
693 goto fail;
694 if (penum->icc_setup.is_lab) {
695 /* Free what ever profile was created and use the icc manager's
696 cielab profile */
697 gs_color_space *curr_pcs = (gs_color_space *)pcs;
698 rc_decrement(curr_pcs->icc_equivalent,"gx_image_enum_begin");
699 gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, -1,"gx_image_enum_begin");
700 curr_pcs->cmm_icc_profile_data = pgs->icc_manager->lab_profile;
701 gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, 1,"gx_image_enum_begin");
702 }
703 }
704 /* Try to transform non-default RasterOps to something */
705 /* that we implement less expensively. */
706 if (!pim->CombineWithColor)
707 lop = rop3_know_T_0(lop);
708 else if ((rop3_uses_T(lop) && color_draws_b_w(dev, pdcolor) == 0))
709 lop = rop3_know_T_0(lop);
710
711 if (lop != rop3_S && /* if best case, no more work needed */
712 !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
713 (b_w_color =
714 color_draws_b_w(dev, penum->icolor0)) >= 0 &&
715 color_draws_b_w(dev, penum->icolor1) == (b_w_color ^ 1)
716 ) {
717 if (b_w_color) { /* Swap the colors and invert the RasterOp source. */
718 gx_device_color dcolor;
719
720 dcolor = *(penum->icolor0);
721 *(penum->icolor0) = *(penum->icolor1);
722 *(penum->icolor1) = dcolor;
723 lop = rop3_invert_S(lop);
724 }
725 /*
726 * At this point, we know that the source pixels
727 * correspond directly to the S input for the raster op,
728 * i.e., icolor0 is black and icolor1 is white.
729 */
730 switch (lop) {
731 case rop3_D & rop3_S:
732 /* Implement this as an inverted mask writing 0s. */
733 *(penum->icolor1) = *(penum->icolor0);
734 /* (falls through) */
735 case rop3_D | rop3_not(rop3_S):
736 /* Implement this as an inverted mask writing 1s. */
737 memcpy(&penum->map[0].table.lookup4x1to32[0],
738 lookup4x1to32_inverted, 16 * 4);
739 rmask: /* Fill in the remaining parameters for a mask. */
740 penum->masked = masked = true;
741 set_nonclient_dev_color(penum->icolor0, gx_no_color_index);
742 penum->map[0].decoding = sd_none;
743 lop = rop3_T;
744 break;
745 case rop3_D & rop3_not(rop3_S):
746 /* Implement this as a mask writing 0s. */
747 *(penum->icolor1) = *(penum->icolor0);
748 /* (falls through) */
749 case rop3_D | rop3_S:
750 /* Implement this as a mask writing 1s. */
751 memcpy(&penum->map[0].table.lookup4x1to32[0],
752 lookup4x1to32_identity, 16 * 4);
753 goto rmask;
754 default:
755 ;
756 }
757 }
758 }
759 penum->device_color = device_color;
760 /*
761 * Adjust width upward for unpacking up to 7 trailing bits in
762 * the row, plus 1 byte for end-of-run, plus up to 7 leading
763 * bits for data_x offset within a packed byte.
764 */
765 bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
766 buffer = gs_alloc_bytes(mem, bsize, "image buffer");
767 if (buffer == 0) {
768 code = gs_error_VMerror;
769 goto fail;
770 }
771 penum->bps = bps;
772 penum->unpack_bps = bps;
773 penum->log2_xbytes = log2_xbytes;
774 penum->spp = spp;
775 switch (format) {
776 case gs_image_format_chunky:
777 nplanes = 1;
778 spread = 1 << log2_xbytes;
779 break;
780 case gs_image_format_component_planar:
781 nplanes = spp;
782 spread = spp << log2_xbytes;
783 break;
784 case gs_image_format_bit_planar:
785 nplanes = spp * bps;
786 spread = spp << log2_xbytes;
787 break;
788 default:
789 /* No other cases are possible (checked by gx_image_enum_alloc). */
790 return_error(gs_error_Fatal);
791 }
792 penum->num_planes = nplanes;
793 penum->spread = spread;
794 /*
795 * If we're asked to interpolate in a partial image, we have to
796 * assume that the client either really only is interested in
797 * the given sub-image, or else is constructing output out of
798 * overlapping pieces.
799 */
800 penum->interpolate = force_interpolation ? interp_force : pim->Interpolate ? interp_on : interp_off;
801 penum->x_extent = x_extent;
802 penum->y_extent = y_extent;
803 penum->posture =
804 ((x_extent.y | y_extent.x) == 0 ? image_portrait :
805 (x_extent.x | y_extent.y) == 0 ? image_landscape :
806 image_skewed);
807 penum->pgs = pgs;
808 penum->pcs = pcs;
809 penum->memory = mem;
810 penum->buffer = buffer;
811 penum->buffer_size = bsize;
812 penum->line = NULL;
813 penum->icc_link = NULL;
814 penum->color_cache = NULL;
815 penum->ht_buffer = NULL;
816 penum->thresh_buffer = NULL;
817 penum->use_cie_range = false;
818 penum->line_size = 0;
819 penum->use_rop = lop != (masked ? rop3_T : rop3_S);
820 #ifdef DEBUG
821 if (gs_debug_c('*')) {
822 if (penum->use_rop)
823 dmprintf1(mem, "[%03x]", lop);
824 dmprintf5(mem, "%c%d%c%dx%d ",
825 (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
826 bps,
827 (penum->posture == image_portrait ? ' ' :
828 penum->posture == image_landscape ? 'L' : 'T'),
829 width, height);
830 }
831 #endif
832 penum->slow_loop = 0;
833 if (pcpath == 0) {
834 (*dev_proc(dev, get_clipping_box)) (dev, &obox);
835 cbox = obox;
836 penum->clip_image = 0;
837 } else
838 penum->clip_image =
839 (gx_cpath_outer_box(pcpath, &obox) | /* not || */
840 gx_cpath_inner_box(pcpath, &cbox) ?
841 0 : image_clip_region);
842 penum->clip_outer = obox;
843 penum->clip_inner = cbox;
844 penum->log_op = rop3_T; /* rop device takes care of this */
845 penum->clip_dev = 0; /* in case we bail out */
846 penum->rop_dev = 0; /* ditto */
847 penum->scaler = 0; /* ditto */
848 /*
849 * If all four extrema of the image fall within the clipping
850 * rectangle, clipping is never required. When making this check,
851 * we must carefully take into account the fact that we only care
852 * about pixel centers.
853 */
854 {
855 fixed
856 epx = min(row_extent.x, 0) + min(col_extent.x, 0),
857 eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
858 epy = min(row_extent.y, 0) + min(col_extent.y, 0),
859 eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
860
861 {
862 int hwx, hwy;
863
864 switch (penum->posture) {
865 case image_portrait:
866 hwx = width, hwy = height;
867 break;
868 case image_landscape:
869 hwx = height, hwy = width;
870 break;
871 default:
872 hwx = hwy = 0;
873 }
874 /*
875 * If the image is only 1 sample wide or high,
876 * and is less than 1 device pixel wide or high,
877 * move it slightly so that it covers pixel centers.
878 * This is a hack to work around a bug in some old
879 * versions of TeX/dvips, which use 1-bit-high images
880 * to draw horizontal and vertical lines without
881 * positioning them properly.
882 */
883 if (hwx == 1 && eqx - epx < fixed_1) {
884 fixed diff =
885 arith_rshift_1(row_extent.x + col_extent.x);
886
887 mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
888 }
889 if (hwy == 1 && eqy - epy < fixed_1) {
890 fixed diff =
891 arith_rshift_1(row_extent.y + col_extent.y);
892
893 mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
894 }
895 }
896 if_debug5m('b', mem, "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
897 (masked? "masked, " : ""), spp, bps,
898 fixed2float(mtx), fixed2float(mty));
899 if_debug9m('b', mem,
900 "[b] cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
901 fixed2float(cbox.p.x), fixed2float(cbox.p.y),
902 fixed2float(cbox.q.x), fixed2float(cbox.q.y),
903 fixed2float(obox.p.x), fixed2float(obox.p.y),
904 fixed2float(obox.q.x), fixed2float(obox.q.y),
905 penum->clip_image);
906 /* These DDAs enumerate the starting position of each source pixel
907 * row in device space. */
908 dda_init(penum->dda.row.x, mtx, col_extent.x, height);
909 dda_init(penum->dda.row.y, mty, col_extent.y, height);
910 if (penum->posture == image_portrait) {
911 penum->dst_width = row_extent.x;
912 penum->dst_height = col_extent.y;
913 } else {
914 penum->dst_width = col_extent.x;
915 penum->dst_height = row_extent.y;
916 }
917 /* For gs_image_class_0_interpolate. */
918 penum->yi0 = fixed2int_pixround_perfect(dda_current(penum->dda.row.y)); /* For gs_image_class_0_interpolate. */
919 if (penum->rect.y) {
920 int y = penum->rect.y;
921
922 while (y--) {
923 dda_next(penum->dda.row.x);
924 dda_next(penum->dda.row.y);
925 }
926 }
927 penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
928 penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
929 /* These DDAs enumerate the starting positions of each row of our
930 * source pixel data, in the subrectangle ('strip') that we are
931 * actually rendering. */
932 dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
933 dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
934 if (penum->rect.x) {
935 dda_advance(penum->dda.strip.x, penum->rect.x);
936 dda_advance(penum->dda.strip.y, penum->rect.x);
937 }
938 {
939 fixed ox = dda_current(penum->dda.strip.x);
940 fixed oy = dda_current(penum->dda.strip.y);
941
942 if (!penum->clip_image) /* i.e., not clip region */
943 penum->clip_image =
944 (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
945 image_clip_xmin : 0) +
946 (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
947 image_clip_xmax : 0) +
948 (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
949 image_clip_ymin : 0) +
950 (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
951 image_clip_ymax : 0);
952 }
953 }
954 penum->y = 0;
955 penum->used.x = 0;
956 penum->used.y = 0;
957 if (penum->clip_image && pcpath) { /* Set up the clipping device. */
958 gx_device_clip *cdev =
959 gs_alloc_struct(mem, gx_device_clip,
960 &st_device_clip, "image clipper");
961
962 if (cdev == NULL) {
963 code = gs_error_VMerror;
964 goto fail;
965 }
966 gx_make_clip_device_in_heap(cdev, pcpath, dev, mem);
967 penum->clip_dev = cdev;
968 penum->dev = (gx_device *)cdev; /* Will restore this in a mo. Hacky! */
969 }
970 if (penum->use_rop) { /* Set up the RasterOp source device. */
971 gx_device_rop_texture *rtdev;
972
973 code = gx_alloc_rop_texture_device(&rtdev, mem,
974 "image RasterOp");
975 if (code < 0)
976 goto fail;
977 /* The 'target' must not be NULL for gx_make_rop_texture_device */
978 if (!penum->clip_dev && !dev)
979 return_error(gs_error_undefined);
980
981 gx_make_rop_texture_device(rtdev,
982 (penum->clip_dev != 0 ?
983 (gx_device *) penum->clip_dev :
984 dev), lop, pdcolor);
985 gx_device_retain((gx_device *)rtdev, true);
986 penum->rop_dev = rtdev;
987 penum->dev = (gx_device *)rtdev; /* Will restore this in a mo. Hacky! */
988 }
989 {
990 static sample_unpack_proc_t procs[2][6] = {
991 { sample_unpack_1, sample_unpack_2,
992 sample_unpack_4, sample_unpack_8,
993 sample_unpack_12, sample_unpack_16
994 },
995 { sample_unpack_1_interleaved, sample_unpack_2_interleaved,
996 sample_unpack_4_interleaved, sample_unpack_8_interleaved,
997 sample_unpack_12, sample_unpack_16
998 }};
999 int num_planes = penum->num_planes;
1000 bool interleaved = (num_planes == 1 && penum->plane_depths[0] != penum->bps);
1001 irender_proc_t render_fn = NULL;
1002 int i;
1003
1004 if (interleaved) {
1005 int num_components = penum->plane_depths[0] / penum->bps;
1006
1007 for (i = 1; i < num_components; i++) {
1008 if (decode[0] != decode[i * 2 + 0] ||
1009 decode[1] != decode[i * 2 + 1])
1010 break;
1011 }
1012 if (i == num_components)
1013 interleaved = false; /* Use single table. */
1014 }
1015 penum->unpack = procs[interleaved][index_bps];
1016
1017 if_debug1m('b', mem, "[b]unpack=%d\n", bps);
1018 /* Set up pixel0 for image class procedures. */
1019 penum->dda.pixel0 = penum->dda.strip;
1020 penum->skip_next_line = NULL;
1021 for (i = 0; i < gx_image_class_table_count; ++i) {
1022 code = gx_image_class_table[i](penum, &render_fn);
1023 if (code < 0)
1024 goto fail;
1025
1026 if (render_fn != NULL) {
1027 penum->render = render_fn;
1028 break;
1029 }
1030 }
1031 penum->dev = dev; /* Restore this (in case it was changed to cdev or rtdev) */
1032 if (i == gx_image_class_table_count) {
1033 /* No available class can handle this image. */
1034 return_error(gs_error_rangecheck);
1035 }
1036 }
1037 return 0;
1038
1039 fail:
1040 gs_free_object(mem, buffer, "image buffer");
1041 gs_free_object(mem, penum->clues, "gx_image_enum_begin");
1042 gs_free_object(mem, penum->clip_dev, "image clipper");
1043 gs_free_object(mem, penum, "gx_begin_image1");
1044 return code;
1045 }
1046
1047 /* If a drawing color is black or white, return 0 or 1 respectively, */
1048 /* otherwise return -1. */
1049 static int
color_draws_b_w(gx_device * dev,const gx_drawing_color * pdcolor)1050 color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
1051 {
1052 if (color_is_pure(pdcolor)) {
1053 gx_color_value rgb[3];
1054
1055 (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
1056 rgb);
1057 if (!(rgb[0] | rgb[1] | rgb[2]))
1058 return 0;
1059 if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
1060 return 1;
1061 }
1062 return -1;
1063 }
1064
1065
1066 static void
image_cache_decode(gx_image_enum * penum,byte input,byte * output,bool scale)1067 image_cache_decode(gx_image_enum *penum, byte input, byte *output, bool scale)
1068 {
1069 float temp;
1070
1071 switch ( penum->map[0].decoding ) {
1072 case sd_none:
1073 *output = input;
1074 break;
1075 case sd_lookup:
1076 temp = penum->map[0].decode_lookup[input >> 4]*255.0f;
1077 if (temp > 255) temp = 255;
1078 if (temp < 0 ) temp = 0;
1079 *output = (unsigned char) temp;
1080 break;
1081 case sd_compute:
1082 temp = penum->map[0].decode_base +
1083 (float) input * penum->map[0].decode_factor;
1084 if (scale) {
1085 temp = temp * 255.0;
1086 }
1087 if (temp > 255) temp = 255;
1088 if (temp < 0 ) temp = 0;
1089 *output = (unsigned char) temp;
1090 break;
1091 default:
1092 *output = 0;
1093 break;
1094 }
1095 }
1096
1097 static bool
decode_range_needed(gx_image_enum * penum)1098 decode_range_needed(gx_image_enum *penum)
1099 {
1100 bool scale = true;
1101
1102 if (penum->map[0].decoding == sd_compute) {
1103 if (!(gs_color_space_is_ICC(penum->pcs) ||
1104 gs_color_space_is_PSCIE(penum->pcs))) {
1105 scale = false;
1106 }
1107 }
1108 return scale;
1109 }
1110
1111 /* A special case where we go ahead and initialize the whole index cache with
1112 contone. Device colors. If we are halftoning we will then go ahead and
1113 apply the thresholds to the device contone values. Only used for gray,
1114 rgb or cmyk source colors (No DeviceN for now) */
1115 /* TO DO Add in PSCIE decoder */
1116 int
image_init_color_cache(gx_image_enum * penum,int bps,int spp)1117 image_init_color_cache(gx_image_enum * penum, int bps, int spp)
1118 {
1119 int num_des_comp = penum->dev->color_info.num_components;
1120 int num_src_comp;
1121 int num_entries = 1 << bps;
1122 bool need_decode = penum->icc_setup.need_decode;
1123 bool has_transfer = penum->icc_setup.has_transfer;
1124 byte value;
1125 bool decode_scale = true;
1126 int k, kk;
1127 byte psrc[4];
1128 byte *temp_buffer;
1129 byte *byte_ptr;
1130 bool is_indexed = (gs_color_space_get_index(penum->pcs) ==
1131 gs_color_space_index_Indexed);
1132 bool free_temp_buffer = true;
1133 gsicc_bufferdesc_t input_buff_desc;
1134 gsicc_bufferdesc_t output_buff_desc;
1135 gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
1136
1137 if (penum->icc_link == NULL) {
1138 return gs_rethrow(-1, "ICC Link not created during image render color");
1139 }
1140 if (is_indexed) {
1141 num_src_comp = gs_color_space_num_components(penum->pcs->base_space);
1142 } else {
1143 /* Detect case where cache is not needed. Colors are already in the
1144 device space. Need to fast track this one and halftone row directly.
1145 Detected in gximono.c by looking if penum->color_cache is NULL */
1146 if (penum->icc_link->is_identity && !need_decode && !has_transfer) {
1147 return 0;
1148 }
1149 num_src_comp = 1;
1150 }
1151 /* Allocate cache of device contone values */
1152 penum->color_cache = gs_alloc_struct(penum->memory, gx_image_color_cache_t,
1153 &st_color_cache,
1154 "image_init_color_cache");
1155 penum->color_cache->device_contone = (byte*) gs_alloc_bytes(penum->memory,
1156 num_des_comp * num_entries * sizeof(byte), "image_init_color_cache");
1157 penum->color_cache->is_transparent = (bool*) gs_alloc_bytes(penum->memory,
1158 num_entries * sizeof(bool), "image_init_color_cache");
1159 /* Initialize */
1160 memset(penum->color_cache->is_transparent,0,num_entries * sizeof(bool));
1161 /* Depending upon if we need decode and ICC CM, fill the cache a couple
1162 different ways. If the link is the identity, then we don't need to do any
1163 color conversions except for potentially a decode. This is written in
1164 the manner shown below so that the common case of no decode and indexed
1165 image with a look-up-table uses the table data directly or does as many
1166 operations with memcpy as we can */
1167 /* Need to check the decode output range so we know how we need to scale.
1168 We want 8 bit output */
1169 if (need_decode) {
1170 decode_scale = decode_range_needed(penum);
1171 }
1172 if (penum->icc_link->is_identity) {
1173 /* No CM needed. */
1174 if (need_decode || has_transfer) {
1175 /* Slower case. This could be sped up later to avoid the tests
1176 within the loop by use of specialized loops. */
1177 for (k = 0; k < num_entries; k++) {
1178 /* Data is in k */
1179 if (need_decode) {
1180 image_cache_decode(penum, k, &value, decode_scale);
1181 } else {
1182 value = k;
1183 }
1184 /* Data is in value */
1185 if (is_indexed) {
1186 gs_cspace_indexed_lookup_bytes(penum->pcs, value, psrc);
1187 } else {
1188 psrc[0] = value;
1189 }
1190 /* Data is in psrc */
1191 /* These silly transforms need to go away. ToDo. */
1192 if (has_transfer) {
1193 for (kk = 0; kk < num_des_comp; kk++) {
1194 conc[kk] = gx_color_value_from_byte(psrc[kk]);
1195 }
1196 cmap_transfer(&(conc[0]), penum->pgs, penum->dev);
1197 for (kk = 0; kk < num_des_comp; kk++) {
1198 psrc[kk] = gx_color_value_to_byte(conc[kk]);
1199 }
1200 }
1201 memcpy(&(penum->color_cache->device_contone[k * num_des_comp]),
1202 psrc, num_des_comp);
1203 }
1204 } else {
1205 /* Indexing only. No CM, decode or transfer functions. */
1206 for (k = 0; k < num_entries; k++) {
1207 gs_cspace_indexed_lookup_bytes(penum->pcs, (float)k, psrc);
1208 memcpy(&(penum->color_cache->device_contone[k * num_des_comp]),
1209 psrc, num_des_comp);
1210 }
1211 }
1212 } else {
1213 /* Need CM */
1214 /* We need to worry about if the source is indexed and if we need
1215 to decode first. Then we can apply CM. Create a temp buffer in
1216 the source space and then transform it with one call */
1217 temp_buffer = (byte*) gs_alloc_bytes(penum->memory,
1218 num_entries * num_src_comp,
1219 "image_init_color_cache");
1220 if (need_decode) {
1221 if (is_indexed) {
1222 /* Decode and lookup in index */
1223 for (k = 0; k < num_entries; k++) {
1224 image_cache_decode(penum, k, &value, decode_scale);
1225 gs_cspace_indexed_lookup_bytes(penum->pcs, value, psrc);
1226 memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1227 }
1228 } else {
1229 /* Decode only */
1230 for (k = 0; k < num_entries; k++) {
1231 image_cache_decode(penum, k, &(temp_buffer[k]), decode_scale);
1232 }
1233 }
1234 } else {
1235 /* No Decode */
1236 if (is_indexed) {
1237 /* If index uses a num_entries sized table then just use its pointer */
1238 if (penum->pcs->params.indexed.use_proc ||
1239 penum->pcs->params.indexed.hival < (num_entries - 1)) {
1240 /* Have to do the slow way */
1241 for (k = 0; k <= penum->pcs->params.indexed.hival; k++) {
1242 gs_cspace_indexed_lookup_bytes(penum->pcs, (float)k, psrc);
1243 memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1244 }
1245 /* just use psrc results from converting 'hival' to fill the remaining slots */
1246 for (; k < num_entries; k++) {
1247 memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1248 }
1249 } else {
1250 /* Use the index table directly. */
1251 gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1252 free_temp_buffer = false;
1253 temp_buffer = (byte *)(penum->pcs->params.indexed.lookup.table.data);
1254 }
1255 } else {
1256 /* CM only */
1257 for (k = 0; k < num_entries; k++) {
1258 temp_buffer[k] = k;
1259 }
1260 }
1261 }
1262 /* Set up the buffer descriptors. */
1263 gsicc_init_buffer(&input_buff_desc, num_src_comp, 1, false, false, false,
1264 0, num_entries * num_src_comp, 1, num_entries);
1265 gsicc_init_buffer(&output_buff_desc, num_des_comp, 1, false, false, false,
1266 0, num_entries * num_des_comp,
1267 1, num_entries);
1268 (penum->icc_link->procs.map_buffer)(penum->dev, penum->icc_link,
1269 &input_buff_desc, &output_buff_desc,
1270 (void*) temp_buffer,
1271 (void*) penum->color_cache->device_contone);
1272 /* Check if we need to apply any transfer functions. If so then do it now */
1273 if (has_transfer) {
1274 for (k = 0; k < num_entries; k++) {
1275 byte_ptr =
1276 &(penum->color_cache->device_contone[k * num_des_comp]);
1277 for (kk = 0; kk < num_des_comp; kk++) {
1278 conc[kk] = gx_color_value_from_byte(byte_ptr[kk]);
1279 }
1280 cmap_transfer(&(conc[0]), penum->pgs, penum->dev);
1281 for (kk = 0; kk < num_des_comp; kk++) {
1282 byte_ptr[kk] = gx_color_value_to_byte(conc[kk]);
1283 }
1284 }
1285 }
1286 if (free_temp_buffer)
1287 gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1288 }
1289 return 0;
1290 }
1291
1292 /* Export this for use by image_render_ functions */
1293 void
image_init_clues(gx_image_enum * penum,int bps,int spp)1294 image_init_clues(gx_image_enum * penum, int bps, int spp)
1295 {
1296 /* Initialize the color table */
1297 #define ictype(i)\
1298 penum->clues[i].dev_color.type
1299
1300 switch ((spp == 1 ? bps : 8)) {
1301 case 8: /* includes all color images */
1302 {
1303 register gx_image_clue *pcht = &penum->clues[0];
1304 register int n = 64; /* 8 bits means 256 clues, do */
1305 /* 4 at a time for efficiency */
1306 do {
1307 pcht[0].dev_color.type =
1308 pcht[1].dev_color.type =
1309 pcht[2].dev_color.type =
1310 pcht[3].dev_color.type =
1311 gx_dc_type_none;
1312 pcht[0].key = pcht[1].key =
1313 pcht[2].key = pcht[3].key = 0;
1314 pcht += 4;
1315 }
1316 while (--n > 0);
1317 penum->clues[0].key = 1; /* guarantee no hit */
1318 break;
1319 }
1320 case 4:
1321 ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
1322 ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
1323 ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
1324 ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
1325 gx_dc_type_none;
1326 /* falls through */
1327 case 2:
1328 ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
1329 #undef ictype
1330 }
1331 }
1332
1333 /* Initialize the color mapping tables for a non-mask image. */
1334 static int
image_init_colors(gx_image_enum * penum,int bps,int spp,gs_image_format_t format,const float * decode,const gs_gstate * pgs,gx_device * dev,const gs_color_space * pcs,bool * pdcb)1335 image_init_colors(gx_image_enum * penum, int bps, int spp,
1336 gs_image_format_t format, const float *decode /*[spp*2] */ ,
1337 const gs_gstate * pgs, gx_device * dev,
1338 const gs_color_space * pcs, bool * pdcb)
1339 {
1340 int ci, decode_type, code;
1341 static const float default_decode[] = {
1342 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
1343 };
1344
1345 /* Clues are only used with image_mono_render */
1346 if (spp == 1) {
1347 image_init_clues(penum, bps, spp);
1348 }
1349 decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */
1350 for (ci = 0; ci < spp; ci +=2 ) {
1351 decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) |
1352 (decode[ci] == 1. && decode[ci + 1] == 0.) << 1;
1353 }
1354
1355 /* Initialize the maps from samples to intensities. */
1356 for (ci = 0; ci < spp; ci++) {
1357 sample_map *pmap = &penum->map[ci];
1358
1359 /* If the decoding is [0 1] or [1 0], we can fold it */
1360 /* into the expansion of the sample values; */
1361 /* otherwise, we have to use the floating point method. */
1362
1363 const float *this_decode = &decode[ci * 2];
1364 const float *map_decode; /* decoding used to */
1365 /* construct the expansion map */
1366 const float *real_decode; /* decoding for expanded samples */
1367
1368 map_decode = real_decode = this_decode;
1369 if (!(decode_type & 1)) {
1370 if ((decode_type & 2) && bps <= 8) {
1371 real_decode = default_decode;
1372 } else {
1373 *pdcb = false;
1374 map_decode = default_decode;
1375 }
1376 }
1377 if (bps > 2 || format != gs_image_format_chunky) {
1378 if (bps <= 8)
1379 image_init_map(&pmap->table.lookup8[0], 1 << bps,
1380 map_decode);
1381 } else { /* The map index encompasses more than one pixel. */
1382 byte map[4];
1383 register int i;
1384
1385 image_init_map(&map[0], 1 << bps, map_decode);
1386 switch (bps) {
1387 case 1:
1388 {
1389 register bits32 *p = &pmap->table.lookup4x1to32[0];
1390
1391 if (map[0] == 0 && map[1] == 0xff)
1392 memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
1393 else if (map[0] == 0xff && map[1] == 0)
1394 memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
1395 else
1396 for (i = 0; i < 16; i++, p++)
1397 ((byte *) p)[0] = map[i >> 3],
1398 ((byte *) p)[1] = map[(i >> 2) & 1],
1399 ((byte *) p)[2] = map[(i >> 1) & 1],
1400 ((byte *) p)[3] = map[i & 1];
1401 }
1402 break;
1403 case 2:
1404 {
1405 register bits16 *p = &pmap->table.lookup2x2to16[0];
1406
1407 for (i = 0; i < 16; i++, p++)
1408 ((byte *) p)[0] = map[i >> 2],
1409 ((byte *) p)[1] = map[i & 3];
1410 }
1411 break;
1412 }
1413 }
1414 pmap->decode_base /* = decode_lookup[0] */ = real_decode[0];
1415 pmap->decode_factor =
1416 (real_decode[1] - real_decode[0]) /
1417 (bps <= 8 ? 255.0 : (float)frac_1);
1418 pmap->decode_max /* = decode_lookup[15] */ = real_decode[1];
1419 if (decode_type) {
1420 pmap->decoding = sd_none;
1421 pmap->inverted = map_decode[0] != 0;
1422 } else if (bps <= 4) {
1423 int step = 15 / ((1 << bps) - 1);
1424 int i;
1425
1426 pmap->decoding = sd_lookup;
1427 for (i = 15 - step; i > 0; i -= step)
1428 pmap->decode_lookup[i] = pmap->decode_base +
1429 i * (255.0 / 15) * pmap->decode_factor;
1430 pmap->inverted = 0;
1431 } else {
1432 pmap->decoding = sd_compute;
1433 pmap->inverted = 0;
1434 }
1435 if (spp == 1) { /* and ci == 0 *//* Pre-map entries 0 and 255. */
1436 gs_client_color cc;
1437
1438 /* Image clues are used in this case */
1439 cc.paint.values[0] = real_decode[0];
1440 code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0,
1441 pgs, dev, gs_color_select_source);
1442 if (code < 0)
1443 return code;
1444 cc.paint.values[0] = real_decode[1];
1445 code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1,
1446 pgs, dev, gs_color_select_source);
1447 if (code < 0)
1448 return code;
1449 }
1450 }
1451 return 0;
1452 }
1453 /* Construct a mapping table for sample values. */
1454 /* map_size is 2, 4, 16, or 256. Note that 255 % (map_size - 1) == 0, */
1455 /* so the division 0xffffL / (map_size - 1) is always exact. */
1456 void
image_init_map(byte * map,int map_size,const float * decode)1457 image_init_map(byte * map, int map_size, const float *decode)
1458 {
1459 float min_v = decode[0];
1460 float diff_v = decode[1] - min_v;
1461
1462 if (diff_v == 1 || diff_v == -1) { /* We can do the stepping with integers, without overflow. */
1463 byte *limit = map + map_size;
1464 uint value = (uint)(min_v * 0xffffL);
1465 int diff = (int)(diff_v * (0xffffL / (map_size - 1)));
1466
1467 for (; map != limit; map++, value += diff)
1468 *map = value >> 8;
1469 } else { /* Step in floating point, with clamping. */
1470 int i;
1471
1472 for (i = 0; i < map_size; ++i) {
1473 int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
1474
1475 map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
1476 }
1477 }
1478 }
1479
1480 /*
1481 * Scale a pair of mask_color values to match the scaling of each sample to
1482 * a full byte, and complement and swap them if the map incorporates
1483 * a Decode = [1 0] inversion.
1484 */
1485 void
gx_image_scale_mask_colors(gx_image_enum * penum,int component_index)1486 gx_image_scale_mask_colors(gx_image_enum *penum, int component_index)
1487 {
1488 uint scale = 255 / ((1 << penum->bps) - 1);
1489 uint *values = &penum->mask_color.values[component_index * 2];
1490 uint v0 = values[0] *= scale;
1491 uint v1 = values[1] *= scale;
1492
1493 if (penum->map[component_index].decoding == sd_none &&
1494 penum->map[component_index].inverted
1495 ) {
1496 values[0] = 255 - v1;
1497 values[1] = 255 - v0;
1498 }
1499 }
1500
1501 /* Used to indicate for ICC procesing if we have decoding to do */
1502 bool
gx_has_transfer(const gs_gstate * pgs,int num_comps)1503 gx_has_transfer(const gs_gstate *pgs, int num_comps)
1504 {
1505 int k;
1506
1507 for (k = 0; k < num_comps; k++) {
1508 if (pgs->effective_transfer[k]->proc != gs_identity_transfer) {
1509 return(true);
1510 }
1511 }
1512 return(false);
1513 }
1514