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

« back to all changes in this revision

Viewing changes to base/gsalphac.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: gsalphac.c 8585 2008-03-03 16:01:12Z leonardo $ */
 
15
/* Alpha-compositing implementation */
 
16
#include "memory_.h"
 
17
#include "gx.h"
 
18
#include "gserrors.h"
 
19
#include "gsalphac.h"
 
20
#include "gsiparam.h"           /* for gs_image_alpha_t */
 
21
#include "gsutil.h"             /* for gs_next_ids */
 
22
#include "gxalpha.h"
 
23
#include "gxcomp.h"
 
24
#include "gxdevice.h"
 
25
#include "gxgetbit.h"
 
26
#include "gxlum.h"
 
27
 
 
28
/* ---------------- Internal definitions ---------------- */
 
29
 
 
30
/* Define the parameters for a compositing operation. */
 
31
typedef struct gs_composite_params_s {
 
32
    gs_composite_op_t cop;
 
33
    float delta;                /* only for dissolve */
 
34
    uint source_alpha;          /* only if !psource->alpha */
 
35
    uint source_values[4];      /* only if !psource->data */
 
36
} gs_composite_params_t;
 
37
 
 
38
/* Define the source or destination for a compositing operation. */
 
39
#define pixel_row_fields(elt_type)\
 
40
  elt_type *data;\
 
41
  int bits_per_value;   /* 1, 2, 4, 8, 12, 16 */\
 
42
  int initial_x;\
 
43
  gs_image_alpha_t alpha
 
44
typedef struct pixel_row_s {
 
45
    pixel_row_fields(byte);
 
46
} pixel_row_t;
 
47
typedef struct const_pixel_row_s {
 
48
    pixel_row_fields(const byte);
 
49
} const_pixel_row_t;
 
50
 
 
51
/*
 
52
 * Composite two arrays of (premultiplied) pixel values.  Legal values of
 
53
 * values_per_pixel are 1-4, not including alpha.  Note that if pdest->alpha
 
54
 * is "none", the alpha value for all destination pixels will be taken as
 
55
 * unity, and any operation that could generate alpha values other than
 
56
 * unity will return an error.  "Could generate" means that there are
 
57
 * possible values of the source and destination alpha values for which the
 
58
 * result has non-unity alpha: the error check does not scan the actual
 
59
 * alpha data to test whether there are any actual values that would
 
60
 * generate a non-unity alpha result.
 
61
 */
 
62
int composite_values(const pixel_row_t * pdest,
 
63
                     const const_pixel_row_t * psource,
 
64
                     int values_per_pixel, uint num_pixels,
 
65
                     const gs_composite_params_t * pcp);
 
66
 
 
67
/* ---------------- Alpha-compositing objects ---------------- */
 
68
 
 
69
/*
 
70
 * Define which operations can generate non-unity alpha values in 3 of the 4
 
71
 * cases of source and destination not having unity alphas.  (This is always
 
72
 * possible in the fourth case, both S & D non-unity, except for CLEAR.)  We
 
73
 * do this with a bit mask indexed by the operation, counting from the LSB.
 
74
 * The name indicates whether S and/or D has non-unity alphas.
 
75
 */
 
76
#define alpha_out_notS_notD\
 
77
  (1<<composite_Dissolve)
 
78
#define _alpha_out_either\
 
79
  (alpha_out_notS_notD|(1<<composite_Satop)|(1<<composite_Datop)|\
 
80
    (1<<composite_Xor)|(1<<composite_PlusD)|(1<<composite_PlusL))
 
81
#define alpha_out_S_notD\
 
82
  (_alpha_out_either|(1<<composite_Copy)|(1<<composite_Sover)|\
 
83
    (1<<composite_Din)|(1<<composite_Dout))
 
84
#define alpha_out_notS_D\
 
85
  (_alpha_out_either|(1<<composite_Sin)|(1<<composite_Sout)|\
 
86
    (1<<composite_Dover)|(1<<composite_Highlight))
 
87
 
 
88
/* ------ Object definition and creation ------ */
 
89
 
 
90
/* Define alpha-compositing objects. */
 
91
static composite_create_default_compositor_proc(c_alpha_create_default_compositor);
 
92
static composite_equal_proc(c_alpha_equal);
 
93
static composite_write_proc(c_alpha_write);
 
94
static composite_read_proc(c_alpha_read);
 
95
const gs_composite_type_t gs_composite_alpha_type =
 
96
{
 
97
    GX_COMPOSITOR_ALPHA,
 
98
    {
 
99
        c_alpha_create_default_compositor,
 
100
        c_alpha_equal,
 
101
        c_alpha_write,
 
102
        c_alpha_read,
 
103
        gx_default_composite_adjust_ctm,
 
104
        gx_default_composite_is_closing,
 
105
        gx_default_composite_is_friendly,
 
106
        gx_default_composite_clist_write_update,
 
107
        gx_default_composite_clist_read_update,
 
108
        gx_default_composite_get_cropping
 
109
    }
 
110
};
 
