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

« back to all changes in this revision

Viewing changes to base/gxicolor.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: gxicolor.c 8677 2008-04-29 06:34:17Z mvrhel $ */
 
15
/* Color image rendering */
 
16
 
 
17
#include "gx.h"
 
18
#include "memory_.h"
 
19
#include "gpcheck.h"
 
20
#include "gserrors.h"
 
21
#include "gxfixed.h"
 
22
#include "gxfrac.h"
 
23
#include "gxarith.h"
 
24
#include "gxmatrix.h"
 
25
#include "gsccolor.h"
 
26
#include "gspaint.h"
 
27
#include "gzstate.h"
 
28
#include "gxdevice.h"
 
29
#include "gxcmap.h"
 
30
#include "gxdcconv.h"
 
31
#include "gxdcolor.h"
 
32
#include "gxistate.h"
 
33
#include "gxdevmem.h"
 
34
#include "gxcpath.h"
 
35
#include "gximage.h"
 
36
#include "icc.h"                        
 
37
#include "gsicc.h"
 
38
 
 
39
typedef union {
 
40
    byte v[GS_IMAGE_MAX_COLOR_COMPONENTS];
 
41
#define BYTES_PER_BITS32 4
 
42
#define BITS32_PER_COLOR_SAMPLES\
 
43
  ((GS_IMAGE_MAX_COLOR_COMPONENTS + BYTES_PER_BITS32 - 1) / BYTES_PER_BITS32)
 
44
    bits32 all[BITS32_PER_COLOR_SAMPLES];       /* for fast comparison */
 
45
} color_samples;
 
46
 
 
47
/* ------ Strategy procedure ------ */
 
48
 
 
49
/* Check the prototype. */
 
50
iclass_proc(gs_image_class_4_color);
 
51
 
 
52
static irender_proc(image_render_color);
 
53
irender_proc_t
 
54
gs_image_class_4_color(gx_image_enum * penum)
 
55
{
 
56
    if (penum->use_mask_color) {
 
57
        /*
 
58
         * Scale the mask colors to match the scaling of each sample to
 
59
         * a full byte, and set up the quick-filter parameters.
 
60
         */
 
61
        int i;
 
62
        color_samples mask, test;
 
63
        bool exact = penum->spp <= BYTES_PER_BITS32;
 
64
 
 
65
        memset(&mask, 0, sizeof(mask));
 
66
        memset(&test, 0, sizeof(test));
 
67
        for (i = 0; i < penum->spp; ++i) {
 
68
            byte v0, v1;
 
69
            byte match = 0xff;
 
70
 
 
71
            gx_image_scale_mask_colors(penum, i);
 
72
            v0 = (byte)penum->mask_color.values[2 * i];
 
73
            v1 = (byte)penum->mask_color.values[2 * i + 1];
 
74
            while ((v0 & match) != (v1 & match))
 
75
                match <<= 1;
 
76
            mask.v[i] = match;
 
77
            test.v[i] = v0 & match;
 
78
            exact &= (v0 == match && (v1 | match) == 0xff);
 
79
        }
 
80
        penum->mask_color.mask = mask.all[0];
 
81
        penum->mask_color.test = test.all[0];
 
82
        penum->mask_color.exact = exact;
 
83
    } else {
 
84
        penum->mask_color.mask = 0;
 
85
        penum->mask_color.test = ~0;
 
86
    }
 
87
    return &image_render_color;
 
88
}
 
89
 
 
90
/* ------ Rendering procedures ------ */
 
91
 
 
92
/* Test whether a color is transparent. */
 
93
static bool
 
94
mask_color_matches(const byte *v, const gx_image_enum *penum,
 
95
                   int num_components)
 
96
{
 
97
    int i;
 
98
 
 
99
    for (i = num_components * 2, v += num_components - 1; (i -= 2) >= 0; --v)
 
100
        if (*v < penum->mask_color.values[i] ||
 
101
            *v > penum->mask_color.values[i + 1]
 
102
            )
 
103
            return false;
 
104
    return true;
 
105
}
 
