984 lines · 28.8 KB · Text
RawDownload
%    Copyright (C) 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_cspace.ps,v 1.6 2003/06/26 22:42:33 dan Exp $% basic colorspace mechanism %% This new implementation of color spaces extends the color space % formalism to all PostScript levels. Level specific features and % operators continue to be accessible only in the appropriate level, % but the colorspace concept and associated mechanisms are used % throughout.%% The color space mechanism is built around two dictionaries:%%   .cspace_util%       A dictionary in global VM that is accessible in userdict only%       during initialization. This dictionary is intended for various%       utility procedures that are used in implementing the individual%       color spaces.%%   colorspacedict%       A dictionary of methods for each color space type. The keys%       in this dictionary are color space type names (e.g.: /DeviceGray,%       /Separation, etc.), and the values are dictionaries of methods.%       The set of methods is the same for each color space type, and%       provides a complete implementation for the corresponding color%       space type. This dictionary is in global VM.%% The information specific to a color space type is created in a file% for that type or group of types (e.g.: gs_csdev.ps, gs_csindx.ps,% etc.). These files will generally adhere to the template:%%      .currentglobal true .setglobal%      <level-specific dictionary> begin%      ...%      .cspace_util begin%      colorspacedict%      /<color space type name>%       mark%          /cs_validate%            {%               ...%            }%          bind%          ...%       .dicttomark%      put%      end      % .cspace_util%      end ...  % level-specific dictionary%      .setglobal%% The methods associated with a color space are listed below (along with% their stack handling), followed by descriptions.%%   -   cs_potential_indexed_base   <bool>%%   -   cs_potential_pattern_base   <bool>%%   -   cs_potential_alternate   <bool>%%   -   cs_potential_icc_alternate   <bool>%%%   <name | array>   cs_get_ncomps   <int>%%   <name | array>   cs_get_range   <range_array>%%   <name | array>   cs_get_default_color   <c1> ... <cn>%%%   <c1> ... <cn>  <name | array>   cs_get_currentgray   <gray>%%   <c1> ... <cn>  <name | array>   cs_get_currentrgb   <red>  <green>  <blue>%%   <c1> ... <cn>  <name | array>   cs_get_currentcmyk %                                       <cyan>  <magenta>  <yellow>  <black>%%%   <name | array>   cs_validate   <name | array>%%   <name1 | array1>    cs_substitute   <name1 | array1>  <array2>%%   <name1 | array1>  <array2>   cs_prepare   <name1 | array1>  <array2>%%   <name | array>   cs_install   -%%%   <c1> ... <cn>  <array>   cs_verify_color   <c1> ... <cn>%%   <array>   cs_complete_color   -%%% cs_potential_indexed_base, cs_potential_pattern_base,% cs_potential_alternate, cs_potential_icc_alternate%   These are booleans rather than procedures. They indicate if the color%   space can be a base space of an Indexed color space (anything except%   Indexed and Pattern), a Pattern color space (anything except Pattern),%   the alternative color space of a Separation or DeviceN color space, or%   the alternative color space of an ICCBased color space. The two%   parameters are distinct only because of a Ghostscript-specific%   implementation problem; in principle, there is nothing special about%   ICCBased color spaces in this regard.%% cs_get_ncomps%   Return the number of color components for the color spaces. For Pattern%   color spaces, the value is -1 if there is no base space, or -(n + 1) if%   the base space has n components.%% cs_get_range%   Return the input Range array appropriate for this color space. This is%   defined for all color spaces, though it is of interest primarily for%   CIEBased and ICCBased color spaces. For Indexed color spaces this is%   [ 0 hival ], where hival is the maximum support index value. For all%   other non-CIEBased, non-ICCBased color spaces, the range is an array%   of ncomps elements, all of which are [ 0 1 ], where ncomps is the %   number of color space components.%% cs_get_default_color%   Generates the default color for the current color space. Under normal%   circumstances this is done internally. It is provided in PostScript%   only to support an optimization that doesn't change the current color%   space more often than necessary.%% cs_get_currentgray, cs_get_currentrgb, cs_get_currentcmyk%   These procedures are used to implement the currentgray, currentrgb,%   and currentcmyk operators (which are pseudo-operators in the current%   implementation).%% cs_validate%   Validate the operand color space. Because color spaces are extensively%   manipulated in PostScript in this implementation, error handling can%   become burdensome. To make the code somewhat simpler, it is useful to%   be able to validate a color space prior to manipulation, so as to%   ensure that errors are not discovered in awkward places.%% cs_substitute%   Substitute a device-independent color space for device specific color%   space. This applies directly to the device-specific color spaces%   (DeviceGray, DeviceRGB, DeviceCMYK), and indirectly when these color%   spaces are used as base/alternative color spaces. The mechanism for%   color substitution is included in all language levels, though it may%   only be accessed for Language Level 3.%%   The substituted color space is the topmost of the operands pushed.%   this may or may not be the same as the original color space, which%   is immediately below it on the operand stack. If the two differ,%   the substituted space will always be in local VM (and will be%   writable).%%   Substitution is applied recursively to the base/alternate color%   space of ICCBased, Indexed, Separation, DeviceN, or Pattern%   color spaces. Because Ghostscript currently requires that any%   base or alternative color space be the current color space when%   the enclosing color space is set, this substitution effectively%   occurs twice: once in the original color space, and once when the%   base/alternative color space is made the current color space.%   We retain the first substitution as we would eventually like to%   remove the restriction on making the base/alternative color space%   the current color space.%% cs_prepare%   Perform any operations required on the color space for installation.%   This method exists primarily to allow conversion of PostScript%   procedures to functions for CIEBased color spaces. Two operands are%   provided: the original and the substituted color space. If the two%   differ and the latter is writable, required modifications can%   be made "in place". Otherwise, a new instance of the second color%   space must be built.%%   Currently, cs_prepare is not explicitly recursive. Because%   Ghostscript requires a base/alternate color space to be installed%   as the current color space prior to installing the enclosing color%   space, the cs_prepare method will implicitly be called recursively.%   The reason for not making this explicit is that color space%   preparation may involve a considerable amount of work, which could%   be avoided if, for example, an alternative color space will not%   be used because the enclosing Separation/DeviceN color space is%   supported in native mode by the process color model. We would%   eventually like to remove the need to prepare color spaces that%   will not be used.%% cs_install%   This method actually installs the color space in the graphic state.%   Only the substituted/prepared space (which may be the same as the%   original space) is passed as an operand; the original space is handled%   directly by the .setcolorspace operator.%%   The provision of a separate method for this tasks reflects the%   historical implementation of color spaces in the Ghostscript%   interpreter. This implementation provides a unique operator for each%   color space type.%% cs_prepare_color%   Modify a set of color operands as required by a color space. This%   is used primarily to verify the color operands, as this is most%   conveniently done in PostScript.%% cs_complete_setcolor%   This method is invoked immediately after a (successful) invocation%   of setcolor. Ii is provided as a separate method for compatibility%   with Adobe implementations. These implementations invoke the lookup%   (Indexed) or tint procedure each time setcolor is invoked (only if%   the alternative color space is used in the case of the tint%   transform). Because Ghostscript may convert these procedures to%   functions (or pre-sample them), the procedures may not always be%   called when expected. There are applications that depend on this%   behavior (e.g.: Adobe PhotoShop 5+), so this method provides a way%   to emulate it.%%   In principle, a cs_complete_setcolor procedure for an Indexed color%   space whose base space should invoke cs_complete_setcolor on its%   base space. Currently we don't do this, because it has not been%   shown to be necessary. It would be simple to add if it is every%   needed.%% All of these methods are procedures.%% For each of these methods, there is a procedure in .cspace_util with% a dot ('.') prefix that will invoke the appropriate procedure for the% operand array.% .currentglobal true .setglobaluserdict /.cspace_util 80 dict put.cspace_util begin %% Colorspacedict is initially in .cspace_util; it is copied to level2dict% in the Level 2 initialization code to retain compatibility with % earlier implementations.%/colorspacedict 20 dict def  %%   <obj>   make_array1   <array>%% procedure for conditionally converting a named color space to a% 1-element array. Since names are always global, the array will be% as well.%/make_array1  {    dup type /nametype eq      { currentglobal true setglobal exch 1 array astore exch setglobal }    if  }bind def %%  <name|array>   .get_cspace_type   name%% Provide generic routine for retrieving the color space type.%/.get_cspace_type  {    dup type dup /arraytype eq exch /packedarraytype eq or      { 0 get }    if  }bind def %%   <name|array>   .get_method_dict   <dict>%% Get the method dictionary for a specific color space. Note that the% color space is left on the stack.%/.get_method_dict  { //colorspacedict exch //.get_cspace_type exec get }bind def %%   <name|array>  <proc_name>   .get_method   <name|array>  <proc | bool>%% Get the named method for the operand color space.%/.get_method  { exch //.get_method_dict exec exch get }bind def  %%   <name_array>   .cs_potential_indexed_base   <bool>%   <name_array>   .cs_potential_pattern_base   <bool>%   <name_array>   .cs_potential_alternate    <bool>%   <name_array>   .cs_potential_icc_alternate   <bool>%   <name | array>   .cs_get_ncomps   <int>%   <name | array>   .cs_get_range   <range_array>%   <name | array>   .cs_get_default_color   <c1>  ...  <cn>%   <c1> ... <cn>  <name | array>   .cs_get_currentgray   <gray>%   <c1> ... <cn>  <name | array>   .cs_get_currentrgb   <r>  <g>  <b>%   <c1> ... <cn>  <name | array>   .cs_get_currentcmyk   <c>  <m>  <y>  <k>%   <name | array>   .cs_validate   <name | array>%   <name1 | array1>   .cs_substitute   <name1 | array1>  <array2>%   <name1 | array1>  <array2>   .cs_prepare   <name1 | array1>  <array2>%   <name | array>   .cs_install   -%   <c1> ... <cn> <array>   .cs_prepare_color   <c1> ... <cn>%   <array>   .cs_complete_setcolor   -%% These procedures provide access to the corresponding methods of the% operand color space.%/.cs_potential_indexed_base  { /cs_potential_indexed_base //.get_method exec }bind def /.cs_potential_pattern_base  { /cs_potential_pattern_base //.get_method exec }bind def /.cs_potential_alternate  { /cs_potential_alternate //.get_method exec }bind def /.cs_potential_icc_alternate  { /cs_potential_icc_alternate //.get_method exec }bind def /.cs_get_ncomps  { dup /cs_get_ncomps //.get_method exec exec }bind def /.cs_get_range  { dup /cs_get_range //.get_method exec exec }bind def /.cs_get_default_color  { dup /cs_get_default_color //.get_method exec exec }bind def /.cs_get_currentgray  { dup /cs_get_currentgray //.get_method exec exec }bind def /.cs_get_currentrgb  { dup /cs_get_currentrgb //.get_method exec exec }bind def /.cs_get_currentcmyk  { dup /cs_get_currentcmyk //.get_method exec exec }bind def /.cs_validate  { dup /cs_validate //.get_method exec exec }bind def /.cs_substitute  { dup /cs_substitute //.get_method exec exec }bind def /.cs_prepare  { dup /cs_prepare //.get_method exec exec }bind def /.cs_install  { dup /cs_install //.get_method exec exec }bind def /.cs_prepare_color  { dup /cs_prepare_color //.get_method exec exec }bind def /.cs_complete_setcolor  { dup /cs_complete_setcolor //.get_method exec exec }bind def  %% Make sure we have an interpreter color space before redefining% setcolorspace. The interpreter internal code only sets the effective% color space; the interpreters color spaces begins as a null object.%% NB: This should come prior to the redefinition of setcolorspace, and%     must use an array operand.%[ /DeviceGray ] setcolorspace  %%   <c1> ... <cn>   setcolor   -%% As with setcolorspace, setcolor is initially placed in .cspace_util,% and is copied to level2dict by the Level 2 initialization code. The% internal definition of setcolor is removed from systemdict as soon% as this procedure is defined.%/setcolor  {      {        currentcolorspace //.cs_prepare_color exec //setcolor        currentcolorspace //.cs_complete_setcolor exec      }    stopped      { //.cspace_util /setcolor get $error /errorname get signalerror }    if  }bind odef systemdict /setcolor .undef  %%   <name|array>  <bool>   _setcolorspace   -%   <name|array>   _setcolorspace_nosub   -%%   <name|array>   setcolorspace   -%   <name|array>   forcesetcolorspace   -%% setcolorspace is initially placed in .cspace_util. It is copied to% level2dict by the Level 2 initialization code. The internal% setcolorspace operator is removed from systemdict as soon as this% procedure is defined.%% Because some jobs, in particular PDF jobs, repeatedly set the same% color space, this procedure will check if the operand and current% color spaces are the same. The check is absolute for parameterless% color spaces, conservative for others. For PostScript, this% optimization can only be employed if color space substitution is% disabled, as otherwise there is no way to account for  possible changes% in the /Default* instances of the ColorSpace resource category. For PDF% jobs, resource category instances can only be changed at very specific% times (typically page boundaries), so the "operand color space is the% same as current color space" optimization may be used even if color% space substitution is in effect. The optimization is also highly% desirable in such cases, as it greatly improves performance.%% In certain situations, it is critical that a color space be set,% even if it is the same as the current color space. This is the case% when a CIEBased color space is used as a base or alternative color% space, due to some long-standing problems with the graphics libraries% handling of sampled information from the procedures in CIE color% spaces and the color rendering dictionary. The forcesetcolorspace% operator is provided for those situations.%% Note also that, if the current color space is not reset, at least% the current color must be reset to its default value.%% Another problem arises in the case of ICCBased color spaces. These% color spaces may be used to substitute for a DeviceGray/DeviceRGB/% DeviceCMYK color space, and may themselves require such a color% space as an alternate. Obviously, when this is the case the normal% setcolorspace mechanism would encounter and infinite loop if the% alternate colro space needed to be used. For this particular case,% the special _setcolorspace_nosub is provided, which suppresses% color space substitution. This routine does not bother to check if% the operand and current color space are the same.%/_setcolorspace  {      {        % see if the operand space is the same as the current space        currentcolorspace dup length 1 eq          {            0 get            2 index dup type dup /arraytype eq exch /packedarraytype eq or              {                dup length 1 eq                  { 0 get }                if              }            if          }          { 2 index }        ifelse        eq and dup          {            %            % If PDFfile is defined on the dictionary stack, this is a            % PDF job. No additional check is required in this case (see            % comment above).            %            /PDFfile where              { pop }              { .getuseciecolor not and }   % check that UseCIEColor is off            ifelse          }        if          { //.cs_get_default_color exec setcolor }          {            //.cs_validate exec            //.cs_substitute exec            //.cs_prepare exec            //.cs_install exec            //make_array1 exec //setcolorspace          }        ifelse

Lines 1–500 of 984.