111
typedef struct gs_composite_alpha_s {
 
112
    gs_composite_common;
 
113
    gs_composite_alpha_params_t params;
 
114
} gs_composite_alpha_t;
 
115
 
 
116
gs_private_st_simple(st_composite_alpha, gs_composite_alpha_t,
 
117
                     "gs_composite_alpha_t");
 
118
 
 
119
/* Create an alpha-compositing object. */
 
120
int
 
121
gs_create_composite_alpha(gs_composite_t ** ppcte,
 
122
              const gs_composite_alpha_params_t * params, gs_memory_t * mem)
 
123
{
 
124
    gs_composite_alpha_t *pcte;
 
125
 
 
126
    pcte = gs_alloc_struct(mem, gs_composite_alpha_t, &st_composite_alpha,
 
127
                             "gs_create_composite_alpha");
 
128
    if (pcte == NULL)
 
129
        return_error(gs_error_VMerror);
 
130
    pcte->type = &gs_composite_alpha_type;
 
131
    pcte->id = gs_next_ids(mem, 1);
 
132
    pcte->params = *params;
 
133
    pcte->idle = false;
 
134
    *ppcte = (gs_composite_t *) pcte;
 
135
    return 0;
 
136
}
 
137
 
 
138
/* ------ Object implementation ------ */
 
139
 
 
140
#define pacte ((const gs_composite_alpha_t *)pcte)
 
141
 
 
142
static bool
 
143
c_alpha_equal(const gs_composite_t * pcte, const gs_composite_t * pcte2)
 
144
{
 
145
    return (pcte2->type == pcte->type &&
 
146
#define pacte2 ((const gs_composite_alpha_t *)pcte2)
 
147
            pacte2->params.op == pacte->params.op &&
 
148
            (pacte->params.op != composite_Dissolve ||
 
149
             pacte2->params.delta == pacte->params.delta));
 
150
#undef pacte2
 
151
}
 
152
 
 
153
static int
 
154
c_alpha_write(const gs_composite_t * pcte, byte * data, uint * psize, gx_device_clist_writer *cdev)
 
155
{
 
156
    uint size = *psize;
 
157
    uint used;
 
158
 
 
159
    if_debug1('v', "[v]c_alpha_write(%d)\n", pacte->params.op);
 
160
    if (pacte->params.op == composite_Dissolve) {
 
161
        used = 1 + sizeof(pacte->params.delta);
 
162
        if (size < used) {
 
163
            *psize = used;
 
164
            return_error(gs_error_rangecheck);
 
165
        }
 
166
        memcpy(data + 1, &pacte->params.delta, sizeof(pacte->params.delta));
 
167
    } else {
 
168
        used = 1;
 
169
        if (size < used) {
 
170
            *psize = used;
 
171
            return_error(gs_error_rangecheck);
 
172
        }
 
173
    }
 
174
    *data = (byte) pacte->params.op;
 
175
    *psize = used;
 
176
    return 0;
 
177
}
 
178
 
 
179
static int
 
180
c_alpha_read(gs_composite_t ** ppcte, const byte * data, uint size,
 
181
             gs_memory_t * mem)
 
182
{
 
183
    gs_composite_alpha_params_t params;
 
184
    int code, nbytes = 1;
 
185
 
 
186
    if (size < 1 || *data > composite_op_last)
 
187
        return_error(gs_error_rangecheck);
 
188
    params.op = *data;
 
189
    if_debug1('v', "[v]c_alpha_read(%d)\n", params.op);
 
190
    if (params.op == composite_Dissolve) {
 
191
        if (size < 1 + sizeof(params.delta))
 
192
            return_error(gs_error_rangecheck);
 
193
        memcpy(&params.delta, data + 1, sizeof(params.delta));
 
194
        nbytes += sizeof(params.delta);
 
195
    }
 
196
    code = gs_create_composite_alpha(ppcte, &params, mem);
 
197
    return code < 0 ? code : nbytes;
 
198
}
 
199
 
 
200
/* ---------------- Alpha-compositing device ---------------- */
 
201
 
 
202
/* Define the default alpha-compositing device. */
 
203
typedef struct gx_device_composite_alpha_s {
 
204
    gx_device_forward_common;
 
205
    gs_composite_alpha_params_t params;
 
206
} gx_device_composite_alpha;
 