106
 
 
107
/* Render a color image with 8 or fewer bits per sample. */
 
108
static int
 
109
image_render_color(gx_image_enum *penum_orig, const byte *buffer, int data_x,
 
110
                   uint w, int h, gx_device * dev)
 
111
{
 
112
    const gx_image_enum *const penum = penum_orig; /* const within proc */
 
113
    gx_image_clue *const clues = penum_orig->clues; /* not const */
 
114
    const gs_imager_state *pis = penum->pis;
 
115
    gs_logical_operation_t lop = penum->log_op;
 
116
    gx_dda_fixed_point pnext;
 
117
    image_posture posture = penum->posture;
 
118
    fixed xprev, yprev;
 
119
    fixed pdyx, pdyy;           /* edge of parallelogram */
 
120
    int vci, vdi;
 
121
    const gs_color_space *pcs = penum->pcs;
 
122
    cs_proc_remap_color((*remap_color)) = pcs->type->remap_color;
 
123
    cs_proc_remap_concrete_color((*remap_concrete_color)) =
 
124
            pcs->type->remap_concrete_color;
 
125
    gs_client_color cc;
 
126
    bool device_color = penum->device_color;
 
127
    const gx_color_map_procs *cmap_procs = gx_get_cmap_procs(pis, dev);
 
128
    bits32 mask = penum->mask_color.mask;
 
129
    bits32 test = penum->mask_color.test;
 
130
    gx_image_clue *pic = &clues[0];
 
131
#define pdevc (&pic->dev_color)
 
132
    gx_image_clue *pic_next = &clues[1];
 
133
#define pdevc_next (&pic_next->dev_color)
 
134
    gx_image_clue empty_clue;
 
135
    gx_image_clue clue_temp;
 
136
    int spp = penum->spp;
 
137
    const byte *psrc_initial = buffer + data_x * spp;
 
138
    const byte *psrc = psrc_initial;
 
139
    const byte *rsrc = psrc + spp; /* psrc + spp at start of run */
 
140
    fixed xrun;                 /* x ditto */
 
141
    fixed yrun;                 /* y ditto */
 
142
    int irun;                   /* int x/rrun */
 
143
    color_samples run;          /* run value */
 
144
    color_samples next;         /* next sample value */
 
145
    const byte *bufend = psrc + w;
 
146
    bool use_cache = spp * penum->bps <= 12;
 
147
    int code = 0, mcode = 0;
 
148
    gs_cie_icc * picc_info; /*used for detecting if image source color space is CIELAB.  */
 
149
 
 
150
    if (h == 0)
 
151
        return 0;
 
152
    pnext = penum->dda.pixel0;
 
153
    xrun = xprev = dda_current(pnext.x);
 
154
    yrun = yprev = dda_current(pnext.y);
 
155
    pdyx = dda_current(penum->dda.row.x) - penum->cur.x;
 
156
    pdyy = dda_current(penum->dda.row.y) - penum->cur.y;
 
157
    switch (posture) {
 
158
        case image_portrait:
 
159
            vci = penum->yci, vdi = penum->hci;
 
160
            irun = fixed2int_var_rounded(xrun);
 
161
            break;
 
162
        case image_landscape:
 
163
        default:    /* we don't handle skew -- treat as landscape */
 
164
            vci = penum->xci, vdi = penum->wci;
 
165
            irun = fixed2int_var_rounded(yrun);
 
166
            break;
 
167
    }
 
168
 
 
169
    if_debug5('b', "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n",
 
170
              penum->y, data_x, w, fixed2float(xprev), fixed2float(yprev));
 
171
    memset(&run, 0, sizeof(run));
 
172
    memset(&next, 0, sizeof(next));
 
173
    /* Ensure that we don't get any false dev_color_eq hits. */
 
174
    if (use_cache) {
 
175
        set_nonclient_dev_color(&empty_clue.dev_color, gx_no_color_index);
 
176
        pic = &empty_clue;
 
177
    }
 
178
    cs_full_init_color(&cc, pcs);
 
179
    run.v[0] = ~psrc[0];        /* force remap */
 
180
    while (psrc < bufend) {
 
181
        dda_next(pnext.x);
 
182
        dda_next(pnext.y);
 
183
#define CLUE_HASH3(penum, next)\
 
184
  &clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4)) & 255];
 
