|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862 |
- % (C) 2002 Artifex, Inc. All rights reserved.
- %
- % This software is provided AS-IS with no warranty, either express or
- % implied.
- %
- % This software is distributed under license and may not be copied,
- % modified or distributed except as expressly authorized under the terms
- % of the license contained in the file LICENSE in this distribution.
- %
- % For more information about licensing, please refer to
- % http://www.ghostscript.com/licensing/. For information on
- % commercial licensing, go to http://www.artifex.com/licensing/ or
- % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
-
- % $Id: gs_img.ps 8954 2008-08-08 04:22:38Z ray $
- % image, colorimage, and imagemask implementation
-
- %
- % The design of the overprint facility in Ghostscript requires that color
- % specifications include the color space from which they were expressed,
- % even after conversion to the device color model. Directly including this
- % information in color specifications is usually not efficient, and is
- % difficult to integrate into the existing code structure. The alternative
- % approach taken is to extend a state mechanism through the device
- % interface, and make the current color space, or more specifically,
- % certain information about the current color space, a property of this
- % state.
- %
- % For such a mechanism to work, it is necessary to identify all changes
- % to the current color space. This is accomplished in the graphic library
- % by funneling all changes to the current color space through the
- % gs_setcolorspace procedure. At the PostScript interpreter level, this
- % result is achieved by forcing color space changes through the
- % setcolorspace operator.
- %
- % Aside from explicit use of setcolorspace, PostScript provides a few
- % implicit methods of changing the current color space. The setgray,
- % setrgbcolor, and setcmykcolor operators implicitly set the color space
- % while explicitly setting the current color. Similarly, the colorimage
- % operator and the traditional form of the image operator (5 operands)
- % both temporarily modify the current color space while an image is
- % being processed. The current file is concerned with the implementation
- % of these two operators. In addition, the traditional form of the
- % imagemask operator (5 operands), while it does not affect the current
- % color space, is closely related to the image operator and thus is
- % implemented in this file as well.
- %
- % In this implementation, all sampled objects are passed through one of
- % the internal operators .image1, .imagemask1, .image1alpha, .image2,
- % .image3, or .image4, each of which handles a specific ImageType value.
- %
- % The procedures in this file are responsible for constructing
- % image dictionaries from a set of stack entries. This is, in principle,
- % a trivial exercise. In practice it appears to be far more complex,
- % primarily due to the need to reconstruct the original state in the
- % event of an error. This is a particular problem for operators such as
- % image, which include data source objects that may, directly or
- % indirectly, be procedures. When these procedures are executed, the
- % image operator's operands must have been cleared from the operand
- % stack. Hence, the operand stack cannot be used to store state
- % information. Similarly, the dictionary stack also cannot be used to
- % store state information, as the data source procedures may depend on
- % a particular dictionary being on the top of this stack.
- %
- % Adobe's PostScript implementations determine the extent to which the
- % interpreter state is restored in the event of an error by the point at
- % which the error is detected. Errors in the image/colorimage/imagemask
- % operators that are detected before the data source procedures are
- % executed restore the state in effect before the image was processed.
- % Those that are detected as part of running the data source procedures
- % only attempt to restore the state to that in effect at the start of
- % the operator that failed (or at the conclusion of the data source
- % procedure, if this procedure failed to push a string).
- %
- % The implementation given here follows the Adobe convention. The
- % mechanism used is as follows:
- %
- % 1. Check that the stack has a sufficient number of operands, and
- % that enough of them have the proper type to allow construction
- % of the image dictionary. Any errors at this point are handled
- % in the conventional manner.
- %
- % 2. Build the image dictionary, in the process clearing the image/
- % colorimage/imagemask operands from the stack. No errors can
- % occur during this process.
- %
- % (Special precautions could be taken during this step to handle
- % a limitcheck or VMError during the building of the image
- % dictionary, but this essentially never occurs in practice and, if
- % it did, is very unlikely to leave a useable state. Hence, we don't
- % bother with this possibility.)
- %
- % 3. The .image operator is executed in a stopped context. If it
- % returns abnormally, a check is made to see if the uppermost
- % operand on the stack is a color image dictionary. If so, the
- % original stack is created anew using this dictionary. (Because
- % the image operand works via colorimage, some additional special
- % handling is required in this case.)
- %
-
-
- %
- % Create a dictionary of operators for specific image and image mask types.
- % Each of these will always handle ImageType 1. Additional types are added
- % as they are supported in specific interpreter levels or versions.
- %
- % These dictionaries are in systemdict for historical reasons.
- %
- .currentglobal true .setglobal
- systemdict begin
- /.imagetypes
- 5 dict
- dup 1 /.image1 load put
- def
- /.imagemasktypes
- 5 dict
- dup 1 /.imagemask1 load put
- def
- end
- .setglobal
-
- %
- % Build a dictionary of utility procedures and constants for use in
- % impelementing the image operators. This dictionary is in global VM but
- % is maintained (during initialization) in userdict. It should be pushed
- % onto the dictionary stack when constructing image-related procedures
- % and pseudo-operators.
- %
- % This dictionary is removed from userdict when initialization is
- % completed.
- %
- .currentglobal true .setglobal
- userdict /img_utils_dict 30 dict put
- img_utils_dict begin
-
-
- %
- % Some useful local data structures:
- %
- % img_csary maps the number of components in an image to the implied
- % color space.
- %
- % img_decary is a prototype Decode array; subintervals of this array
- % may be used for fewer than 4 color components.
- %
- % img_params_ary is a list of the parameters to be built in the image
- % dictionary for a colorimage invocation. ImageType is given a
- % fixed value; the other parameters are in stack order (IMG_NComps
- % is the number of components).
- %
- % img_mask_params_ary is the equivalent of img_params_ary for imagemask
- % invocations. Polarity is a proxy for Decode, and is replaced
- % by the Decode key in the image dictionary.
- %
- % img_mask_check_ary is the set of parameters that must be present in
- % an image dictionary generated by an imagemask invocation. This
- % differs from img_mask_params_ary in that Decode replaces Polarity.
- %
- /img_csary [ null /DeviceGray null /DeviceRGB /DeviceCMYK ] def
- /img_decary [ 0 1 0 1 0 1 0 1 ] def
-
- /img_params_ary
- [
- /ImageType /IMG_NComps /MultipleDataSources /DataSource
- /ImageMatrix /BitsPerComponent /Height /Width /Decode
- ]
- def
- /img_check_ary //img_params_ary def
- /img_unbuild_ary
- //img_params_ary 1 1 index length 2 sub getinterval
- def
-
- /img_mask_params_ary
- [ /ImageType /DataSource /ImageMatrix /Polarity /Height /Width ]
- def
- /img_mask_check_ary
- [
- /ImageType /BitsPerComponent
- /DataSource /ImageMatrix /Decode /Height /Width
- ]
- def
- /img_mask_unbuild_ary
- //img_mask_check_ary 2 1 index length 2 sub getinterval
- def
-
-
- %
- % <?any?> <array> img_check_keys <?any?> <bool>
- %
- % Verify that:
- % that there are at least two entries on the stack, and
- % the second (lower) entry is a dictionary, and
- % that dictionary contains all of the keys in the array
- %
- % If any one of these conditions does not hold, pop the array and push
- % false; otherwise pop the array and push true. This utility is used by
- % the colorimage and imagematrix procedures to determine if .image left
- % the image dictionary on the stack after an abnormal return.
- %
- /img_check_keys
- {
- count 2 ge
- {
- 1 index type /dicttype eq
- {
- true exch
- {
- 2 index exch known and
- dup not
- { exit }
- if
- }
- forall
- }
- { pop //false }
- ifelse
- }
- { pop //false }
- ifelse
- }
- .bind def
-
- %
- % Procedures to convert a set of stack entries to a dictionary. There is
- % a procedure associated with each key, though most keys use the same
- % procedure. The dictionary to be built is at the top of the dictionary
- % stack. Stack handling for the procedures is:
- %
- % <?val0?> ... <?val(n - 1)?> <key> proc -
- %
- % Parameters are handle in inverse-stack order, so inter-parameter
- % dependencies that on the stack can generally be used here.
- %
- /img_params_dict
- mark
- /ImageType { 1 def } .bind
-
- /IMG_NComps { exch def } .bind % number of components
- /MultipleDataSources 1 index
- /Width 1 index
- /Height 1 index
- /ImageMatrix 1 index
- /BitsPerComponent 1 index
- /DataSource 1 index
-
- % Polarity is a proxy for Decode; it never appears in a dictionary
- /Polarity
- {
- pop
- { { 1 0 } }
- { { 0 1 } }
- ifelse
- /Decode exch cvlit def
- }
- .bind
-
- % the definition of Decode is based on the number of components
- /Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind
- .dicttomark
- def
-
- %
- % <oper_0> ... <oper_n> <array> img_build_dict <dict>
- %
- % Build a dictionary. This will always be done in local VM. The array is
- % a list of the keys to be associated with operands on the stack, in
- % inverse stack order (topmost element first). The caller should verify
- % that the dictionary can be built successfully (except for a possible
- % VMerror) before calling this routine.
- %
- /img_build_dict
- {
- % build the dictionary in local VM; all for 2 extra entries
- .currentglobal false .setglobal
- 1 index length 2 add dict
- exch .setglobal
- begin
-
- % process all keys in the array
- { //img_params_dict 1 index get exec }
- forall
-
- % if BitsPerComponent is not yet defined, define it to be 1
- currentdict /BitsPerComponent known not
- { /BitsPerComponent 1 def }
- if
-
- currentdict end
- }
- .bind def
-
- %
- % <dict> <array> img_unbuild_dict <oper_0> ... <oper_n>
- %
- % "Unbuild" a dictionary: spread the contents the dictionary back onto the
- % stack, in the inverse of the order indicated in the array (inverse is
- % used as this order is more convenient for img_build_dict, which is
- % expected to be invoked far more frequently).
- %
- /img_unbuild_dict
- {
- exch begin
- dup length 1 sub -1 0
- { 1 index exch get load exch }
- for
- pop
- end
- }
- .bind def
-
- %
- % Check the image types that can be used as data sources
- % <any> foo <bool>
- %
- /good_image_types mark
- /filetype { pop //true } .bind
- /stringtype 1 index
- /arraytype //xcheck
- /packedarraytype //xcheck
- .dicttomark readonly def
-
- %
- % <width> <height> <bits/component> <matrix> <dsrc0> ...
- % <multi> <ncomp> <has_alpha>
- % img_build_image_dict
- % <dict> <has_alpha>
- %
- % Build the dictionary corresponding to a colorimage operand stack. This
- % routine will check just enough of the stack to verify that the
- % dictionary can be built, and will generate the appropriate error if this
- % is not the case.
- %
- % The <has_alpha> boolean is used to support the Next alphaimage extension.
- %
- % At the first level, errors in this procedure are reported as colorimage
- % errors. The error actually reported will usually be determined by the
- % pseudo-operator which invokes this routine.
- %
- /img_build_image_dict
- {
- % Veify that at least 8 operands are available, and that the top three
- % operands have the expected types
- count 8 lt
- { /.colorimage cvx /stackunderflow signalerror }
- if
- 3 copy
- type /booleantype ne exch
- type /integertype ne or exch
- type /booleantype ne or
- { /.colorimage cvx /typecheck signalerror }
- if
-
- % verify that the number of components is 1, 3, or 4
- 1 index 1 lt 2 index 2 eq or 2 index 4 gt or
- { /.colorimage cvx /rangecheck signalerror }
- if
-
- % Verify that the required number of operands are present if multiple
- % data sources are being used. If this test is successful, convert
- % the data sources to an array (in local VM).
- 2 index
- {
- % if an alpha component is present, this adds one more component
- 2 copy
- { 1 add }
- if
- dup count 9 sub gt
- {
- % Adobe interpreters appear to test the arguments sequentially
- % starting from the top of the stack and report the 1st error found.
- % To satisfy CET test 12-02.PS we emulate this logic.
- //true exch -1 1
- { 3 add index
- //good_image_types 1 index type .knownget
- { exec and
- }
- { pop pop //false
- }
- ifelse
- }
- for
- { /stackunderflow
- }
- { /typecheck
- }
- ifelse
- /.colorimage cvx exch signalerror
- }
- if
-
- % build the DataSource array in local VM
- dup .currentglobal false .setglobal exch array exch .setglobal
-
- % stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
- 5 1 roll 4 add 3 roll astore 4 1 roll
- }
- if
-
- % the image dictionary can be built; do so
- % stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
- 8 1 roll //img_params_ary //img_build_dict exec exch
- }
- .bind def
- currentdict /good_image_types .undef
-
- %
- % <?dict?>
- % img_unbuild_image_dict
- % <width> <height> <bits/component> <matrix> <dsrc0> ...
- % <multi> <ncomp>
- %
- % If the top entry of the stack is a dictionary that has the keys required
- % by a colorimage dictionary, unpack that dictionary onto the stack.
- % Otherwise just leave things as they are. Note that the <has_alpha>
- % parameter is not pushd onto the stack.
- %
- /img_unbuild_image_dict
- {
- //img_check_ary //img_check_keys exec
- {
- //img_unbuild_ary //img_unbuild_dict exec
- 1 index type /booleantype eq
- {
- 1 index
- { 3 -1 roll aload length 2 add -2 roll }
- if
- }
- if
- }
- if
- }
- .bind def
-
-
- %
- % <width> <height> <polarity> <matrix> <dsrc>
- % img_unbuild_imagemask_dict
- % <dict>
- %
- % Build the dictionary corresponding to an imagemask stack. This routine
- % will verify that the appropriate number of operands are on the stack,
- % and that polarity is a boolean. This is all that is necessary to build
- % the dictionary.
- %
- /img_build_imagemask_dict
- {
- % check for proper number of operands
- count 5 lt
- { /imagemask .systemvar /stackunderflow signalerror }
- if
-
- % verify that polarity is a boolean
- 2 index type /booleantype ne
- { /imagemask .systemvar /typecheck signalerror }
- if
-
- % the imagemask dictionary can be built; do so
- //img_mask_params_ary //img_build_dict exec
- }
- .bind def
-
- %
- % <?dict?>
- % img_unbuild_imagemask_dict
- % <width> <height> <polarity> <matrix> <dsrc>
- %
- % If the top entry of the stack is a dictionary that has the keys rquired
- % by an imagemask dictionary, unpack that dictionary onto the stack.
- % Otherwise just leave things as they are.
- %
- /img_unbuild_imagemask_dict
- {
- //img_mask_check_ary //img_check_keys exec
- {
- //img_mask_unbuild_ary //img_unbuild_dict exec
- 3 -1 roll
- dup type dup /arraytype eq exch /packedarraytype eq or
- 1 index rcheck and
- { 0 get 1 eq }
- if
- 3 1 roll
- }
- if
- }
- .bind def
-
-
- %
- % <width> <height> <bits/component> <matrix> <dsrc_0> ...
- % <multi> <ncomp> <has_alpha>
- % .colorimage
- % -
- %
- % Convert the image/colorimage operator from their traditional form to
- % the dictionary form. The <has_alpha> operand is used ot support the
- % Next alphaimage extension.
- %
- % Error handling for these operators is a bit complex, due to the stack
- % handling required of operators that potentially invoke procedures.
- % This problem is discussed in the comment above. The facts relevant to
- % this particular implementation are:
- %
- % 1. The .image1 (or .alphaimage) operator is executed in a stopped
- % context, so that we can undo the gsave context in the event of
- % an error.
- %
- % 2. In the event of an error, the stack is examined to see if the
- % dictionary passed to .image1 (.alphaimage) is still present.
- % If so, this dictionary is "unpacked" onto the stack to re-
- % create the original stack. The <has_alpha> parameter is not
- % pushed onto the stack, as it is not required for any of the
- % pseudo-operators than invoke this procedure.
- %
- % 3. The use of pseudo-operators in this case may yield incorrect
- % results for late-detected errors, as the stack depth will be
- % restored (even though the stack is not). This is, however, no
- % worse than the prior (level >= 2) code, so it should cause no
- % new problems.
- %
- /.colorimage
- {
- % build the image dictionary
- //img_build_image_dict exec
-
- % execute .image1 in a stopped context
- {
- gsave
- % The CET test file 12-02.ps creates colorimages with a width and
- % height of 0. Ignore these since that is what the CET expects.
- 1 index dup /Height get 0 eq exch /Width get 0 eq or
- { pop pop } % Ignore colorimage. Pop bool and dict
- {
- 0 .setoverprintmode % disable overprint mode for images
- //img_csary 2 index /IMG_NComps get get setcolorspace
- { .alphaimage }
- { .image1 }
- ifelse
- }
- ifelse
- }
- stopped
- grestore
- {
- //img_unbuild_image_dict exec
- /.colorimage cvx $error /errorname get
- signalerror
- }
- if
- }
- .bind def
-
-
- %
- % <width> <height> <bits/component> <matrix> <dsrc_0> ...
- % <multi> <ncomp>
- % colorimage
- % -
- %
- % Build the colorimage pseudo-operator only if setcolorscreen is visible.
- %
- systemdict /setcolorscreen .knownget
- {
- type /operatortype eq
- {
- /colorimage
- {
- //false
- //.colorimage
- stopped
- { /colorimage .systemvar $error /errorname get signalerror }
- if
- }
- .bind systemdict begin odef end
- }
- if
- }
- if
-
-
- %
- % width height bits_per_component matrix data_src image -
- %
- % <dict> image -
- %
- % Some special handling is required for ImageType 2 (Display PostScript
- % pixmap images) so as to set the appropriate color space as the current
- % color space.
- %
- /image
- {
- dup type /dicttype eq .languagelevel 2 ge and
- {
- dup /ImageType get dup 2 eq
- {
- % verify the ImageType 2 is supported
- //.imagetypes exch known
- {
- %
- % Set either DevicePixel or DeviceRGB as the current
- % color space. DevicePixel is used if the image data is
- % to be copied directly, with only a geometric
- % transformation (PixelCopy true). The use of DeviceRGB
- % in the alternate case is not, in general, correct, and
- % reflects a current implementation limitation. Ideally,
- % an intermediate color space should be used only if
- % the source and destination color models vary; otherwise
- % the native color space corresponding to the color model
- % should be used.
- %
- % The mechanism to determine depth for the DevicePixel
- % color space when BitsPerPixel is not available is
- % somewhat of a hack.
- %
- gsave
- 0 .setoverprintmode % disable overprintmode for images
- dup /PixelCopy .knownget dup
- { pop }
- if
- {
- [
- /DevicePixel
- currentpagedevice dup /BitsPerPixel .knownget
- { exch pop }
- {
- /GrayValues .knownget not
- { 2 } % try a guess
- if
- ln 2 ln div round cvi
- }
- ifelse
- ]
- }
- { /DeviceRGB }
- ifelse
- setcolorspace
- //.imagetypes 2 get
- stopped
- grestore
- { /image .systemvar $error /errorname get signalerror }
- if
- }
- { /image .systemvar /rangecheck signalerror
- }
- ifelse
- }
- {
- dup //.imagetypes exch .knownget
- {
- exch pop gsave
- 0 .setoverprintmode % disable overprintmode for images
- stopped
- grestore
- { /image .systemvar $error /errorname get signalerror }
- if
- }
- {
- /image .systemvar exch type /integertype eq
- { /rangecheck } { /typecheck }
- ifelse signalerror
- }
- ifelse
- }
- ifelse
- }
- {
- //false 1 //false
- //.colorimage
- stopped
- { /image .systemvar $error /errorname get signalerror }
- if
- }
- ifelse
- }
- .bind systemdict begin odef end
-
- % An auxiliary function for checking whether an imagemask to be interpolated.
- /.is_low_resolution % <image dict> .is_low_resolution <bool>
- { % Checking whether image pixel maps to more than 2 device pixels.
- % The threshold 2 is arbitrary.
- 1 exch 0 exch
- 0 exch 1 exch
- /ImageMatrix get dup
- 2 {
- 4 1 roll
- idtransform dtransform dup mul exch dup mul add sqrt
- } repeat
- max
- 2 gt % arbitrary
- } .bind def
-
-
- %
- % width height polarity matrix datasrc imagemask -
- %
- % See the comment preceding the definition of .colorimage for information
- % as to the handling of error conditions.
- %
- /imagemask
- {
- dup type /dicttype eq .languagelevel 2 ge and
- { dup /ImageType get
- //.imagemasktypes exch .knownget
- { 1 index //.is_low_resolution exec
- 2 index /ImageType get 1 eq and
- 2 index /BitsPerComponent get 1 eq and
- 2 index /Interpolate .knownget not { false } if and
- //filterdict /ImscaleDecode known and {
- % Apply interpolated imagemask scaling filter
- exch .currentglobal exch dup .gcheck .setglobal
- dup length dict .copydict
- dup dup /DataSource get
- dup type /stringtype eq {
- 1 array astore cvx % image.* operators read strings repeatesly
- } if
- mark /Width 3 index /Width get /Height 5 index /Height get .dicttomark
- /ImscaleDecode filter /DataSource exch put
- dup dup /Width get 4 mul /Width exch put
- dup dup /Height get 4 mul /Height exch put
- dup dup /ImageMatrix get
- { 4 0 0 4 0 0 } matrix concatmatrix /ImageMatrix exch put
- 3 1 roll .setglobal
- } if
- exec
- }
- { % CET 12-08b.ps wants /typecheck
- /imagemask .systemvar /typecheck signalerror
- }
- ifelse
- }
- {
- //img_build_imagemask_dict exec
- { .imagemask1 }
- stopped
- {
- //img_unbuild_imagemask_dict exec
- /imagemask .systemvar $error /errorname get signalerror
- }
- if
- }
- ifelse
- }
- .bind systemdict begin odef end
-
- end % img_utils_dict
-
- % Conditionally turn image interpolation on or off.
- % INTERPOLATE is not yet set, handle all cases
- currentdict /INTERPOLATE known
- currentdict /DOTERPOLATE known or
- currentdict /NOTERPOLATE known or not {
- currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile
- } if
-
- /.interpolate {
- dup /Interpolate .knownget not { //false } if
- /INTERPOLATE .systemvar ne {
- dup gcheck .currentglobal exch .setglobal
- exch dup length dict copy
- dup /Interpolate /INTERPOLATE .systemvar put
- exch .setglobal
- } if
- } .bind odef
-
- /colorimage
- { /INTERPOLATE .systemvar
- { .currentglobal % w h bit [] {}...{} multi ncomp glob
- //false .setglobal
- 9 dict begin % w h bit [] {}...{} multi ncomp glob
- 2 .argindex { 1 index 7 add } { 8 } ifelse
- dup .argindex pop % check # of arguments
- copy gsave pop % preserve the arguments
- { 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK }
- 1 index get setcolorspace % ... glob w h bit [] {}...{} multi ncomp
- {0 1 0 1 0 1 0 1}
- 1 index 2 mul 0 exch % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp
- getinterval /Decode exch def % ... glob w h bit [] {}...{} multi ncomp
- exch dup % ... glob w h bit [] {}...{} ncomp multi multi
- /MultipleDataSources exch def % ... glob w h bit [] {}...{} ncomp multi
- { array astore} { pop } ifelse % ... glob w h bit [] [{}...{}]
- /DataSource exch def % ... glob w h bit []
- /ImageMatrix exch def % ... glob w h bit
- /BitsPerComponent exch def % ... glob w h
- /Height exch def % ... glob w
- /Width exch def % ... glob
- /ImageType 1 def
- /Interpolate //true def
- .setglobal currentdict end % ... <<>>
- image grestore
- exch { 4 add } { 6 } ifelse
- { pop } repeat % -
- }
- { colorimage
- }
- ifelse
- } .bind odef
-
- /image
- { dup type /dicttype eq
- { dup /ImageType get 3 eq
- { .currentglobal //false .setglobal exch
- dup length dict copy begin .setglobal
- /DataDict DataDict .interpolate def
- /MaskDict MaskDict .interpolate def
- currentdict end
- }
- { .interpolate
- }
- ifelse
- image
- }
- { /INTERPOLATE .systemvar
- { 4 .argindex pop % check # of args
- .currentglobal //false .setglobal
- 8 dict begin .setglobal
- /ImageType 1 def
- /DataSource 1 index def
- /ImageMatrix 2 index def
- /BitsPerComponent 3 index def
- /Decode {0 1} def
- /Height 4 index def
- /Width 5 index def
- /Interpolate //true def
- currentdict end
- gsave /DeviceGray setcolorspace image grestore
- 5 { pop } repeat
- }
- { image
- }
- ifelse
- }
- ifelse
- } .bind odef
-
- /imagemask {
- dup type /dicttype eq {
- .interpolate imagemask
- } {
- /INTERPOLATE .systemvar {
- 4 .argindex pop % check # of args
- .currentglobal //false .setglobal
- 8 dict begin .setglobal
- /ImageType 1 def
- /DataSource 1 index def
- /ImageMatrix 2 index def
- /BitsPerComponent 1 def
- 2 index { {1 0} } { {0 1} } ifelse /Decode exch def
- /Height 4 index def
- /Width 5 index def
- /Interpolate //true def
- currentdict end imagemask 5 { pop } repeat
- } {
- imagemask
- } ifelse
- } ifelse
- } .bind odef
-
- currentdict /.interpolate .undef
-
- %END INTERPOLATE
-
- .setglobal % restore VM mode
|