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