星火微课系统客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gs_img.ps 28KB

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