1
% (C) 2002 Artifex, Inc. All rights reserved.
3
% This software is provided AS-IS with no warranty, either express or
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.
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.
16
% $Id: gs_img.ps 8854 2008-07-21 18:55:31Z alexcher $
17
% image, colorimage, and imagemask implementation
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
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.
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.
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.
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.
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).
76
% The implementation given here follows the Adobe convention. The
77
% mechanism used is as follows:
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.
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.
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.)
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.)
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.
108
% These dictionaries are in systemdict for historical reasons.
110
.currentglobal true .setglobal
114
dup 1 /.image1 load put
118
dup 1 /.imagemask1 load put
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.
130
% This dictionary is removed from userdict when initialization is
133
.currentglobal true .setglobal
134
userdict /img_utils_dict 30 dict put
139
% Some useful local data structures:
141
% img_csary maps the number of components in an image to the implied
144
% img_decary is a prototype Decode array; subintervals of this array
145
% may be used for fewer than 4 color components.
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).
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.
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.
160
/img_csary [ null /DeviceGray null /DeviceRGB /DeviceCMYK ] def
161
/img_decary [ 0 1 0 1 0 1 0 1 ] def
165
/ImageType /IMG_NComps /MultipleDataSources /DataSource
166
/ImageMatrix /BitsPerComponent /Height /Width /Decode
169
/img_check_ary //img_params_ary def
171
//img_params_ary 1 1 index length 2 sub getinterval
175
[ /ImageType /DataSource /ImageMatrix /Polarity /Height /Width ]
179
/ImageType /BitsPerComponent
180
/DataSource /ImageMatrix /Decode /Height /Width
183
/img_mask_unbuild_ary
184
//img_mask_check_ary 2 1 index length 2 sub getinterval
189
% <?any?> <array> img_check_keys <?any?> <bool>
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
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.
205
1 index type /dicttype eq
209
2 index exch known and
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:
230
% <?val0?> ... <?val(n - 1)?> <key> proc -
232
% Parameters are handle in inverse-stack order, so inter-parameter
233
% dependencies that on the stack can generally be used here.
237
/ImageType { 1 def } .bind
239
/IMG_NComps { exch def } .bind % number of components
240
/MultipleDataSources 1 index
244
/BitsPerComponent 1 index
247
% Polarity is a proxy for Decode; it never appears in a dictionary
254
/Decode exch cvlit def
258
% the definition of Decode is based on the number of components
259
/Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind
264
% <oper_0> ... <oper_n> <array> img_build_dict <dict>
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.
274
% build the dictionary in local VM; all for 2 extra entries
275
.currentglobal false .setglobal
276
1 index length 2 add dict
280
% process all keys in the array
281
{ //img_params_dict 1 index get exec }
284
% if BitsPerComponent is not yet defined, define it to be 1
285
currentdict /BitsPerComponent known not
286
{ /BitsPerComponent 1 def }
294
% <dict> <array> img_unbuild_dict <oper_0> ... <oper_n>
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).
304
dup length 1 sub -1 0
305
{ 1 index exch get load exch }
313
% Check the image types that can be used as data sources
316
/good_image_types mark
317
/filetype { pop //true } .bind
320
/packedarraytype //xcheck
321
.dicttomark readonly def
324
% <width> <height> <bits/component> <matrix> <dsrc0> ...
325
% <multi> <ncomp> <has_alpha>
326
% img_build_image_dict
329
% Build the dictionary corresponding to a colorimage operand stack. This
330
% routine will check just enough of the stack to verify that the
331
% dictionary can be built, and will generate the appropriate error if this
334
% The <has_alpha> boolean is used to support the Next alphaimage extension.
336
% At the first level, errors in this procedure are reported as colorimage
337
% errors. The error actually reported will usually be determined by the
338
% pseudo-operator which invokes this routine.
340
/img_build_image_dict
342
% Veify that at least 8 operands are available, and that the top three
343
% operands have the expected types
345
{ /.colorimage cvx /stackunderflow signalerror }
348
type /booleantype ne exch
349
type /integertype ne or exch
350
type /booleantype ne or
351
{ /.colorimage cvx /typecheck signalerror }
354
% verify that the number of components is 1, 3, or 4
355
1 index 1 lt 2 index 2 eq or 2 index 4 gt or
356
{ /.colorimage cvx /rangecheck signalerror }
359
% Verify that the required number of operands are present if multiple
360
% data sources are being used. If this test is successful, convert
361
% the data sources to an array (in local VM).
364
% if an alpha component is present, this adds one more component
370
% Adobe interpreters appear to test the arguments sequentially
371
% starting from the top of the stack and report the 1st error found.
372
% To satisfy CET test 12-02.PS we emulate this logic.
375
//good_image_types 1 index type .knownget
388
/.colorimage cvx exch signalerror
392
% build the DataSource array in local VM
393
dup .currentglobal false .setglobal exch array exch .setglobal
395
% stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
396
5 1 roll 4 add 3 roll astore 4 1 roll
400
% the image dictionary can be built; do so
401
% stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
402
8 1 roll //img_params_ary //img_build_dict exec exch
405
currentdict /good_image_types .undef
409
% img_unbuild_image_dict
410
% <width> <height> <bits/component> <matrix> <dsrc0> ...
413
% If the top entry of the stack is a dictionary that has the keys required
414
% by a colorimage dictionary, unpack that dictionary onto the stack.
415
% Otherwise just leave things as they are. Note that the <has_alpha>
416
% parameter is not pushd onto the stack.
418
/img_unbuild_image_dict
420
//img_check_ary //img_check_keys exec
422
//img_unbuild_ary //img_unbuild_dict exec
423
1 index type /booleantype eq
426
{ 3 -1 roll aload length 2 add -2 roll }
437
% <width> <height> <polarity> <matrix> <dsrc>
438
% img_unbuild_imagemask_dict
441
% Build the dictionary corresponding to an imagemask stack. This routine
442
% will verify that the appropriate number of operands are on the stack,
443
% and that polarity is a boolean. This is all that is necessary to build
446
/img_build_imagemask_dict
448
% check for proper number of operands
450
{ /imagemask .systemvar /stackunderflow signalerror }
453
% verify that polarity is a boolean
454
2 index type /booleantype ne
455
{ /imagemask .systemvar /typecheck signalerror }
458
% the imagemask dictionary can be built; do so
459
//img_mask_params_ary //img_build_dict exec
465
% img_unbuild_imagemask_dict
466
% <width> <height> <polarity> <matrix> <dsrc>
468
% If the top entry of the stack is a dictionary that has the keys rquired
469
% by an imagemask dictionary, unpack that dictionary onto the stack.
470
% Otherwise just leave things as they are.
472
/img_unbuild_imagemask_dict
474
//img_mask_check_ary //img_check_keys exec
476
//img_mask_unbuild_ary //img_unbuild_dict exec
478
dup type dup /arraytype eq exch /packedarraytype eq or
490
% <width> <height> <bits/component> <matrix> <dsrc_0> ...
491
% <multi> <ncomp> <has_alpha>
495
% Convert the image/colorimage operator from their traditional form to
496
% the dictionary form. The <has_alpha> operand is used ot support the
497
% Next alphaimage extension.
499
% Error handling for these operators is a bit complex, due to the stack
500
% handling required of operators that potentially invoke procedures.
501
% This problem is discussed in the comment above. The facts relevant to
502
% this particular implementation are:
504
% 1. The .image1 (or .alphaimage) operator is executed in a stopped
505
% context, so that we can undo the gsave context in the event of
508
% 2. In the event of an error, the stack is examined to see if the
509
% dictionary passed to .image1 (.alphaimage) is still present.
510
% If so, this dictionary is "unpacked" onto the stack to re-
511
% create the original stack. The <has_alpha> parameter is not
512
% pushed onto the stack, as it is not required for any of the
513
% pseudo-operators than invoke this procedure.
515
% 3. The use of pseudo-operators in this case may yield incorrect
516
% results for late-detected errors, as the stack depth will be
517
% restored (even though the stack is not). This is, however, no
518
% worse than the prior (level >= 2) code, so it should cause no
523
% build the image dictionary
524
//img_build_image_dict exec
526
% execute .image1 in a stopped context
529
% The CET test file 12-02.ps creates colorimages with a width and
530
% height of 0. Ignore these since that is what the CET expects.
531
1 index dup /Height get 0 eq exch /Width get 0 eq or
532
{ pop pop } % Ignore colorimage. Pop bool and dict
534
0 .setoverprintmode % disable overprint mode for images
535
//img_csary 2 index /IMG_NComps get get setcolorspace
545
//img_unbuild_image_dict exec
546
/.colorimage cvx $error /errorname get
555
% <width> <height> <bits/component> <matrix> <dsrc_0> ...
560
% Build the colorimage pseudo-operator only if setcolorscreen is visible.
562
systemdict /setcolorscreen .knownget
564
type /operatortype eq
571
{ /colorimage .systemvar $error /errorname get signalerror }
574
.bind systemdict begin odef end
582
% width height bits_per_component matrix data_src image -
586
% Some special handling is required for ImageType 2 (Display PostScript
587
% pixmap images) so as to set the appropriate color space as the current
592
dup type /dicttype eq .languagelevel 2 ge and
594
dup /ImageType get dup 2 eq
596
% verify the ImageType 2 is supported
597
//.imagetypes exch known
600
% Set either DevicePixel or DeviceRGB as the current
601
% color space. DevicePixel is used if the image data is
602
% to be copied directly, with only a geometric
603
% transformation (PixelCopy true). The use of DeviceRGB
604
% in the alternate case is not, in general, correct, and
605
% reflects a current implementation limitation. Ideally,
606
% an intermediate color space should be used only if
607
% the source and destination color models vary; otherwise
608
% the native color space corresponding to the color model
611
% The mechanism to determine depth for the DevicePixel
612
% color space when BitsPerPixel is not available is
613
% somewhat of a hack.
616
0 .setoverprintmode % disable overprintmode for images
617
dup /PixelCopy .knownget dup
623
currentpagedevice dup /BitsPerPixel .knownget
626
/GrayValues .knownget not
629
ln 2 ln div round cvi
640
{ /image .systemvar $error /errorname get signalerror }
643
{ /image .systemvar /rangecheck signalerror
648
dup //.imagetypes exch .knownget
651
0 .setoverprintmode % disable overprintmode for images
654
{ /image .systemvar $error /errorname get signalerror }
658
/image .systemvar exch type /integertype eq
659
{ /rangecheck } { /typecheck }
670
{ /image .systemvar $error /errorname get signalerror }
675
.bind systemdict begin odef end
677
% An auxiliary function for checking whether an imagemask to be interpolated.
678
/.is_low_resolution % <image dict> .is_low_resolution <bool>
679
{ % Checking whether image pixel maps to more than 2 device pixels.
680
% The threshold 2 is arbitrary.
686
idtransform dtransform dup mul exch dup mul add sqrt
694
% width height polarity matrix datasrc imagemask -
696
% See the comment preceding the definition of .colorimage for information
697
% as to the handling of error conditions.
701
dup type /dicttype eq .languagelevel 2 ge and
703
//.imagemasktypes exch .knownget
704
{ 1 index //.is_low_resolution exec
705
2 index /ImageType get 1 eq and
706
2 index /BitsPerComponent get 1 eq and
707
2 index /Interpolate .knownget not { false } if and
708
//filterdict /ImscaleDecode known and {
709
% Apply interpolated imagemask scaling filter
710
exch .currentglobal exch dup .gcheck .setglobal
711
dup length dict .copydict
712
dup dup /DataSource get
713
dup type /stringtype eq {
714
1 array astore cvx % image.* operators read strings repeatesly
716
mark /Width 3 index /Width get /Height 5 index /Height get .dicttomark
717
/ImscaleDecode filter /DataSource exch put
718
dup dup /Width get 4 mul /Width exch put
719
dup dup /Height get 4 mul /Height exch put
720
dup dup /ImageMatrix get
721
{ 4 0 0 4 0 0 } matrix concatmatrix /ImageMatrix exch put
726
{ % CET 12-08b.ps wants /typecheck
727
/imagemask .systemvar /typecheck signalerror
732
//img_build_imagemask_dict exec
736
//img_unbuild_imagemask_dict exec
737
/imagemask .systemvar $error /errorname get signalerror
743
.bind systemdict begin odef end
747
% Conditionally turn image interpolation on or off.
748
% INTERPOLATE is not yet set, handle all cases
749
currentdict /INTERPOLATE known
750
currentdict /DOTERPOLATE known or
751
currentdict /NOTERPOLATE known or not {
752
currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile
756
dup /Interpolate .knownget not { //false } if
757
/INTERPOLATE .systemvar ne {
758
dup gcheck .currentglobal exch .setglobal
759
exch dup length dict copy
760
dup /Interpolate /INTERPOLATE .systemvar put
766
{ /INTERPOLATE .systemvar
767
{ .currentglobal % w h bit [] {}...{} multi ncomp glob
769
9 dict begin % w h bit [] {}...{} multi ncomp glob
770
2 .argindex { 1 index 7 add } { 8 } ifelse
771
dup .argindex pop % check # of arguments
772
copy gsave pop % preserve the arguments
773
{ 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK }
774
1 index get setcolorspace % ... glob w h bit [] {}...{} multi ncomp
776
1 index 2 mul 0 exch % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp
777
getinterval /Decode exch def % ... glob w h bit [] {}...{} multi ncomp
778
exch dup % ... glob w h bit [] {}...{} ncomp multi multi
779
/MultipleDataSources exch def % ... glob w h bit [] {}...{} ncomp multi
780
{ array astore} { pop } ifelse % ... glob w h bit [] [{}...{}]
781
/DataSource exch def % ... glob w h bit []
782
/ImageMatrix exch def % ... glob w h bit
783
/BitsPerComponent exch def % ... glob w h
784
/Height exch def % ... glob w
785
/Width exch def % ... glob
787
/Interpolate //true def
788
.setglobal currentdict end % ... <<>>
790
exch { 4 add } { 6 } ifelse
799
{ dup type /dicttype eq
800
{ dup /ImageType get 3 eq
801
{ .currentglobal //false .setglobal exch
802
dup length dict copy begin .setglobal
803
/DataDict DataDict .interpolate def
804
/MaskDict MaskDict .interpolate def
812
{ /INTERPOLATE .systemvar
813
{ 4 .argindex pop % check # of args
814
.currentglobal //false .setglobal
815
8 dict begin .setglobal
817
/DataSource 1 index def
818
/ImageMatrix 2 index def
819
/BitsPerComponent 3 index def
823
/Interpolate //true def
825
gsave /DeviceGray setcolorspace image grestore
836
dup type /dicttype eq {
837
.interpolate imagemask
839
/INTERPOLATE .systemvar {
840
4 .argindex pop % check # of args
841
.currentglobal //false .setglobal
842
8 dict begin .setglobal
844
/DataSource 1 index def
845
/ImageMatrix 2 index def
846
/BitsPerComponent 1 def
847
2 index { {1 0} } { {0 1} } ifelse /Decode exch def
850
/Interpolate //true def
851
currentdict end imagemask 5 { pop } repeat
858
currentdict /.interpolate .undef
862
.setglobal % restore VM mode