2 |
- |
1 |
% (C) 2002 Artifex, Inc. 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 |
% $Id: gs_img.ps,v 1.3 2002/10/08 00:49:48 dan Exp $
|
|
|
17 |
% image, colorimage, and imagemask implementation
|
|
|
18 |
|
|
|
19 |
%
|
|
|
20 |
% The design of the overprint facility in Ghostscript requires that color
|
|
|
21 |
% specifications include the color space from which they were expressed,
|
|
|
22 |
% even after conversion to the device color model. Directly including this
|
|
|
23 |
% information in color specifications is usually not efficient, and is
|
|
|
24 |
% difficult to integrate into the existing code structure. The alternative
|
|
|
25 |
% approach taken is to extend a state mechanism through the device
|
|
|
26 |
% interface, and make the current color space, or more specifically,
|
|
|
27 |
% certain information about the current color space, a property of this
|
|
|
28 |
% state.
|
|
|
29 |
%
|
|
|
30 |
% For such a mechanism to work, it is necessary to identify all changes
|
|
|
31 |
% to the current color space. This is accomplished in the graphic library
|
|
|
32 |
% by funneling all changes to the current color space through the
|
|
|
33 |
% gs_setcolorspace procedure. At the PostScript interpreter level, this
|
|
|
34 |
% result is achieved by forcing color space changes through the
|
|
|
35 |
% setcolorspace operator.
|
|
|
36 |
%
|
|
|
37 |
% Aside from explicit use of setcolorspace, PostScript provides a few
|
|
|
38 |
% implicit methods of changing the current color space. The setgray,
|
|
|
39 |
% setrgbcolor, and setcmykcolor operators implicitly set the color space
|
|
|
40 |
% while explicitly setting the current color. Similarly, the colorimage
|
|
|
41 |
% operator and the traditional form of the image operator (5 operands)
|
|
|
42 |
% both temporarily modify the current color space while an image is
|
|
|
43 |
% being processed. The current file is concerned with the implementation
|
|
|
44 |
% of these two operators. In addition, the traditional form of the
|
|
|
45 |
% imagemask operator (5 operands), while it does not affect the current
|
|
|
46 |
% color space, is closely related to the image operator and thus is
|
|
|
47 |
% implemented in this file as well.
|
|
|
48 |
%
|
|
|
49 |
% In this implementation, all sampled objects are passed through one of
|
|
|
50 |
% the internal operators .image1, .imagemask1, .image1alpha, .image2,
|
|
|
51 |
% .image3, or .image4, each of which handles a specific ImageType value.
|
|
|
52 |
%
|
|
|
53 |
% The procedures in this file are responsible for constructing
|
|
|
54 |
% image dictionaries from a set of stack entries. This is, in principle,
|
|
|
55 |
% a trivial exercise. In practice it appears to be far more complex,
|
|
|
56 |
% primarily due to the need to reconstruct the original state in the
|
|
|
57 |
% event of an error. This is a particular problem for operators such as
|
|
|
58 |
% image, which include data source objects that may, directly or
|
|
|
59 |
% indirectly, be procedures. When these procedures are executed, the
|
|
|
60 |
% image operator's operands must have been cleared from the operand
|
|
|
61 |
% stack. Hence, the operand stack cannot be used to store state
|
|
|
62 |
% information. Similarly, the dictionary stack also cannot be used to
|
|
|
63 |
% store state information, as the data source procedures may depend on
|
|
|
64 |
% a particular dictionary being on the top of this stack.
|
|
|
65 |
%
|
|
|
66 |
% Adobe's PostScript implementations determine the extent to which the
|
|
|
67 |
% interpreter state is restored in the event of an error by the point at
|
|
|
68 |
% which the error is detected. Errors in the image/colorimage/imagemask
|
|
|
69 |
% operators that are detected before the data source procedures are
|
|
|
70 |
% executed restore the state in effect before the image was processed.
|
|
|
71 |
% Those that are detected as part of running the data source procedures
|
|
|
72 |
% only attempt to restore the state to that in effect at the start of
|
|
|
73 |
% the operator that failed (or at the conclusion of the data source
|
|
|
74 |
% procedure, if this procedure failed to push a string).
|
|
|
75 |
%
|
|
|
76 |
% The implementation given here follows the Adobe convention. The
|
|
|
77 |
% mechanism used is as follows:
|
|
|
78 |
%
|
|
|
79 |
% 1. Check that the stack has a sufficient number of operands, and
|
|
|
80 |
% that enough of them have the proper type to allow construction
|
|
|
81 |
% of the image dictionary. Any errors at this point are handled
|
|
|
82 |
% in the conventional manner.
|
|
|
83 |
%
|
|
|
84 |
% 2. Build the image dictionary, in the process clearing the image/
|
|
|
85 |
% colorimage/imagemask operands from the stack. No errors can
|
|
|
86 |
% occur during this process.
|
|
|
87 |
%
|
|
|
88 |
% (Special precautions could be taken during this step to handle
|
|
|
89 |
% a limitcheck or VMError during the building of the image
|
|
|
90 |
% dictionary, but this essentially never occurs in practice and, if
|
|
|
91 |
% it did, is very unlikely to leave a useable state. Hence, we don't
|
|
|
92 |
% bother with this possibility.)
|
|
|
93 |
%
|
|
|
94 |
% 3. The .image operator is executed in a stopped context. If it
|
|
|
95 |
% returns abnormally, a check is made to see if the uppermost
|
|
|
96 |
% operand on the stack is a color image dictionary. If so, the
|
|
|
97 |
% original stack is created anew using this dictionary. (Because
|
|
|
98 |
% the image operand works via colorimage, some additional special
|
|
|
99 |
% handling is required in this case.)
|
|
|
100 |
%
|
|
|
101 |
|
|
|
102 |
|
|
|
103 |
%
|
|
|
104 |
% Create a dictionary of operators for specific image and image mask types.
|
|
|
105 |
% Each of these will always handle ImageType 1. Additional types are added
|
|
|
106 |
% as they are supported in specific interpreter levels or versions.
|
|
|
107 |
%
|
|
|
108 |
% These dictionaries are in systemdict for historical reasons.
|
|
|
109 |
%
|
|
|
110 |
.currentglobal true .setglobal
|
|
|
111 |
systemdict begin
|
|
|
112 |
/.imagetypes
|
|
|
113 |
5 dict
|
|
|
114 |
dup 1 /.image1 load put
|
|
|
115 |
def
|
|
|
116 |
/.imagemasktypes
|
|
|
117 |
5 dict
|
|
|
118 |
dup 1 /.imagemask1 load put
|
|
|
119 |
def
|
|
|
120 |
end
|
|
|
121 |
.setglobal
|
|
|
122 |
|
|
|
123 |
%
|
|
|
124 |
% Build a dictionary of utility procedures and constants for use in
|
|
|
125 |
% impelementing the image operators. This dictionary is in global VM but
|
|
|
126 |
% is maintained (during initialization) in userdict. It should be pushed
|
|
|
127 |
% onto the dictionary stack when constructing image-related procedures
|
|
|
128 |
% and pseudo-operators.
|
|
|
129 |
%
|
|
|
130 |
% This dictionary is removed from userdict when initialization is
|
|
|
131 |
% completed.
|
|
|
132 |
%
|
|
|
133 |
.currentglobal true .setglobal
|
|
|
134 |
userdict /img_utils_dict 30 dict put
|
|
|
135 |
img_utils_dict begin
|
|
|
136 |
|
|
|
137 |
|
|
|
138 |
%
|
|
|
139 |
% Some useful local data structures:
|
|
|
140 |
%
|
|
|
141 |
% img_csary maps the number of components in an image to the implied
|
|
|
142 |
% color space.
|
|
|
143 |
%
|
|
|
144 |
% img_decary is a prototype Decode array; subintervals of this array
|
|
|
145 |
% may be used for fewer than 4 color components.
|
|
|
146 |
%
|
|
|
147 |
% img_params_ary is a list of the parameters to be built in the image
|
|
|
148 |
% dictionary for a colorimage invocation. ImageType is given a
|
|
|
149 |
% fixed value; the other parameters are in stack order (IMG_NComps
|
|
|
150 |
% is the number of components).
|
|
|
151 |
%
|
|
|
152 |
% img_mask_params_ary is the equivalent of img_params_ary for imagemask
|
|
|
153 |
% invocations. Polarity is a proxy for Decode, and is replaced
|
|
|
154 |
% by the Decode key in the image dictionary.
|
|
|
155 |
%
|
|
|
156 |
% img_mask_check_ary is the set of parameters that must be present in
|
|
|
157 |
% an image dictionary generated by an imagemask invocation. This
|
|
|
158 |
% differs from img_mask_params_ary in that Decode replaces Polarity.
|
|
|
159 |
%
|
|
|
160 |
/img_csary [ null /DeviceGray null /DeviceRGB /DeviceCMYK ] def
|
|
|
161 |
/img_decary [ 0 1 0 1 0 1 0 1 ] def
|
|
|
162 |
|
|
|
163 |
/img_params_ary
|
|
|
164 |
[
|
|
|
165 |
/ImageType /IMG_NComps /MultipleDataSources /DataSource
|
|
|
166 |
/ImageMatrix /BitsPerComponent /Height /Width /Decode
|
|
|
167 |
]
|
|
|
168 |
def
|
|
|
169 |
/img_check_ary //img_params_ary def
|
|
|
170 |
/img_unbuild_ary
|
|
|
171 |
//img_params_ary 1 1 index length 2 sub getinterval
|
|
|
172 |
def
|
|
|
173 |
|
|
|
174 |
/img_mask_params_ary
|
|
|
175 |
[ /ImageType /DataSource /ImageMatrix /Polarity /Height /Width ]
|
|
|
176 |
def
|
|
|
177 |
/img_mask_check_ary
|
|
|
178 |
[
|
|
|
179 |
/ImageType /BitsPerComponent
|
|
|
180 |
/DataSource /ImageMatrix /Decode /Height /Width
|
|
|
181 |
]
|
|
|
182 |
def
|
|
|
183 |
/img_mask_unbuild_ary
|
|
|
184 |
//img_mask_check_ary 2 1 index length 2 sub getinterval
|
|
|
185 |
def
|
|
|
186 |
|
|
|
187 |
|
|
|
188 |
%
|
|
|
189 |
% <?any?> <array> img_check_keys <?any?> <bool>
|
|
|
190 |
%
|
|
|
191 |
% Verify that:
|
|
|
192 |
% that there are at least two entries on the stack, and
|
|
|
193 |
% the second (lower) entry is a dictionary, and
|
|
|
194 |
% that dictionary contains all of the keys in the array
|
|
|
195 |
%
|
|
|
196 |
% If any one of these conditions does not hold, pop the array and push
|
|
|
197 |
% false; otherwise pop the array and push true. This utility is used by
|
|
|
198 |
% the colorimage and imagematrix procedures to determine if .image left
|
|
|
199 |
% the image dictionary on the stack after an abnormal return.
|
|
|
200 |
%
|
|
|
201 |
/img_check_keys
|
|
|
202 |
{
|
|
|
203 |
count 2 ge
|
|
|
204 |
{
|
|
|
205 |
1 index type /dicttype eq
|
|
|
206 |
{
|
|
|
207 |
true exch
|
|
|
208 |
{
|
|
|
209 |
2 index exch known and
|
|
|
210 |
dup not
|
|
|
211 |
{ exit }
|
|
|
212 |
if
|
|
|
213 |
}
|
|
|
214 |
forall
|
|
|
215 |
}
|
|
|
216 |
{ pop //false }
|
|
|
217 |
ifelse
|
|
|
218 |
}
|
|
|
219 |
{ pop //false }
|
|
|
220 |
ifelse
|
|
|
221 |
}
|
|
|
222 |
.bind def
|
|
|
223 |
|
|
|
224 |
%
|
|
|
225 |
% Procedures to convert a set of stack entries to a dictionary. There is
|
|
|
226 |
% a procedure associated with each key, though most keys use the same
|
|
|
227 |
% procedure. The dictionary to be built is at the top of the dictionary
|
|
|
228 |
% stack. Stack handling for the procedures is:
|
|
|
229 |
%
|
|
|
230 |
% <?val0?> ... <?val(n - 1)?> <key> proc -
|
|
|
231 |
%
|
|
|
232 |
% Parameters are handle in inverse-stack order, so inter-parameter
|
|
|
233 |
% dependencies that on the stack can generally be used here.
|
|
|
234 |
%
|
|
|
235 |
/img_params_dict
|
|
|
236 |
mark
|
|
|
237 |
/ImageType { 1 def } .bind
|
|
|
238 |
|
|
|
239 |
/IMG_NComps { exch def } .bind % number of components
|
|
|
240 |
/MultipleDataSources 1 index
|
|
|
241 |
/Width 1 index
|
|
|
242 |
/Height 1 index
|
|
|
243 |
/ImageMatrix 1 index
|
|
|
244 |
/BitsPerComponent 1 index
|
|
|
245 |
/DataSource 1 index
|
|
|
246 |
|
|
|
247 |
% Polarity is a proxy for Decode; it never appears in a dictionary
|
|
|
248 |
/Polarity
|
|
|
249 |
{
|
|
|
250 |
pop
|
|
|
251 |
{ { 1 0 } }
|
|
|
252 |
{ { 0 1 } }
|
|
|
253 |
ifelse
|
|
|
254 |
/Decode exch cvlit def
|
|
|
255 |
}
|
|
|
256 |
.bind
|
|
|
257 |
|
|
|
258 |
% the definition of Decode is based on the number of components
|
|
|
259 |
/Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind
|
|
|
260 |
.dicttomark
|
|
|
261 |
def
|
|
|
262 |
|
|
|
263 |
%
|
|
|
264 |
% <oper_0> ... <oper_n> <array> img_build_dict <dict>
|
|
|
265 |
%
|
|
|
266 |
% Build a dictionary. This will always be done in local VM. The array is
|
|
|
267 |
% a list of the keys to be associated with operands on the stack, in
|
|
|
268 |
% inverse stack order (topmost element first). The caller should verify
|
|
|
269 |
% that the dictionary can be built successfully (except for a possible
|
|
|
270 |
% VMerror) before calling this routine.
|
|
|
271 |
%
|
|
|
272 |
/img_build_dict
|
|
|
273 |
{
|
|
|
274 |
% build the dictionary in local VM; all for 2 extra entries
|
|
|
275 |
.currentglobal false .setglobal
|
|
|
276 |
1 index length 2 add dict
|
|
|
277 |
exch .setglobal
|
|
|
278 |
begin
|
|
|
279 |
|
|
|
280 |
% process all keys in the array
|
|
|
281 |
{ //img_params_dict 1 index get exec }
|
|
|
282 |
forall
|
|
|
283 |
|
|
|
284 |
% if BitsPerComponent is not yet defined, define it to be 1
|
|
|
285 |
currentdict /BitsPerComponent known not
|
|
|
286 |
{ /BitsPerComponent 1 def }
|
|
|
287 |
if
|
|
|
288 |
|
|
|
289 |
currentdict end
|
|
|
290 |
}
|
|
|
291 |
.bind def
|
|
|
292 |
|
|
|
293 |
%
|
|
|
294 |
% <dict> <array> img_unbuild_dict <oper_0> ... <oper_n>
|
|
|
295 |
%
|
|
|
296 |
% "Unbuild" a dictionary: spread the contents the dictionary back onto the
|
|
|
297 |
% stack, in the inverse of the order indicated in the array (inverse is
|
|
|
298 |
% used as this order is more convenient for img_build_dict, which is
|
|
|
299 |
% expected to be invoked far more frequently).
|
|
|
300 |
%
|
|
|
301 |
/img_unbuild_dict
|
|
|
302 |
{
|
|
|
303 |
exch begin
|
|
|
304 |
dup length 1 sub -1 0
|
|
|
305 |
{ 1 index exch get load exch }
|
|
|
306 |
for
|
|
|
307 |
pop
|
|
|
308 |
end
|
|
|
309 |
}
|
|
|
310 |
.bind def
|
|
|
311 |
|
|
|
312 |
|
|
|
313 |
%
|
|
|
314 |
% <width> <height> <bits/component> <matrix> <dsrc0> ...
|
|
|
315 |
% <multi> <ncomp> <has_alpha>
|
|
|
316 |
% img_build_image_dict
|
|
|
317 |
% <dict> <has_alpha>
|
|
|
318 |
%
|
|
|
319 |
% Build the dictionary corresponding to a colorimage operand stack. This
|
|
|
320 |
% routine will check just enough of the stack to verify that the
|
|
|
321 |
% dictionary can be built, and will generate the appropriate error if this
|
|
|
322 |
% is not the case.
|
|
|
323 |
%
|
|
|
324 |
% The <has_alpha> boolean is used to support the Next alphaimage extension.
|
|
|
325 |
%
|
|
|
326 |
% At the first level, errors in this procedure are reported as colorimage
|
|
|
327 |
% errors. The error actually reported will usually be determined by the
|
|
|
328 |
% pseudo-operator which invokes this routine.
|
|
|
329 |
%
|
|
|
330 |
/img_build_image_dict
|
|
|
331 |
{
|
|
|
332 |
% Veify that at least 8 operands are available, and that the top three
|
|
|
333 |
% operands have the expected types
|
|
|
334 |
count 8 lt
|
|
|
335 |
{ /.colorimage cvx /stackunderflow signalerror }
|
|
|
336 |
if
|
|
|
337 |
3 copy
|
|
|
338 |
type /booleantype ne exch
|
|
|
339 |
type /integertype ne or exch
|
|
|
340 |
type /booleantype ne or
|
|
|
341 |
{ /.colorimage cvx /typecheck signalerror }
|
|
|
342 |
if
|
|
|
343 |
|
|
|
344 |
% verify that the number of components is 1, 3, or 4
|
|
|
345 |
1 index 1 lt 2 index 2 eq or 2 index 4 gt or
|
|
|
346 |
{ /.colorimage cvx /rangecheck signalerror }
|
|
|
347 |
if
|
|
|
348 |
|
|
|
349 |
% Verify that the required number of operands are present if multiple
|
|
|
350 |
% data sources are being used. If this test is successful, convert
|
|
|
351 |
% the data sources to an array (in local VM).
|
|
|
352 |
2 index
|
|
|
353 |
{
|
|
|
354 |
% if an alpha component is present, this adds one more component
|
|
|
355 |
2 copy
|
|
|
356 |
{ 1 add }
|
|
|
357 |
if
|
|
|
358 |
dup count 9 sub gt
|
|
|
359 |
{ /.colorimage cvx /stackunderflow signalerror }
|
|
|
360 |
if
|
|
|
361 |
|
|
|
362 |
% build the DataSource array in local VM
|
|
|
363 |
dup .currentglobal false .setglobal exch array exch .setglobal
|
|
|
364 |
|
|
|
365 |
% stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
|
|
|
366 |
5 1 roll 4 add 3 roll astore 4 1 roll
|
|
|
367 |
}
|
|
|
368 |
if
|
|
|
369 |
|
|
|
370 |
% the image dictionary can be built; do so
|
|
|
371 |
% stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
|
|
|
372 |
8 1 roll //img_params_ary //img_build_dict exec exch
|
|
|
373 |
}
|
|
|
374 |
.bind def
|
|
|
375 |
|
|
|
376 |
%
|
|
|
377 |
% <?dict?>
|
|
|
378 |
% img_unbuild_image_dict
|
|
|
379 |
% <width> <height> <bits/component> <matrix> <dsrc0> ...
|
|
|
380 |
% <multi> <ncomp>
|
|
|
381 |
%
|
|
|
382 |
% If the top entry of the stack is a dictionary that has the keys required
|
|
|
383 |
% by a colorimage dictionary, unpack that dictionary onto the stack.
|
|
|
384 |
% Otherwise just leave things as they are. Note that the <has_alpha>
|
|
|
385 |
% parameter is not pushd onto the stack.
|
|
|
386 |
%
|
|
|
387 |
/img_unbuild_image_dict
|
|
|
388 |
{
|
|
|
389 |
//img_check_ary //img_check_keys exec
|
|
|
390 |
{
|
|
|
391 |
//img_unbuild_ary //img_unbuild_dict exec
|
|
|
392 |
1 index type /booleantype eq
|
|
|
393 |
{
|
|
|
394 |
1 index
|
|
|
395 |
{ 3 1 roll aload length 2 add -2 roll }
|
|
|
396 |
if
|
|
|
397 |
}
|
|
|
398 |
if
|
|
|
399 |
}
|
|
|
400 |
if
|
|
|
401 |
}
|
|
|
402 |
.bind def
|
|
|
403 |
|
|
|
404 |
|
|
|
405 |
%
|
|
|
406 |
% <width> <height> <polarity> <matrix> <dsrc>
|
|
|
407 |
% img_unbuild_imagemask_dict
|
|
|
408 |
% <dict>
|
|
|
409 |
%
|
|
|
410 |
% Build the dictionary corresponding to an imagemask stack. This routine
|
|
|
411 |
% will verify that the appropriate number of operands are on the stack,
|
|
|
412 |
% and that polarity is a boolean. This is all that is necessary to build
|
|
|
413 |
% the dictionary.
|
|
|
414 |
%
|
|
|
415 |
/img_build_imagemask_dict
|
|
|
416 |
{
|
|
|
417 |
% check for proper number of operands
|
|
|
418 |
count 5 lt
|
|
|
419 |
{ /imagemask load /stackunderflow signalerror }
|
|
|
420 |
if
|
|
|
421 |
|
|
|
422 |
% verify that polarity is a boolean
|
|
|
423 |
2 index type /booleantype ne
|
|
|
424 |
{ /imagemask load /typecheck signalerror }
|
|
|
425 |
if
|
|
|
426 |
|
|
|
427 |
% the imagemask dictionary can be built; do so
|
|
|
428 |
//img_mask_params_ary //img_build_dict exec
|
|
|
429 |
}
|
|
|
430 |
.bind def
|
|
|
431 |
|
|
|
432 |
%
|
|
|
433 |
% <?dict?>
|
|
|
434 |
% img_unbuild_imagemask_dict
|
|
|
435 |
% <width> <height> <polarity> <matrix> <dsrc>
|
|
|
436 |
%
|
|
|
437 |
% If the top entry of the stack is a dictionary that has the keys rquired
|
|
|
438 |
% by an imagemask dictionary, unpack that dictionary onto the stack.
|
|
|
439 |
% Otherwise just leave things as they are.
|
|
|
440 |
%
|
|
|
441 |
/img_unbuild_imagemask_dict
|
|
|
442 |
{
|
|
|
443 |
//img_mask_check_ary //img_check_keys exec
|
|
|
444 |
{
|
|
|
445 |
//img_mask_unbuild_ary //img_unbuild_dict exec
|
|
|
446 |
3 -1 roll
|
|
|
447 |
dup type dup /arraytype eq exch /packedarraytype eq or
|
|
|
448 |
1 index rcheck and
|
|
|
449 |
{ 0 get 1 eq }
|
|
|
450 |
if
|
|
|
451 |
3 1 roll
|
|
|
452 |
}
|
|
|
453 |
if
|
|
|
454 |
}
|
|
|
455 |
.bind def
|
|
|
456 |
|
|
|
457 |
|
|
|
458 |
%
|
|
|
459 |
% <width> <height> <bits/component> <matrix> <dsrc_0> ...
|
|
|
460 |
% <multi> <ncomp> <has_alpha>
|
|
|
461 |
% .colorimage
|
|
|
462 |
% -
|
|
|
463 |
%
|
|
|
464 |
% Convert the image/colorimage operator from their traditional form to
|
|
|
465 |
% the dictionary form. The <has_alpha> operand is used ot support the
|
|
|
466 |
% Next alphaimage extension.
|
|
|
467 |
%
|
|
|
468 |
% Error handling for these operators is a bit complex, due to the stack
|
|
|
469 |
% handling required of operators that potentially invoke procedures.
|
|
|
470 |
% This problem is discussed in the comment above. The facts relevant to
|
|
|
471 |
% this particular implementation are:
|
|
|
472 |
%
|
|
|
473 |
% 1. The .image1 (or .alphaimage) operator is executed in a stopped
|
|
|
474 |
% context, so that we can undo the gsave context in the event of
|
|
|
475 |
% an error.
|
|
|
476 |
%
|
|
|
477 |
% 2. In the event of an error, the stack is examined to see if the
|
|
|
478 |
% dictionary passed to .image1 (.alphaimage) is still present.
|
|
|
479 |
% If so, this dictionary is "unpacked" onto the stack to re-
|
|
|
480 |
% create the original stack. The <has_alpha> parameter is not
|
|
|
481 |
% pushed onto the stack, as it is not required for any of the
|
|
|
482 |
% pseudo-operators than invoke this procedure.
|
|
|
483 |
%
|
|
|
484 |
% 3. The use of pseudo-operators in this case may yield incorrect
|
|
|
485 |
% results for late-detected errors, as the stack depth will be
|
|
|
486 |
% restored (even though the stack is not). This is, however, no
|
|
|
487 |
% worse than the prior (level >= 2) code, so it should cause no
|
|
|
488 |
% new problems.
|
|
|
489 |
%
|
|
|
490 |
/.colorimage
|
|
|
491 |
{
|
|
|
492 |
% build the image dictionary
|
|
|
493 |
//img_build_image_dict exec
|
|
|
494 |
|
|
|
495 |
% execute .image1 in a stopped context
|
|
|
496 |
{
|
|
|
497 |
gsave
|
|
|
498 |
|
|
|
499 |
//img_csary 2 index /IMG_NComps get get setcolorspace
|
|
|
500 |
{ .alphaimage }
|
|
|
501 |
{ .image1 }
|
|
|
502 |
ifelse
|
|
|
503 |
}
|
|
|
504 |
stopped
|
|
|
505 |
grestore
|
|
|
506 |
{
|
|
|
507 |
//img_unbuild_image_dict exec
|
|
|
508 |
/.colorimage cvx $error /errorname get
|
|
|
509 |
signalerror
|
|
|
510 |
}
|
|
|
511 |
if
|
|
|
512 |
}
|
|
|
513 |
.bind def
|
|
|
514 |
|
|
|
515 |
|
|
|
516 |
%
|
|
|
517 |
% <width> <height> <bits/component> <matrix> <dsrc_0> ...
|
|
|
518 |
% <multi> <ncomp>
|
|
|
519 |
% colorimage
|
|
|
520 |
% -
|
|
|
521 |
%
|
|
|
522 |
% Build the colorimage pseudo-operator only if setcolorscreen is visible.
|
|
|
523 |
%
|
|
|
524 |
systemdict /setcolorscreen .knownget
|
|
|
525 |
{
|
|
|
526 |
type /operatortype eq
|
|
|
527 |
{
|
|
|
528 |
/colorimage
|
|
|
529 |
{
|
|
|
530 |
//false
|
|
|
531 |
//.colorimage
|
|
|
532 |
stopped
|
|
|
533 |
{ /colorimage load $error /errorname get signalerror }
|
|
|
534 |
if
|
|
|
535 |
}
|
|
|
536 |
.bind systemdict begin odef end
|
|
|
537 |
}
|
|
|
538 |
if
|
|
|
539 |
}
|
|
|
540 |
if
|
|
|
541 |
|
|
|
542 |
|
|
|
543 |
%
|
|
|
544 |
% width height bits_per_component matrix data_src image -
|
|
|
545 |
%
|
|
|
546 |
% <dict> image -
|
|
|
547 |
%
|
|
|
548 |
% Some special handling is required for ImageType 2 (Display PostScript
|
|
|
549 |
% pixmap images) so as to set the appropriate color space as the current
|
|
|
550 |
% color space.
|
|
|
551 |
%
|
|
|
552 |
/image
|
|
|
553 |
{
|
|
|
554 |
dup type /dicttype eq languagelevel 2 ge and
|
|
|
555 |
{
|
|
|
556 |
dup /ImageType get dup 2 eq
|
|
|
557 |
{
|
|
|
558 |
% verify the ImageType 2 is supported
|
|
|
559 |
//.imagetypes exch known
|
|
|
560 |
{
|
|
|
561 |
%
|
|
|
562 |
% Set either DevicePixel or DeviceRGB as the current
|
|
|
563 |
% color space. DevicePixel is used if the image data is
|
|
|
564 |
% to be copied directly, with only a geometric
|
|
|
565 |
% transformation (PixelCopy true). The use of DeviceRGB
|
|
|
566 |
% in the alternate case is not, in general, correct, and
|
|
|
567 |
% reflects a current implementation limitation. Ideally,
|
|
|
568 |
% an intermediate color space should be used only if
|
|
|
569 |
% the source and destination color models vary; otherwise
|
|
|
570 |
% the native color space corresponding to the color model
|
|
|
571 |
% should be used.
|
|
|
572 |
%
|
|
|
573 |
% The mechanism to determine depth for the DevicePixel
|
|
|
574 |
% color space when BitsPerPixel is not available is
|
|
|
575 |
% somewhat of a hack.
|
|
|
576 |
%
|
|
|
577 |
gsave
|
|
|
578 |
|
|
|
579 |
dup /PixelCopy .knownget dup
|
|
|
580 |
{ pop }
|
|
|
581 |
if
|
|
|
582 |
{
|
|
|
583 |
[
|
|
|
584 |
/DevicePixel
|
|
|
585 |
currentpagedevice dup /BitsPerPixel .knownget
|
|
|
586 |
{ exch pop }
|
|
|
587 |
{
|
|
|
588 |
/GrayValues .knownget not
|
|
|
589 |
{ 2 } % try a guess
|
|
|
590 |
if
|
|
|
591 |
ln 2 ln div round cvi
|
|
|
592 |
}
|
|
|
593 |
ifelse
|
|
|
594 |
]
|
|
|
595 |
}
|
|
|
596 |
{ /DeviceRGB }
|
|
|
597 |
ifelse
|
|
|
598 |
setcolorspace
|
|
|
599 |
//.imagetypes 2 get
|
|
|
600 |
stopped
|
|
|
601 |
grestore
|
|
|
602 |
{ /image load $error /errorname get signalerror }
|
|
|
603 |
if
|
|
|
604 |
}
|
|
|
605 |
{ /image load /undefined signalerror }
|
|
|
606 |
ifelse
|
|
|
607 |
}
|
|
|
608 |
{
|
|
|
609 |
gsave
|
|
|
610 |
|
|
|
611 |
//.imagetypes exch get
|
|
|
612 |
stopped
|
|
|
613 |
grestore
|
|
|
614 |
{ /image load $error /errorname get signalerror }
|
|
|
615 |
if
|
|
|
616 |
}
|
|
|
617 |
ifelse
|
|
|
618 |
}
|
|
|
619 |
{
|
|
|
620 |
//false 1 //false
|
|
|
621 |
//.colorimage
|
|
|
622 |
stopped
|
|
|
623 |
{ /image load $error /errorname get signalerror }
|
|
|
624 |
if
|
|
|
625 |
}
|
|
|
626 |
ifelse
|
|
|
627 |
}
|
|
|
628 |
.bind systemdict begin odef end
|
|
|
629 |
|
|
|
630 |
|
|
|
631 |
%
|
|
|
632 |
% width height polarity matrix datasrc imagemask -
|
|
|
633 |
%
|
|
|
634 |
% See the comment preceding the definition of .colorimage for information
|
|
|
635 |
% as to the handling of error conditions.
|
|
|
636 |
%
|
|
|
637 |
/imagemask
|
|
|
638 |
{
|
|
|
639 |
dup type /dicttype eq languagelevel 2 ge and
|
|
|
640 |
{ dup /ImageType get //.imagemasktypes exch get exec }
|
|
|
641 |
{
|
|
|
642 |
//img_build_imagemask_dict exec
|
|
|
643 |
{ .imagemask1 }
|
|
|
644 |
stopped
|
|
|
645 |
{
|
|
|
646 |
//img_unbuild_imagemask_dict exec
|
|
|
647 |
/imagemask load $error /errorname get signalerror
|
|
|
648 |
}
|
|
|
649 |
if
|
|
|
650 |
}
|
|
|
651 |
ifelse
|
|
|
652 |
}
|
|
|
653 |
.bind systemdict begin odef end
|
|
|
654 |
|
|
|
655 |
end % img_utils_dict
|
|
|
656 |
.setglobal % restore VM mode
|