xref: /plan9/sys/src/cmd/gs/src/gximage1.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 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: gximage1.c,v 1.7 2002/02/21 22:24:53 giles Exp $ */
18 /* ImageType 1 initialization */
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gxiparam.h"
22 #include "gximage.h"
23 #include "stream.h"
24 
25 /* Structure descriptor */
26 public_st_gs_image1();
27 
28 /*
29  * Define the image types for ImageType 1 images.
30  * Note that opaque images and masks have different types, although
31  * they have the same ImageType.
32  */
33 private image_proc_sput(gx_image1_sput);
34 private image_proc_sget(gx_image1_sget);
35 private image_proc_release(gx_image1_release);
36 const gx_image_type_t gs_image_type_1 = {
37     &st_gs_image1, gx_begin_image1, gx_data_image_source_size,
38     gx_image1_sput, gx_image1_sget, gx_image1_release, 1
39 };
40 private image_proc_sput(gx_image1_mask_sput);
41 private image_proc_sget(gx_image1_mask_sget);
42 /*
43  * Image masks are not actually pixel images, so they don't need to
44  * worry about releasing the color space.
45  */
46 const gx_image_type_t gs_image_type_mask1 = {
47     &st_gs_image1, gx_begin_image1, gx_data_image_source_size,
48     gx_image1_mask_sput, gx_image1_mask_sget, gx_image_default_release, 1
49 };
50 
51 /* Define the procedures for initializing gs_image_ts to default values. */
52 void
gs_image_t_init_adjust(gs_image_t * pim,const gs_color_space * color_space,bool adjust)53 gs_image_t_init_adjust(gs_image_t * pim, const gs_color_space * color_space,
54 		       bool adjust)
55 {
56     gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
57     pim->ImageMask = (color_space == NULL);
58     pim->adjust = adjust;
59     pim->type = (pim->ImageMask ? &gs_image_type_mask1 : &gs_image_type_1);
60     pim->Alpha = gs_image_alpha_none;
61 }
62 void
gs_image_t_init_mask_adjust(gs_image_t * pim,bool write_1s,bool adjust)63 gs_image_t_init_mask_adjust(gs_image_t * pim, bool write_1s, bool adjust)
64 {
65     gs_image_t_init(pim, NULL);
66     if (write_1s)
67 	pim->Decode[0] = 1, pim->Decode[1] = 0;
68     else
69 	pim->Decode[0] = 0, pim->Decode[1] = 1;
70     pim->adjust = adjust;
71 }
72 
73 /* Start processing an ImageType 1 image. */
74 int
gx_begin_image1(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)75 gx_begin_image1(gx_device * dev,
76 		const gs_imager_state * pis, const gs_matrix * pmat,
77 		const gs_image_common_t * pic, const gs_int_rect * prect,
78 		const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
79 		gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
80 {
81     gx_image_enum *penum;
82     const gs_image_t *pim = (const gs_image_t *)pic;
83     int code = gx_image_enum_alloc(pic, prect, mem, &penum);
84 
85     if (code < 0)
86 	return code;
87     penum->alpha = pim->Alpha;
88     penum->use_mask_color = false;
89     penum->masked = pim->ImageMask;
90     penum->adjust =
91 	(pim->ImageMask && pim->adjust ? float2fixed(0.25) : fixed_0);
92     code = gx_image_enum_begin(dev, pis, pmat, pic, pdcolor, pcpath, mem,
93 			       penum);
94     if (code >= 0)
95 	*pinfo = (gx_image_enum_common_t *)penum;
96     return code;
97 }
98 
99 /* Serialization */
100 
101 /*
102  * We add the Alpha value to the control word.
103  */
104 
105 private int
gx_image1_sput(const gs_image_common_t * pic,stream * s,const gs_color_space ** ppcs)106 gx_image1_sput(const gs_image_common_t *pic, stream *s,
107 	       const gs_color_space **ppcs)
108 {
109     const gs_image_t *const pim = (const gs_image_t *)pic;
110 
111     return gx_pixel_image_sput((const gs_pixel_image_t *)pic, s, ppcs,
112 			       (int)pim->Alpha);
113 }
114 
115 private int
gx_image1_sget(gs_image_common_t * pic,stream * s,const gs_color_space * pcs)116 gx_image1_sget(gs_image_common_t *pic, stream *s,
117 	       const gs_color_space *pcs)
118 {
119     gs_image1_t *const pim = (gs_image1_t *)pic;
120     int code = gx_pixel_image_sget((gs_pixel_image_t *)pim, s, pcs);
121 
122     if (code < 0)
123 	return code;
124     pim->type = &gs_image_type_1;
125     pim->ImageMask = false;
126     pim->Alpha = code;
127     return 0;
128 }
129 
130 /*
131  * Masks have different parameters, so we use a different encoding:
132  *	FFFFEEDCBA
133  *	    A = 0 if standard ImageMatrix, 1 if explicit ImageMatrix
134  *	    B = 0 if Decode=[0 1], 1 if Decode=[1 0]
135  *	    C = Interpolate
136  *	    D = adjust
137  *	    EE = Alpha
138  *	    FFFF = BitsPerComponent - 1 (only needed for soft masks)
139  *	Width, encoded as a variable-length uint
140  *	Height, encoded like Width
141  *	ImageMatrix (if A = 1), per gs_matrix_store/fetch
142  */
143 #define MI_ImageMatrix 0x01
144 #define MI_Decode 0x02
145 #define MI_Interpolate 0x04
146 #define MI_adjust 0x08
147 #define MI_Alpha_SHIFT 4
148 #define MI_Alpha_MASK 0x3
149 #define MI_BPC_SHIFT 6
150 #define MI_BPC_MASK 0xf
151 #define MI_BITS 10
152 
153 private int
gx_image1_mask_sput(const gs_image_common_t * pic,stream * s,const gs_color_space ** ignore_ppcs)154 gx_image1_mask_sput(const gs_image_common_t *pic, stream *s,
155 		    const gs_color_space **ignore_ppcs)
156 {
157     const gs_image_t *pim = (const gs_image_t *)pic;
158     uint control =
159 	(gx_image_matrix_is_default((const gs_data_image_t *)pim) ? 0 :
160 	 MI_ImageMatrix) |
161 	(pim->Decode[0] != 0 ? MI_Decode : 0) |
162 	(pim->Interpolate ? MI_Interpolate : 0) |
163 	(pim->adjust ? MI_adjust : 0) |
164 	(pim->Alpha << MI_Alpha_SHIFT) |
165 	((pim->BitsPerComponent - 1) << MI_BPC_SHIFT);
166 
167     sput_variable_uint(s, control);
168     sput_variable_uint(s, (uint)pim->Width);
169     sput_variable_uint(s, (uint)pim->Height);
170     if (control & MI_ImageMatrix)
171 	sput_matrix(s, &pim->ImageMatrix);
172     return 0;
173 }
174 
175 private int
gx_image1_mask_sget(gs_image_common_t * pic,stream * s,const gs_color_space * ignore_pcs)176 gx_image1_mask_sget(gs_image_common_t *pic, stream *s,
177 		    const gs_color_space *ignore_pcs)
178 {
179     gs_image1_t *const pim = (gs_image1_t *)pic;
180     int code;
181     uint control;
182 
183     if ((code = sget_variable_uint(s, &control)) < 0)
184 	return code;
185     gs_image_t_init_mask(pim, (control & MI_Decode) != 0);
186     if ((code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
187 	(code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
188 	)
189 	return code;
190     if (control & MI_ImageMatrix) {
191 	if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
192 	    return code;
193     } else
194 	gx_image_matrix_set_default((gs_data_image_t *)pim);
195     pim->Interpolate = (control & MI_Interpolate) != 0;
196     pim->adjust = (control & MI_adjust) != 0;
197     pim->Alpha = (control >> MI_Alpha_SHIFT) & MI_Alpha_MASK;
198     pim->BitsPerComponent = ((control >> MI_BPC_SHIFT) & MI_BPC_MASK) + 1;
199     return 0;
200 }
201 
202 private void
gx_image1_release(gs_image_common_t * pic,gs_memory_t * mem)203 gx_image1_release(gs_image_common_t *pic, gs_memory_t *mem)
204 {
205     gx_pixel_image_release((gs_pixel_image_t *)pic, mem);
206 }
207