185
#define CLUE_HASH4(penum, next)\
 
186
  &clues[(next.v[0] + (next.v[1] << 2) + (next.v[2] << 4) +\
 
187
                 (next.v[3] << 6)) & 255]
 
188
 
 
189
        if (spp == 4) {         /* may be CMYK or RGBA */
 
190
            next.v[0] = psrc[0];
 
191
            next.v[1] = psrc[1];
 
192
            next.v[2] = psrc[2];
 
193
            next.v[3] = psrc[3];
 
194
            psrc += 4;
 
195
map4:       if (posture != image_skewed && next.all[0] == run.all[0])
 
196
                goto inc;
 
197
            if (use_cache) {
 
198
                pic_next = CLUE_HASH4(penum, next);
 
199
                if (pic_next->key == next.all[0])
 
200
                    goto f;
 
201
                /*
 
202
                 * If we are really unlucky, pic_next == pic,
 
203
                 * so mapping this color would clobber the one
 
204
                 * we're about to use for filling the run.
 
205
                 */
 
206
                if (pic_next == pic) {
 
207
                    clue_temp = *pic;
 
208
                    pic = &clue_temp;
 
209
                }
 
210
                pic_next->key = next.all[0];
 
211
            }
 
212
            /* Check for transparent color. */
 
213
            if ((next.all[0] & mask) == test &&
 
214
                (penum->mask_color.exact ||
 
215
                 mask_color_matches(next.v, penum, 4))
 
216
                ) {
 
217
                color_set_null(pdevc_next);
 
218
                goto mapped;
 
219
            }
 
220
            if (device_color) {
 
221
                frac frac_color[4];
 
222
 
 
223
                if (penum->alpha) {
 
224
                    /*
 
225
                     * We do not have support for DeviceN color and alpha.
 
226
                     */
 
227
                    cmap_procs->map_rgb_alpha
 
228
                        (byte2frac(next.v[0]), byte2frac(next.v[1]),
 
229
                         byte2frac(next.v[2]), byte2frac(next.v[3]),
 
230
                         pdevc_next, pis, dev,
 
231
                         gs_color_select_source);
 
232
                    goto mapped;
 
233
                }
 
234
                /*
 
235
                 * We can call the remap concrete_color for the colorspace
 
236
                 * directly since device_color is only true if the colorspace
 
237
                 * is concrete.
 
238
                 */
 
239
                frac_color[0] = byte2frac(next.v[0]);
 
240
                frac_color[1] = byte2frac(next.v[1]);
 
241
                frac_color[2] = byte2frac(next.v[2]);
 
242
                frac_color[3] = byte2frac(next.v[3]);
 
243
                remap_concrete_color(frac_color, pcs, pdevc_next, pis,
 
244
                                            dev, gs_color_select_source);
 
245
                goto mapped;
 
246
            }
 
247
            decode_sample(next.v[3], cc, 3);
 
248
            if_debug1('B', "[B]cc[3]=%g\n", cc.paint.values[3]);
 
249
do3:    if(spp == 3 && pcs->type->index == gs_color_space_index_CIEICC)
 
250
                {
 
251
                        /* It is 3 channel with an ICC profile.
 
252
                         We need to check if it is an LAB image */
 
253
 
 
254
                        picc_info = pcs->params.icc.picc_info;
 
255
 
 
256
                        if( picc_info->plu->e_inSpace == icSigLabData )
 
257
                        {
 
258
 
 
259
                                /* It is a CIELAB image.  For now, put in true CIELAB float values rather than normalized 0 to 1 floats */
 
260
                                /* concretization will handle the proper conversion  this way */
 
261
 
 
262
                                decode_sample(next.v[0], cc, 0);
 
263
                                cc.paint.values[0]*=100.0;
 
264
                                decode_sample(next.v[1], cc, 1);
 
265
                                cc.paint.values[1] = 255.0*cc.paint.values[1] - 128.0;
 
266
                                decode_sample(next.v[2], cc, 2);
 
267
                                cc.paint.values[2] = 255.0*cc.paint.values[2] - 128.0;
 
268
 
 
269
                        } else {
 
270
 
 
271
                                /* To floats */
 
272
 
 
273
                                decode_sample(next.v[0], cc, 0);
 
274
                                decode_sample(next.v[1], cc, 1);
 
275
                                decode_sample(next.v[2], cc, 2);
 
276
 
 
277
                        }
 
278
 
 
279
                } else {
 
280
 
 
281
                        /* To floats */
 
282
 
 
283
                        decode_sample(next.v[0], cc, 0);
 
284
                        decode_sample(next.v[1], cc, 1);
 
285
                        decode_sample(next.v[2], cc, 2);
 
286
 
 
287
                }
 
288
 
 
289
            if_debug3('B', "[B]cc[0..2]=%g,%g,%g\n",
 
290
                      cc.paint.values[0], cc.paint.values[1],
 
291
                      cc.paint.values[2]);
 
292
 
 
293
        } else if (spp == 3) {      /* may be RGB, but could be LAB image file with ICC profile... */
 
294
            next.v[0] = psrc[0];
 
295
            next.v[1] = psrc[1];
 
296
            next.v[2] = psrc[2];
 
297
            psrc += 3;
 
298
            if (posture != image_skewed && next.all[0] == run.all[0])
 
299
                goto inc;
 
300
            if (use_cache) {
 
301
                pic_next = CLUE_HASH3(penum, next);
 
302
                if (pic_next->key == next.all[0])
 
303
                    goto f;
 
304
                /* See above re the following check. */
 
305
                if (pic_next == pic) {
 
306
                    clue_temp = *pic;
 
307
                    pic = &clue_temp;
 
308
                }
 
309
                pic_next->key = next.all[0];
 
310
            }
 
311
            /* Check for transparent color. */
 
312
            if ((next.all[0] & mask) == test &&
 
313
                (penum->mask_color.exact ||
 
314
                 mask_color_matches(next.v, penum, 3))
 
315
                ) {
 
316
                color_set_null(pdevc_next);
 
317
                goto mapped;
 
318
            }
 
319
            if (device_color) {
 
320
 
 
321
                        frac frac_color[3];
 
322
                        /*
 
323
                         * We can call the remap concrete_color for the colorspace
 
324
                         * directly since device_color is only true if the colorspace
 
325
                         * is concrete.
 
326
                         */
 
327
                        frac_color[0] = byte2frac(next.v[0]);
 
328
                        frac_color[1] = byte2frac(next.v[1]);
 
329
                        frac_color[2] = byte2frac(next.v[2]);
 
330
                        remap_concrete_color(frac_color, pcs, pdevc_next, pis,
 
331
                                                        dev, gs_color_select_source);
 
332
                        goto mapped;
 
333
 
 
334
            }
 
335
            goto do3;
 
336
        } else if (penum->alpha) {
 
337
            if (spp == 2) {     /* might be Gray + alpha */
 
338
                next.v[2] = next.v[1] = next.v[0] = psrc[0];
 
339
                next.v[3] = psrc[1];
 
340
                psrc += 2;
 
341
                goto map4;
 
342
            } else if (spp == 5) {      /* might be CMYK + alpha */
 
343
                /* Convert CMYK to RGB. */
 
344
                frac rgb[3];
 
345
 
 
346
                color_cmyk_to_rgb(byte2frac(psrc[0]), byte2frac(psrc[1]),
 
347
                                  byte2frac(psrc[2]), byte2frac(psrc[3]),
 
348
                                  pis, rgb);
 
349
                /*
 
350
                 * It seems silly to do all this converting between
 
351
                 * fracs and bytes, but that's what the current
 
352
                 * APIs require.
 
353
                 */
 
354
                next.v[0] = frac2byte(rgb[0]);
 
355
                next.v[1] = frac2byte(rgb[1]);
 
356
                next.v[2] = frac2byte(rgb[2]);
 
357
                next.v[3] = psrc[4];
 
358
                psrc += 5;
 
359
                goto map4;
 
360
            }
 
361
        } else {                /* DeviceN */
 
362
            int i;
 
363
 
 
364
            use_cache = false;  /* should do in initialization */
 
365
            if (posture != image_skewed && !memcmp(psrc, run.v, spp)) {
 
366
                psrc += spp;
 
367
                goto inc;
 
368
            }
 
369
            memcpy(next.v, psrc, spp);
 
370
            psrc += spp;
 
371
            if ((next.all[0] & mask) == test &&
 
372
                (penum->mask_color.exact ||
 
373
                 mask_color_matches(next.v, penum, spp))
 
374
                ) {
 
375
                color_set_null(pdevc_next);
 
376
                goto mapped;
 
377
            }
 
378
            for (i = 0; i < spp; ++i)
 
379
                decode_sample(next.v[i], cc, i);
 
380
#ifdef DEBUG
 
381
            if (gs_debug_c('B')) {
 
382
                dprintf2("[B]cc[0..%d]=%g", spp - 1,
 
383
                         cc.paint.values[0]);
 
384
                for (i = 1; i < spp; ++i)
 
385
                    dprintf1(",%g", cc.paint.values[i]);
 
386
                dputs("\n");
 
387
            }
 
388
#endif
 
389
        }
 
