335 lines · 10.3 KB · Text
RawDownload
%    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 .dicttomarkdef %%   <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   .dicttomarkput 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 loadcurrentuserparams /ProcessDSCComment get dup null eq {pop {pop pop}} if /exec load4 array astore cvx readonly<< /ProcessDSCComment 3 -1 roll >> setuserparams end	% systemdict%END PSICC.setglobal