gs_img.ps 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  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,v 1.3 2002/10/08 00:49:48 dan Exp $
  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. % <width> <height> <bits/component> <matrix> <dsrc0> ...
  293. % <multi> <ncomp> <has_alpha>
  294. % img_build_image_dict
  295. % <dict> <has_alpha>
  296. %
  297. % Build the dictionary corresponding to a colorimage operand stack. This
  298. % routine will check just enough of the stack to verify that the
  299. % dictionary can be built, and will generate the appropriate error if this
  300. % is not the case.
  301. %
  302. % The <has_alpha> boolean is used to support the Next alphaimage extension.
  303. %
  304. % At the first level, errors in this procedure are reported as colorimage
  305. % errors. The error actually reported will usually be determined by the
  306. % pseudo-operator which invokes this routine.
  307. %
  308. /img_build_image_dict
  309. {
  310. % Veify that at least 8 operands are available, and that the top three
  311. % operands have the expected types
  312. count 8 lt
  313. { /.colorimage cvx /stackunderflow signalerror }
  314. if
  315. 3 copy
  316. type /booleantype ne exch
  317. type /integertype ne or exch
  318. type /booleantype ne or
  319. { /.colorimage cvx /typecheck signalerror }
  320. if
  321. % verify that the number of components is 1, 3, or 4
  322. 1 index 1 lt 2 index 2 eq or 2 index 4 gt or
  323. { /.colorimage cvx /rangecheck signalerror }
  324. if
  325. % Verify that the required number of operands are present if multiple
  326. % data sources are being used. If this test is successful, convert
  327. % the data sources to an array (in local VM).
  328. 2 index
  329. {
  330. % if an alpha component is present, this adds one more component
  331. 2 copy
  332. { 1 add }
  333. if
  334. dup count 9 sub gt
  335. { /.colorimage cvx /stackunderflow signalerror }
  336. if
  337. % build the DataSource array in local VM
  338. dup .currentglobal false .setglobal exch array exch .setglobal
  339. % stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
  340. 5 1 roll 4 add 3 roll astore 4 1 roll
  341. }
  342. if
  343. % the image dictionary can be built; do so
  344. % stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
  345. 8 1 roll //img_params_ary //img_build_dict exec exch
  346. }
  347. .bind def
  348. %
  349. % <?dict?>
  350. % img_unbuild_image_dict
  351. % <width> <height> <bits/component> <matrix> <dsrc0> ...
  352. % <multi> <ncomp>
  353. %
  354. % If the top entry of the stack is a dictionary that has the keys required
  355. % by a colorimage dictionary, unpack that dictionary onto the stack.
  356. % Otherwise just leave things as they are. Note that the <has_alpha>
  357. % parameter is not pushd onto the stack.
  358. %
  359. /img_unbuild_image_dict
  360. {
  361. //img_check_ary //img_check_keys exec
  362. {
  363. //img_unbuild_ary //img_unbuild_dict exec
  364. 1 index type /booleantype eq
  365. {
  366. 1 index
  367. { 3 1 roll aload length 2 add -2 roll }
  368. if
  369. }
  370. if
  371. }
  372. if
  373. }
  374. .bind def
  375. %
  376. % <width> <height> <polarity> <matrix> <dsrc>
  377. % img_unbuild_imagemask_dict
  378. % <dict>
  379. %
  380. % Build the dictionary corresponding to an imagemask stack. This routine
  381. % will verify that the appropriate number of operands are on the stack,
  382. % and that polarity is a boolean. This is all that is necessary to build
  383. % the dictionary.
  384. %
  385. /img_build_imagemask_dict
  386. {
  387. % check for proper number of operands
  388. count 5 lt
  389. { /imagemask load /stackunderflow signalerror }
  390. if
  391. % verify that polarity is a boolean
  392. 2 index type /booleantype ne
  393. { /imagemask load /typecheck signalerror }
  394. if
  395. % the imagemask dictionary can be built; do so
  396. //img_mask_params_ary //img_build_dict exec
  397. }
  398. .bind def
  399. %
  400. % <?dict?>
  401. % img_unbuild_imagemask_dict
  402. % <width> <height> <polarity> <matrix> <dsrc>
  403. %
  404. % If the top entry of the stack is a dictionary that has the keys rquired
  405. % by an imagemask dictionary, unpack that dictionary onto the stack.
  406. % Otherwise just leave things as they are.
  407. %
  408. /img_unbuild_imagemask_dict
  409. {
  410. //img_mask_check_ary //img_check_keys exec
  411. {
  412. //img_mask_unbuild_ary //img_unbuild_dict exec
  413. 3 -1 roll
  414. dup type dup /arraytype eq exch /packedarraytype eq or
  415. 1 index rcheck and
  416. { 0 get 1 eq }
  417. if
  418. 3 1 roll
  419. }
  420. if
  421. }
  422. .bind def
  423. %
  424. % <width> <height> <bits/component> <matrix> <dsrc_0> ...
  425. % <multi> <ncomp> <has_alpha>
  426. % .colorimage
  427. % -
  428. %
  429. % Convert the image/colorimage operator from their traditional form to
  430. % the dictionary form. The <has_alpha> operand is used ot support the
  431. % Next alphaimage extension.
  432. %
  433. % Error handling for these operators is a bit complex, due to the stack
  434. % handling required of operators that potentially invoke procedures.
  435. % This problem is discussed in the comment above. The facts relevant to
  436. % this particular implementation are:
  437. %
  438. % 1. The .image1 (or .alphaimage) operator is executed in a stopped
  439. % context, so that we can undo the gsave context in the event of
  440. % an error.
  441. %
  442. % 2. In the event of an error, the stack is examined to see if the
  443. % dictionary passed to .image1 (.alphaimage) is still present.
  444. % If so, this dictionary is "unpacked" onto the stack to re-
  445. % create the original stack. The <has_alpha> parameter is not
  446. % pushed onto the stack, as it is not required for any of the
  447. % pseudo-operators than invoke this procedure.
  448. %
  449. % 3. The use of pseudo-operators in this case may yield incorrect
  450. % results for late-detected errors, as the stack depth will be
  451. % restored (even though the stack is not). This is, however, no
  452. % worse than the prior (level >= 2) code, so it should cause no
  453. % new problems.
  454. %
  455. /.colorimage
  456. {
  457. % build the image dictionary
  458. //img_build_image_dict exec
  459. % execute .image1 in a stopped context
  460. {
  461. gsave
  462. 0 .setoverprintmode % disable overprint mode for images
  463. //img_csary 2 index /IMG_NComps get get setcolorspace
  464. { .alphaimage }
  465. { .image1 }
  466. ifelse
  467. }
  468. stopped
  469. grestore
  470. {
  471. //img_unbuild_image_dict exec
  472. /.colorimage cvx $error /errorname get
  473. signalerror
  474. }
  475. if
  476. }
  477. .bind def
  478. %
  479. % <width> <height> <bits/component> <matrix> <dsrc_0> ...
  480. % <multi> <ncomp>
  481. % colorimage
  482. % -
  483. %
  484. % Build the colorimage pseudo-operator only if setcolorscreen is visible.
  485. %
  486. systemdict /setcolorscreen .knownget
  487. {
  488. type /operatortype eq
  489. {
  490. /colorimage
  491. {
  492. //false
  493. //.colorimage
  494. stopped
  495. { /colorimage load $error /errorname get signalerror }
  496. if
  497. }
  498. .bind systemdict begin odef end
  499. }
  500. if
  501. }
  502. if
  503. %
  504. % width height bits_per_component matrix data_src image -
  505. %
  506. % <dict> image -
  507. %
  508. % Some special handling is required for ImageType 2 (Display PostScript
  509. % pixmap images) so as to set the appropriate color space as the current
  510. % color space.
  511. %
  512. /image
  513. {
  514. dup type /dicttype eq languagelevel 2 ge and
  515. {
  516. dup /ImageType get dup 2 eq
  517. {
  518. % verify the ImageType 2 is supported
  519. //.imagetypes exch known
  520. {
  521. %
  522. % Set either DevicePixel or DeviceRGB as the current
  523. % color space. DevicePixel is used if the image data is
  524. % to be copied directly, with only a geometric
  525. % transformation (PixelCopy true). The use of DeviceRGB
  526. % in the alternate case is not, in general, correct, and
  527. % reflects a current implementation limitation. Ideally,
  528. % an intermediate color space should be used only if
  529. % the source and destination color models vary; otherwise
  530. % the native color space corresponding to the color model
  531. % should be used.
  532. %
  533. % The mechanism to determine depth for the DevicePixel
  534. % color space when BitsPerPixel is not available is
  535. % somewhat of a hack.
  536. %
  537. gsave
  538. 0 .setoverprintmode % disable overprintmode for images
  539. dup /PixelCopy .knownget dup
  540. { pop }
  541. if
  542. {
  543. [
  544. /DevicePixel
  545. currentpagedevice dup /BitsPerPixel .knownget
  546. { exch pop }
  547. {
  548. /GrayValues .knownget not
  549. { 2 } % try a guess
  550. if
  551. ln 2 ln div round cvi
  552. }
  553. ifelse
  554. ]
  555. }
  556. { /DeviceRGB }
  557. ifelse
  558. setcolorspace
  559. //.imagetypes 2 get
  560. stopped
  561. grestore
  562. { /image load $error /errorname get signalerror }
  563. if
  564. }
  565. { /image load /undefined signalerror }
  566. ifelse
  567. }
  568. {
  569. gsave
  570. 0 .setoverprintmode % disable overprintmode for images
  571. //.imagetypes exch get
  572. stopped
  573. grestore
  574. { /image load $error /errorname get signalerror }
  575. if
  576. }
  577. ifelse
  578. }
  579. {
  580. //false 1 //false
  581. //.colorimage
  582. stopped
  583. { /image load $error /errorname get signalerror }
  584. if
  585. }
  586. ifelse
  587. }
  588. .bind systemdict begin odef end
  589. %
  590. % width height polarity matrix datasrc imagemask -
  591. %
  592. % See the comment preceding the definition of .colorimage for information
  593. % as to the handling of error conditions.
  594. %
  595. /imagemask
  596. {
  597. dup type /dicttype eq languagelevel 2 ge and
  598. { dup /ImageType get //.imagemasktypes exch get exec }
  599. {
  600. //img_build_imagemask_dict exec
  601. { .imagemask1 }
  602. stopped
  603. {
  604. //img_unbuild_imagemask_dict exec
  605. /imagemask load $error /errorname get signalerror
  606. }
  607. if
  608. }
  609. ifelse
  610. }
  611. .bind systemdict begin odef end
  612. end % img_utils_dict
  613. .setglobal % restore VM mode