Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
% (C) 2002 Artifex, Inc.  All rights reserved.
2
% 
3
% This software is provided AS-IS with no warranty, either express or
4
% implied.
5
% 
6
% This software is distributed under license and may not be copied,
7
% modified or distributed except as expressly authorized under the terms
8
% of the license contained in the file LICENSE in this distribution.
9
% 
10
% For more information about licensing, please refer to
11
% http://www.ghostscript.com/licensing/. For information on
12
% commercial licensing, go to http://www.artifex.com/licensing/ or
13
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
 
16
% $Id: gs_img.ps,v 1.3 2002/10/08 00:49:48 dan Exp $
17
% image, colorimage, and imagemask implementation
18
 
19
%
20
% The design of the overprint facility in Ghostscript requires that color
21
% specifications include the color space from which they were expressed,
22
% even after conversion to the device color model. Directly including this
23
% information in color specifications is usually not efficient, and is
24
% difficult to integrate into the existing code structure. The alternative
25
% approach taken is to extend a state mechanism through the device
26
% interface, and make the current color space, or more specifically,
27
% certain information about the current color space, a property of this
28
% state.
29
%
30
% For such a mechanism to work, it is necessary to identify all changes
31
% to the current color space. This is accomplished in the graphic library
32
% by funneling all changes to the current color space through the
33
% gs_setcolorspace procedure. At the PostScript interpreter level, this
34
% result is achieved by forcing color space changes through the
35
% setcolorspace operator.
36
%
37
% Aside from explicit use of setcolorspace, PostScript provides a few
38
% implicit methods of changing the current color space. The setgray,
39
% setrgbcolor, and setcmykcolor operators implicitly set the color space
40
% while explicitly setting the current color. Similarly, the colorimage
41
% operator and the traditional form of the image operator (5 operands)
42
% both temporarily modify the current color space while an image is
43
% being processed. The current file is concerned with the implementation
44
% of these two operators. In addition, the traditional form of the
45
% imagemask operator (5 operands), while it does not affect the current
46
% color space, is closely related to the image operator and thus is
47
% implemented in this file as well.
48
%
49
% In this implementation, all sampled objects are passed through one of
50
% the internal operators .image1, .imagemask1, .image1alpha, .image2,
51
% .image3, or .image4, each of which handles a specific ImageType value.
52
%
53
% The procedures in this file are responsible for constructing
54
% image dictionaries from a set of stack entries. This is, in principle,
55
% a trivial exercise. In practice it appears to be far more complex,
56
% primarily due to the need to reconstruct the original state in the
57
% event of an error. This is a particular problem for operators such as
58
% image, which include data source objects that may, directly or
59
% indirectly, be procedures. When these procedures are executed, the
60
% image operator's operands must have been cleared from the operand
61
% stack. Hence, the operand stack cannot be used to store state
62
% information. Similarly, the dictionary stack also cannot be used to
63
% store state information, as the data source procedures may depend on
64
% a particular dictionary being on the top of this stack.
65
%
66
% Adobe's PostScript implementations determine the extent to which the
67
% interpreter state is restored in the event of an error by the point at
68
% which the error is detected. Errors in the image/colorimage/imagemask
69
% operators that are detected before the data source procedures are
70
% executed restore the state in effect before the image was processed.
71
% Those that are detected as part of running the data source procedures
72
% only attempt to restore the state to that in effect at the start of
73
% the operator that failed (or at the conclusion of the data source
74
% procedure, if this procedure failed to push a string).
75
%
76
% The implementation given here follows the Adobe convention. The
77
% mechanism used is as follows:
78
%
79
%   1. Check that the stack has a sufficient number of operands, and
80
%      that enough of them have the proper type to allow construction
81
%      of the image dictionary. Any errors at this point are handled
82
%      in the conventional manner.
83
%
84
%   2. Build the image dictionary, in the process clearing the image/
85
%      colorimage/imagemask operands from the stack. No errors can
86
%      occur during this process.
87
%
88
%      (Special precautions could be taken during this step to handle
89
%      a limitcheck or VMError during the building of the image
90
%      dictionary, but this essentially never occurs in practice and, if
91
%      it did, is very unlikely to leave a useable state. Hence, we don't
92
%      bother with this possibility.)
93
%
94
%   3. The .image operator is executed in a stopped context. If it
95
%      returns abnormally, a check is made to see if the uppermost
96
%      operand on the stack is a color image dictionary. If so, the
97
%      original stack is created anew using this dictionary. (Because
98
%      the image operand works via colorimage, some additional special
99
%      handling is required in this case.)
100
%
101
 
