1 /* Copyright (C) 1998, 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: gximage4.c,v 1.6 2005/04/13 20:04:46 ray Exp $ */
18 /* ImageType 4 image implementation */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gscspace.h"
23 #include "gsiparm4.h"
24 #include "gxiparam.h"
25 #include "gximage.h"
26 #include "stream.h"
27
28 /* Forward references */
29 private dev_proc_begin_typed_image(gx_begin_image4);
30
31 /* Structure descriptor */
32 private_st_gs_image4();
33
34 /* Define the image type for ImageType 4 images. */
35 private image_proc_sput(gx_image4_sput);
36 private image_proc_sget(gx_image4_sget);
37 private image_proc_release(gx_image4_release);
38 const gx_image_type_t gs_image_type_4 = {
39 &st_gs_image4, gx_begin_image4, gx_data_image_source_size,
40 gx_image4_sput, gx_image4_sget, gx_image4_release, 4
41 };
42 /*
43 * The implementation is shared with ImageType 1, so we don't need our own
44 * enum_procs.
45 */
46 /*
47 private const gx_image_enum_procs_t image4_enum_procs = {
48 gx_image1_plane_data, gx_image1_end_image
49 };
50 */
51
52 /* Initialize an ImageType 4 image. */
53 void
gs_image4_t_init(gs_image4_t * pim,const gs_color_space * color_space)54 gs_image4_t_init(gs_image4_t * pim, const gs_color_space * color_space)
55 {
56 gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
57 pim->type = &gs_image_type_4;
58 pim->MaskColor_is_range = false;
59 }
60
61 /* Start processing an ImageType 4 image. */
62 private int
gx_begin_image4(gx_device * dev,const gs_imager_state * pis,const gs_matrix * pmat,const gs_image_common_t * pic,const gs_int_rect * prect,const gx_drawing_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * mem,gx_image_enum_common_t ** pinfo)63 gx_begin_image4(gx_device * dev,
64 const gs_imager_state * pis, const gs_matrix * pmat,
65 const gs_image_common_t * pic, const gs_int_rect * prect,
66 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
67 gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
68 {
69 gx_image_enum *penum;
70 const gs_image4_t *pim = (const gs_image4_t *)pic;
71 int code = gx_image_enum_alloc(pic, prect, mem, &penum);
72
73 if (code < 0)
74 return code;
75 penum->alpha = gs_image_alpha_none;
76 penum->masked = false;
77 penum->adjust = fixed_0;
78 /* Check that MaskColor values are within the valid range. */
79 {
80 bool opaque = false;
81 uint max_value = (1 << pim->BitsPerComponent) - 1;
82 int spp = cs_num_components(pim->ColorSpace);
83 int i;
84
85 for (i = 0; i < spp * 2; i += 2) {
86 uint c0, c1;
87
88 if (pim->MaskColor_is_range)
89 c0 = pim->MaskColor[i], c1 = pim->MaskColor[i + 1];
90 else
91 c0 = c1 = pim->MaskColor[i >> 1];
92
93 if ((c0 | c1) > max_value) {
94 gs_free_object(mem, penum, "gx_begin_image4");
95 return_error(gs_error_rangecheck);
96 }
97 if (c0 > c1) {
98 opaque = true; /* pixel can never match mask color */
99 break;
100 }
101 penum->mask_color.values[i] = c0;
102 penum->mask_color.values[i + 1] = c1;
103 }
104 penum->use_mask_color = !opaque;
105 }
106 code = gx_image_enum_begin(dev, pis, pmat, pic, pdcolor, pcpath, mem,
107 penum);
108 if (code >= 0)
109 *pinfo = (gx_image_enum_common_t *)penum;
110 return code;
111 }
112
113 /* Serialization */
114
115 private int
gx_image4_sput(const gs_image_common_t * pic,stream * s,const gs_color_space ** ppcs)116 gx_image4_sput(const gs_image_common_t *pic, stream *s,
117 const gs_color_space **ppcs)
118 {
119 const gs_image4_t *pim = (const gs_image4_t *)pic;
120 bool is_range = pim->MaskColor_is_range;
121 int code = gx_pixel_image_sput((const gs_pixel_image_t *)pim, s, ppcs,
122 is_range);
123 int num_values =
124 gs_color_space_num_components(pim->ColorSpace) * (is_range ? 2 : 1);
125 int i;
126
127 if (code < 0)
128 return code;
129 for (i = 0; i < num_values; ++i)
130 sput_variable_uint(s, pim->MaskColor[i]);
131 *ppcs = pim->ColorSpace;
132 return 0;
133 }
134
135 private int
gx_image4_sget(gs_image_common_t * pic,stream * s,const gs_color_space * pcs)136 gx_image4_sget(gs_image_common_t *pic, stream *s,
137 const gs_color_space *pcs)
138 {
139 gs_image4_t *const pim = (gs_image4_t *)pic;
140 int num_values;
141 int i;
142 int code = gx_pixel_image_sget((gs_pixel_image_t *)pim, s, pcs);
143
144 if (code < 0)
145 return code;
146 pim->type = &gs_image_type_4;
147 pim->MaskColor_is_range = code;
148 num_values =
149 gs_color_space_num_components(pcs) *
150 (pim->MaskColor_is_range ? 2 : 1);
151 for (i = 0; i < num_values; ++i)
152 sget_variable_uint(s, &pim->MaskColor[i]);
153 return 0;
154 }
155
156 private void
gx_image4_release(gs_image_common_t * pic,gs_memory_t * mem)157 gx_image4_release(gs_image_common_t *pic, gs_memory_t *mem)
158 {
159 gx_pixel_image_release((gs_pixel_image_t *)pic, mem);
160 }
161