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