summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/lib/gs_icc.ps
blob: 7068940ed922f4b7f4bc4486638c5a950632fa2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
%    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 8306 2007-10-20 16:34:38Z alexcher $
% 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
            dup //.cs_potential_icc_alternate exec not
              {
                0 get /ICCBased ne
                  //setcspace_rangecheck
                if
              }
              { pop }
            ifelse
          }
        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