1 /* Copyright (C) 2001-2006 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, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13
14 /* $Id: zimage.c 10443 2009-12-03 19:14:12Z alexcher $ */
15 /* Image operators */
16 #include "math_.h"
17 #include "memory_.h"
18 #include "stat_.h" /* get system header early to avoid name clash on Cygwin */
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gscolor.h"
22 #include "gscspace.h"
23 #include "gscolor2.h"
24 #include "gsmatrix.h"
25 #include "gsimage.h"
26 #include "gxfixed.h"
27 #include "gsstruct.h"
28 #include "gxiparam.h"
29 #include "idict.h"
30 #include "idparam.h"
31 #include "estack.h" /* for image[mask] */
32 #include "ialloc.h"
33 #include "igstate.h"
34 #include "ilevel.h"
35 #include "store.h"
36 #include "stream.h"
37 #include "ifilter.h" /* for stream exception handling */
38 #include "iimage.h"
39 #include "gxcspace.h"
40
41 /* Forward references */
42 static int zimage_data_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
43 gx_image_enum_common_t * pie,
44 const ref * sources, int npop);
45 static int image_proc_process(i_ctx_t *);
46 static int image_file_continue(i_ctx_t *);
47 static int image_string_continue(i_ctx_t *);
48 static int image_cleanup(i_ctx_t *);
49
50
51
52 /* Extract and check the parameters for a gs_data_image_t. */
53 int
data_image_params(const gs_memory_t * mem,const ref * op,gs_data_image_t * pim,image_params * pip,bool require_DataSource,int num_components,int max_bits_per_component,bool has_alpha)54 data_image_params(const gs_memory_t *mem,
55 const ref *op, gs_data_image_t *pim,
56 image_params *pip, bool require_DataSource,
57 int num_components, int max_bits_per_component,
58 bool has_alpha)
59 {
60 int code;
61 int decode_size;
62 ref *pds;
63
64 check_type(*op, t_dictionary);
65 check_dict_read(*op);
66 if ((code = dict_int_param(op, "Width", 0, max_int_in_fixed / 2,
67 -1, &pim->Width)) < 0 ||
68 (code = dict_int_param(op, "Height", 0, max_int_in_fixed / 2,
69 -1, &pim->Height)) < 0 ||
70 (code = dict_matrix_param(mem, op, "ImageMatrix",
71 &pim->ImageMatrix)) < 0 ||
72 (code = dict_bool_param(op, "MultipleDataSources", false,
73 &pip->MultipleDataSources)) < 0 ||
74 (code = dict_int_param(op, "BitsPerComponent", 1,
75 max_bits_per_component, -1,
76 &pim->BitsPerComponent)) < 0 ||
77 (code = decode_size = dict_floats_param(mem, op, "Decode",
78 num_components * 2,
79 &pim->Decode[0], NULL)) < 0 ||
80 (code = dict_bool_param(op, "Interpolate", false,
81 &pim->Interpolate)) < 0
82 )
83 return code;
84 pip->pDecode = &pim->Decode[0];
85 /* Extract and check the data sources. */
86 if ((code = dict_find_string(op, "DataSource", &pds)) <= 0) {
87 if (require_DataSource)
88 return (code < 0 ? code : gs_note_error(e_rangecheck));
89 return 1; /* no data source */
90 }
91 if (pip->MultipleDataSources) {
92 ref *ds = pip->DataSource;
93 long i, n = num_components + (has_alpha ? 1 : 0);
94 if (!r_is_array(pds))
95 return_error(e_typecheck);
96 if (r_size(pds) != n)
97 return_error(e_rangecheck);
98 for (i = 0; i < n; ++i)
99 array_get(mem, pds, i, &ds[i]);
100 if (r_type(&ds[0]) == t_string) {
101 /* We don't have a problem with the strings of different length
102 * but Adobe does and CET tast 12-02.ps reports this as an error.
103 */
104 if (has_alpha)
105 n--;
106 for (i = 1; i < n; ++i) {
107 if (r_type(&ds[i]) == t_string && r_size(&ds[i]) != r_size(&ds[0])) {
108 return_error(e_rangecheck);
109 }
110 }
111 }
112 } else
113 pip->DataSource[0] = *pds;
114 return 0;
115 }
116
117 /* Extract and check the parameters for a gs_pixel_image_t. */
118 int
pixel_image_params(i_ctx_t * i_ctx_p,const ref * op,gs_pixel_image_t * pim,image_params * pip,int max_bits_per_component,bool has_alpha,gs_color_space * csp)119 pixel_image_params(i_ctx_t *i_ctx_p, const ref *op, gs_pixel_image_t *pim,
120 image_params *pip, int max_bits_per_component,
121 bool has_alpha, gs_color_space *csp)
122 {
123 int num_components =
124 gs_color_space_num_components(csp);
125 int code;
126
127 if (num_components < 1)
128 return_error(e_rangecheck); /* Pattern space not allowed */
129 pim->ColorSpace = csp;
130 code = data_image_params(imemory, op, (gs_data_image_t *) pim, pip, true,
131 num_components, max_bits_per_component,
132 has_alpha);
133 if (code < 0)
134 return code;
135 pim->format =
136 (pip->MultipleDataSources ? gs_image_format_component_planar :
137 gs_image_format_chunky);
138 return dict_bool_param(op, "CombineWithColor", false,
139 &pim->CombineWithColor);
140 }
141
142 /* Common setup for all Level 1 and 2 images, and ImageType 4 images. */
143 int
zimage_setup(i_ctx_t * i_ctx_p,const gs_pixel_image_t * pim,const ref * sources,bool uses_color,int npop)144 zimage_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
145 const ref * sources, bool uses_color, int npop)
146 {
147 gx_image_enum_common_t *pie;
148 int code =
149 gs_image_begin_typed((const gs_image_common_t *)pim, igs,
150 uses_color, &pie);
151
152 if (code < 0)
153 return code;
154 return zimage_data_setup(i_ctx_p, (const gs_pixel_image_t *)pim, pie,
155 sources, npop);
156 }
157
158 /* Common code for .image1 and .alphaimage operators */
159 int
image1_setup(i_ctx_t * i_ctx_p,bool has_alpha)160 image1_setup(i_ctx_t * i_ctx_p, bool has_alpha)
161 {
162 os_ptr op = osp;
163 gs_image_t image;
164 image_params ip;
165 int code;
166 gs_color_space *csp = gs_currentcolorspace(igs);
167 extern bool CPSI_mode;
168
169 /* Adobe interpreters accept sampled images when the current color
170 * space is a pattern color space using the base color space instead
171 * of the pattern space. CET 12-07a-12
172 * If all conditions are not met the pattern color space goes through
173 * triggering a rangecheck error.
174 */
175 if (CPSI_mode && gs_color_space_num_components(csp) < 1) {
176 gs_color_space *bsp = csp->base_space;
177 if (bsp)
178 csp = bsp;
179 }
180
181 gs_image_t_init(&image, csp);
182 code = pixel_image_params( i_ctx_p,
183 op,
184 (gs_pixel_image_t *)&image,
185 &ip,
186 (level2_enabled ? 16 : 8),
187 has_alpha, csp);
188 if (code < 0)
189 return code;
190
191 image.Alpha = (has_alpha ? gs_image_alpha_last : gs_image_alpha_none);
192 return zimage_setup( i_ctx_p,
193 (gs_pixel_image_t *)&image,
194 &ip.DataSource[0],
195 image.CombineWithColor,
196 1 );
197 }
198
199 /* <dict> .image1 - */
200 static int
zimage1(i_ctx_t * i_ctx_p)201 zimage1(i_ctx_t *i_ctx_p)
202 {
203 return image1_setup(i_ctx_p, false);
204 }
205
206 /* <dict> .imagemask1 - */
207 static int
zimagemask1(i_ctx_t * i_ctx_p)208 zimagemask1(i_ctx_t *i_ctx_p)
209 {
210 os_ptr op = osp;
211 gs_image_t image;
212 image_params ip;
213 int code;
214
215 gs_image_t_init_mask_adjust(&image, false,
216 gs_incachedevice(igs) != CACHE_DEVICE_NONE);
217 code = data_image_params(imemory, op, (gs_data_image_t *) & image,
218 &ip, true, 1, 1, false);
219 if (code < 0)
220 return code;
221 return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
222 true, 1);
223 }
224
225
226 /* Common setup for all Level 1 and 2 images, and ImageType 3 and 4 images. */
227 /*
228 * We push the following on the estack.
229 * control mark,
230 * num_sources,
231 * for I = num_sources-1 ... 0:
232 * data source I,
233 * aliasing information:
234 * if source is not file, 1, except that the topmost value
235 * is used for bookkeeping in the procedure case (see below);
236 * if file is referenced by a total of M different sources and
237 * this is the occurrence with the lowest I, M;
238 * otherwise, -J, where J is the lowest I of the same file as
239 * this one;
240 * current plane index,
241 * num_sources,
242 * enumeration structure.
243 */
244 #define NUM_PUSH(nsource) ((nsource) * 2 + 5)
245 /*
246 * We can access these values either from the bottom (esp at control mark - 1,
247 * EBOT macros) or the top (esp = enumeration structure, ETOP macros).
248 * Note that all macros return pointers.
249 */
250 #define EBOT_NUM_SOURCES(ep) ((ep) + 2)
251 #define EBOT_SOURCE(ep, i)\
252 ((ep) + 3 + (EBOT_NUM_SOURCES(ep)->value.intval - 1 - (i)) * 2)
253 #define ETOP_SOURCE(ep, i)\
254 ((ep) - 4 - (i) * 2)
255 #define ETOP_PLANE_INDEX(ep) ((ep) - 2)
256 #define ETOP_NUM_SOURCES(ep) ((ep) - 1)
257 static int
zimage_data_setup(i_ctx_t * i_ctx_p,const gs_pixel_image_t * pim,gx_image_enum_common_t * pie,const ref * sources,int npop)258 zimage_data_setup(i_ctx_t *i_ctx_p, const gs_pixel_image_t * pim,
259 gx_image_enum_common_t * pie, const ref * sources, int npop)
260 {
261 int num_sources = pie->num_planes;
262 int inumpush = NUM_PUSH(num_sources);
263 int code;
264 gs_image_enum *penum;
265 int px;
266 const ref *pp;
267 bool string_sources = true;
268
269 check_estack(inumpush + 2); /* stuff above, + continuation + proc */
270 make_int(EBOT_NUM_SOURCES(esp), num_sources);
271 /*
272 * Note that the data sources may be procedures, strings, or (Level
273 * 2 only) files. (The Level 1 reference manual says that Level 1
274 * requires procedures, but Adobe Level 1 interpreters also accept
275 * strings.) The sources must all be of the same type.
276 *
277 * The Adobe documentation explicitly says that if two or more of the
278 * data sources are the same or inter-dependent files, the result is not
279 * defined. We don't have a problem with the bookkeeping for
280 * inter-dependent files, since each one has its own buffer, but we do
281 * have to be careful if two or more sources are actually the same file.
282 * That is the reason for the aliasing information described above.
283 */
284 for (px = 0, pp = sources; px < num_sources; px++, pp++) {
285 es_ptr ep = EBOT_SOURCE(esp, px);
286
287 make_int(ep + 1, 1); /* default is no aliasing */
288 switch (r_type(pp)) {
289 case t_file:
290 if (!level2_enabled)
291 return_error(e_typecheck);
292 /* Check for aliasing. */
293 {
294 int pi;
295
296 for (pi = 0; pi < px; ++pi)
297 if (sources[pi].value.pfile == pp->value.pfile) {
298 /* Record aliasing */
299 make_int(ep + 1, -pi);
300 EBOT_SOURCE(esp, pi)[1].value.intval++;
301 break;
302 }
303 }
304 string_sources = false;
305 /* falls through */
306 case t_string:
307 if (r_type(pp) != r_type(sources)) {
308 gx_image_end(pie, false); /* Clean up pie */
309 return_error(e_typecheck);
310 }
311 check_read(*pp);
312 break;
313 default:
314 if (!r_is_proc(sources)) {
315 static const char ds[] = "DataSource";
316 gx_image_end(pie, false); /* Clean up pie */
317 gs_errorinfo_put_pair(i_ctx_p, ds, sizeof(ds) - 1, pp);
318 return_error(e_typecheck);
319 }
320 check_proc(*pp);
321 string_sources = false;
322 }
323 *ep = *pp;
324 }
325 /* Always place the image enumerator into local memory,
326 because pie may have local objects inherited from igs,
327 which may be local when the current allocation mode is global.
328 Bug 688140. */
329 if ((penum = gs_image_enum_alloc(imemory_local, "image_setup")) == 0)
330 return_error(e_VMerror);
331 code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, igs);
332 if (code != 0 || (pie->skipping && string_sources)) { /* error, or empty image */
333 int code1 = gs_image_cleanup_and_free_enum(penum, igs);
334
335 if (code >= 0) /* empty image */
336 pop(npop);
337 if (code >= 0 && code1 < 0)
338 code = code1;
339 return code;
340 }
341 push_mark_estack(es_other, image_cleanup);
342 esp += inumpush - 1;
343 make_int(ETOP_PLANE_INDEX(esp), 0);
344 make_int(ETOP_NUM_SOURCES(esp), num_sources);
345 make_struct(esp, avm_local, penum);
346 switch (r_type(sources)) {
347 case t_file:
348 push_op_estack(image_file_continue);
349 break;
350 case t_string:
351 push_op_estack(image_string_continue);
352 break;
353 default: /* procedure */
354 push_op_estack(image_proc_process);
355 break;
356 }
357 pop(npop);
358 return o_push_estack;
359 }
360 /* Pop all the control information off the e-stack. */
361 static es_ptr
zimage_pop_estack(es_ptr tep)362 zimage_pop_estack(es_ptr tep)
363 {
364 return tep - NUM_PUSH(ETOP_NUM_SOURCES(tep)->value.intval);
365 }
366
367 /*
368 * Continuation for procedure data source. We use the topmost aliasing slot
369 * to remember whether we've just called the procedure (1) or whether we're
370 * returning from a RemapColor callout (0).
371 */
372 static int
image_proc_continue(i_ctx_t * i_ctx_p)373 image_proc_continue(i_ctx_t *i_ctx_p)
374 {
375 os_ptr op = osp;
376 gs_image_enum *penum = r_ptr(esp, gs_image_enum);
377 int px = ETOP_PLANE_INDEX(esp)->value.intval;
378 int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
379 uint size, used[GS_IMAGE_MAX_COMPONENTS];
380 gs_const_string plane_data[GS_IMAGE_MAX_COMPONENTS];
381 const byte *wanted;
382 int i, code;
383
384 if (!r_has_type_attrs(op, t_string, a_read)) {
385 check_op(1);
386 /* Procedure didn't return a (readable) string. Quit. */
387 esp = zimage_pop_estack(esp);
388 image_cleanup(i_ctx_p);
389 return_error(!r_has_type(op, t_string) ? e_typecheck : e_invalidaccess);
390 }
391 size = r_size(op);
392 if (size == 0 && ETOP_SOURCE(esp, 0)[1].value.intval == 0)
393 code = 1;
394 else {
395 for (i = 0; i < num_sources; i++)
396 plane_data[i].size = 0;
397 plane_data[px].data = op->value.bytes;
398 plane_data[px].size = size;
399 code = gs_image_next_planes(penum, plane_data, used);
400 if (code == e_RemapColor) {
401 op->value.bytes += used[px]; /* skip used data */
402 r_dec_size(op, used[px]);
403 ETOP_SOURCE(esp, 0)[1].value.intval = 0; /* RemapColor callout */
404 return code;
405 }
406 }
407 if (code) { /* Stop now. */
408 esp = zimage_pop_estack(esp);
409 pop(1);
410 image_cleanup(i_ctx_p);
411 return (code < 0 ? code : o_pop_estack);
412 }
413 pop(1);
414 wanted = gs_image_planes_wanted(penum);
415 do {
416 if (++px == num_sources)
417 px = 0;
418 } while (!wanted[px]);
419 ETOP_PLANE_INDEX(esp)->value.intval = px;
420 return image_proc_process(i_ctx_p);
421 }
422 static int
image_proc_process(i_ctx_t * i_ctx_p)423 image_proc_process(i_ctx_t *i_ctx_p)
424 {
425 int px = ETOP_PLANE_INDEX(esp)->value.intval;
426 gs_image_enum *penum = r_ptr(esp, gs_image_enum);
427 const byte *wanted = gs_image_planes_wanted(penum);
428 int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
429 const ref *pp;
430
431 ETOP_SOURCE(esp, 0)[1].value.intval = 0; /* procedure callout */
432 while (!wanted[px]) {
433 if (++px == num_sources)
434 px = 0;
435 ETOP_PLANE_INDEX(esp)->value.intval = px;
436 }
437 pp = ETOP_SOURCE(esp, px);
438 push_op_estack(image_proc_continue);
439 *++esp = *pp;
440 return o_push_estack;
441 }
442
443 /* Continue processing data from an image with file data sources. */
444 static int
image_file_continue(i_ctx_t * i_ctx_p)445 image_file_continue(i_ctx_t *i_ctx_p)
446 {
447 gs_image_enum *penum = r_ptr(esp, gs_image_enum);
448 int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
449
450 for (;;) {
451 uint min_avail = max_int;
452 gs_const_string plane_data[GS_IMAGE_MAX_COMPONENTS];
453 int code;
454 int px;
455 const ref *pp;
456 int at_eof_count = 0;
457
458 /*
459 * Do a first pass through the files to ensure that at least
460 * one has data available in its buffer.
461 */
462
463 for (px = 0, pp = ETOP_SOURCE(esp, 0); px < num_sources;
464 ++px, pp -= 2
465 ) {
466 int num_aliases = pp[1].value.intval;
467 stream *s = pp->value.pfile;
468 int min_left;
469 uint avail;
470
471 if (num_aliases <= 0)
472 num_aliases = ETOP_SOURCE(esp, -num_aliases)[1].value.intval;
473 while ((avail = sbufavailable(s)) <=
474 (min_left = sbuf_min_left(s)) + num_aliases - 1) {
475 int next = s->end_status;
476
477 switch (next) {
478 case 0:
479 s_process_read_buf(s);
480 continue;
481 case EOFC:
482 at_eof_count++;
483 break; /* with no data available */
484 case INTC:
485 case CALLC:
486 return
487 s_handle_read_exception(i_ctx_p, next, pp,
488 NULL, 0, image_file_continue);
489 default:
490 /* case ERRC: */
491 return_error(e_ioerror);
492 }
493 break; /* for EOFC */
494 }
495 /*
496 * Note that in the EOF case, we can get here with no data
497 * available.
498 */
499 if (avail >= min_left)
500 avail = (avail - min_left) / num_aliases; /* may be 0 */
501 if (avail < min_avail)
502 min_avail = avail;
503 plane_data[px].data = sbufptr(s);
504 plane_data[px].size = avail;
505 }
506
507 /*
508 * Now pass the available buffered data to the image processor.
509 * Even if there is no available data, we must call
510 * gs_image_next_planes one more time to finish processing any
511 * retained data.
512 */
513
514 {
515 int pi;
516 uint used[GS_IMAGE_MAX_COMPONENTS];
517
518 code = gs_image_next_planes(penum, plane_data, used);
519 /* Now that used has been set, update the streams. */
520 for (pi = 0, pp = ETOP_SOURCE(esp, 0); pi < num_sources;
521 ++pi, pp -= 2
522 )
523 sbufskip(pp->value.pfile, used[pi]);
524 if (code == e_RemapColor)
525 return code;
526 }
527 if (at_eof_count >= num_sources)
528 code = 1;
529 if (code) {
530 int code1;
531
532 esp = zimage_pop_estack(esp);
533 code1 = image_cleanup(i_ctx_p);
534 return (code < 0 ? code : code1 < 0 ? code1 : o_pop_estack);
535 }
536 }
537 }
538
539 /* Process data from an image with string data sources. */
540 /* This may still encounter a RemapColor callback. */
541 static int
image_string_continue(i_ctx_t * i_ctx_p)542 image_string_continue(i_ctx_t *i_ctx_p)
543 {
544 gs_image_enum *penum = r_ptr(esp, gs_image_enum);
545 int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
546 gs_const_string sources[GS_IMAGE_MAX_COMPONENTS];
547 uint used[GS_IMAGE_MAX_COMPONENTS];
548
549 /* Pass no data initially, to find out how much is retained. */
550 memset(sources, 0, sizeof(sources[0]) * num_sources);
551 for (;;) {
552 int px;
553 int code = gs_image_next_planes(penum, sources, used);
554
555 if (code == e_RemapColor)
556 return code;
557 stop_now:
558 if (code) { /* Stop now. */
559 esp -= NUM_PUSH(num_sources);
560 image_cleanup(i_ctx_p);
561 return (code < 0 ? code : o_pop_estack);
562 }
563 for (px = 0; px < num_sources; ++px)
564 if (sources[px].size == 0) {
565 const ref *psrc = ETOP_SOURCE(esp, px);
566 uint size = r_size(psrc);
567
568 if (size == 0) { /* empty source */
569 code = 1;
570 goto stop_now;
571 }
572 sources[px].data = psrc->value.bytes;
573 sources[px].size = size;
574 }
575 }
576 }
577
578 /* Clean up after enumerating an image */
579 static int
image_cleanup(i_ctx_t * i_ctx_p)580 image_cleanup(i_ctx_t *i_ctx_p)
581 {
582 es_ptr ep_top = esp + NUM_PUSH(EBOT_NUM_SOURCES(esp)->value.intval);
583 gs_image_enum *penum = r_ptr(ep_top, gs_image_enum);
584
585 return gs_image_cleanup_and_free_enum(penum, igs);
586 }
587
588 /* ------ Initialization procedure ------ */
589
590 const op_def zimage_op_defs[] =
591 {
592 {"1.image1", zimage1},
593 {"1.imagemask1", zimagemask1},
594 /* Internal operators */
595 {"1%image_proc_continue", image_proc_continue},
596 {"0%image_file_continue", image_file_continue},
597 {"0%image_string_continue", image_string_continue},
598 op_def_end(0)
599 };
600