~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to psi/ztrans.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
 
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
7
   This software is distributed under license and may not be copied, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
 
 
14
/* $Id: ztrans.c 9043 2008-08-28 22:48:19Z giles $ */
 
15
/* Transparency operators */
 
16
#include "string_.h"
 
17
#include "memory_.h"
 
18
#include "ghost.h"
 
19
#include "oper.h"
 
20
#include "gscspace.h"           /* for gscolor2.h */
 
21
#include "gscolor2.h"
 
22
#include "gsipar3x.h"
 
23
#include "gstrans.h"
 
24
#include "gxiparam.h"           /* for image enumerator */
 
25
#include "gxcspace.h"
 
26
#include "idict.h"
 
27
#include "idparam.h"
 
28
#include "ifunc.h"
 
29
#include "igstate.h"
 
30
#include "iimage.h"
 
31
#include "iname.h"
 
32
#include "store.h"
 
33
#include "gsdfilt.h"
 
34
#include "gdevdevn.h"
 
35
#include "gxblend.h"
 
36
#include "gdevp14.h"
 
37
 
 
38
/* ------ Utilities ------ */
 
39
 
 
40
static int
 
41
set_float_value(i_ctx_t *i_ctx_p, int (*set_value)(gs_state *, floatp))
 
42
{
 
43
    os_ptr op = osp;
 
44
    double value;
 
45
    int code;
 
46
 
 
47
    if (real_param(op, &value) < 0)
 
48
        return_op_typecheck(op);
 
49
    if ((code = set_value(igs, value)) < 0)
 
50
        return code;
 
51
    pop(1);
 
52
    return 0;
 
53
}
 
54
 
 
55
static int
 
56
current_float_value(i_ctx_t *i_ctx_p,
 
57
                    float (*current_value)(const gs_state *))
 
58
{
 
59
    os_ptr op = osp;
 
60
 
 
61
    push(1);
 
62
    make_real(op, current_value(igs));
 
63
    return 0;
 
64
}
 
65
 
 
66
static int
 
67
enum_param(const gs_memory_t *mem, const ref *pnref,
 
68
           const char *const names[])
 
69
{
 
70
    const char *const *p;
 
71
    ref nsref;
 
72
 
 
73
    name_string_ref(mem, pnref, &nsref);
 
74
    for (p = names; *p; ++p)
 
75
        if (r_size(&nsref) == strlen(*p) &&
 
76
            !memcmp(*p, nsref.value.const_bytes, r_size(&nsref))
 
77
            )
 
78
            return p - names;
 
79
    return_error(e_rangecheck);
 
80
}
 
81
 
 
82
/* ------ Graphics state operators ------ */
 
83
 
 
84
static const char *const blend_mode_names[] = {
 
85
    GS_BLEND_MODE_NAMES, 0
 
86
};
 
87
 
 
88
/* <modename> .setblendmode - */
 
89
static int
 
90
zsetblendmode(i_ctx_t *i_ctx_p)
 
91
{
 
92
    os_ptr op = osp;
 
93
    int code;
 
94
 
 
95
    check_type(*op, t_name);
 
96
    if ((code = enum_param(imemory, op, blend_mode_names)) < 0 ||
 
97
        (code = gs_setblendmode(igs, code)) < 0
 
98
        )
 
99
        return code;
 
100
    pop(1);
 
101
    return 0;
 
102
}
 
103
 
 
104
/* - .currentblendmode <modename> */
 
105
static int
 
106
zcurrentblendmode(i_ctx_t *i_ctx_p)
 
107
{
 
108
    os_ptr op = osp;
 
109
    const char *mode_name = blend_mode_names[gs_currentblendmode(igs)];
 
110
    ref nref;
 
111
    int code = name_enter_string(imemory, mode_name, &nref);
 
112
 
 
113
    if (code < 0)
 
114
        return code;
 
115
    push(1);
 
116
    *op = nref;
 
117
    return 0;
 
118
}
 
119
 
 
120
/* <0..1> .setopacityalpha - */
 
121
static int
 
122
zsetopacityalpha(i_ctx_t *i_ctx_p)
 
123
{
 
124
    return set_float_value(i_ctx_p, gs_setopacityalpha);
 
125
}
 
126
 
 
127
/* - .currentopacityalpha <0..1> */
 
128
static int
 
129
zcurrentopacityalpha(i_ctx_t *i_ctx_p)
 
130
{
 
131
    return current_float_value(i_ctx_p, gs_currentopacityalpha);
 
132
}
 
133
 
 
134
/* <0..1> .setshapealpha - */
 
135
static int
 
136
zsetshapealpha(i_ctx_t *i_ctx_p)
 
137
{
 
138
    return set_float_value(i_ctx_p, gs_setshapealpha);
 
139
}
 