207
 
 
208
gs_private_st_suffix_add0_final(st_device_composite_alpha,
 
209
                     gx_device_composite_alpha, "gx_device_composite_alpha",
 
210
    device_c_alpha_enum_ptrs, device_c_alpha_reloc_ptrs, gx_device_finalize,
 
211
                                st_device_forward);
 
212
/* The device descriptor. */
 
213
static dev_proc_close_device(dca_close);
 
214
static dev_proc_fill_rectangle(dca_fill_rectangle);
 
215
static dev_proc_map_rgb_color(dca_map_rgb_color);
 
216
static dev_proc_map_color_rgb(dca_map_color_rgb);
 
217
static dev_proc_copy_mono(dca_copy_mono);
 
218
static dev_proc_copy_color(dca_copy_color);
 
219
static dev_proc_map_rgb_alpha_color(dca_map_rgb_alpha_color);
 
220
static dev_proc_map_color_rgb_alpha(dca_map_color_rgb_alpha);
 
221
static dev_proc_copy_alpha(dca_copy_alpha);
 
222
static const gx_device_composite_alpha gs_composite_alpha_device =
 
223
{std_device_std_body_open(gx_device_composite_alpha, 0,
 
224
                          "alpha compositor", 0, 0, 1, 1),
 
225
 {gx_default_open_device,
 
226
  gx_forward_get_initial_matrix,
 
227
  gx_default_sync_output,
 
228
  gx_default_output_page,
 
229
  dca_close,
 
230
  dca_map_rgb_color,
 
231
  dca_map_color_rgb,
 
232
  dca_fill_rectangle,
 
233
  gx_default_tile_rectangle,
 
234
  dca_copy_mono,
 
235
  dca_copy_color,
 
236
  gx_default_draw_line,
 
237
  gx_default_get_bits,
 
238
  gx_forward_get_params,
 
239
  gx_forward_put_params,
 
240
  gx_default_cmyk_map_cmyk_color,       /* only called for CMYK */
 
241
  gx_forward_get_xfont_procs,
 
242
  gx_forward_get_xfont_device,
 
243
  dca_map_rgb_alpha_color,
 
244
  gx_forward_get_page_device,
 
245
  gx_forward_get_alpha_bits,
 
246
  dca_copy_alpha,
 
247
  gx_forward_get_band,
 
248
  gx_default_copy_rop,
 
249
  gx_default_fill_path,
 
250
  gx_default_stroke_path,
 
251
  gx_default_fill_mask,
 
252
  gx_default_fill_trapezoid,
 
253
  gx_default_fill_parallelogram,
 
254
  gx_default_fill_triangle,
 
255
  gx_default_draw_thin_line,
 
256
  gx_default_begin_image,
 
257
  gx_default_image_data,
 
258
  gx_default_end_image,
 
259
  gx_default_strip_tile_rectangle,
 
260
  gx_default_strip_copy_rop,
 
261
  gx_forward_get_clipping_box,
 
262
  gx_default_begin_typed_image,
 
263
  gx_forward_get_bits_rectangle,
 
264
  dca_map_color_rgb_alpha,
 
265
  gx_no_create_compositor
 
266
 }
 
267
};
 
268
 
 
269
/* Create an alpha compositor. */
 
270
static int
 
271
c_alpha_create_default_compositor(const gs_composite_t * pcte,
 
272
           gx_device ** pcdev, gx_device * dev, gs_imager_state * pis,
 
273
           gs_memory_t * mem)
 
274
{
 
275
    gx_device_composite_alpha *cdev;
 
276
 
 
277
    if (pacte->params.op == composite_Copy) {
 
278
        /* Just use the original device. */
 
279
        *pcdev = dev;
 
280
        return 0;
 
281
    }
 
282
    cdev =
 
283
        gs_alloc_struct_immovable(mem, gx_device_composite_alpha,
 
284
                                  &st_device_composite_alpha,
 
285
                                  "create default alpha compositor");
 
286
    *pcdev = (gx_device *)cdev;
 
287
    if (cdev == 0)
 
288
        return_error(gs_error_VMerror);
 
289
    gx_device_init((gx_device *)cdev,
 
290
                   (const gx_device *)&gs_composite_alpha_device, mem, true);
 
291
    gx_device_copy_params((gx_device *)cdev, dev);
 
292
    /*
 
293
     * Set the color_info and depth to be compatible with the target,
 
294
     * but using standard chunky color storage, including alpha.
 
295
     ****** CURRENTLY ALWAYS USE 8-BIT COLOR ******
 
296
     */
 
297
    cdev->color_info.depth =
 
298
        (dev->color_info.num_components == 4 ? 32 /* CMYK, no alpha */ :
 
299
         (dev->color_info.num_components + 1) * 8);
 
300
    cdev->color_info.max_gray = cdev->color_info.max_color = 255;
 
301
    /* No halftoning will occur, but we fill these in anyway.... */
 
302
    cdev->color_info.dither_grays = cdev->color_info.dither_colors = 256;
 
303
    /*
 
304
     * We could speed things up a little by tailoring the procedures in
 
305
     * the device to the specific num_components, but for simplicity,
 
306
     * we'll defer considering that until there is a demonstrated need.
 
307
     */
 
308
    gx_device_set_target((gx_device_forward *)cdev, dev);
 
309
    cdev->params = pacte->params;
 
310
    return 0;
 
311
}
 
