xref: /plan9/sys/src/cmd/gs/src/zimage3.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1997, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: zimage3.c,v 1.7 2004/08/04 19:36:13 stefan Exp $ */
18 /* LanguageLevel 3 ImageTypes (3 & 4 - masked images) */
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "oper.h"
22 #include "gscspace.h"		/* for gscolor2.h */
23 #include "gscolor2.h"
24 #include "gsiparm3.h"
25 #include "gsiparm4.h"
26 #include "gxiparam.h"		/* for image enumerator */
27 #include "idict.h"
28 #include "idparam.h"
29 #include "igstate.h"
30 #include "iimage.h"
31 #include "ialloc.h"
32 
33 /* <dict> .image3 - */
34 private int
zimage3(i_ctx_t * i_ctx_p)35 zimage3(i_ctx_t *i_ctx_p)
36 {
37     os_ptr op = osp;
38     gs_image3_t image;
39     int interleave_type;
40     ref *pDataDict;
41     ref *pMaskDict;
42     image_params ip_data, ip_mask;
43     int ignored;
44     int code, mcode;
45 
46     check_type(*op, t_dictionary);
47     check_dict_read(*op);
48     if ((code = dict_int_param(op, "InterleaveType", 1, 3, -1,
49 			       &interleave_type)) < 0
50 	)
51 	return code;
52     gs_image3_t_init(&image, NULL, interleave_type);
53     if (dict_find_string(op, "DataDict", &pDataDict) <= 0 ||
54 	dict_find_string(op, "MaskDict", &pMaskDict) <= 0
55 	)
56 	return_error(e_rangecheck);
57     if ((code = pixel_image_params(i_ctx_p, pDataDict,
58 				   (gs_pixel_image_t *)&image, &ip_data,
59 				   12, false)) < 0 ||
60 	(mcode = code = data_image_params(imemory, pMaskDict, &image.MaskDict,
61 				   &ip_mask, false, 1, 12, false)) < 0 ||
62 	(code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
63 	(code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0
64 	)
65 	return code;
66     /*
67      * MaskDict must have a DataSource iff InterleaveType == 3.
68      */
69     if ((ip_data.MultipleDataSources && interleave_type != 3) ||
70 	ip_mask.MultipleDataSources ||
71 	mcode != (image.InterleaveType != 3)
72 	)
73 	return_error(e_rangecheck);
74     if (image.InterleaveType == 3) {
75 	/* Insert the mask DataSource before the data DataSources. */
76 	memmove(&ip_data.DataSource[1], &ip_data.DataSource[0],
77 		(countof(ip_data.DataSource) - 1) *
78 		sizeof(ip_data.DataSource[0]));
79 	ip_data.DataSource[0] = ip_mask.DataSource[0];
80     }
81     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
82 			&ip_data.DataSource[0],
83 			image.CombineWithColor, 1);
84 }
85 
86 /* <dict> .image4 - */
87 private int
zimage4(i_ctx_t * i_ctx_p)88 zimage4(i_ctx_t *i_ctx_p)
89 {
90     os_ptr op = osp;
91     gs_image4_t image;
92     image_params ip;
93     int num_components =
94 	gs_color_space_num_components(gs_currentcolorspace(igs));
95     int colors[countof(image.MaskColor)];
96     int code;
97     int i;
98 
99     gs_image4_t_init(&image, NULL);
100     code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
101 			      12, false);
102     if (code < 0)
103 	return code;
104     code = dict_int_array_check_param(op, "MaskColor", num_components * 2,
105 				      colors, 0, e_rangecheck);
106     /* Clamp the color values to the unsigned range. */
107     if (code == num_components) {
108 	image.MaskColor_is_range = false;
109 	for (i = 0; i < code; ++i)
110 	    image.MaskColor[i] = (colors[i] < 0 ? ~(uint)0 : colors[i]);
111     }
112     else if (code == num_components * 2) {
113 	image.MaskColor_is_range = true;
114 	for (i = 0; i < code; i += 2) {
115 	    if (colors[i+1] < 0) /* no match possible */
116 		image.MaskColor[i] = 1, image.MaskColor[i+1] = 0;
117 	    else {
118 		image.MaskColor[i+1] = colors[i+1];
119 		image.MaskColor[i] = max(colors[i], 0);
120 	    }
121 	}
122     } else
123 	return_error(code < 0 ? code : gs_note_error(e_rangecheck));
124     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
125 			image.CombineWithColor, 1);
126 }
127 
128 /* ------ Initialization procedure ------ */
129 
130 const op_def zimage3_op_defs[] =
131 {
132     op_def_begin_ll3(),
133     {"1.image3", zimage3},
134     {"1.image4", zimage4},
135     op_def_end(0)
136 };
137