1 % Copyright (C) 2001, 2002 Aladdin Enterprises. All rights reserved.
3 % This software is provided AS-IS with no warranty, either express or
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.
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.
16 % $Id: gs_icc.ps,v 1.10 2003/07/14 19:32:17 ray Exp $
17 % ICCBased color space method dictionaries.
18 % This assumes gs_ciecs2.ps has already been processed.
21 % Note that the substitution procedure in this routine will dynamically
22 % check for support of ICCBased color space. If such support is not
23 % provided, the alternative color space will be used.
25 % The validation routine in dictionary (cs_validate) performs a more
26 % extensive validation than is done for other color spaces, because
27 % .seticcspace does less checking than most other color space setting
32 .currentglobal true .setglobal
36 % A dictionary for mapping the number of components of an ICCBased color
37 % space to the appropriate alternative color space. This is used only
38 % if an alternative color space is not specifically provided.
41 mark 1 /DeviceGray 3 /DeviceRGB 4 /DeviceCMYK .dicttomark
45 % <array1> get_icc_alternative_space <name | array2>
47 % Get the alternative color space for an ICCBased color space.
49 /get_icc_alternative_space
51 1 get dup /Alternate .knownget
53 { /N get //icc_comp_map_dict exch get }
62 /cs_potential_indexed_base true
63 /cs_potential_pattern_base true
64 /cs_potential_alternate true
65 /cs_potential_icc_alternate false
66 /cs_get_ncomps { 1 get /N get } bind
70 1 get dup /Range .knownget
72 { /N get 2 mul //dflt_range_4 exch 0 exch getinterval }
77 /cs_get_default_color { 1 get /N get { 0 } repeat } bind
80 % For generating a gray, RGB, or CMYK equivalent color, we will
81 % assume that the alternative color space provides reasonable
84 { //get_icc_alternative_space exec //.cs_get_currentgray exec }
87 { //get_icc_alternative_space exec //.cs_get_currentrgb exec }
90 { //get_icc_alternative_space exec //.cs_get_currentcmyk exec }
93 % a lot of validation is done by the cs_validate method
96 //check_cie_cspace exec
99 dup type /integertype ne
100 //setcspace_typecheck
102 //icc_comp_map_dict exch known not
103 //setcspace_rangecheck
106 dup type dup /stringtype ne exch /filetype ne and
107 //setcspace_typecheck
110 //setcspace_invalidaccess
116 type dup /integertype ne exch /realtype ne and
117 //setcspace_typecheck
126 //.cs_potential_icc_alternate exec not
127 //setcspace_rangecheck
134 % substitute the Alternate space, if appropriate
138 % A design problem in the Ghostscript graphic library color
139 % space code prevents an ICCBased color space from having an
140 % ICCBased alternative color space. This situation actually
141 % arises fairly frequently in PDF, as an ICCBased color space
142 % is used as the substitute color for a Device{Gray|RGB|CMYK}
143 % color space, which in turn are used as the alternative color
144 % space to another (or possibly even the same) ICCBased color
147 % This situation causes no fundamental problems, as
148 % Ghostscript nominally supports ICCBased color spaces, so the
149 % Alternate color space is not used. Where this is not true
150 % (primarily because the NOCIE option is selected), the code
151 % would (except for the design flaw noted above) select the
152 % Alternate of the Alternate color space.
154 % The code below works around this problem by suprressing
155 % color space substitution for alternative color spaces if
156 % the substituting space is an ICCBased color space.
158 dup //get_icc_alternative_space exec
159 //.cs_substitute exec
161 1 index //.cs_potential_icc_alternate exec not
165 % retain just the new Alternate space
168 % build all new structures in local VM
169 .currentglobal 3 1 roll //false .setglobal
171 % copy the original ICCBased color space array
172 1 index dup length array copy
174 % copy the ICCBased dictionary
175 dup 1 2 copy get dup length dict copy
177 % insert the new alterante color space
178 dup /Alternate 7 -1 roll put
180 % insert the new dictionary into the arra
183 % restore the VM mode
191 % The current implementation of ICCBased color spaces requires the
192 % DataSource to be a file.
196 % make DataSource a file
197 dup 1 get /DataSource get type /stringtype eq
199 % build all new structures in local VM
200 .currentglobal exch //false .setglobal
202 % check if we need to copy the color space and dictionary
205 dup length array copy
206 dup 1 2 copy get dup length dict copy put
210 % fetch DataSource, setting up stack for multiple puts
211 dup 1 2 copy get dup /DataSource 2 copy get
213 % convert the string into a file
214 /ReusableStreamDecode filter
216 % put the file into the dictioary, the dictionary into the array
219 % restore the VM mode
227 % Install the current color space.
229 % The current Ghostscript color space implementation requires that
230 % color spaces that provide a base or alternative color space set
231 % that base/alternative color space to be the current color space
232 % before attempting to set the original color space. This can cause
233 % difficulty if an ICCBased color space is being used as a substitute
234 % color space for a device-specific color space, and uses that same
235 % device-specific color space as an alternative space. For this
236 % reason, a special _setcolorspace_nosub operator is provided.
240 % set the alternative color space to be the current color space
241 dup //get_icc_alternative_space exec //_setcolorspace_nosub exec
243 % check for native support
251 % Acrobat Reader silently ignores errors with ICC profiles
252 % and uses the alternate color space -- do the same.
262 % for now, the alternative spaces for an ICCBased color space do
263 % not require special preparation
264 /cs_prepare_color { dup 1 get /N get //check_num_stack exec pop } bind
265 /cs_complete_setcolor //pop_1
272 NOPSICC { (%END PSICC) .skipeof } if
273 % Now set up ICC profile loading for PostScript %%BeginICCProfile sections.
276 /.ProcessICCcomment { % file comment -- file comment
278 (%%BeginICCProfile) anchorsearch {
280 DEBUG { (.ProcessICCcomment found %%BeginICCProfile) print flush } if
282 % load an ICC profile defined as comments (hex encoded).
283 % Ends with %%End at the start of a line. Read the data into
284 % a bytestring to allow seeking. This string can be used as a
285 % seekable ReusableStreamDecode filter source by the ICC logic.
287 % Since .bigstring needs to know the size, we first read an array of
288 % strings each 64000 max length.
290 % stack: --file-- (%%BeginICCProfile: ...)
291 1 index 0 (%%EndICCProfile) /SubFileDecode filter
292 [ { counttomark 1 add index
293 64000 string readhexstring
297 0 1 index { length add } forall
300 % stack: --file-- (%%BeginICCProfile: ...) --bytestring-- cur_index --string--
301 2 copy length add % calculate next string start point
302 3 1 roll 3 index 3 1 roll putinterval
304 pop % discard length of bytestring
305 % make a seekable -file- out of the bytestring
306 mark /AsyncRead true .dicttomark /ReusableStreamDecode filter
307 % stack: --file-- (%%BeginICCProfile: ...) --icc_subfile--
308 /DeviceCMYK setcolorspace
309 << /DataSource 3 -1 roll
310 /N 4 % Try CMYK first
311 >> { .seticcspace } stopped {
312 /DeviceRGB setcolorspace
313 dup /N 3 put { .seticcspace } stopped {
314 /DeviceGray setcolorspace
315 dup /N 1 put { .seticcspace } stopped { % last choice
316 QUIET not { ( *** Unable to load ICC profile from PostScript DSC comments ***) = flush } if
322 pop % Not interested in this DSC comment
326 % Merge ProcessICCcomment with existing handler
327 /.ProcessICCcomment load /exec load
328 currentuserparams /ProcessDSCComment get
329 dup null eq {pop {pop pop}} if /exec load
330 4 array astore cvx readonly
331 << /ProcessDSCComment 3 -1 roll >> setuserparams