312
 
 
313
/* Close the device and free its storage. */
 
314
static int
 
315
dca_close(gx_device * dev)
 
316
{                               /*
 
317
                                 * Finalization will call close again: avoid a recursion loop.
 
318
                                 */
 
319
    set_dev_proc(dev, close_device, gx_default_close_device);
 
320
    gs_free_object(dev->memory, dev, "dca_close");
 
321
    return 0;
 
322
}
 
323
 
 
324
/* ------ (RGB) color mapping ------ */
 
325
 
 
326
static gx_color_index
 
327
dca_map_rgb_color(gx_device * dev, const gx_color_value cv[])
 
328
{
 
329
    return dca_map_rgb_alpha_color(dev, cv[0], cv[1], cv[2], gx_max_color_value);
 
330
}
 
331
static gx_color_index
 
332
dca_map_rgb_alpha_color(gx_device * dev,
 
333
              gx_color_value red, gx_color_value green, gx_color_value blue,
 
334
                        gx_color_value alpha)
 
335
{                               /*
 
336
                                 * We work exclusively with premultiplied color values, so we
 
337
                                 * have to premultiply the color components by alpha here.
 
338
                                 */
 
339
    byte a = gx_color_value_to_byte(alpha);
 
340
 
 
341
#define premult_(c)\
 
342
  (((c) * a + gx_max_color_value / 2) / gx_max_color_value)
 
343
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
344
    byte bias = ~a;
 
345
 
 
346
#  define premult(c) (premult_(c) + bias)
 
347
#else
 
348
#  define premult(c) premult_(c)
 
349
#endif
 
350
    gx_color_index color;
 
351
 
 
352
    if (dev->color_info.num_components == 1) {
 
353
        uint lum =
 
354
        (red * lum_red_weight + green * lum_green_weight +
 
355
         blue * lum_blue_weight + lum_all_weights / 2) /
 
356
        lum_all_weights;
 
357
 
 
358
        if (a == 0xff)
 
359
            color = gx_color_value_to_byte(lum);
 
360
        else                    /* Premultiplication is necessary. */
 
361
            color = premult(lum);
 
362
    } else {
 
363
        if (a == 0xff)
 
364
            color =
 
365
                ((uint) gx_color_value_to_byte(red) << 16) +
 
366
                ((uint) gx_color_value_to_byte(green) << 8) +
 
367
                gx_color_value_to_byte(blue);
 
368
        else                    /* Premultiplication is necessary. */
 
369
            color =
 
370
                (premult(red) << 16) + (premult(green) << 8) + premult(blue);
 
371
    }
 
372
#undef premult
 
373
    return (color << 8) + a;
 
374
}
 
375
static int
 
376
dca_map_color_rgb(gx_device * dev, gx_color_index color,
 
377
                  gx_color_value prgb[3])
 
378
{
 
379
    gx_color_value red = gx_color_value_from_byte((byte) (color >> 24));
 
380
    byte a = (byte) color;
 
381
 
 
382
#define postdiv_(c)\
 
383
  (((c) * 0xff + a / 2) / a)
 
384
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
385
    byte bias = ~a;
 
386
 
 
387
#  define postdiv(c) postdiv_(c - bias)
 
388
#else
 
389
#  define postdiv(c) postdiv_(c)
 
390
#endif
 
391
 
 
392
    if (dev->color_info.num_components == 1) {
 
393
        if (a != 0xff) {
 
394
            /* Undo premultiplication. */
 
395
            if (a == 0)
 
396
                red = 0;
 
397
            else
 
398
                red = postdiv(red);
 
399
        }
 
400
        prgb[0] = prgb[1] = prgb[2] = red;
 
401
    } else {
 
402
        gx_color_value
 
403
            green = gx_color_value_from_byte((byte) (color >> 16)),
 
404
            blue = gx_color_value_from_byte((byte) (color >> 8));
 
405
 
 
406
        if (a != 0xff) {
 
407
            /* Undo premultiplication. */
 
408
/****** WHAT TO DO ABOUT BIG LOSS OF PRECISION? ******/
 
409
            if (a == 0)
 
410
                red = green = blue = 0;
 
411
            else {
 
412
                red = postdiv(red);
 
413
                green = postdiv(green);
 
414
                blue = postdiv(blue);
 
415
            }
 
416
        }
 
417
        prgb[0] = red, prgb[1] = green, prgb[2] = blue;
 
418
    }
 
419
#undef postdiv
 
420
    return 0;
 
421
}
 