140
 
 
141
/* - .currentshapealpha <0..1> */
 
142
static int
 
143
zcurrentshapealpha(i_ctx_t *i_ctx_p)
 
144
{
 
145
    return current_float_value(i_ctx_p, gs_currentshapealpha);
 
146
}
 
147
 
 
148
/* <bool> .settextknockout - */
 
149
static int
 
150
zsettextknockout(i_ctx_t *i_ctx_p)
 
151
{
 
152
    os_ptr op = osp;
 
153
 
 
154
    check_type(*op, t_boolean);
 
155
    gs_settextknockout(igs, op->value.boolval);
 
156
    pop(1);
 
157
    return 0;
 
158
}
 
159
 
 
160
/* - .currenttextknockout <bool> */
 
161
static int
 
162
zcurrenttextknockout(i_ctx_t *i_ctx_p)
 
163
{
 
164
    os_ptr op = osp;
 
165
 
 
166
    push(1);
 
167
    make_bool(op, gs_currenttextknockout(igs));
 
168
    return 0;
 
169
}
 
170
 
 
171
/* ------ Rendering stack operators ------ */
 
172
 
 
173
static int
 
174
rect_param(gs_rect *prect, os_ptr op)
 
175
{
 
176
    double coords[4];
 
177
    int code = num_params(op, 4, coords);
 
178
 
 
179
    if (code < 0)
 
180
        return code;
 
181
    prect->p.x = coords[0], prect->p.y = coords[1];
 
182
    prect->q.x = coords[2], prect->q.y = coords[3];
 
183
    return 0;
 
184
}
 
185
 
 
186
static int
 
187
mask_op(i_ctx_t *i_ctx_p,
 
188
        int (*mask_proc)(gs_state *, gs_transparency_channel_selector_t))
 
189
{
 
190
    int csel;
 
191
    int code = int_param(osp, 1, &csel);
 
192
 
 
193
    if (code < 0)
 
194
        return code;
 
195
    code = mask_proc(igs, csel);
 
196
    if (code >= 0)
 
197
        pop(1);
 
198
    return code;
 
199
 
 
200
}
 
201
 
 
202
/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencygroup - */
 
203
static int
 
204
zbegintransparencygroup(i_ctx_t *i_ctx_p)
 
205
{
 
206
    os_ptr op = osp;
 
207
    os_ptr dop = op - 4;
 
208
    gs_transparency_group_params_t params;
 
209
    gs_rect bbox;
 
210
    int code;
 
211
 
 
212
    check_type(*dop, t_dictionary);
 
213
    check_dict_read(*dop);
 
214
    gs_trans_group_params_init(&params);
 
215
    if ((code = dict_bool_param(dop, "Isolated", false, &params.Isolated)) < 0 ||
 
216
        (code = dict_bool_param(dop, "Knockout", false, &params.Knockout)) < 0 ||
 
217
        (code = dict_bool_param(dop, ".image_with_SMask", false, &params.image_with_SMask)) < 0
 
218
        )
 
219
        return code;
 
220
    code = rect_param(&bbox, op);
 
221
    if (code < 0)
 
222
        return code;
 
223
    params.ColorSpace = gs_currentcolorspace(igs);
 
224
    code = gs_begin_transparency_group(igs, &params, &bbox);
 
225
    if (code < 0)
 
226
        return code;
 
227
    pop(5);
 
228
    return code;
 
229
}
 
230
 
 
231
/* - .discardtransparencygroup - */
 
232
static int
 
233
zdiscardtransparencygroup(i_ctx_t *i_ctx_p)
 
234
{
 
235
    if (gs_current_transparency_type(igs) != TRANSPARENCY_STATE_Group)
 
236
        return_error(e_rangecheck);
 
237
    return gs_discard_transparency_layer(igs);
 
238
}
 
239
 
 
240
/* - .endtransparencygroup - */
 
241
static int
 
242
zendtransparencygroup(i_ctx_t *i_ctx_p)
 
243
{
 
244
    return gs_end_transparency_group(igs);
 
245
}
 
246
 
 
247
/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencymaskgroup - */
 
248
static int tf_using_function(floatp, float *, void *);
 
249
static int
 
250
zbegintransparencymaskgroup(i_ctx_t *i_ctx_p)
 