102
 
103
%
104
% Create a dictionary of operators for specific image and image mask types.
105
% Each of these will always handle ImageType 1. Additional types are added
106
% as they are supported in specific interpreter levels or versions.
107
%
108
% These dictionaries are in systemdict for historical reasons.
109
%
110
.currentglobal true .setglobal
111
systemdict begin
112
/.imagetypes
113
  5 dict
114
  dup 1 /.image1 load put
115
def
116
/.imagemasktypes
117
  5 dict
118
  dup 1 /.imagemask1 load put
119
def
120
end
121
.setglobal
122
 
123
% 
124
% Build a dictionary of utility procedures and constants for use in
125
% impelementing the image operators. This dictionary is in global VM but
126
% is maintained (during initialization) in userdict. It should be pushed
127
% onto the dictionary stack when constructing image-related procedures
128
% and pseudo-operators.
129
%
130
% This dictionary is removed from userdict when initialization is
131
% completed.
132
%
133
.currentglobal true .setglobal
134
userdict /img_utils_dict 30 dict put
135
img_utils_dict begin
136
 
137
 
138
%
139
% Some useful local data structures:
140
%
141
%   img_csary maps the number of components in an image to the implied
142
%       color space.
143
%
144
%   img_decary is a prototype Decode array; subintervals of this array
145
%       may be used for fewer than 4 color components.
146
%
147
%   img_params_ary is a list of the parameters to be built in the image
148
%       dictionary for a colorimage invocation. ImageType is given a
149
%       fixed value; the other parameters are in stack order (IMG_NComps
150
%       is the number of components).
151
%
152
%   img_mask_params_ary is the equivalent of img_params_ary for imagemask
153
%       invocations. Polarity is a proxy for Decode, and is replaced
154
%       by the Decode key in the image dictionary.
155
%
156
%   img_mask_check_ary is the set of parameters that must be present in
157
%       an image dictionary generated by an imagemask invocation. This
158
%       differs from img_mask_params_ary in that Decode replaces Polarity.
159
%
160
/img_csary [ null /DeviceGray null /DeviceRGB /DeviceCMYK ] def
161
/img_decary [ 0 1  0 1  0 1  0 1 ] def
162
 
163
/img_params_ary
164
  [
165
    /ImageType  /IMG_NComps  /MultipleDataSources  /DataSource
166
    /ImageMatrix  /BitsPerComponent  /Height  /Width   /Decode
167
  ]
168
def
169
/img_check_ary //img_params_ary def
170
/img_unbuild_ary
171
 //img_params_ary 1 1 index length 2 sub getinterval
172
def
173
 
174
/img_mask_params_ary
175
  [ /ImageType  /DataSource  /ImageMatrix  /Polarity  /Height  /Width ]
176
def
177
/img_mask_check_ary
178
  [
179
    /ImageType  /BitsPerComponent
180
    /DataSource  /ImageMatrix  /Decode  /Height  /Width
181
  ]
182
def
183
/img_mask_unbuild_ary
184
 //img_mask_check_ary 2 1 index length 2 sub getinterval
185
def
186
 
187
 