390
        mcode = remap_color(&cc, pcs, pdevc_next, pis, dev,
 
391
                           gs_color_select_source);
 
392
        if (mcode < 0)
 
393
            goto fill;
 
394
mapped: if (pic == pic_next)
 
395
            goto fill;
 
396
f:      if (sizeof(pdevc_next->colors.binary.color[0]) <= sizeof(ulong))
 
397
            if_debug7('B', "[B]0x%x,0x%x,0x%x,0x%x -> 0x%lx,0x%lx,0x%lx\n",
 
398
                  next.v[0], next.v[1], next.v[2], next.v[3],
 
399
                  (ulong)pdevc_next->colors.binary.color[0],
 
400
                  (ulong)pdevc_next->colors.binary.color[1],
 
401
                  (ulong) pdevc_next->type);
 
402
        else
 
403
            if_debug9('B', "[B]0x%x,0x%x,0x%x,0x%x -> 0x%08lx%08lx,0x%08lx%08lx,0x%lx\n",
 
404
                  next.v[0], next.v[1], next.v[2], next.v[3],
 
405
                  (ulong)(pdevc_next->colors.binary.color[0] >> 
 
406
                        8 * (sizeof(pdevc_next->colors.binary.color[0]) - sizeof(ulong))),
 
407
                  (ulong)pdevc_next->colors.binary.color[0],
 
408
                  (ulong)(pdevc_next->colors.binary.color[1] >> 
 
409
                        8 * (sizeof(pdevc_next->colors.binary.color[1]) - sizeof(ulong))),
 
410
                  (ulong)pdevc_next->colors.binary.color[1],
 
411
                  (ulong) pdevc_next->type);
 