251
{
 
252
    os_ptr op = osp;
 
253
    os_ptr dop = op - 4;
 
254
    gs_transparency_mask_params_t params;
 
255
    ref *pparam;
 
256
    gs_rect bbox;
 
257
    int code;
 
258
    static const char *const subtype_names[] = {
 
259
        GS_TRANSPARENCY_MASK_SUBTYPE_NAMES, 0
 
260
    };
 
261
 
 
262
    check_type(*dop, t_dictionary);
 
263
    check_dict_read(*dop);
 
264
    if (dict_find_string(dop, "Subtype", &pparam) <= 0)
 
265
        return_error(e_rangecheck);
 
266
    if ((code = enum_param(imemory, pparam, subtype_names)) < 0)
 
267
        return code;
 
268
    gs_trans_mask_params_init(&params, code);
 
269
    params.replacing = true;
 
270
    if ((code = dict_floats_param(imemory, dop, "Background",
 
271
                    cs_num_components(gs_currentcolorspace(i_ctx_p->pgs)),
 
272
                                  params.Background, NULL)) < 0
 
273
        )
 
274
        return code;
 
275
    else if (code > 0)
 
276
        params.Background_components = code;
 
277
    if ((code = dict_floats_param(imemory, dop, "GrayBackground",
 
278
                    1, &params.GrayBackground, NULL)) < 0
 
279
        )
 
280
        return code;
 
281
    if (dict_find_string(dop, "TransferFunction", &pparam) >0) {
 
282
        gs_function_t *pfn = ref_function(pparam);
 
283
 
 
284
        if (pfn == 0 || pfn->params.m != 1 || pfn->params.n != 1)
 
285
            return_error(e_rangecheck);
 
286
        params.TransferFunction = tf_using_function;
 
287
        params.TransferFunction_data = pfn;
 
288
    }
 
289
    code = rect_param(&bbox, op);
 
290
    if (code < 0)
 
291
        return code;
 
292
    code = gs_begin_transparency_mask(igs, &params, &bbox, false);
 
293
    if (code < 0)
 
294
        return code;
 
295
    pop(5);
 
296
    return code;
 
297
}
 
298
 
 
299
/* - .begintransparencymaskimage - */
 
300
static int
 
301
zbegintransparencymaskimage(i_ctx_t *i_ctx_p)
 
302
{
 
303
    gs_transparency_mask_params_t params;
 
304
    gs_rect bbox = { { 0, 0} , { 1, 1} };
 
305
    int code;
 
306
 
 
307
    gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
 
308
    code = gs_begin_transparency_mask(igs, &params, &bbox, true);
 
309
    if (code < 0)
 
310
        return code;
 
311
    return code;
 
312
}
 
313
 
 
314
/* Implement the TransferFunction using a Function. */
 
315
static int
 
316
tf_using_function(floatp in_val, float *out, void *proc_data)
 
317
{
 
318
    float in = in_val;
 
319
    gs_function_t *const pfn = proc_data;
 
320
 
 
321
    return gs_function_evaluate(pfn, &in, out);
 
322
}
 
323
 
 
324
/* - .discardtransparencymask - */
 
325
static int
 
326
zdiscardtransparencymask(i_ctx_t *i_ctx_p)
 
327
{
 
328
    if (gs_current_transparency_type(igs) != TRANSPARENCY_STATE_Mask)
 
329
        return_error(e_rangecheck);
 
330
    return gs_discard_transparency_layer(igs);
 
331
}
 
332
 
 
333
/* <mask#> .endtransparencymask - */
 
334
static int
 
335
zendtransparencymask(i_ctx_t *i_ctx_p)
 
336
{
 
337
    return mask_op(i_ctx_p, gs_end_transparency_mask);
 
338
}
 
339
 
 
340
/* ------ Soft-mask images ------ */
 
341
 
 
342
/* <dict> .image3x - */
 
343
static int mask_dict_param(const gs_memory_t *mem, os_ptr,
 
344
                            image_params *, const char *, int,
 
345
                            gs_image3x_mask_t *);
 
346
static int
 
347
zimage3x(i_ctx_t *i_ctx_p)
 
348
{
 
349
    os_ptr op = osp;
 
350
    gs_image3x_t image;
 
351
    ref *pDataDict;
 
352
    image_params ip_data;
 
353
    int num_components =
 
354
        gs_color_space_num_components(gs_currentcolorspace(igs));
 
355
    int ignored;
 
356
    int code;
 
357
 
 
358
    check_type(*op, t_dictionary);
 
359
    check_dict_read(*op);
 
360
    gs_image3x_t_init(&image, NULL);
 
361
    if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
 
362
        return_error(e_rangecheck);
 
363
    if ((code = pixel_image_params(i_ctx_p, pDataDict,
 
364
                   (gs_pixel_image_t *)&image, &ip_data,
 
365
                   16, false, gs_currentcolorspace(igs))) < 0 ||
 
366
        (code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0
 
367
        )
 
368
        return code;
 
369
    /*
 
370
     * We have to process the masks in the reverse order, because they
 
371
     * insert their DataSource before the one(s) for the DataDict.
 
372
     */
 
373
    if ((code = mask_dict_param(imemory, op, &ip_data,
 
374
                                "ShapeMaskDict", num_components,
 
375
                                &image.Shape)) < 0 ||
 
376
        (code = mask_dict_param(imemory, op, &ip_data,
 
377
                                "OpacityMaskDict", num_components,
 
378
                                &image.Opacity)) < 0
 
379
        )
 
380
        return code;
 
381
    return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
 
382
                        &ip_data.DataSource[0],
 
383
                        image.CombineWithColor, 1);
 
384
}
 
