gs_icc.ps 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. % Copyright (C) 2001, 2002 Aladdin Enterprises. 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_icc.ps,v 1.10 2003/07/14 19:32:17 ray Exp $
  16. % ICCBased color space method dictionaries.
  17. % This assumes gs_ciecs2.ps has already been processed.
  18. %
  19. % Note that the substitution procedure in this routine will dynamically
  20. % check for support of ICCBased color space. If such support is not
  21. % provided, the alternative color space will be used.
  22. %
  23. % The validation routine in dictionary (cs_validate) performs a more
  24. % extensive validation than is done for other color spaces, because
  25. % .seticcspace does less checking than most other color space setting
  26. % operators.
  27. %
  28. .currentglobal true .setglobal
  29. .cspace_util begin
  30. %
  31. % A dictionary for mapping the number of components of an ICCBased color
  32. % space to the appropriate alternative color space. This is used only
  33. % if an alternative color space is not specifically provided.
  34. %
  35. /icc_comp_map_dict
  36. mark 1 /DeviceGray 3 /DeviceRGB 4 /DeviceCMYK .dicttomark
  37. def
  38. %
  39. % <array1> get_icc_alternative_space <name | array2>
  40. %
  41. % Get the alternative color space for an ICCBased color space.
  42. %
  43. /get_icc_alternative_space
  44. {
  45. 1 get dup /Alternate .knownget
  46. { exch pop }
  47. { /N get //icc_comp_map_dict exch get }
  48. ifelse
  49. }
  50. bind def
  51. colorspacedict
  52. /ICCBased
  53. mark
  54. /cs_potential_indexed_base true
  55. /cs_potential_pattern_base true
  56. /cs_potential_alternate true
  57. /cs_potential_icc_alternate false
  58. /cs_get_ncomps { 1 get /N get } bind
  59. /cs_get_range
  60. {
  61. 1 get dup /Range .knownget
  62. { exch pop }
  63. { /N get 2 mul //dflt_range_4 exch 0 exch getinterval }
  64. ifelse
  65. }
  66. bind
  67. /cs_get_default_color { 1 get /N get { 0 } repeat } bind
  68. %
  69. % For generating a gray, RGB, or CMYK equivalent color, we will
  70. % assume that the alternative color space provides reasonable
  71. % mapping.
  72. /cs_get_currentgray
  73. { //get_icc_alternative_space exec //.cs_get_currentgray exec }
  74. bind
  75. /cs_get_currentrgb
  76. { //get_icc_alternative_space exec //.cs_get_currentrgb exec }
  77. bind
  78. /cs_get_currentcmyk
  79. { //get_icc_alternative_space exec //.cs_get_currentcmyk exec }
  80. bind
  81. % a lot of validation is done by the cs_validate method
  82. /cs_validate
  83. {
  84. //check_cie_cspace exec
  85. dup 1 get
  86. dup /N get
  87. dup type /integertype ne
  88. //setcspace_typecheck
  89. if
  90. //icc_comp_map_dict exch known not
  91. //setcspace_rangecheck
  92. if
  93. dup /DataSource get
  94. dup type dup /stringtype ne exch /filetype ne and
  95. //setcspace_typecheck
  96. if
  97. rcheck not
  98. //setcspace_invalidaccess
  99. if
  100. dup /Range .knownget
  101. {
  102. //check_array exec
  103. {
  104. type dup /integertype ne exch /realtype ne and
  105. //setcspace_typecheck
  106. if
  107. }
  108. forall
  109. }
  110. if
  111. /Alternate .knownget
  112. {
  113. //.cs_validate exec
  114. //.cs_potential_icc_alternate exec not
  115. //setcspace_rangecheck
  116. if
  117. }
  118. if
  119. }
  120. bind
  121. % substitute the Alternate space, if appropriate
  122. /cs_substitute
  123. {
  124. %
  125. % A design problem in the Ghostscript graphic library color
  126. % space code prevents an ICCBased color space from having an
  127. % ICCBased alternative color space. This situation actually
  128. % arises fairly frequently in PDF, as an ICCBased color space
  129. % is used as the substitute color for a Device{Gray|RGB|CMYK}
  130. % color space, which in turn are used as the alternative color
  131. % space to another (or possibly even the same) ICCBased color
  132. % space.
  133. %
  134. % This situation causes no fundamental problems, as
  135. % Ghostscript nominally supports ICCBased color spaces, so the
  136. % Alternate color space is not used. Where this is not true
  137. % (primarily because the NOCIE option is selected), the code
  138. % would (except for the design flaw noted above) select the
  139. % Alternate of the Alternate color space.
  140. %
  141. % The code below works around this problem by suprressing
  142. % color space substitution for alternative color spaces if
  143. % the substituting space is an ICCBased color space.
  144. %
  145. dup //get_icc_alternative_space exec
  146. //.cs_substitute exec
  147. 2 copy eq
  148. 1 index //.cs_potential_icc_alternate exec not
  149. or
  150. { pop pop dup }
  151. {
  152. % retain just the new Alternate space
  153. exch pop
  154. % build all new structures in local VM
  155. .currentglobal 3 1 roll //false .setglobal
  156. % copy the original ICCBased color space array
  157. 1 index dup length array copy
  158. % copy the ICCBased dictionary
  159. dup 1 2 copy get dup length dict copy
  160. % insert the new alterante color space
  161. dup /Alternate 7 -1 roll put
  162. % insert the new dictionary into the arra
  163. put
  164. % restore the VM mode
  165. 3 -1 roll .setglobal
  166. }
  167. ifelse
  168. }
  169. bind
  170. %
  171. % The current implementation of ICCBased color spaces requires the
  172. % DataSource to be a file.
  173. %
  174. /cs_prepare
  175. {
  176. % make DataSource a file
  177. dup 1 get /DataSource get type /stringtype eq
  178. {
  179. % build all new structures in local VM
  180. .currentglobal exch //false .setglobal
  181. % check if we need to copy the color space and dictionary
  182. 2 copy eq
  183. {
  184. dup length array copy
  185. dup 1 2 copy get dup length dict copy put
  186. }
  187. if
  188. % fetch DataSource, setting up stack for multiple puts
  189. dup 1 2 copy get dup /DataSource 2 copy get
  190. % convert the string into a file
  191. /ReusableStreamDecode filter
  192. % put the file into the dictioary, the dictionary into the array
  193. put put
  194. % restore the VM mode
  195. exch .setglobal
  196. }
  197. if
  198. }
  199. bind
  200. %
  201. % Install the current color space.
  202. %
  203. % The current Ghostscript color space implementation requires that
  204. % color spaces that provide a base or alternative color space set
  205. % that base/alternative color space to be the current color space
  206. % before attempting to set the original color space. This can cause
  207. % difficulty if an ICCBased color space is being used as a substitute
  208. % color space for a device-specific color space, and uses that same
  209. % device-specific color space as an alternative space. For this
  210. % reason, a special _setcolorspace_nosub operator is provided.
  211. %
  212. /cs_install
  213. {
  214. % set the alternative color space to be the current color space
  215. dup //get_icc_alternative_space exec //_setcolorspace_nosub exec
  216. % check for native support
  217. /.seticcspace where
  218. { pop //false }
  219. { //true }
  220. ifelse
  221. NOCIE or
  222. //pop_1 % do nothing
  223. {
  224. % Acrobat Reader silently ignores errors with ICC profiles
  225. % and uses the alternate color space -- do the same.
  226. mark exch 1 get
  227. { .seticcspace }
  228. .internalstopped
  229. cleartomark
  230. }
  231. ifelse
  232. }
  233. bind
  234. % for now, the alternative spaces for an ICCBased color space do
  235. % not require special preparation
  236. /cs_prepare_color { dup 1 get /N get //check_num_stack exec pop } bind
  237. /cs_complete_setcolor //pop_1
  238. .dicttomark
  239. put
  240. end % .cspace_util
  241. NOPSICC { (%END PSICC) .skipeof } if
  242. % Now set up ICC profile loading for PostScript %%BeginICCProfile sections.
  243. systemdict begin
  244. /.ProcessICCcomment { % file comment -- file comment
  245. dup
  246. (%%BeginICCProfile) anchorsearch {
  247. pop pop
  248. DEBUG { (.ProcessICCcomment found %%BeginICCProfile) print flush } if
  249. % load an ICC profile defined as comments (hex encoded).
  250. % Ends with %%End at the start of a line. Read the data into
  251. % a bytestring to allow seeking. This string can be used as a
  252. % seekable ReusableStreamDecode filter source by the ICC logic.
  253. %
  254. % Since .bigstring needs to know the size, we first read an array of
  255. % strings each 64000 max length.
  256. %
  257. % stack: --file-- (%%BeginICCProfile: ...)
  258. 1 index 0 (%%EndICCProfile) /SubFileDecode filter
  259. [ { counttomark 1 add index
  260. 64000 string readhexstring
  261. not { exit } if
  262. } loop
  263. ] exch closefile
  264. 0 1 index { length add } forall
  265. .bigstring
  266. exch 0 exch {
  267. % stack: --file-- (%%BeginICCProfile: ...) --bytestring-- cur_index --string--
  268. 2 copy length add % calculate next string start point
  269. 3 1 roll 3 index 3 1 roll putinterval
  270. } forall
  271. pop % discard length of bytestring
  272. % make a seekable -file- out of the bytestring
  273. mark /AsyncRead true .dicttomark /ReusableStreamDecode filter
  274. % stack: --file-- (%%BeginICCProfile: ...) --icc_subfile--
  275. /DeviceCMYK setcolorspace
  276. << /DataSource 3 -1 roll
  277. /N 4 % Try CMYK first
  278. >> { .seticcspace } stopped {
  279. /DeviceRGB setcolorspace
  280. dup /N 3 put { .seticcspace } stopped {
  281. /DeviceGray setcolorspace
  282. dup /N 1 put { .seticcspace } stopped { % last choice
  283. QUIET not { ( *** Unable to load ICC profile from PostScript DSC comments ***) = flush } if
  284. pop
  285. } if
  286. } if
  287. } if
  288. } {
  289. pop % Not interested in this DSC comment
  290. } ifelse
  291. } bind def
  292. % Merge ProcessICCcomment with existing handler
  293. /.ProcessICCcomment load /exec load
  294. currentuserparams /ProcessDSCComment get
  295. dup null eq {pop {pop pop}} if /exec load
  296. 4 array astore cvx readonly
  297. << /ProcessDSCComment 3 -1 roll >> setuserparams
  298. end % systemdict
  299. %END PSICC
  300. .setglobal