412
        /* NB: printf above fails to account for sizeof gx_color_index 4 or 8 bytes */
 
413
 
 
414
        /* Even though the supplied colors don't match, */
 
415
        /* the device colors might. */
 
416
        if (posture != image_skewed && dev_color_eq(*pdevc, *pdevc_next))
 
417
            goto set;
 
418
fill:   /* Fill the region between */
 
419
        /* xrun/irun and xprev */
 
420
        /*
 
421
         * Note;  This section is nearly a copy of a simlar section below
 
422
         * for processing the last image pixel in the loop.  This would have been
 
423
         * made into a subroutine except for complications about the number of
 
424
         * variables that would have been needed to be passed to the routine.
 
425
         */
 
426
        switch (posture) {
 
427
        case image_portrait:
 
428
            {           /* Rectangle */
 
429
                int xi = irun;
 
430
                int wi = (irun = fixed2int_var_rounded(xprev)) - xi;
 
431
 
 
432
                if (wi < 0)
 
433
                    xi += wi, wi = -wi;
 
434
                if (wi > 0)
 
435
                    code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi,
 
436
                                                        pdevc, dev, lop);
 
437
            }
 
438
            break;
 
439
        case image_landscape:
 
440
            {           /* 90 degree rotated rectangle */
 
441
                int yi = irun;
 
442
                int hi = (irun = fixed2int_var_rounded(yprev)) - yi;
 
443
 
 
444
                if (hi < 0)
 
445
                    yi += hi, hi = -hi;
 
446
                if (hi > 0)
 
447
                    code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi,
 
448
                                                        pdevc, dev, lop);
 