422
static int
 
423
dca_map_color_rgb_alpha(gx_device * dev, gx_color_index color,
 
424
                        gx_color_value prgba[4])
 
425
{
 
426
    prgba[3] = gx_color_value_from_byte((byte) color);
 
427
    return dca_map_color_rgb(dev, color, prgba);
 
428
}
 
429
 
 
430
/* ------ Imaging ------ */
 
431
 
 
432
static int
 
433
dca_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
 
434
                   gx_color_index color)
 
435
{                               /* This is where all the real work gets done! */
 
436
    gx_device_composite_alpha *adev = (gx_device_composite_alpha *) dev;
 
437
    gx_device *target = adev->target;
 
438
    byte *std_row;
 
439
    byte *native_row;
 
440
    gs_int_rect rect;
 
441
    gs_get_bits_params_t std_params, native_params;
 
442
    int code = 0;
 
443
    int yi;
 
444
    gs_composite_params_t cp;
 
445
    const_pixel_row_t source;
 
446
    pixel_row_t dest;
 
447
 
 
448
    fit_fill(dev, x, y, w, h);
 
449
    std_row = gs_alloc_bytes(dev->memory,
 
450
                             (dev->color_info.depth * w + 7) >> 3,
 
451
                             "dca_fill_rectangle(std)");
 
452
    native_row = gs_alloc_bytes(dev->memory,
 
453
                                (target->color_info.depth * w + 7) >> 3,
 
454
                                "dca_fill_rectangle(native)");
 
455
    if (std_row == 0 || native_row == 0) {
 
456
        code = gs_note_error(gs_error_VMerror);
 
457
        goto out;
 
458
    }
 
459
    rect.p.x = x, rect.q.x = x + w;
 
460
    std_params.options =
 
461
        GB_COLORS_NATIVE |
 
462
        (GB_ALPHA_LAST | GB_DEPTH_8 | GB_PACKING_CHUNKY |
 
463
         GB_RETURN_COPY | GB_RETURN_POINTER | GB_ALIGN_ANY |
 
464
         GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD |
 
465
         GB_RASTER_ANY);
 
466
    cp.cop = adev->params.op;
 
467
    if (cp.cop == composite_Dissolve)
 
468
        cp.delta = adev->params.delta;
 
469
    {
 
470
        gx_color_value rgba[4];
 
471
 
 
472
/****** DOESN'T HANDLE CMYK ******/
 
473
        (*dev_proc(dev, map_color_rgb_alpha)) (dev, color, rgba);
 
474
        cp.source_values[0] = gx_color_value_to_byte(rgba[0]);
 
475
        cp.source_values[1] = gx_color_value_to_byte(rgba[1]);
 
476
        cp.source_values[2] = gx_color_value_to_byte(rgba[2]);
 
477
        cp.source_alpha = gx_color_value_to_byte(rgba[3]);
 
478
    }
 
479
    source.data = 0;
 
480
    source.bits_per_value = 8;
 
481
    source.alpha = gs_image_alpha_none;
 
482
    for (yi = y; yi < y + h; ++yi) {
 
483
        /* Read a row in standard representation. */
 
484
        rect.p.y = yi, rect.q.y = yi + 1;
 
485
        std_params.data[0] = std_row;
 
486
        code = (*dev_proc(target, get_bits_rectangle))
 
487
            (target, &rect, &std_params, NULL);
 
488
        if (code < 0)
 
489
            break;
 
490
        /* Do the work. */
 
491
        dest.data = std_params.data[0];
 
492
        dest.bits_per_value = 8;
 
493
        dest.initial_x =
 
494
            (std_params.options & GB_OFFSET_ANY ? std_params.x_offset : 0);
 
495
        dest.alpha =
 
496
            (std_params.options & GB_ALPHA_FIRST ? gs_image_alpha_first :
 
497
             std_params.options & GB_ALPHA_LAST ? gs_image_alpha_last :
 
498
             gs_image_alpha_none);
 
499
        code = composite_values(&dest, &source,
 
500
                                dev->color_info.num_components, w, &cp);
 
501
        if (code < 0)
 
502
            break;
 
503
        if (std_params.data[0] == std_row) {
 
504
            /* Convert the row back to native representation. */
 
505
            /* (Otherwise, we had a direct pointer to device data.) */
 
506
            native_params.options =
 
507
                (GB_COLORS_NATIVE | GB_PACKING_CHUNKY | GB_RETURN_COPY |
 
508
                 GB_OFFSET_0 | GB_RASTER_ALL | GB_ALIGN_STANDARD);
 
509
            native_params.data[0] = native_row;
 
510
            code = gx_get_bits_copy(target, 0, w, 1, &native_params,
 
511
                                    &std_params, std_row,
 
512
                                    0 /* raster is irrelevant */ );
 
513
            if (code < 0)
 
514
                break;
 
515
            code = (*dev_proc(target, copy_color))
 
516
                (target, native_row, 0, 0 /* raster is irrelevant */ ,
 
517
                 gx_no_bitmap_id, x, yi, w, 1);
 
518
            if (code < 0)
 
519
                break;
 
520
        }
 
521
    }
 
522
  out:gs_free_object(dev->memory, native_row, "dca_fill_rectangle(native)");
 
523
    gs_free_object(dev->memory, std_row, "dca_fill_rectangle(std)");
 
524
    return code;
 
525
}
 
