1 /* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* LanguageLevel 3 ImageTypes (3 & 4 - masked images) */
18 #include "memory_.h"
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gscspace.h"		/* for gscolor2.h */
22 #include "gscolor2.h"
23 #include "gsiparm3.h"
24 #include "gsiparm4.h"
25 #include "gxiparam.h"		/* for image enumerator */
26 #include "idict.h"
27 #include "idparam.h"
28 #include "igstate.h"
29 #include "iimage.h"
30 #include "ialloc.h"
31 
32 /* <dict> .image3 - */
33 static int
zimage3(i_ctx_t * i_ctx_p)34 zimage3(i_ctx_t *i_ctx_p)
35 {
36     os_ptr op = osp;
37     gs_image3_t image;
38     int interleave_type;
39     ref *pDataDict;
40     ref *pMaskDict;
41     image_params ip_data, ip_mask;
42     int ignored;
43     int code, mcode;
44 
45     check_type(*op, t_dictionary);
46     check_dict_read(*op);
47     if ((code = dict_int_param(op, "InterleaveType", 1, 3, -1,
48                                &interleave_type)) < 0
49         )
50         return code;
51     gs_image3_t_init(&image, NULL, interleave_type);
52     if (dict_find_string(op, "DataDict", &pDataDict) <= 0 ||
53         dict_find_string(op, "MaskDict", &pMaskDict) <= 0
54         )
55         return_error(e_rangecheck);
56     if ((code = pixel_image_params(i_ctx_p, pDataDict,
57                         (gs_pixel_image_t *)&image, &ip_data,
58                         12, false, gs_currentcolorspace(igs))) < 0 ||
59         (mcode = code = data_image_params(imemory, pMaskDict, &image.MaskDict,
60                                    &ip_mask, false, 1, 12, false, false)) < 0 ||
61         (code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
62         (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0
63         )
64         return code;
65     /*
66      * MaskDict must have a DataSource iff InterleaveType == 3.
67      */
68     if ((ip_data.MultipleDataSources && interleave_type != 3) ||
69         ip_mask.MultipleDataSources ||
70         mcode != (image.InterleaveType != 3)
71         )
72         return_error(e_rangecheck);
73     if (image.InterleaveType == 3) {
74         /* Insert the mask DataSource before the data DataSources. */
75         memmove(&ip_data.DataSource[1], &ip_data.DataSource[0],
76                 (countof(ip_data.DataSource) - 1) *
77                 sizeof(ip_data.DataSource[0]));
78         ip_data.DataSource[0] = ip_mask.DataSource[0];
79     }
80     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
81                         &ip_data.DataSource[0],
82                         image.CombineWithColor, 1);
83 }
84 
85 /* <dict> .image4 - */
86 static int
zimage4(i_ctx_t * i_ctx_p)87 zimage4(i_ctx_t *i_ctx_p)
88 {
89     os_ptr op = osp;
90     gs_image4_t image;
91     image_params ip;
92     int num_components =
93         gs_color_space_num_components(gs_currentcolorspace(igs));
94     int colors[countof(image.MaskColor)];
95     int code;
96     int i;
97 
98     gs_image4_t_init(&image, NULL);
99     code = pixel_image_params(i_ctx_p, op, (gs_pixel_image_t *)&image, &ip,
100                               12, false, gs_currentcolorspace(igs));
101     if (code < 0)
102         return code;
103     code = dict_int_array_check_param(imemory, op, "MaskColor",
104        num_components * 2, colors, 0, e_rangecheck);
105     /* Clamp the color values to the unsigned range. */
106     if (code == num_components) {
107         image.MaskColor_is_range = false;
108         for (i = 0; i < code; ++i)
109             image.MaskColor[i] = (colors[i] < 0 ? ~(uint)0 : colors[i]);
110     }
111     else if (code == num_components * 2) {
112         image.MaskColor_is_range = true;
113         for (i = 0; i < code; i += 2) {
114             if (colors[i+1] < 0) /* no match possible */
115                 image.MaskColor[i] = 1, image.MaskColor[i+1] = 0;
116             else {
117                 image.MaskColor[i+1] = colors[i+1];
118                 image.MaskColor[i] = max(colors[i], 0);
119             }
120         }
121     } else
122         return_error(code < 0 ? code : gs_note_error(e_rangecheck));
123     return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip.DataSource[0],
124                         image.CombineWithColor, 1);
125 }
126 
127 /* ------ Initialization procedure ------ */
128 
129 const op_def zimage3_op_defs[] =
130 {
131     op_def_begin_ll3(),
132     {"1.image3", zimage3},
133     {"1.image4", zimage4},
134     op_def_end(0)
135 };
136