1 /* Copyright (C) 1997, 2000 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: zimage3.c,v 1.3.6.1.2.1 2003/01/17 00:49:06 giles Exp $ */
20 /* LanguageLevel 3 ImageTypes (3 & 4 - masked images) */
21 #include "memory_.h"
22 #include "ghost.h"
23 #include "oper.h"
24 #include "gscspace.h"		/* for gscolor2.h */
25 #include "gscolor2.h"
26 #include "gsiparm3.h"
27 #include "gsiparm4.h"
28 #include "gxiparam.h"		/* for image enumerator */
29 #include "idict.h"
30 #include "idparam.h"
31 #include "igstate.h"
32 #include "iimage.h"
33 #include "iimage2.h"
34 
35 /* <dict> .image3 - */
36 private int
zimage3(i_ctx_t * i_ctx_p)37 zimage3(i_ctx_t *i_ctx_p)
38 {
39     os_ptr op = osp;
40     gs_image3_t image;
41     int interleave_type;
42     ref *pDataDict;
43     ref *pMaskDict;
44     image_params ip_data, ip_mask;
45     int ignored;
46     int code, mcode;
47 
48     check_type(*op, t_dictionary);
49     check_dict_read(*op);
50     if ((code = dict_int_param(op, "InterleaveType", 1, 3, -1,
51 			       &interleave_type)) < 0
52 	)
53 	return code;
54     gs_image3_t_init(&image, NULL, interleave_type);
55     if (dict_find_string(op, "DataDict", &pDataDict) <= 0 ||
56 	dict_find_string(op, "MaskDict", &pMaskDict) <= 0
57 	)
58 	return_error(e_rangecheck);
59     if ((code = pixel_image_params(i_ctx_p, pDataDict,
60 				   (gs_pixel_image_t *)&image, &ip_data,
61 				   12)) < 0 ||
62 	(mcode = code = data_image_params(pMaskDict, &image.MaskDict, &ip_mask, false, 1, 12)) < 0 ||
63 	(code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
64 	(code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0
65 	)
66 	return code;
67     /*
68      * MaskDict must have a DataSource iff InterleaveType == 3.
69      */
70     if ((ip_data.MultipleDataSources && interleave_type != 3) ||
71 	ip_mask.MultipleDataSources ||
72 	mcode != (image.InterleaveType != 3)
73 	)
74 	return_error(e_rangecheck);
75     if (image.InterleaveType == 3) {
76 	/* Insert the mask DataSource before the data DataSources. */
77 	memmove(&ip_data.DataSource[1], &ip_data.DataSource[0],
78 		(countof(ip_data.DataSource) - 1) *
79 		sizeof(ip_data.DataSource[0]));
80 	ip_data.DataSource[0] = ip_mask.DataSource[0];
81     }
82     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
83 			&ip_data.DataSource[0],
84 			image.CombineWithColor, 1);
85 }
86 
87 /* <dict> .image4 - */
88 private int
zimage4(i_ctx_t * i_ctx_p)89 zimage4(i_ctx_t *i_ctx_p)
90 {
91     os_ptr op = osp;
92     gs_image4_t image;
93     image_params ip;
94     int num_components =
95 	gs_color_space_num_components(gs_currentcolorspace(igs));
96     int colors[countof(image.MaskColor)];
97     int code;
98     int i;
99 
100     gs_image4_t_init(&image, NULL);
101     code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
102 			      12);
103     if (code < 0)
104 	return code;
105     code = dict_int_array_check_param(op, "MaskColor", num_components * 2,
106 				      colors, 0, e_rangecheck);
107     /* Clamp the color values to the unsigned range. */
108     if (code == num_components) {
109 	image.MaskColor_is_range = false;
110 	for (i = 0; i < code; ++i)
111 	    image.MaskColor[i] = (colors[i] < 0 ? ~(uint)0 : colors[i]);
112     }
113     else if (code == num_components * 2) {
114 	image.MaskColor_is_range = true;
115 	for (i = 0; i < code; i += 2) {
116 	    if (colors[i+1] < 0) /* no match possible */
117 		image.MaskColor[i] = 1, image.MaskColor[i+1] = 0;
118 	    else {
119 		image.MaskColor[i+1] = colors[i+1];
120 		image.MaskColor[i] = max(colors[i], 0);
121 	    }
122 	}
123     } else
124 	return_error(code < 0 ? code : gs_note_error(e_rangecheck));
125     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
126 			image.CombineWithColor, 1);
127 }
128 
129 /* ------ Initialization procedure ------ */
130 
131 const op_def zimage3_op_defs[] =
132 {
133     op_def_begin_ll3(),
134     {"1.image3", zimage3},
135     {"1.image4", zimage4},
136     op_def_end(0)
137 };
138