188
%
189
%   <?any?>  <array>   img_check_keys   <?any?>  <bool>
190
%
191
% Verify that:
192
%   that there are at least two entries on the stack, and
193
%   the second (lower) entry is a dictionary, and
194
%   that dictionary contains all of the keys in the array
195
%
196
% If any one of these conditions does not hold, pop the array and push
197
% false; otherwise pop the array and push true. This utility is used by
198
% the colorimage and imagematrix procedures to determine if .image left
199
% the image dictionary on the stack after an abnormal return.
200
%
201
/img_check_keys
202
  {
203
    count 2 ge
204
      {
205
        1 index type /dicttype eq
206
          {
207
            true exch
208
              {
209
                2 index exch known and
210
                dup not
211
                  { exit }
212
                if
213
              }
214
            forall
215
          }
216
          { pop //false }
217
        ifelse
218
      }
219
      { pop //false }
220
    ifelse
221
  }
222
.bind def
223
 
224
%
225
% Procedures to convert a set of stack entries to a dictionary. There is
226
% a procedure associated with each key, though most keys use the same
227
% procedure. The dictionary to be built is at the top of the dictionary
228
% stack. Stack handling for the procedures is:
229
%
230
%   <?val0?> ... <?val(n - 1)?>  <key>   proc   -
231
%
232
% Parameters are handle in inverse-stack order, so inter-parameter
233
% dependencies that on the stack can generally be used here.
234
%
235
/img_params_dict
236
  mark
237
    /ImageType { 1 def } .bind
238
 
239
    /IMG_NComps { exch def } .bind      % number of components
240
    /MultipleDataSources 1 index
241
    /Width 1 index
242
    /Height 1 index
243
    /ImageMatrix 1 index
244
    /BitsPerComponent 1 index
245
    /DataSource 1 index
246
 
247
    % Polarity is a proxy for Decode; it never appears in a dictionary
248
    /Polarity
249
      {
250
        pop
251
          { { 1 0 } }
252
          { { 0 1 } }
253
        ifelse
254
        /Decode exch cvlit def
255
      }
256
    .bind
257
 
258
    % the definition of Decode is based on the number of components
259
    /Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind
260
  .dicttomark
261
def
262
 
263
%
264
%    <oper_0>  ...  <oper_n>  <array>   img_build_dict   <dict>
265
%
266
% Build a dictionary. This will always be done in local VM. The array is
267
% a list of the keys to be associated with operands on the stack, in
268
% inverse stack order (topmost element first). The caller should verify
269
% that the dictionary can be built successfully (except for a possible
270
% VMerror) before calling this routine.
271
%
272
/img_build_dict
273
  {
274
    % build the dictionary in local VM; all for 2 extra entries
275
    .currentglobal false .setglobal
276
    1 index length 2 add dict
277
    exch .setglobal
278
    begin
279
 
280
    % process all keys in the array
281
      { //img_params_dict 1 index get exec }
282
    forall
283
 
284
    % if BitsPerComponent is not yet defined, define it to be 1
285
    currentdict /BitsPerComponent known not
286
      { /BitsPerComponent 1 def }
287
    if
288
 
289
    currentdict end
290
  }
291
.bind def
292
 
293
%
294
%   <dict>  <array>   img_unbuild_dict   <oper_0>  ...  <oper_n>
295
%
296
% "Unbuild" a dictionary: spread the contents the dictionary back onto the
297
% stack, in the inverse of the order indicated in the array (inverse is
298
% used as this order is more convenient for img_build_dict, which is
299
% expected to be invoked far more frequently).
300
%
301
/img_unbuild_dict
302
  {
303
    exch begin
304
    dup length 1 sub -1 0
305
      { 1 index exch get load exch }
306
    for
307
    pop
308
    end
309
  }
310
.bind def
311
 
312
 
313
%
314
%   <width>  <height>  <bits/component>  <matrix>  <dsrc0> ...
315
%   <multi>  <ncomp>  <has_alpha>
316
%   img_build_image_dict
317
%   <dict>  <has_alpha>
318
%
319
% Build the dictionary corresponding to a colorimage operand stack. This
320
% routine will check just enough of the stack to verify that the
321
% dictionary can be built, and will generate the appropriate error if this
322
% is not the case.
323
%
324
% The <has_alpha> boolean is used to support the Next alphaimage extension.
325
%
326
% At the first level, errors in this procedure are reported as colorimage
327
% errors. The error actually reported will usually be determined by the
328
% pseudo-operator which invokes this routine.
329
%
330
/img_build_image_dict
331
  {
332
    % Veify that at least 8 operands are available, and that the top three
333
    % operands have the expected types
334
    count 8 lt
335
      { /.colorimage cvx /stackunderflow signalerror }
336
    if
337
    3 copy
338
    type /booleantype ne exch
339
    type /integertype ne or exch
340
    type /booleantype ne or
341
      { /.colorimage cvx /typecheck signalerror }
342
    if
343
 
344
    % verify that the number of components is 1, 3, or 4
345
    1 index 1 lt 2 index 2 eq or 2 index 4 gt or
346
      { /.colorimage cvx /rangecheck signalerror }
347
    if
348
 
349
    % Verify that the required number of operands are present if multiple
350
    % data sources are being used. If this test is successful, convert
351
    % the data sources to an array (in local VM).
352
    2 index
353
      {
354
        % if an alpha component is present, this adds one more component
355
        2 copy
356
          { 1 add }
357
        if
358
        dup count 9 sub gt
359
          { /.colorimage cvx /stackunderflow signalerror }
360
        if
361
 
362
        % build the DataSource array in local VM
363
        dup .currentglobal false .setglobal exch array exch .setglobal
364
 
365
        % stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array>
366
        5 1 roll 4 add 3 roll astore 4 1 roll
367
      }
368
    if
369
 
370
    % the image dictionary can be built; do so
371
    % stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha>
372
    8 1 roll //img_params_ary //img_build_dict exec exch
373
  }
374
.bind def
375
 
376
%
377
%   <?dict?>
378
%   img_unbuild_image_dict
379
%   <width>  <height>  <bits/component>  <matrix>  <dsrc0> ...
380
%   <multi>  <ncomp>
381
%
382
% If the top entry of the stack is a dictionary that has the keys required
383
% by a colorimage dictionary, unpack that dictionary onto the stack.
384
% Otherwise just leave things as they are. Note that the <has_alpha>
385
% parameter is not pushd onto the stack.
386
%
387
/img_unbuild_image_dict
388
  {
389
    //img_check_ary //img_check_keys exec
390
      {
391
        //img_unbuild_ary //img_unbuild_dict exec
392
        1 index type /booleantype eq
393
          {
394
            1 index
395
              { 3 1 roll aload length 2 add -2 roll }
396
            if
397
          }
398
        if
399
      }
400
    if
401
  }
402
.bind def
403
 
404
 
405
%
406
%   <width>  <height>  <polarity>  <matrix>  <dsrc>
407
%   img_unbuild_imagemask_dict
408
%   <dict>
409
%
410
% Build the dictionary corresponding to an imagemask stack. This routine
411
% will verify that the appropriate number of operands are on the stack,
412
% and that polarity is a boolean. This is all that is necessary to build
413
% the dictionary.
414
%
415
/img_build_imagemask_dict
416
  {
417
    % check for proper number of operands
418
    count 5 lt
419
      { /imagemask load /stackunderflow signalerror }
420
    if
421
 
422
    % verify that polarity is a boolean
423
    2 index type /booleantype ne
424
      { /imagemask load /typecheck signalerror }
425
    if
426
 
427
    % the imagemask dictionary can be built; do so
428
    //img_mask_params_ary //img_build_dict exec
429
  }
430
.bind def
431
 
432
%
433
%   <?dict?>
434
%   img_unbuild_imagemask_dict
435
%   <width>  <height>  <polarity>  <matrix>  <dsrc>
436
%
437
% If the top entry of the stack is a dictionary that has the keys rquired
438
% by an imagemask dictionary, unpack that dictionary onto the stack.
439
% Otherwise just leave things as they are.
440
%
441
/img_unbuild_imagemask_dict
442
  {
443
    //img_mask_check_ary //img_check_keys exec
444
      {
445
        //img_mask_unbuild_ary //img_unbuild_dict exec
446
        3 -1 roll
447
        dup type dup /arraytype eq exch /packedarraytype eq or
448
        1 index rcheck and
449
          { 0 get 1 eq }
450
        if
451
        3 1 roll
452
      }
453
    if
454
  }
455
.bind def
456
 
457
 
458
%
459
%   <width>  <height>  <bits/component>  <matrix>  <dsrc_0> ...
460
%   <multi>  <ncomp>  <has_alpha>
461
%   .colorimage 
462
%   -
463
%
464
% Convert the image/colorimage operator from their traditional form to
465
% the dictionary form. The <has_alpha> operand is used ot support the
466
% Next alphaimage extension.
467
%
468
% Error handling for these operators is a bit complex, due to the stack
469
% handling required of operators that potentially invoke procedures.
470
% This problem is discussed in the comment above. The facts relevant to
471
% this particular implementation are:
472
%
473
%   1. The .image1 (or .alphaimage) operator is executed in a stopped
474
%      context, so that we can undo the gsave context in the event of
475
%      an error.
476
%
477
%   2. In the event of an error, the stack is examined to see if the
478
%      dictionary passed to .image1 (.alphaimage) is still present.
479
%      If so, this dictionary is "unpacked" onto the stack to re-
480
%      create the original stack. The <has_alpha> parameter is not
481
%      pushed onto the stack, as it is not required for any of the
482
%      pseudo-operators than invoke this procedure.
483
%
484
%   3. The use of pseudo-operators in this case may yield incorrect
485
%      results for late-detected errors, as the stack depth will be
486
%      restored (even though the stack is not). This is, however, no
487
%      worse than the prior (level >= 2) code, so it should cause no
488
%      new problems.
489
%
490
/.colorimage
491
  {
492
    % build the image dictionary
493
    //img_build_image_dict exec
494
 
495
    % execute .image1 in a stopped context
496
      {
497
        gsave
498
 
499
        //img_csary 2 index /IMG_NComps get get setcolorspace
500
          { .alphaimage }
501
          { .image1 }
502
        ifelse
503
      }
504
    stopped
505
    grestore
506
      {
507
        //img_unbuild_image_dict exec
508
        /.colorimage cvx $error /errorname get
509
        signalerror
510
      }
511
    if
512
  }
513
.bind def
514
 
515
 
516
% 
517
%   <width>  <height>  <bits/component>  <matrix>  <dsrc_0> ...
518
%   <multi>  <ncomp>
519
%   colorimage 
520
%   -
521
%
522
% Build the colorimage pseudo-operator only if setcolorscreen is visible.
523
%
524
systemdict /setcolorscreen .knownget
525
  {
526
    type /operatortype eq
527
      {
528
        /colorimage 
529
          {
530
             //false
531
               //.colorimage
532
             stopped
533
               { /colorimage load  $error /errorname get signalerror }
534
             if
535
          }
536
        .bind systemdict begin odef end
537
      }
538
    if
539
  }
540
if
541
 
542
 
543
%
544
%   width  height  bits_per_component  matrix  data_src   image   -
545
%   
546
%   <dict>   image   -
547
%
548
% Some special handling is required for ImageType 2 (Display PostScript
549
% pixmap images) so as to set the appropriate color space as the current
550
% color space.
551
%
552
/image
553
  {
554
    dup type /dicttype eq languagelevel 2 ge and
555
      { 
556
        dup /ImageType get dup 2 eq
557
          {
558
            % verify the ImageType 2 is supported
559
            //.imagetypes exch known
560
              {
561
                %
562
                % Set either DevicePixel or DeviceRGB as the current
563
                % color space. DevicePixel is used if the image data is
564
                % to be copied directly, with only a geometric
565
                % transformation (PixelCopy true). The use of DeviceRGB
566
                % in the alternate case is not, in general, correct, and
567
                % reflects a current implementation limitation. Ideally,
568
                % an intermediate color space should be used only if
569
                % the source and destination color models vary; otherwise
570
                % the native color space corresponding to the color model
571
                % should be used.
572
                %
573
                % The mechanism to determine depth for the DevicePixel
574
                % color space when BitsPerPixel is not available is 
575
                % somewhat of a hack.
576
                %
577
                gsave
578
 
579
                dup /PixelCopy .knownget dup
580
                  { pop }
581
                if
582
                  {
583
                      [
584
                        /DevicePixel
585
                        currentpagedevice dup /BitsPerPixel .knownget
586
                          { exch pop }
587
                          {
588
                            /GrayValues .knownget not
589
                              { 2 }     % try a guess
590
                            if
591
                            ln 2 ln div round cvi
592
                          }
593
                        ifelse
594
                      ]
595
                  }
596
                  { /DeviceRGB }
597
                ifelse
598
                setcolorspace
599
                //.imagetypes 2 get
600
                stopped
601
                grestore
602
                  { /image load $error /errorname get signalerror }
603
                if
604
              }
605
              { /image load /undefined signalerror }
606
            ifelse
607
          }
608
          {
609
            gsave
610
 
611
            //.imagetypes exch get
612
            stopped
613
            grestore
614
              { /image load $error /errorname get signalerror }
615
            if
616
          }
617
        ifelse
618
      }
619
      { 
620
        //false 1 //false
621
          //.colorimage
622
        stopped
623
          { /image load $error /errorname get signalerror }
624
        if
625
      }
626
    ifelse
627
  }
628
.bind systemdict begin odef end
629
 
630
 
631
%
632
%   width  height  polarity  matrix  datasrc   imagemask   -
633
%
634
% See the comment preceding the definition of .colorimage for information
635
% as to the handling of error conditions.
636
%
637
/imagemask
638
  {
639
    dup type /dicttype eq languagelevel 2 ge and
640
      { dup /ImageType get //.imagemasktypes exch get exec }
641
      {
642
        //img_build_imagemask_dict exec
643
          { .imagemask1 }
644
        stopped
645
          {
646
            //img_unbuild_imagemask_dict exec
647
            /imagemask load $error /errorname get signalerror
648
          }
649
        if
650
      }
651
    ifelse
652
  }
653
.bind systemdict begin odef end
654
 
655
end        % img_utils_dict
656
.setglobal  % restore VM mode