526
 
 
527
static int
 
528
dca_copy_mono(gx_device * dev, const byte * data,
 
529
            int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h,
 
530
              gx_color_index zero, gx_color_index one)
 
531
{
 
532
/****** TEMPORARY ******/
 
533
    return gx_default_copy_mono(dev, data, dx, raster, id, x, y, w, h,
 
534
                                zero, one);
 
535
}
 
536
 
 
537
static int
 
538
dca_copy_color(gx_device * dev, const byte * data,
 
539
               int dx, int raster, gx_bitmap_id id,
 
540
               int x, int y, int w, int h)
 
541
{
 
542
/****** TEMPORARY ******/
 
543
    return gx_default_copy_color(dev, data, dx, raster, id, x, y, w, h);
 
544
}
 
545
 
 
546
static int
 
547
dca_copy_alpha(gx_device * dev, const byte * data, int data_x,
 
548
           int raster, gx_bitmap_id id, int x, int y, int width, int height,
 
549
               gx_color_index color, int depth)
 
550
{
 
551
/****** TEMPORARY ******/
 
552
    return gx_default_copy_alpha(dev, data, data_x, raster, id, x, y,
 
553
                                 width, height, color, depth);
 
554
}
 
555
 
 
556
/*
 
557
 * Composite two arrays of (premultiplied) pixel values.
 
558
 * See gsdpnext.h for the specification.
 
559
 *
 
560
 * The current implementation is simple but inefficient.  We'll speed it up
 
561
 * later if necessary.
 
562
 */
 
563
int
 
564
composite_values(const pixel_row_t * pdest, const const_pixel_row_t * psource,
 
565
   int values_per_pixel, uint num_pixels, const gs_composite_params_t * pcp)
 
