home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / gs_img.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  27.5 KB  |  863 lines

  1. % (C) 2002 Artifex, Inc.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_img.ps 8954 2008-08-08 04:22:38Z ray $
  14. % image, colorimage, and imagemask implementation
  15.  
  16. %
  17. % The design of the overprint facility in Ghostscript requires that color
  18. % specifications include the color space from which they were expressed,
  19. % even after conversion to the device color model. Directly including this
  20. % information in color specifications is usually not efficient, and is
  21. % difficult to integrate into the existing code structure. The alternative
  22. % approach taken is to extend a state mechanism through the device
  23. % interface, and make the current color space, or more specifically,
  24. % certain information about the current color space, a property of this
  25. % state.
  26. %
  27. % For such a mechanism to work, it is necessary to identify all changes
  28. % to the current color space. This is accomplished in the graphic library
  29. % by funneling all changes to the current color space through the
  30. % gs_setcolorspace procedure. At the PostScript interpreter level, this
  31. % result is achieved by forcing color space changes through the
  32. % setcolorspace operator.
  33. %
  34. % Aside from explicit use of setcolorspace, PostScript provides a few
  35. % implicit methods of changing the current color space. The setgray,
  36. % setrgbcolor, and setcmykcolor operators implicitly set the color space
  37. % while explicitly setting the current color. Similarly, the colorimage
  38. % operator and the traditional form of the image operator (5 operands)
  39. % both temporarily modify the current color space while an image is
  40. % being processed. The current file is concerned with the implementation
  41. % of these two operators. In addition, the traditional form of the
  42. % imagemask operator (5 operands), while it does not affect the current
  43. % color space, is closely related to the image operator and thus is
  44. % implemented in this file as well.
  45. %
  46. % In this implementation, all sampled objects are passed through one of
  47. % the internal operators .image1, .imagemask1, .image1alpha, .image2,
  48. % .image3, or .image4, each of which handles a specific ImageType value.
  49. %
  50. % The procedures in this file are responsible for constructing
  51. % image dictionaries from a set of stack entries. This is, in principle,
  52. % a trivial exercise. In practice it appears to be far more complex,
  53. % primarily due to the need to reconstruct the original state in the
  54. % event of an error. This is a particular problem for operators such as
  55. % image, which include data source objects that may, directly or
  56. % indirectly, be procedures. When these procedures are executed, the
  57. % image operator's operands must have been cleared from the operand
  58. % stack. Hence, the operand stack cannot be used to store state
  59. % information. Similarly, the dictionary stack also cannot be used to
  60. % store state information, as the data source procedures may depend on
  61. % a particular dictionary being on the top of this stack.
  62. %
  63. % Adobe's PostScript implementations determine the extent to which the
  64. % interpreter state is restored in the event of an error by the point at
  65. % which the error is detected. Errors in the image/colorimage/imagemask
  66. % operators that are detected before the data source procedures are
  67. % executed restore the state in effect before the image was processed.
  68. % Those that are detected as part of running the data source procedures
  69. % only attempt to restore the state to that in effect at the start of
  70. % the operator that failed (or at the conclusion of the data source
  71. % procedure, if this procedure failed to push a string).
  72. %
  73. % The implementation given here follows the Adobe convention. The
  74. % mechanism used is as follows:
  75. %
  76. %   1. Check that the stack has a sufficient number of operands, and
  77. %      that enough of them have the proper type to allow construction
  78. %      of the image dictionary. Any errors at this point are handled
  79. %      in the conventional manner.
  80. %
  81. %   2. Build the image dictionary, in the process clearing the image/
  82. %      colorimage/imagemask operands from the stack. No errors can
  83. %      occur during this process.
  84. %
  85. %      (Special precautions could be taken during this step to handle
  86. %      a limitcheck or VMError during the building of the image
  87. %      dictionary, but this essentially never occurs in practice and, if
  88. %      it did, is very unlikely to leave a useable state. Hence, we don't
  89. %      bother with this possibility.)
  90. %
  91. %   3. The .image operator is executed in a stopped context. If it
  92. %      returns abnormally, a check is made to see if the uppermost
  93. %      operand on the stack is a color image dictionary. If so, the
  94. %      original stack is created anew using this dictionary. (Because
  95. %      the image operand works via colorimage, some additional special
  96. %      handling is required in this case.)
  97. %
  98.  
  99.  
  100. %
  101. % Create a dictionary of operators for specific image and image mask types.
  102. % Each of these will always handle ImageType 1. Additional types are added
  103. % as they are supported in specific interpreter levels or versions.
  104. %
  105. % These dictionaries are in systemdict for historical reasons.
  106. %
  107. .currentglobal true .setglobal
  108. systemdict begin
  109. /.imagetypes
  110.   5 dict
  111.   dup 1 /.image1 load put
  112. def
  113. /.imagemasktypes
  114.   5 dict
  115.   dup 1 /.imagemask1 load put
  116. def
  117. end
  118. .setglobal
  119.  
  120. % Build a dictionary of utility procedures and constants for use in
  121. % impelementing the image operators. This dictionary is in global VM but
  122. % is maintained (during initialization) in userdict. It should be pushed
  123. % onto the dictionary stack when constructing image-related procedures
  124. % and pseudo-operators.
  125. %
  126. % This dictionary is removed from userdict when initialization is
  127. % completed.
  128. %
  129. .currentglobal true .setglobal
  130. userdict /img_utils_dict 30 dict put
  131. img_utils_dict begin
  132.  
  133.  
  134. %
  135. % Some useful local data structures:
  136. %
  137. %   img_csary maps the number of components in an image to the implied
  138. %       color space.
  139. %
  140. %   img_decary is a prototype Decode array; subintervals of this array
  141. %       may be used for fewer than 4 color components.
  142. %
  143. %   img_params_ary is a list of the parameters to be built in the image
  144. %       dictionary for a colorimage invocation. ImageType is given a
  145. %       fixed value; the other parameters are in stack order (IMG_NComps
  146. %       is the number of components).
  147. %
  148. %   img_mask_params_ary is the equivalent of img_params_ary for imagemask
  149. %       invocations. Polarity is a proxy for Decode, and is replaced
  150. %       by the Decode key in the image dictionary.
  151. %
  152. %   img_mask_check_ary is the set of parameters that must be present in
  153. %       an image dictionary generated by an imagemask invocation. This
  154. %       differs from img_mask_params_ary in that Decode replaces Polarity.
  155. %
  156. /img_csary [ null /DeviceGray null /DeviceRGB /DeviceCMYK ] def
  157. /img_decary [ 0 1  0 1  0 1  0 1 ] def
  158.  
  159. /img_params_ary
  160.   [
  161.     /ImageType  /IMG_NComps  /MultipleDataSources  /DataSource
  162.     /ImageMatrix  /BitsPerComponent  /Height  /Width   /Decode
  163.   ]
  164. def
  165. /img_check_ary //img_params_ary def
  166. /img_unbuild_ary
  167.  //img_params_ary 1 1 index length 2 sub getinterval
  168. def
  169.  
  170. /img_mask_params_ary
  171.   [ /ImageType  /DataSource  /ImageMatrix  /Polarity  /Height  /Width ]
  172. def
  173. /img_mask_check_ary
  174.   [
  175.     /ImageType  /BitsPerComponent
  176.     /DataSource  /ImageMatrix  /Decode  /Height  /Width
  177.   ]
  178. def
  179. /img_mask_unbuild_ary
  180.  //img_mask_check_ary 2 1 index length 2 sub getinterval
  181. def
  182.  
  183.  
  184. %
  185. %   <?any?>  <array>   img_check_keys   <?any?>  <bool>
  186. %
  187. % Verify that:
  188. %   that there are at least two entries on the stack, and
  189. %   the second (lower) entry is a dictionary, and
  190. %   that dictionary contains all of the keys in the array
  191. %
  192. % If any one of these conditions does not hold, pop the array and push
  193. % false; otherwise pop the array and push true. This utility is used by
  194. % the colorimage and imagematrix procedures to determine if .image left
  195. % the image dictionary on the stack after an abnormal return.
  196. %
  197. /img_check_keys
  198.   {
  199.     count 2 ge
  200.       {
  201.         1 index type /dicttype eq
  202.           {
  203.             true exch
  204.               {
  205.                 2 index exch known and
  206.                 dup not
  207.                   { exit }
  208.                 if
  209.               }
  210.             forall
  211.           }
  212.           { pop //false }
  213.         ifelse
  214.       }
  215.       { pop //false }
  216.     ifelse
  217.   }
  218. .bind def
  219.  
  220. %
  221. % Procedures to convert a set of stack entries to a dictionary. There is
  222. % a procedure associated with each key, though most keys use the same
  223. % procedure. The dictionary to be built is at the top of the dictionary
  224. % stack. Stack handling for the procedures is:
  225. %
  226. %   <?val0?> ... <?val(n - 1)?>  <key>   proc   -
  227. %
  228. % Parameters are handle in inverse-stack order, so inter-parameter
  229. % dependencies that on the stack can generally be used here.
  230. %
  231. /img_params_dict
  232.   mark
  233.     /ImageType { 1 def } .bind
  234.  
  235.     /IMG_NComps { exch def } .bind      % number of components
  236.     /MultipleDataSources 1 index
  237.     /Width 1 index
  238.     /Height 1 index
  239.     /ImageMatrix 1 index
  240.     /BitsPerComponent 1 index
  241.     /DataSource 1 index
  242.  
  243.     % Polarity is a proxy for Decode; it never appears in a dictionary
  244.     /Polarity
  245.       {
  246.         pop
  247.           { { 1 0 } }
  248.           { { 0 1 } }
  249.         ifelse
  250.         /Decode exch cvlit def
  251.       }
  252.     .bind
  253.  
  254.     % the definition of Decode is based on the number of components
  255.     /Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind
  256.   .dicttomark
  257. def
  258.  
  259. %
  260. %    <oper_0>  ...  <oper_n>  <array>   img_build_dict   <dict>
  261. %
  262. % Build a dictionary. This will always be done in local VM. The array is
  263. % a list of the keys to be associated with operands on the stack, in
  264. % inverse stack order (topmost element first). The caller should verify
  265. % that the dictionary can be built successfully (except for a possible
  266. % VMerror) before calling this routine.
  267. %
  268. /img_build_dict
  269.   {
  270.     % build the dictionary in local VM; all for 2 extra entries
  271.     .currentglobal false .setglobal
  272.     1 index length 2 add dict
  273.     exch .setglobal
  274.     begin
  275.  
  276.     % process all keys in the array
  277.       { //img_params_dict 1 index get exec }
  278.     forall
  279.  
  280.     % if BitsPerComponent is not yet defined, define it to be 1
  281.     currentdict /BitsPerComponent known not
  282.       { /BitsPerComponent 1 def }
  283.     if
  284.  
  285.     currentdict end
  286.   }
  287. .bind def
  288.  
  289. %
  290. %   <dict>  <array>   img_unbuild_dict   <oper_0>  ...  <oper_n>
  291. %
  292. % "Unbuild" a dictionary: spread the contents the dictionary back onto the
  293. % stack, in the inverse of the order indicated in the array (inverse is
  294. % used as this order is more convenient for img_build_dict, which is
  295. % expected to be invoked far more frequently).
  296. %
  297. /img_unbuild_dict
  298.   {
  299.     exch begin
  300.     dup length 1 sub -1 0
  301.       { 1 index exch get load exch }
  302.     for
  303.     pop
  304.     end
  305.   }
  306. .bind def
  307.  
  308. %
  309. % Check the image types that can be used as data sources
  310. % <any> foo <bool>
  311. %
  312. /good_image_types mark
  313.   /filetype { pop //true } .bind
  314.   /stringtype 1 index
  315.   /arraytype //xcheck
  316.   /packedarraytype //xcheck
  317. .dicttomark readonly def
  318.  
  319. %
  320. %   <width>  <height>  <bits/component>  <matrix>  <dsrc0> ...
  321. %   <multi>  <ncomp>  <has_alpha>
  322. %   img_build_image_dict
  323. %   <dict>  <has_alpha>
  324. %
  325. % Build the dictionary corresponding to a colorimage operand stack. This
  326. % routine will check just enough of the stack to verify that the
  327. % dictionary can be built, and will generate the appropriate error if this
  328. % is not the case.
  329. %
  330. % The <has_alpha> boolean is used to support the Next alphaimage extension.
  331. %
  332. % At the first level, errors in this procedure are reported as colorimage
  333. % errors. The error actually reported will usually be determined by the
  334. % pseudo-operator which invokes this routine.
  335. %
  336. /img_build_image_dict
  337.   {
  338.     % Veify that at least 8 operands are available, and that the top three
  339.     % operands have the expected types
  340.     count 8 lt
  341.       { /.colorimage cvx /stackunderflow signalerror }
  342.     if
  343.     3 copy
  344.     type /booleantype ne exch
  345.     type /integertype ne or exch
  346.     type /booleantype ne or
  347.       { /.colorimage cvx /typecheck signalerror }
  348.     if
  349.  
  350.     % verify that the number of components is 1, 3, or 4
  351.     1 index 1 lt 2 index 2 eq or 2 index 4 gt or
  352.       { /.colorimage cvx /rangecheck signalerror }
  353.     if
  354.  
  355.     % Verify that the required number of operands are present if multiple
  356.     % data sources are being used. If this test is successful, convert
  357.     % the data sources to an array (in local VM).
  358.     2 index
  359.       {
  360.         % if an alpha component is present, this adds one more component
  361.         2 copy
  362.           { 1 add }
  363.         if
  364.         dup count 9 sub gt
  365.           {
  366.             % Adobe interpreters appear to test the arguments sequentially
  367.             % starting from the top of the stack and report the 1st error found.
  368.             % To satisfy CET test 12-02.PS we emulate this logic.
  369.             //true exch -1 1
  370.               { 3 add index
  371.                 //good_image_types 1 index type .knownget
  372.                   { exec and
  373.                   }
  374.                   { pop pop //false
  375.                   }
  376.                 ifelse
  377.               }
  378.             for
  379.               { /stackunderflow
  380.               }
  381.               { /typecheck
  382.               }
  383.             ifelse
  384.             /.colorimage cvx exch signalerror
  385.           }
  386.         if
  387.  
  388.         % build the DataSource array in local VM
  389.         dup .currentglobal false .setglobal exch array exch .setglobal
  390.  
  391.         % stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
  392.         5 1 roll 4 add 3 roll astore 4 1 roll
  393.       }
  394.     if
  395.  
  396.     % the image dictionary can be built; do so
  397.     % stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
  398.     8 1 roll //img_params_ary //img_build_dict exec exch
  399.   }
  400. .bind def
  401. currentdict /good_image_types .undef
  402.  
  403. %
  404. %   <?dict?>
  405. %   img_unbuild_image_dict
  406. %   <width>  <height>  <bits/component>  <matrix>  <dsrc0> ...
  407. %   <multi>  <ncomp>
  408. %
  409. % If the top entry of the stack is a dictionary that has the keys required
  410. % by a colorimage dictionary, unpack that dictionary onto the stack.
  411. % Otherwise just leave things as they are. Note that the <has_alpha>
  412. % parameter is not pushd onto the stack.
  413. %
  414. /img_unbuild_image_dict
  415.   {
  416.     //img_check_ary //img_check_keys exec
  417.       {
  418.         //img_unbuild_ary //img_unbuild_dict exec
  419.         1 index type /booleantype eq
  420.           {
  421.             1 index
  422.               { 3 -1 roll aload length 2 add -2 roll }
  423.             if
  424.           }
  425.         if
  426.       }
  427.     if
  428.   }
  429. .bind def
  430.  
  431.  
  432. %
  433. %   <width>  <height>  <polarity>  <matrix>  <dsrc>
  434. %   img_unbuild_imagemask_dict
  435. %   <dict>
  436. %
  437. % Build the dictionary corresponding to an imagemask stack. This routine
  438. % will verify that the appropriate number of operands are on the stack,
  439. % and that polarity is a boolean. This is all that is necessary to build
  440. % the dictionary.
  441. %
  442. /img_build_imagemask_dict
  443.   {
  444.     % check for proper number of operands
  445.     count 5 lt
  446.       { /imagemask .systemvar /stackunderflow signalerror }
  447.     if
  448.  
  449.     % verify that polarity is a boolean
  450.     2 index type /booleantype ne
  451.       { /imagemask .systemvar /typecheck signalerror }
  452.     if
  453.  
  454.     % the imagemask dictionary can be built; do so
  455.     //img_mask_params_ary //img_build_dict exec
  456.   }
  457. .bind def
  458.  
  459. %
  460. %   <?dict?>
  461. %   img_unbuild_imagemask_dict
  462. %   <width>  <height>  <polarity>  <matrix>  <dsrc>
  463. %
  464. % If the top entry of the stack is a dictionary that has the keys rquired
  465. % by an imagemask dictionary, unpack that dictionary onto the stack.
  466. % Otherwise just leave things as they are.
  467. %
  468. /img_unbuild_imagemask_dict
  469.   {
  470.     //img_mask_check_ary //img_check_keys exec
  471.       {
  472.         //img_mask_unbuild_ary //img_unbuild_dict exec
  473.         3 -1 roll
  474.         dup type dup /arraytype eq exch /packedarraytype eq or
  475.         1 index rcheck and
  476.           { 0 get 1 eq }
  477.         if
  478.         3 1 roll
  479.       }
  480.     if
  481.   }
  482. .bind def
  483.  
  484.  
  485. %
  486. %   <width>  <height>  <bits/component>  <matrix>  <dsrc_0> ...
  487. %   <multi>  <ncomp>  <has_alpha>
  488. %   .colorimage 
  489. %   -
  490. %
  491. % Convert the image/colorimage operator from their traditional form to
  492. % the dictionary form. The <has_alpha> operand is used ot support the
  493. % Next alphaimage extension.
  494. %
  495. % Error handling for these operators is a bit complex, due to the stack
  496. % handling required of operators that potentially invoke procedures.
  497. % This problem is discussed in the comment above. The facts relevant to
  498. % this particular implementation are:
  499. %
  500. %   1. The .image1 (or .alphaimage) operator is executed in a stopped
  501. %      context, so that we can undo the gsave context in the event of
  502. %      an error.
  503. %
  504. %   2. In the event of an error, the stack is examined to see if the
  505. %      dictionary passed to .image1 (.alphaimage) is still present.
  506. %      If so, this dictionary is "unpacked" onto the stack to re-
  507. %      create the original stack. The <has_alpha> parameter is not
  508. %      pushed onto the stack, as it is not required for any of the
  509. %      pseudo-operators than invoke this procedure.
  510. %
  511. %   3. The use of pseudo-operators in this case may yield incorrect
  512. %      results for late-detected errors, as the stack depth will be
  513. %      restored (even though the stack is not). This is, however, no
  514. %      worse than the prior (level >= 2) code, so it should cause no
  515. %      new problems.
  516. %
  517. /.colorimage
  518.   {
  519.     % build the image dictionary
  520.     //img_build_image_dict exec
  521.  
  522.     % execute .image1 in a stopped context
  523.       {
  524.         gsave
  525.     % The CET test file 12-02.ps creates colorimages with a width and
  526.     % height of 0.  Ignore these since that is what the CET expects.
  527.     1 index dup /Height get 0 eq exch /Width get 0 eq or
  528.           { pop pop }    % Ignore colorimage.  Pop bool and dict
  529.       {
  530.             0 .setoverprintmode             % disable overprint mode for images
  531.             //img_csary 2 index /IMG_NComps get get setcolorspace
  532.               { .alphaimage }
  533.               { .image1 }
  534.             ifelse
  535.       }
  536.     ifelse
  537.       }
  538.     stopped
  539.     grestore
  540.       {
  541.         //img_unbuild_image_dict exec
  542.         /.colorimage cvx $error /errorname get
  543.         signalerror
  544.       }
  545.     if
  546.   }
  547. .bind def
  548.  
  549.  
  550. %   <width>  <height>  <bits/component>  <matrix>  <dsrc_0> ...
  551. %   <multi>  <ncomp>
  552. %   colorimage 
  553. %   -
  554. %
  555. % Build the colorimage pseudo-operator only if setcolorscreen is visible.
  556. %
  557. systemdict /setcolorscreen .knownget
  558.   {
  559.     type /operatortype eq
  560.       {
  561.         /colorimage 
  562.           {
  563.              //false
  564.                //.colorimage
  565.              stopped
  566.                { /colorimage .systemvar  $error /errorname get signalerror }
  567.              if
  568.           }
  569.         .bind systemdict begin odef end
  570.       }
  571.     if
  572.   }
  573. if
  574.  
  575.  
  576. %
  577. %   width  height  bits_per_component  matrix  data_src   image   -
  578. %   
  579. %   <dict>   image   -
  580. %
  581. % Some special handling is required for ImageType 2 (Display PostScript
  582. % pixmap images) so as to set the appropriate color space as the current
  583. % color space.
  584. %
  585. /image
  586.   {
  587.     dup type /dicttype eq .languagelevel 2 ge and
  588.       { 
  589.         dup /ImageType get dup 2 eq
  590.           {
  591.             % verify the ImageType 2 is supported
  592.             //.imagetypes exch known
  593.               {
  594.                 %
  595.                 % Set either DevicePixel or DeviceRGB as the current
  596.                 % color space. DevicePixel is used if the image data is
  597.                 % to be copied directly, with only a geometric
  598.                 % transformation (PixelCopy true). The use of DeviceRGB
  599.                 % in the alternate case is not, in general, correct, and
  600.                 % reflects a current implementation limitation. Ideally,
  601.                 % an intermediate color space should be used only if
  602.                 % the source and destination color models vary; otherwise
  603.                 % the native color space corresponding to the color model
  604.                 % should be used.
  605.                 %
  606.                 % The mechanism to determine depth for the DevicePixel
  607.                 % color space when BitsPerPixel is not available is 
  608.                 % somewhat of a hack.
  609.                 %
  610.                 gsave
  611.                 0 .setoverprintmode     % disable overprintmode for images
  612.                 dup /PixelCopy .knownget dup
  613.                   { pop }
  614.                 if
  615.                   {
  616.                       [
  617.                         /DevicePixel
  618.                         currentpagedevice dup /BitsPerPixel .knownget
  619.                           { exch pop }
  620.                           {
  621.                             /GrayValues .knownget not
  622.                               { 2 }     % try a guess
  623.                             if
  624.                             ln 2 ln div round cvi
  625.                           }
  626.                         ifelse
  627.                       ]
  628.                   }
  629.                   { /DeviceRGB }
  630.                 ifelse
  631.                 setcolorspace
  632.                 //.imagetypes 2 get
  633.                 stopped
  634.                 grestore
  635.                   { /image .systemvar $error /errorname get signalerror }
  636.                 if
  637.               }
  638.               { /image .systemvar /rangecheck signalerror
  639.               }
  640.             ifelse
  641.           }
  642.           {
  643.             dup //.imagetypes exch .knownget
  644.               {
  645.                 exch pop gsave
  646.                 0 .setoverprintmode         % disable overprintmode for images
  647.                 stopped
  648.                 grestore
  649.                   { /image .systemvar $error /errorname get signalerror }
  650.                 if
  651.               }
  652.               {
  653.                 /image .systemvar exch type /integertype eq
  654.                   { /rangecheck } { /typecheck } 
  655.                 ifelse signalerror
  656.               }
  657.             ifelse
  658.           }
  659.         ifelse
  660.       }
  661.       { 
  662.         //false 1 //false
  663.           //.colorimage
  664.         stopped
  665.           { /image .systemvar $error /errorname get signalerror }
  666.         if
  667.       }
  668.     ifelse
  669.   }
  670. .bind systemdict begin odef end
  671.  
  672. % An auxiliary function for checking whether an imagemask to be interpolated.
  673. /.is_low_resolution    %  <image dict> .is_low_resolution <bool>
  674. {  % Checking whether image pixel maps to more than 2 device pixels.
  675.    % The threshold 2 is arbitrary.
  676.    1 exch 0 exch
  677.    0 exch 1 exch
  678.    /ImageMatrix get dup
  679.    2 {
  680.      4 1 roll
  681.      idtransform dtransform dup mul exch dup mul add sqrt
  682.    } repeat
  683.    max
  684.    2 gt % arbitrary
  685. } .bind def
  686.  
  687.  
  688. %
  689. %   width  height  polarity  matrix  datasrc   imagemask   -
  690. %
  691. % See the comment preceding the definition of .colorimage for information
  692. % as to the handling of error conditions.
  693. %
  694. /imagemask
  695.   {
  696.     dup type /dicttype eq .languagelevel 2 ge and
  697.       { dup /ImageType get
  698.         //.imagemasktypes exch .knownget
  699.           { 1 index //.is_low_resolution exec
  700.             2 index /ImageType get 1 eq and
  701.         2 index /BitsPerComponent get 1 eq and
  702.         2 index /Interpolate .knownget not { false } if and
  703.         //filterdict /ImscaleDecode known and {
  704.           % Apply interpolated imagemask scaling filter
  705.           exch .currentglobal exch dup .gcheck .setglobal
  706.               dup length dict .copydict
  707.           dup dup /DataSource get
  708.               dup type /stringtype eq {
  709.                 1 array astore cvx        % image.* operators read strings repeatesly
  710.               } if
  711.                  mark /Width 3 index /Width get /Height 5 index /Height get .dicttomark
  712.           /ImscaleDecode filter /DataSource exch put
  713.           dup dup /Width get 4 mul /Width exch put
  714.           dup dup /Height get 4 mul /Height exch put
  715.           dup dup /ImageMatrix get
  716.               { 4 0 0 4 0 0 } matrix concatmatrix /ImageMatrix exch put
  717.           3 1 roll .setglobal
  718.         } if
  719.         exec
  720.           }
  721.           { % CET 12-08b.ps wants /typecheck
  722.             /imagemask .systemvar /typecheck signalerror
  723.           }
  724.         ifelse
  725.       }
  726.       {
  727.         //img_build_imagemask_dict exec
  728.           { .imagemask1 }
  729.         stopped
  730.           {
  731.             //img_unbuild_imagemask_dict exec
  732.             /imagemask .systemvar $error /errorname get signalerror
  733.           }
  734.         if
  735.       }
  736.     ifelse
  737.   }
  738. .bind systemdict begin odef end
  739.  
  740. end        % img_utils_dict
  741.  
  742. % Conditionally turn image interpolation on or off.
  743. % INTERPOLATE is not yet set, handle all cases
  744. currentdict /INTERPOLATE known
  745. currentdict /DOTERPOLATE known or
  746. currentdict /NOTERPOLATE known or not {
  747.   currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile
  748. } if
  749.  
  750. /.interpolate {
  751.   dup /Interpolate .knownget not { //false } if
  752.   /INTERPOLATE .systemvar ne {
  753.     dup gcheck .currentglobal exch .setglobal
  754.     exch dup length dict copy
  755.     dup /Interpolate /INTERPOLATE .systemvar put
  756.     exch .setglobal
  757.   } if
  758. } .bind odef
  759.  
  760. /colorimage
  761.   { /INTERPOLATE .systemvar
  762.       { .currentglobal                    % w h bit [] {}...{} multi ncomp glob
  763.         //false .setglobal
  764.         9 dict begin                      % w h bit [] {}...{} multi ncomp glob
  765.         2 .argindex { 1 index 7 add } { 8 } ifelse
  766.     dup .argindex pop          % check # of arguments
  767.         copy gsave pop                    % preserve the arguments
  768.         { 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK }
  769.         1 index get setcolorspace         % ... glob w h bit [] {}...{} multi ncomp
  770.         {0 1 0 1 0 1 0 1}
  771.         1 index 2 mul 0 exch              % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp
  772.         getinterval /Decode exch def      % ... glob w h bit [] {}...{} multi ncomp
  773.         exch dup                          % ... glob w h bit [] {}...{} ncomp multi multi
  774.         /MultipleDataSources exch def     % ... glob w h bit [] {}...{} ncomp multi
  775.         { array astore} { pop } ifelse    % ... glob w h bit [] [{}...{}]
  776.         /DataSource exch def              % ... glob w h bit []
  777.         /ImageMatrix exch def             % ... glob w h bit
  778.         /BitsPerComponent exch def        % ... glob w h
  779.         /Height exch def                  % ... glob w
  780.         /Width exch def                   % ... glob 
  781.         /ImageType 1 def
  782.         /Interpolate //true def
  783.         .setglobal currentdict end        % ... <<>>
  784.         image grestore
  785.         exch { 4 add } { 6 } ifelse
  786.         { pop } repeat                    % -
  787.       }
  788.       { colorimage
  789.       }
  790.     ifelse
  791.   } .bind odef
  792.  
  793. /image
  794.   { dup type /dicttype eq
  795.       { dup /ImageType get 3 eq
  796.           { .currentglobal //false .setglobal exch
  797.             dup length dict copy begin .setglobal 
  798.             /DataDict DataDict .interpolate def
  799.             /MaskDict MaskDict .interpolate def
  800.             currentdict end
  801.           }
  802.           { .interpolate 
  803.           }
  804.         ifelse
  805.         image
  806.       }
  807.       { /INTERPOLATE .systemvar
  808.           { 4 .argindex pop        % check # of args
  809.         .currentglobal //false .setglobal
  810.             8 dict begin .setglobal
  811.             /ImageType 1 def
  812.             /DataSource 1 index def
  813.             /ImageMatrix 2 index def
  814.             /BitsPerComponent 3 index def
  815.             /Decode {0 1} def
  816.             /Height 4 index def
  817.             /Width 5 index def
  818.             /Interpolate //true def
  819.             currentdict end
  820.             gsave /DeviceGray setcolorspace image grestore
  821.             5 { pop } repeat
  822.           }
  823.           { image
  824.           }
  825.         ifelse
  826.       }
  827.     ifelse
  828.   } .bind odef
  829.  
  830. /imagemask {
  831.   dup type /dicttype eq {
  832.     .interpolate imagemask
  833.   } {
  834.     /INTERPOLATE .systemvar {
  835.       4 .argindex pop            % check # of args
  836.       .currentglobal //false .setglobal
  837.       8 dict begin .setglobal
  838.       /ImageType 1 def
  839.       /DataSource 1 index def
  840.       /ImageMatrix 2 index def
  841.       /BitsPerComponent 1 def
  842.       2 index { {1 0} } { {0 1} } ifelse /Decode exch def
  843.       /Height 4 index def
  844.       /Width 5 index def
  845.       /Interpolate //true def
  846.       currentdict end imagemask 5 { pop } repeat
  847.     } {
  848.       imagemask
  849.     } ifelse
  850.   } ifelse
  851. } .bind odef
  852.  
  853. currentdict /.interpolate .undef
  854.  
  855. %END INTERPOLATE
  856.  
  857. .setglobal  % restore VM mode
  858.