123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- % Copyright (C) 2001, 2002 Aladdin Enterprises. All rights reserved.
- %
- % This software is provided AS-IS with no warranty, either express or
- % implied.
- %
- % This software is distributed under license and may not be copied,
- % modified or distributed except as expressly authorized under the terms
- % of the license contained in the file LICENSE in this distribution.
- %
- % For more information about licensing, please refer to
- % http://www.ghostscript.com/licensing/. For information on
- % commercial licensing, go to http://www.artifex.com/licensing/ or
- % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
- % $Id: gs_icc.ps,v 1.10 2003/07/14 19:32:17 ray Exp $
- % ICCBased color space method dictionaries.
- % This assumes gs_ciecs2.ps has already been processed.
- %
- % Note that the substitution procedure in this routine will dynamically
- % check for support of ICCBased color space. If such support is not
- % provided, the alternative color space will be used.
- %
- % The validation routine in dictionary (cs_validate) performs a more
- % extensive validation than is done for other color spaces, because
- % .seticcspace does less checking than most other color space setting
- % operators.
- %
- .currentglobal true .setglobal
- .cspace_util begin
- %
- % A dictionary for mapping the number of components of an ICCBased color
- % space to the appropriate alternative color space. This is used only
- % if an alternative color space is not specifically provided.
- %
- /icc_comp_map_dict
- mark 1 /DeviceGray 3 /DeviceRGB 4 /DeviceCMYK .dicttomark
- def
- %
- % <array1> get_icc_alternative_space <name | array2>
- %
- % Get the alternative color space for an ICCBased color space.
- %
- /get_icc_alternative_space
- {
- 1 get dup /Alternate .knownget
- { exch pop }
- { /N get //icc_comp_map_dict exch get }
- ifelse
- }
- bind def
- colorspacedict
- /ICCBased
- mark
- /cs_potential_indexed_base true
- /cs_potential_pattern_base true
- /cs_potential_alternate true
- /cs_potential_icc_alternate false
- /cs_get_ncomps { 1 get /N get } bind
- /cs_get_range
- {
- 1 get dup /Range .knownget
- { exch pop }
- { /N get 2 mul //dflt_range_4 exch 0 exch getinterval }
- ifelse
- }
- bind
- /cs_get_default_color { 1 get /N get { 0 } repeat } bind
- %
- % For generating a gray, RGB, or CMYK equivalent color, we will
- % assume that the alternative color space provides reasonable
- % mapping.
- /cs_get_currentgray
- { //get_icc_alternative_space exec //.cs_get_currentgray exec }
- bind
- /cs_get_currentrgb
- { //get_icc_alternative_space exec //.cs_get_currentrgb exec }
- bind
- /cs_get_currentcmyk
- { //get_icc_alternative_space exec //.cs_get_currentcmyk exec }
- bind
- % a lot of validation is done by the cs_validate method
- /cs_validate
- {
- //check_cie_cspace exec
- dup 1 get
- dup /N get
- dup type /integertype ne
- //setcspace_typecheck
- if
- //icc_comp_map_dict exch known not
- //setcspace_rangecheck
- if
- dup /DataSource get
- dup type dup /stringtype ne exch /filetype ne and
- //setcspace_typecheck
- if
- rcheck not
- //setcspace_invalidaccess
- if
- dup /Range .knownget
- {
- //check_array exec
- {
- type dup /integertype ne exch /realtype ne and
- //setcspace_typecheck
- if
- }
- forall
- }
- if
- /Alternate .knownget
- {
- //.cs_validate exec
- //.cs_potential_icc_alternate exec not
- //setcspace_rangecheck
- if
- }
- if
- }
- bind
- % substitute the Alternate space, if appropriate
- /cs_substitute
- {
- %
- % A design problem in the Ghostscript graphic library color
- % space code prevents an ICCBased color space from having an
- % ICCBased alternative color space. This situation actually
- % arises fairly frequently in PDF, as an ICCBased color space
- % is used as the substitute color for a Device{Gray|RGB|CMYK}
- % color space, which in turn are used as the alternative color
- % space to another (or possibly even the same) ICCBased color
- % space.
- %
- % This situation causes no fundamental problems, as
- % Ghostscript nominally supports ICCBased color spaces, so the
- % Alternate color space is not used. Where this is not true
- % (primarily because the NOCIE option is selected), the code
- % would (except for the design flaw noted above) select the
- % Alternate of the Alternate color space.
- %
- % The code below works around this problem by suprressing
- % color space substitution for alternative color spaces if
- % the substituting space is an ICCBased color space.
- %
- dup //get_icc_alternative_space exec
- //.cs_substitute exec
- 2 copy eq
- 1 index //.cs_potential_icc_alternate exec not
- or
- { pop pop dup }
- {
- % retain just the new Alternate space
- exch pop
- % build all new structures in local VM
- .currentglobal 3 1 roll //false .setglobal
- % copy the original ICCBased color space array
- 1 index dup length array copy
- % copy the ICCBased dictionary
- dup 1 2 copy get dup length dict copy
- % insert the new alterante color space
- dup /Alternate 7 -1 roll put
- % insert the new dictionary into the arra
- put
- % restore the VM mode
- 3 -1 roll .setglobal
- }
- ifelse
- }
- bind
- %
- % The current implementation of ICCBased color spaces requires the
- % DataSource to be a file.
- %
- /cs_prepare
- {
- % make DataSource a file
- dup 1 get /DataSource get type /stringtype eq
- {
- % build all new structures in local VM
- .currentglobal exch //false .setglobal
- % check if we need to copy the color space and dictionary
- 2 copy eq
- {
- dup length array copy
- dup 1 2 copy get dup length dict copy put
- }
- if
- % fetch DataSource, setting up stack for multiple puts
- dup 1 2 copy get dup /DataSource 2 copy get
- % convert the string into a file
- /ReusableStreamDecode filter
- % put the file into the dictioary, the dictionary into the array
- put put
- % restore the VM mode
- exch .setglobal
- }
- if
- }
- bind
- %
- % Install the current color space.
- %
- % The current Ghostscript color space implementation requires that
- % color spaces that provide a base or alternative color space set
- % that base/alternative color space to be the current color space
- % before attempting to set the original color space. This can cause
- % difficulty if an ICCBased color space is being used as a substitute
- % color space for a device-specific color space, and uses that same
- % device-specific color space as an alternative space. For this
- % reason, a special _setcolorspace_nosub operator is provided.
- %
- /cs_install
- {
- % set the alternative color space to be the current color space
- dup //get_icc_alternative_space exec //_setcolorspace_nosub exec
- % check for native support
- /.seticcspace where
- { pop //false }
- { //true }
- ifelse
- NOCIE or
- //pop_1 % do nothing
- {
- % Acrobat Reader silently ignores errors with ICC profiles
- % and uses the alternate color space -- do the same.
- mark exch 1 get
- { .seticcspace }
- .internalstopped
- cleartomark
- }
- ifelse
- }
- bind
- % for now, the alternative spaces for an ICCBased color space do
- % not require special preparation
- /cs_prepare_color { dup 1 get /N get //check_num_stack exec pop } bind
- /cs_complete_setcolor //pop_1
- .dicttomark
- put
- end % .cspace_util
- NOPSICC { (%END PSICC) .skipeof } if
- % Now set up ICC profile loading for PostScript %%BeginICCProfile sections.
- systemdict begin
- /.ProcessICCcomment { % file comment -- file comment
- dup
- (%%BeginICCProfile) anchorsearch {
- pop pop
- DEBUG { (.ProcessICCcomment found %%BeginICCProfile) print flush } if
- % load an ICC profile defined as comments (hex encoded).
- % Ends with %%End at the start of a line. Read the data into
- % a bytestring to allow seeking. This string can be used as a
- % seekable ReusableStreamDecode filter source by the ICC logic.
- %
- % Since .bigstring needs to know the size, we first read an array of
- % strings each 64000 max length.
- %
- % stack: --file-- (%%BeginICCProfile: ...)
- 1 index 0 (%%EndICCProfile) /SubFileDecode filter
- [ { counttomark 1 add index
- 64000 string readhexstring
- not { exit } if
- } loop
- ] exch closefile
- 0 1 index { length add } forall
- .bigstring
- exch 0 exch {
- % stack: --file-- (%%BeginICCProfile: ...) --bytestring-- cur_index --string--
- 2 copy length add % calculate next string start point
- 3 1 roll 3 index 3 1 roll putinterval
- } forall
- pop % discard length of bytestring
- % make a seekable -file- out of the bytestring
- mark /AsyncRead true .dicttomark /ReusableStreamDecode filter
- % stack: --file-- (%%BeginICCProfile: ...) --icc_subfile--
- /DeviceCMYK setcolorspace
- << /DataSource 3 -1 roll
- /N 4 % Try CMYK first
- >> { .seticcspace } stopped {
- /DeviceRGB setcolorspace
- dup /N 3 put { .seticcspace } stopped {
- /DeviceGray setcolorspace
- dup /N 1 put { .seticcspace } stopped { % last choice
- QUIET not { ( *** Unable to load ICC profile from PostScript DSC comments ***) = flush } if
- pop
- } if
- } if
- } if
- } {
- pop % Not interested in this DSC comment
- } ifelse
- } bind def
- % Merge ProcessICCcomment with existing handler
- /.ProcessICCcomment load /exec load
- currentuserparams /ProcessDSCComment get
- dup null eq {pop {pop pop}} if /exec load
- 4 array astore cvx readonly
- << /ProcessDSCComment 3 -1 roll >> setuserparams
- end % systemdict
- %END PSICC
- .setglobal
|