335 lines
10 KiB
PostScript
335 lines
10 KiB
PostScript
% 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
|