566
{
 
567
    int dest_bpv = pdest->bits_per_value;
 
568
    int source_bpv = psource->bits_per_value;
 
569
 
 
570
    /*
 
571
     * source_alpha_j gives the source component index for the alpha value,
 
572
     * if the source has alpha.
 
573
     */
 
574
    int source_alpha_j =
 
575
    (psource->alpha == gs_image_alpha_last ? values_per_pixel :
 
576
     psource->alpha == gs_image_alpha_first ? 0 : -1);
 
577
 
 
578
    /* dest_alpha_j does the same for the destination. */
 
579
    int dest_alpha_j =
 
580
    (pdest->alpha == gs_image_alpha_last ? values_per_pixel :
 
581
     pdest->alpha == gs_image_alpha_first ? 0 : -1);
 
582
 
 
583
    /* dest_vpp is the number of stored destination values. */
 
584
    int dest_vpp = values_per_pixel + (dest_alpha_j >= 0);
 
585
 
 
586
    /* source_vpp is the number of stored source values. */
 
587
    int source_vpp = values_per_pixel + (source_alpha_j >= 0);
 
588
 
 
589
    bool constant_colors = psource->data == 0;
 
590
    uint highlight_value = (1 << dest_bpv) - 1;
 
591
 
 
592
    sample_load_declare(sptr, sbit);
 
593
    sample_store_declare(dptr, dbit, dbyte);
 
594
 
 
595
    {
 
596
        uint xbit = pdest->initial_x * dest_bpv * dest_vpp;
 
597
 
 
598
        sample_store_setup(dbit, xbit & 7, dest_bpv);
 
599
        dptr = pdest->data + (xbit >> 3);
 
600
    }
 
601
    {
 
602
        uint xbit = psource->initial_x * source_bpv * source_vpp;
 
603
 
 
604
        sbit = xbit & 7;
 
605
        sptr = psource->data + (xbit >> 3);
 
606
    }
 
607
    {
 
608
        uint source_max = (1 << source_bpv) - 1;
 
609
        uint dest_max = (1 << dest_bpv) - 1;
 
610
 
 
611
        /*
 
612
         * We could save a little work by only setting up source_delta
 
613
         * and dest_delta if the operation is Dissolve.
 
614
         */
 
615
        float source_delta = pcp->delta * dest_max / source_max;
 
616
        float dest_delta = 1.0 - pcp->delta;
 
617
        uint source_alpha = pcp->source_alpha;
 
618
        uint dest_alpha = dest_max;
 
619
 
 
620
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
621
        uint source_bias = source_max - source_alpha;
 
622
        uint dest_bias = 0;
 
623
        uint result_bias = 0;
 
624
 
 
625
#endif
 
626
        uint x;
 
627
 
 
628
        if (!pdest->alpha) {
 
629
            uint mask =
 
630
            (psource->alpha || source_alpha != source_max ?
 
631
             alpha_out_S_notD : alpha_out_notS_notD);
 
632
 
 
633
            if ((mask >> pcp->cop) & 1) {
 
634
                /*
 
635
                 * The operation could produce non-unity alpha values, but
 
636
                 * the destination can't store them.  Return an error.
 
637
                 */
 
638
                return_error(gs_error_rangecheck);
 
639
            }
 
640
        }
 
641
        /* Preload the output byte buffer if necessary. */
 
642
        sample_store_preload(dbyte, dptr, dbit, dest_bpv);
 
643
 
 
644
        for (x = 0; x < num_pixels; ++x) {
 
645
            int j;
 
646
            uint result_alpha = dest_alpha;
 
647
 
 
648
/* get_value does not increment the source pointer. */
 
649
#define get_value(v, ptr, bit, bpv, vmax)\
 
650
  sample_load16(v, ptr, bit, bpv)
 
651
 
 
652
/* put_value increments the destination pointer. */
 
653
#define put_value(v, ptr, bit, bpv, bbyte)\
 
654
  sample_store_next16(v, ptr, bit, bpv, bbyte)
 
655
 
 
656
#define advance(ptr, bit, bpv)\
 
657
  sample_next(ptr, bit, bpv)
 
658
 
 
659
            /* Get destination alpha value. */
 
660
            if (dest_alpha_j >= 0) {
 
661
                int dabit = dbit + dest_bpv * dest_alpha_j;
 
662
                const byte *daptr = dptr + (dabit >> 3);
 
663
 
 
664
                get_value(dest_alpha, daptr, dabit & 7, dest_bpv, dest_max);
 
665
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
666
                dest_bias = dest_max - dest_alpha;
 
667
#endif
 
668
            }
 
669
            /* Get source alpha value. */
 
670
            if (source_alpha_j >= 0) {
 
671
                int sabit = sbit;
 
672
                const byte *saptr = sptr;
 
673
 
 
674
                if (source_alpha_j == 0)
 
675
                    advance(sptr, sbit, source_bpv);
 
676
                else
 
677
                    advance(saptr, sabit, source_bpv * source_alpha_j);
 
678
                get_value(source_alpha, saptr, sabit, source_bpv, source_max);
 
679
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
680
                source_bias = source_max - source_alpha;
 
681
#endif
 
682
            }
 
683
/*
 
684
 * We are always multiplying a dest value by a source value to compute a
 
685
 * dest value, so the denominator is always source_max.  (Dissolve is the
 
686
 * one exception.)
 
687
 */
 
688
#define fr(v, a) ((v) * (a) / source_max)
 
689
#define nfr(v, a, maxv) ((v) * (maxv - (a)) / source_max)
 
690
 
 
691
            /*
 
692
             * Iterate over the components of a single pixel.
 
693
             * j = 0 for alpha, 1 .. values_per_pixel for color
 
694
             * components, regardless of the actual storage order;
 
695
             * we arrange things so that sptr/sbit and dptr/dbit
 
696
             * always point to the right place.
 
697
             */
 
698
            for (j = 0; j <= values_per_pixel; ++j) {
 
699
                uint dest_v, source_v, result;
 
700
 
 
701
#define set_clamped(r, v)\
 
702
  BEGIN if ( (r = (v)) > dest_max ) r = dest_max; END
 
703
 
 
704
                if (j == 0) {
 
705
                    source_v = source_alpha;
 
706
                    dest_v = dest_alpha;
 
707
                } else {
 
708
                    if (constant_colors)
 
709
                        source_v = pcp->source_values[j - 1];
 
710
                    else {
 
711
                        get_value(source_v, sptr, sbit, source_bpv, source_max);
 
712
                        advance(sptr, sbit, source_bpv);
 
713
                    }
 
714
                    get_value(dest_v, dptr, dbit, dest_bpv, dest_max);
 
715
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
716
                    source_v -= source_bias;
 
717
                    dest_v -= dest_bias;
 
718
#endif
 
719
                }
 
720
 
 
721
                switch (pcp->cop) {
 
722
                    case composite_Clear:
 
723
                        /*
 
724
                         * The NeXT documentation doesn't say this, but the CLEAR
 
725
                         * operation sets not only alpha but also all the color
 
726
                         * values to 0.
 
727
                         */
 
728
                        result = 0;
 
729
                        break;
 
730
                    case composite_Copy:
 
731
                        result = source_v;
 
732
                        break;
 
733
                    case composite_PlusD:
 
734
                        /*
 
735
                         * This is the only case where we have to worry about
 
736
                         * clamping a possibly negative result.
 
737
                         */
 
738
                        result = source_v + dest_v;
 
739
                        result = (result < dest_max ? 0 : result - dest_max);
 
740
                        break;
 
741
                    case composite_PlusL:
 
742
                        set_clamped(result, source_v + dest_v);
 
743
                        break;
 
744
                    case composite_Sover:
 
745
                        set_clamped(result, source_v + nfr(dest_v, source_alpha, source_max));
 
746
                        break;
 
747
                    case composite_Dover:
 
748
                        set_clamped(result, nfr(source_v, dest_alpha, dest_max) + dest_v);
 
749
                        break;
 
750
                    case composite_Sin:
 
751
                        result = fr(source_v, dest_alpha);
 
752
                        break;
 
753
                    case composite_Din:
 
754
                        result = fr(dest_v, source_alpha);
 
755
                        break;
 
756
                    case composite_Sout:
 
757
                        result = nfr(source_v, dest_alpha, dest_max);
 
758
                        break;
 
759
                    case composite_Dout:
 
760
                        result = nfr(dest_v, source_alpha, source_max);
 
761
                        break;
 
762
                    case composite_Satop:
 
763
                        set_clamped(result, fr(source_v, dest_alpha) +
 
764
                                    nfr(dest_v, source_alpha, source_max));
 
765
                        break;
 
766
                    case composite_Datop:
 
767
                        set_clamped(result, nfr(source_v, dest_alpha, dest_max) +
 
768
                                    fr(dest_v, source_alpha));
 
769
                        break;
 
770
                    case composite_Xor:
 
771
                        set_clamped(result, nfr(source_v, dest_alpha, dest_max) +
 
772
                                    nfr(dest_v, source_alpha, source_max));
 
773
                        break;
 
774
                    case composite_Highlight:
 
775
                        /*
 
776
                         * Bizarre but true: this operation converts white and
 
777
                         * light gray into each other, and leaves all other values
 
778
                         * unchanged.  We only implement it properly for gray-scale
 
779
                         * devices.
 
780
                         */
 
781
                        if (j != 0 && !((source_v ^ highlight_value) & ~1))
 
782
                            result = source_v ^ 1;
 
783
                        else
 
784
                            result = source_v;
 
785
                        break;
 
786
                    case composite_Dissolve:
 
787
                        /*
 
788
                         * In this case, and only this case, we need to worry about
 
789
                         * source and dest having different bpv values.  For the
 
790
                         * moment, we wimp out and do everything in floating point.
 
791
                         */
 
792
                        result = (uint) (source_v * source_delta + dest_v * dest_delta);
 
793
                        break;
 
794
                    default:
 
795
                        return_error(gs_error_rangecheck);
 
796
                }
 
797
                /*
 
798
                 * Store the result.  We don't have to worry about
 
799
                 * destinations that don't store alpha, because we don't
 
800
                 * even compute an alpha value in that case.
 
801
                 */
 
802
#ifdef PREMULTIPLY_TOWARDS_WHITE
 
803
                if (j == 0) {
 
804
                    result_alpha = result;
 
805
                    result_bias = dest_max - result_alpha;
 
806
                    if (dest_alpha_j != 0)
 
807
                        continue;
 
808
                } else {
 
809
                    result += result_bias;
 
810
                }
 
811
#else
 
812
                if (j == 0 && dest_alpha_j != 0) {
 
813
                    result_alpha = result;
 
814
                    continue;
 
815
                }
 
816
#endif
 
817
                put_value(result, dptr, dbit, dest_bpv, dbyte);
 
818
            }
 
819
            /* Skip a trailing source alpha value. */
 
820
            if (source_alpha_j > 0)
 
821
                advance(sptr, sbit, source_bpv);
 
822
            /* Store a trailing destination alpha value. */
 
823
            if (dest_alpha_j > 0)
 
824
                put_value(result_alpha, dptr, dbit, dest_bpv, dbyte);
 
825
#undef get_value
 
826
#undef put_value
 
827
#undef advance
 
828
        }
 
829
        /* Store any partial output byte. */
 
830
        sample_store_flush(dptr, dbit, dest_bpv, dbyte);
 
831
    }
 
832
    return 0;
 
833
}