449
            }
 
450
            break;
 
451
        default:
 
452
            {           /* Parallelogram */
 
453
                code = (*dev_proc(dev, fill_parallelogram))
 
454
                    (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy,
 
455
                     pdevc, lop);
 
456
                xrun = xprev;
 
457
                yrun = yprev;
 
458
            }
 
459
        }
 
460
        if (code < 0)
 
461
            goto err;
 
462
        rsrc = psrc;
 
463
        if ((code = mcode) < 0) {
 
464
            /* Invalidate any partially built cache entry. */
 
465
            if (use_cache)
 
466
                pic_next->key = ~next.all[0];
 
467
            goto err;
 
468
        }
 
469
        if (use_cache)
 
470
            pic = pic_next;
 
471
        else {
 
472
            gx_image_clue *ptemp = pic;
 
473
 
 
474
            pic = pic_next;
 
475
            pic_next = ptemp;
 
476
        }
 
477
set:    run = next;
 
478
inc:    xprev = dda_current(pnext.x);
 
479
        yprev = dda_current(pnext.y);   /* harmless if no skew */
 
480
    }
 
481
    /* Fill the last run. */
 
482
    /*
 
483
     * Note;  This section is nearly a copy of a simlar section above
 
484
     * for processing an image pixel in the loop.  This would have been
 
485
     * made into a subroutine except for complications about the number
 
486
     * variables that would have been needed to be passed to the routine.
 
487
     */
 
488
    switch (posture) {
 
489
        case image_portrait:
 
490
            {           /* Rectangle */
 
491
                int xi = irun;
 
492
                int wi = (irun = fixed2int_var_rounded(xprev)) - xi;
 
493
 
 
494
                if (wi < 0)
 
495
                    xi += wi, wi = -wi;
 
496
                if (wi > 0)
 
497
                    code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi,
 
498
                                                        pdevc, dev, lop);
 
499
            }
 
500
            break;
 
501
        case image_landscape:
 
502
            {           /* 90 degree rotated rectangle */
 
503
                int yi = irun;
 
504
                int hi = (irun = fixed2int_var_rounded(yprev)) - yi;
 
505
 
 
506
                if (hi < 0)
 
507
                    yi += hi, hi = -hi;
 
508
                if (hi > 0)
 
509
                    code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi,
 
510
                                                        pdevc, dev, lop);
 
511
            }
 
512
            break;
 
513
        default:
 
514
            {           /* Parallelogram */
 
515
                code = (*dev_proc(dev, fill_parallelogram))
 
516
                    (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy,
 
517
                     pdevc, lop);
 
518
            }
 
519
    }
 
520
    return (code < 0 ? code : 1);
 
521
    /* Save position if error, in case we resume. */
 
522
err:
 
523
    penum_orig->used.x = (rsrc - spp - psrc_initial) / spp;
 
524
    penum_orig->used.y = 0;
 
525
    return code;
 
526
}