386BSD 0.1 development
[unix-history] / usr / othersrc / public / ghostscript-2.4.1 / zpaint.c
CommitLineData
5ae70ead
WJ
1/* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved.
2 Distributed by Free Software Foundation, Inc.
3
4This file is part of Ghostscript.
5
6Ghostscript is distributed in the hope that it will be useful, but
7WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
8to anyone for the consequences of using it or for whether it serves any
9particular purpose or works at all, unless he says so in writing. Refer
10to the Ghostscript General Public License for full details.
11
12Everyone is granted permission to copy, modify and redistribute
13Ghostscript, but only under the conditions described in the Ghostscript
14General Public License. A copy of this license is supposed to have been
15given to you along with Ghostscript so you can know your rights and
16responsibilities. It should be in a file named COPYING. Among other
17things, the copyright notice and this notice must be preserved on all
18copies. */
19
20/* zpaint.c */
21/* Painting operators for Ghostscript */
22#include "ghost.h"
23#include "errors.h"
24#include "oper.h"
25#include "alloc.h"
26#include "estack.h" /* for image[mask] */
27#include "store.h"
28#include "gsmatrix.h"
29#include "gspaint.h"
30#include "state.h"
31
32/* Forward references */
33private int image_opaque_setup(P2(os_ptr, int));
34private int image_setup(P3(os_ptr, int, int));
35private int image_continue(P1(os_ptr));
36private int i_image_continue;
37
38/* erasepage */
39int
40zerasepage(register os_ptr op)
41{ return gs_erasepage(igs);
42}
43
44/* fill */
45int
46zfill(register os_ptr op)
47{ return gs_fill(igs);
48}
49
50/* eofill */
51int
52zeofill(register os_ptr op)
53{ return gs_eofill(igs);
54}
55
56/* stroke */
57int
58zstroke(register os_ptr op)
59{ return gs_stroke(igs);
60}
61
62/* colorimage */
63int
64zcolorimage(register os_ptr op)
65{ int spp; /* samples per pixel */
66 int npop = 7;
67 os_ptr procp = op - 2;
68 int code;
69 check_type(*op, t_integer); /* ncolors */
70 check_type(op[-1], t_boolean); /* multiproc */
71 if ( (ulong)(op->value.intval) > 4 ) return e_rangecheck;
72 switch ( (spp = (int)(op->value.intval)) )
73 {
74 case 1:
75 break;
76 case 3: case 4:
77 if ( op[-1].value.index ) /* planar format */
78 npop += spp - 1,
79 procp -= spp - 1,
80 spp = - spp;
81 break;
82 default:
83 return e_rangecheck;
84 }
85 code = image_opaque_setup(procp, spp);
86 if ( code >= 0 ) pop(npop);
87 return code;
88}
89
90/* image */
91int
92zimage(register os_ptr op)
93{ int code = image_opaque_setup(op, 1);
94 if ( code >= 0 ) pop(5);
95 return code;
96}
97
98/* imagemask */
99int
100zimagemask(register os_ptr op)
101{ int code;
102 check_type(op[-2], t_boolean);
103 code = image_setup(op, !op[-2].value.index, 0);
104 if ( code >= 0 ) pop(5);
105 return code;
106}
107
108/* Common setup for image and colorimage. */
109private int
110image_opaque_setup(register os_ptr op, int spp)
111{ check_type(op[-2], t_integer); /* bits/sample */
112 if ( (ulong)(op[-2].value.intval) > 8 ) return e_rangecheck;
113 return image_setup(op, (int)op[-2].value.intval, spp);
114}
115
116/* Common setup for [color]image and imagemask. */
117/* spp is 0 for imagemask, 1 for image, and [-]3 or [-]4 for colorimage. */
118private int
119image_setup(register os_ptr op, int param3 /* bits/sample or invert */, int spp)
120{ int code;
121 gs_image_enum *penum;
122 gs_matrix mat;
123 int px;
124 int pmax = (spp < 0 ? ~ spp : 0);
125 /* We push on the estack: */
126 /* Control mark, 4 procs, last plane index, */
127 /* enumeration structure (as bytes). */
128#define inumpush 7
129 check_estack(inumpush + 2); /* stuff above, + continuation + proc */
130 check_type(op[-4], t_integer); /* width */
131 check_type(op[-3], t_integer); /* height */
132 /* Note that the "procedures" might not be procedures, */
133 /* but might be literal strings. */
134 for ( px = 0; px <= pmax; px++ )
135 if ( !r_has_type(op + px, t_string) )
136 { check_proc(op[px]); /* proc(s) */
137 }
138 if ( op[-4].value.intval <= 0 || op[-3].value.intval < 0 )
139 return e_undefinedresult;
140 if ( op[-3].value.intval == 0 ) return 0; /* empty image */
141 if ( (code = read_matrix(op - 1, &mat)) < 0 )
142 return code;
143 if ( (penum = (gs_image_enum *)alloc(1, gs_image_enum_sizeof, "image_setup")) == 0 )
144 return e_VMerror;
145 code = (spp == 0 ?
146 gs_imagemask_init(penum, igs, (int)op[-4].value.intval,
147 (int)op[-3].value.intval, param3, &mat, 1) :
148 gs_image_init(penum, igs, (int)op[-4].value.intval,
149 (int)op[-3].value.intval, param3, spp, &mat) );
150 if ( code < 0 ) return code;
151 mark_estack(es_other);
152 ++esp;
153 for ( px = 0; px < 4; esp++, px++ )
154 if ( px <= pmax )
155 *esp = op[px];
156 else
157 make_null(esp);
158 make_int(esp, 0); /* current plane */
159 r_set_size(esp, pmax);
160 ++esp;
161 make_tasv(esp, t_string, 0, gs_image_enum_sizeof, bytes, (byte *)penum);
162 push_op_estack(image_continue, i_image_continue);
163 *++esp = *op; /* run the (first) procedure */
164 return o_push_estack;
165}
166/* Continuation procedure. Hand the string to the enumerator. */
167private int
168image_continue(register os_ptr op)
169{ gs_image_enum *penum = (gs_image_enum *)esp->value.bytes;
170 int code;
171 if ( !r_has_type(op, t_string) )
172 { /* Procedure didn't return a string. Quit. */
173 esp -= inumpush;
174 alloc_free((char *)penum, 1, gs_image_enum_sizeof,
175 "image_continue(quit)");
176 return e_typecheck;
177 }
178 code = gs_image_next(penum, op->value.bytes, r_size(op));
179 if ( r_size(op) == 0 || code != 0 ) /* stop now */
180 { esp -= inumpush;
181 alloc_free((char *)penum, 1, gs_image_enum_sizeof,
182 "image_continue(finished)");
183 if ( code < 0 ) return code;
184 code = o_pop_estack;
185 }
186 else
187 { int px = (int)++(esp[-1].value.intval);
188 es_ptr pproc = esp - 5;
189 if ( px > r_size(esp - 1) )
190 esp[-1].value.intval = px = 0;
191 push_op_estack(image_continue, i_image_continue);
192 *++esp = pproc[px];
193 code = o_push_estack;
194 }
195 pop(1);
196 return code;
197}
198
199/* ------ Initialization procedure ------ */
200
201op_def zpaint_op_defs[] = {
202 {"0eofill", zeofill},
203 {"0erasepage", zerasepage},
204 {"0fill", zfill},
205 {"7colorimage", zcolorimage},
206 {"5image", zimage},
207 {"5imagemask", zimagemask},
208 {"0stroke", zstroke},
209 /* Internal operators */
210 {"0%image_continue", image_continue, &i_image_continue},
211 op_def_end(0)
212};