385
 
 
386
/* Get one soft-mask dictionary parameter. */
 
387
static int
 
388
mask_dict_param(const gs_memory_t *mem, os_ptr op,
 
389
image_params *pip_data, const char *dict_name,
 
390
                int num_components, gs_image3x_mask_t *pixm)
 
391
{
 
392
    ref *pMaskDict;
 
393
    image_params ip_mask;
 
394
    int ignored;
 
395
    int code, mcode;
 
396
 
 
397
    if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
 
398
        return 1;
 
399
    if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
 
400
                                          &ip_mask, false, 1, 16, false)) < 0 ||
 
401
        (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
 
402
        (code = dict_int_param(pMaskDict, "InterleaveType", 1, 3, -1,
 
403
                               &pixm->InterleaveType)) < 0 ||
 
404
        (code = dict_floats_param(mem, op, "Matte", num_components,
 
405
                                  pixm->Matte, NULL)) < 0
 
406
        )
 
407
        return code;
 
408
    pixm->has_Matte = code > 0;
 
409
    /*
 
410
     * The MaskDict must have a DataSource iff InterleaveType == 3.
 
411
     */
 
412
    if ((pip_data->MultipleDataSources && pixm->InterleaveType != 3) ||
 
413
        ip_mask.MultipleDataSources ||
 
414
        mcode != (pixm->InterleaveType != 3)
 
415
        )
 
416
        return_error(e_rangecheck);
 
417
    if (pixm->InterleaveType == 3) {
 
418
        /* Insert the mask DataSource before the data DataSources. */
 
419
        memmove(&pip_data->DataSource[1], &pip_data->DataSource[0],
 
420
                (countof(pip_data->DataSource) - 1) *
 
421
                sizeof(pip_data->DataSource[0]));
 
422
        pip_data->DataSource[0] = ip_mask.DataSource[0];
 
423
    }
 
424
    return 0;
 
425
}
 
426
 
 
427
/* depth .pushpdf14devicefilter - */
 
428
/* this is a filter operator, but we include it here to maintain
 
429
   modularity of the pdf14 transparency support */
 
430
static int
 
431
zpushpdf14devicefilter(i_ctx_t *i_ctx_p)
 
432
{
 
433
    int code;
 
434
    os_ptr op = osp;
 
435
 
 
436
    check_type(*op, t_integer);
 
437
    code = gs_push_pdf14trans_device(igs);
 
438
    if (code < 0)
 
439
        return code;
 
440
    pop(1);
 
441
    return 0;
 
442
}
 
443
 
 
444
/* this is a filter operator, but we include it here to maintain
 
445
   modularity of the pdf14 transparency support */
 
446
static int
 
447
zpoppdf14devicefilter(i_ctx_t *i_ctx_p)
 
448
{
 
449
    return gs_pop_pdf14trans_device(igs);
 
450
}
 
451
 
 
452
/* ------ Initialization procedure ------ */
 
453
 
 
454
/* We need to split the table because of the 16-element limit. */
 
455
const op_def ztrans1_op_defs[] = {
 
456
    {"1.setblendmode", zsetblendmode},
 
457
    {"0.currentblendmode", zcurrentblendmode},
 
458
    {"1.setopacityalpha", zsetopacityalpha},
 
459
    {"0.currentopacityalpha", zcurrentopacityalpha},
 
460
    {"1.setshapealpha", zsetshapealpha},
 
461
    {"0.currentshapealpha", zcurrentshapealpha},
 
462
    {"1.settextknockout", zsettextknockout},
 
463
    {"0.currenttextknockout", zcurrenttextknockout},
 
464
    op_def_end(0)
 
465
};
 
466
const op_def ztrans2_op_defs[] = {
 
467
    {"5.begintransparencygroup", zbegintransparencygroup},
 
468
    {"0.discardtransparencygroup", zdiscardtransparencygroup},
 
469
    {"0.endtransparencygroup", zendtransparencygroup},
 
470
    {"5.begintransparencymaskgroup", zbegintransparencymaskgroup},
 
471
    {"5.begintransparencymaskimage", zbegintransparencymaskimage},
 
472
    {"0.discardtransparencymask", zdiscardtransparencymask},
 
473
    {"1.endtransparencymask", zendtransparencymask},
 
474
    {"1.image3x", zimage3x},
 
475
    {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
 
476
    {"0.poppdf14devicefilter", zpoppdf14devicefilter},
 
477
    op_def_end(0)
 
478
};