Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gxipixel.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Common code for ImageType 1 and 4 initialization */
18
#include "gx.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gpcheck.h"
22
#include "gscdefs.h"            /* for image class table */
23
#include "gserrors.h"
24
#include "gsstruct.h"
25
#include "gsutil.h"
26
#include "gxfixed.h"
27
#include "gxfrac.h"
28
#include "gxarith.h"
29
#include "gxmatrix.h"
30
#include "gsccolor.h"
31
#include "gspaint.h"
32
#include "gzstate.h"
33
#include "gxdevice.h"
34
#include "gzpath.h"
35
#include "gzcpath.h"
36
#include "gxdevmem.h"
37
#include "gximage.h"
38
#include "gxiparam.h"
39
#include "gdevmrop.h"
40
#include "gscspace.h"
41
#include "gscindex.h"
42
#include "gsicc_cache.h"
43
#include "gsicc_cms.h"
44
#include "gsicc_manage.h"
45
#include "gxdevsop.h"
46
47
/* Structure descriptors */
48
private_st_gx_image_enum();
49
50
/* Image class procedures */
51
extern_gx_image_class_table();
52
53
/* Enumerator procedures */
54
static const gx_image_enum_procs_t image1_enum_procs = {
55
    gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
56
};
57
58
/* GC procedures */
59
gs_private_st_ptrs2(st_color_cache, gx_image_color_cache_t, "gx_image_color_cache",
60
                    color_cache_enum_ptrs, color_cache_reloc_ptrs,
61
                    is_transparent, device_contone);
62
static
63
2.50k
ENUM_PTRS_WITH(image_enum_enum_ptrs, gx_image_enum *eptr)
64
924
{
65
924
    int bps;
66
924
    gs_ptr_type_t ret;
67
68
    /* Enumerate the used members of clues.dev_color. */
69
924
    index -= gx_image_enum_num_ptrs;
70
924
    bps = eptr->unpack_bps;
71
924
    if (eptr->spp != 1)
72
0
        bps = 8;
73
924
    else if (bps > 8 || eptr->unpack == sample_unpack_copy)
74
0
        bps = 1;
75
924
    if (index >= (1 << bps) * st_device_color_max_ptrs)         /* done */
76
132
        return 0;
77
    /* the clues may have been cleared by gx_image_free_enum, but not freed in that */
78
    /* function due to being at a different save level. Only trace if dev_color.type != 0. */
79
792
    if (eptr->spp == 1) {
80
792
        if (eptr->clues != NULL) {
81
792
            if (eptr->clues[(index/st_device_color_max_ptrs) *
82
792
                (255 / ((1 << bps) - 1))].dev_color.type != 0) {
83
792
                ret = ENUM_USING(st_device_color,
84
792
                                 &eptr->clues[(index / st_device_color_max_ptrs) *
85
792
                                 (255 / ((1 << bps) - 1))].dev_color,
86
792
                                 sizeof(eptr->clues[0].dev_color),
87
792
                                 index % st_device_color_max_ptrs);
88
792
            } else {
89
0
                ret = 0;
90
0
            }
91
792
        } else {
92
0
            ret = 0;
93
0
        }
94
792
    } else {
95
0
        ret = 0;
96
0
    }
97
792
    if (ret == 0)               /* don't stop early */
98
792
        ENUM_RETURN(0);
99
0
    return ret;
100
792
}
101
102
1.58k
#define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
103
2.50k
gx_image_enum_do_ptrs(e1)
104
2.50k
#undef e1
105
2.50k
ENUM_PTRS_END
106
107
132
static RELOC_PTRS_WITH(image_enum_reloc_ptrs, gx_image_enum *eptr)
108
132
{
109
132
    int i;
110
111
1.58k
#define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
112
1.58k
    gx_image_enum_do_ptrs(r1)
113
132
#undef r1
114
132
    {
115
132
        int bps = eptr->unpack_bps;
116
117
132
        if (eptr->spp != 1)
118
0
            bps = 8;
119
132
        else if (bps > 8 || eptr->unpack == sample_unpack_copy)
120
0
            bps = 1;
121
132
        if (eptr->spp == 1) {
122
396
        for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
123
264
            RELOC_USING(st_device_color,
124
132
                        &eptr->clues[i].dev_color, sizeof(gx_device_color));
125
132
    }
126
132
}
127
132
}
128
132
RELOC_PTRS_END
129
130
/* Forward declarations */
131
static int color_draws_b_w(gx_device * dev,
132
                            const gx_drawing_color * pdcolor);
133
static int image_init_colors(gx_image_enum * penum, int bps, int spp,
134
                               gs_image_format_t format,
135
                               const float *decode,
136
                               const gs_gstate * pgs, gx_device * dev,
137
                               const gs_color_space * pcs, bool * pdcb);
138
139
/* Procedures for unpacking the input data into bytes or fracs. */
140
/*extern SAMPLE_UNPACK_PROC(sample_unpack_copy); *//* declared above */
141
142
/*
143
 * Do common initialization for processing an ImageType 1 or 4 image.
144
 * Allocate the enumerator and fill in the following members:
145
 *      rect
146
 */
147
int
148
gx_image_enum_alloc(const gs_image_common_t * pic,
149
                    const gs_int_rect * prect, gs_memory_t * mem,
150
                    gx_image_enum **ppenum)
151
2.28M
{
152
2.28M
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
153
2.28M
    int width = pim->Width, height = pim->Height;
154
2.28M
    int bpc = pim->BitsPerComponent;
155
2.28M
    gx_image_enum *penum;
156
157
2.28M
    if (width < 0 || height < 0)
158
0
        return_error(gs_error_rangecheck);
159
2.28M
    switch (pim->format) {
160
2.23M
    case gs_image_format_chunky:
161
2.28M
    case gs_image_format_component_planar:
162
2.28M
        switch (bpc) {
163
2.28M
        case 1: case 2: case 4: case 8: case 12: case 16: break;
164
2
        default: return_error(gs_error_rangecheck);
165
2.28M
        }
166
2.28M
        break;
167
2.28M
    case gs_image_format_bit_planar:
168
0
        if (bpc < 1 || bpc > 8)
169
0
            return_error(gs_error_rangecheck);
170
2.28M
    }
171
2.28M
    if (prect) {
172
732k
        if (prect->p.x < 0 || prect->p.y < 0 ||
173
732k
            prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
174
732k
            prect->q.x > width || prect->q.y > height
175
732k
            )
176
0
            return_error(gs_error_rangecheck);
177
732k
    }
178
2.28M
    *ppenum = NULL;   /* in case alloc fails and caller doesn't check code */
179
2.28M
    penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
180
2.28M
                            "gx_default_begin_image");
181
2.28M
    if (penum == 0)
182
0
        return_error(gs_error_VMerror);
183
2.28M
    memset(penum, 0, sizeof(gx_image_enum));  /* in case of failure, no dangling pointers */
184
2.28M
    if (prect) {
185
732k
        penum->rect.x = prect->p.x;
186
732k
        penum->rect.y = prect->p.y;
187
732k
        penum->rect.w = prect->q.x - prect->p.x;
188
732k
        penum->rect.h = prect->q.y - prect->p.y;
189
1.54M
    } else {
190
1.54M
        penum->rect.x = 0, penum->rect.y = 0;
191
1.54M
        penum->rect.w = width, penum->rect.h = height;
192
1.54M
    }
193
2.28M
    penum->rrect.x = penum->rect.x;
194
2.28M
    penum->rrect.y = penum->rect.y;
195
2.28M
    penum->rrect.w = penum->rect.w;
196
2.28M
    penum->rrect.h = penum->rect.h;
197
2.28M
    penum->drect.x = penum->rect.x;
198
2.28M
    penum->drect.y = penum->rect.y;
199
2.28M
    penum->drect.w = penum->rect.w;
200
2.28M
    penum->drect.h = penum->rect.h;
201
#ifdef DEBUG
202
    if (gs_debug_c('b')) {
203
        dmlprintf2(mem, "[b]Image: w=%d h=%d", width, height);
204
        if (prect)
205
            dmprintf4(mem, " ((%d,%d),(%d,%d))",
206
                     prect->p.x, prect->p.y, prect->q.x, prect->q.y);
207
    }
208
#endif
209
2.28M
    *ppenum = penum;
210
2.28M
    return 0;
211
2.28M
}
212
213
/* Convert and restrict to a valid range. */
214
6.16M
static inline fixed float2fixed_rounded_boxed(double src) {
215
6.16M
    float v = floor(src*fixed_scale + 0.5);
216
217
6.16M
    if (v <= min_fixed)
218
39.3k
        return min_fixed;
219
6.12M
    else if (v >= max_fixed)
220
71.1k
        return max_fixed;
221
6.05M
    else
222
6.05M
        return  (fixed)v;
223
6.16M
}
224
225
/* Compute the image matrix combining the ImageMatrix with either the pmat or the pgs ctm */
226
int
227
gx_image_compute_mat(const gs_gstate *pgs, const gs_matrix *pmat, const gs_matrix *ImageMatrix,
228
                     gs_matrix_double *rmat)
229
3.22M
{
230
3.22M
    int code = 0;
231
232
3.22M
    if (pmat == 0)
233
3.15M
        pmat = &ctm_only(pgs);
234
3.22M
    if (ImageMatrix->xx == pmat->xx && ImageMatrix->xy == pmat->xy &&
235
3.22M
        ImageMatrix->yx == pmat->yx && ImageMatrix->yy == pmat->yy) {
236
        /* Process common special case separately to accept singular matrix. */
237
1.43M
        rmat->xx = rmat->yy = 1.;
238
1.43M
        rmat->xy = rmat->yx = 0.;
239
1.43M
        rmat->tx = pmat->tx - ImageMatrix->tx;
240
1.43M
        rmat->ty = pmat->ty - ImageMatrix->ty;
241
1.79M
    } else {
242
1.79M
        if ((code = gs_matrix_invert_to_double(ImageMatrix, rmat)) < 0 ||
243
1.79M
            (code = gs_matrix_multiply_double(rmat, pmat, rmat)) < 0
244
1.79M
            ) {
245
125
            return code;
246
125
        }
247
1.79M
    }
248
3.22M
    return code;
249
3.22M
}
250
251
/*
252
 * Finish initialization for processing an ImageType 1 or 4 image.
253
 * Assumes the following members of *penum are set in addition to those
254
 * set by gx_image_enum_alloc:
255
 *      alpha, use_mask_color, mask_color (if use_mask_color is true),
256
 *      masked, adjust
257
 */
258
int
259
gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs,
260
                    const gs_matrix *pmat, const gs_image_common_t * pic,
261
                const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
262
                gs_memory_t * mem, gx_image_enum *penum)
263
2.28M
{
264
2.28M
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
265
2.28M
    gs_image_format_t format = pim->format;
266
2.28M
    const int width = pim->Width;
267
2.28M
    const int height = pim->Height;
268
2.28M
    const int bps = pim->BitsPerComponent;
269
2.28M
    bool masked = penum->masked;
270
2.28M
    const float *decode = pim->Decode;
271
2.28M
    gs_matrix_double mat;
272
2.28M
    int index_bps;
273
2.28M
    gs_color_space *pcs = pim->ColorSpace;
274
2.28M
    gs_logical_operation_t lop = (pgs ? pgs->log_op : lop_default);
275
2.28M
    int code;
276
2.28M
    int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
277
2.28M
    int spp, nplanes, spread;
278
2.28M
    uint bsize;
279
2.28M
    byte *buffer = NULL;
280
2.28M
    fixed mtx, mty;
281
2.28M
    gs_fixed_point row_extent, col_extent, x_extent, y_extent;
282
2.28M
    bool device_color = true;
283
2.28M
    gs_fixed_rect obox, cbox;
284
2.28M
    bool gridfitimages = 0;
285
2.28M
    bool in_pattern_accumulator;
286
2.28M
    bool in_smask;
287
2.28M
    int orthogonal;
288
2.28M
    int force_interpolation = 0;
289
290
2.28M
    penum->pcs = NULL;
291
2.28M
    penum->clues = NULL;
292
2.28M
    penum->icc_setup.has_transfer = false;
293
2.28M
    penum->icc_setup.is_lab = false;
294
2.28M
    penum->icc_setup.must_halftone = false;
295
2.28M
    penum->icc_setup.need_decode = false;
296
2.28M
    penum->Width = width;
297
2.28M
    penum->Height = height;
298
299
2.28M
    if ((code = gx_image_compute_mat(pgs, pmat, &(pim->ImageMatrix), &mat)) < 0) {
300
102
        return code;
301
102
    }
302
2.28M
    lop = lop_sanitize(lop);
303
    /* Grid fit: A common construction in postscript/PDF files is for images
304
     * to be constructed as a series of 'stacked' 1 pixel high images.
305
     * Furthermore, many of these are implemented as an imagemask plotted on
306
     * top of thin rectangles. The different fill rules for images and line
307
     * art produces problems; line art fills a pixel if any part of it is
308
     * touched - images only fill a pixel if the centre of the pixel is
309
     * covered. Bug 692666 is such a problem.
310
     *
311
     * As a workaround for this problem, the code below was introduced. The
312
     * concept is that orthogonal images can be 'grid fitted' (or 'stretch')
313
     * to entirely cover pixels that they touch. Initially I had this working
314
     * for all images regardless of type, but as testing has proceeded, this
315
     * showed more and more regressions, so I've cut the cases back in which
316
     * this code is used until it now only triggers on imagemasks that are
317
     * either 1 pixel high, or wide, and then not if we are rendering a
318
     * glyph (such as from a type3 font).
319
     */
320
321
    /* Ask the device if we are in a pattern accumulator */
322
2.28M
    in_pattern_accumulator = (dev_proc(dev, dev_spec_op)(dev, gxdso_in_pattern_accumulator, NULL, 0));
323
2.28M
    if (in_pattern_accumulator < 0)
324
1.61M
        in_pattern_accumulator = 0;
325
326
    /* Figure out if we are orthogonal */
327
2.28M
    if (mat.xy == 0 && mat.yx == 0)
328
2.07M
        orthogonal = 1;
329
208k
    else if (mat.xx == 0 && mat.yy == 0)
330
92.8k
        orthogonal = 2;
331
115k
    else
332
115k
        orthogonal = 0;
333
334
    /* If we are in a pattern accumulator, we choose to always grid fit
335
     * orthogonal images. We do this by asking the device whether we
336
     * should grid fit. This allows us to avoid nasty blank lines around
337
     * the edges of cells. Similarly, for smasks.
338
     */
339
2.28M
    in_smask = (pim->override_in_smask ||
340
2.28M
                (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0);
341
2.28M
    gridfitimages = (in_smask || in_pattern_accumulator) && orthogonal;
342
343
2.28M
    if (pgs != NULL && pgs->show_gstate != NULL) {
344
        /* If we're a graphics state, and we're in a text object, then we
345
         * must be in a type3 font. Don't fiddle with it. */
346
2.00M
    } else if (!gridfitimages &&
347
2.00M
               (!penum->masked || penum->image_parent_type != 0)) {
348
        /* Other than for images we are specifically looking to grid fit (such as
349
         * ones in a pattern device), we only grid fit imagemasks */
350
1.32M
    } else if (gridfitimages && (penum->masked && penum->image_parent_type == 0)) {
351
        /* We don't gridfit imagemasks in a pattern accumulator */
352
681k
    } else if (pgs != NULL && pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0) {
353
        /* If fill adjust is disabled, so is grid fitting */
354
681k
    } else if (orthogonal == 1) {
355
569k
        if (width == 1 || gridfitimages) {
356
532k
            if (mat.xx > 0) {
357
531k
                fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx)));
358
531k
                double x1 = mat.tx + mat.xx * width;
359
531k
                fixed ix1 = int2fixed(fixed2int_ceiling(float2fixed(x1)));
360
531k
                mat.tx = (double)fixed2float(ix0);
361
531k
                mat.xx = (double)(fixed2float(ix1 - ix0)/width);
362
531k
            } else if (mat.xx < 0) {
363
251
                fixed ix0 = int2fixed(fixed2int_ceiling(float2fixed(mat.tx)));
364
251
                double x1 = mat.tx + mat.xx * width;
365
251
                fixed ix1 = int2fixed(fixed2int(float2fixed(x1)));
366
251
                mat.tx = (double)fixed2float(ix0);
367
251
                mat.xx = (double)(fixed2float(ix1 - ix0)/width);
368
251
            }
369
532k
        }
370
569k
        if (height == 1 || gridfitimages) {
371
532k
            if (mat.yy > 0) {
372
374k
                fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty)));
373
374k
                double y1 = mat.ty + mat.yy * height;
374
374k
                fixed iy1 = int2fixed(fixed2int_ceiling(float2fixed(y1)));
375
374k
                mat.ty = (double)fixed2float(iy0);
376
374k
                mat.yy = (double)(fixed2float(iy1 - iy0)/height);
377
374k
            } else if (mat.yy < 0) {
378
157k
                fixed iy0 = int2fixed(fixed2int_ceiling(float2fixed(mat.ty)));
379
157k
                double y1 = mat.ty + mat.yy * height;
380
157k
                fixed iy1 = int2fixed(fixed2int(float2fixed(y1)));
381
157k
                mat.ty = (double)fixed2float(iy0);
382
157k
                mat.yy = ((double)fixed2float(iy1 - iy0)/height);
383
157k
            }
384
532k
        }
385
569k
    } else if (orthogonal == 2) {
386
91.0k
        if (height == 1 || gridfitimages) {
387
0
            if (mat.yx > 0) {
388
0
                fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx)));
389
0
                double x1 = mat.tx + mat.yx * height;
390
0
                fixed ix1 = int2fixed(fixed2int_ceiling(float2fixed(x1)));
391
0
                mat.tx = (double)fixed2float(ix0);
392
0
                mat.yx = (double)(fixed2float(ix1 - ix0)/height);
393
0
            } else if (mat.yx < 0) {
394
0
                fixed ix0 = int2fixed(fixed2int_ceiling(float2fixed(mat.tx)));
395
0
                double x1 = mat.tx + mat.yx * height;
396
0
                fixed ix1 = int2fixed(fixed2int(float2fixed(x1)));
397
0
                mat.tx = (double)fixed2float(ix0);
398
0
                mat.yx = (double)(fixed2float(ix1 - ix0)/height);
399
0
            }
400
0
        }
401
91.0k
        if (width == 1 || gridfitimages) {
402
0
            if (mat.xy > 0) {
403
0
                fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty)));
404
0
                double y1 = mat.ty + mat.xy * width;
405
0
                fixed iy1 = int2fixed(fixed2int_ceiling(float2fixed(y1)));
406
0
                mat.ty = (double)fixed2float(iy0);
407
0
                mat.xy = (double)(fixed2float(iy1 - iy0)/width);
408
0
            } else if (mat.xy < 0) {
409
0
                fixed iy0 = int2fixed(fixed2int_ceiling(float2fixed(mat.ty)));
410
0
                double y1 = mat.ty + mat.xy * width;
411
0
                fixed iy1 = int2fixed(fixed2int(float2fixed(y1)));
412
0
                mat.ty = (double)fixed2float(iy0);
413
0
                mat.xy = ((double)fixed2float(iy1 - iy0)/width);
414
0
            }
415
0
        }
416
91.0k
    }
417
418
    /* When rendering to a pattern accumulator, if we are downscaling
419
     * then enable interpolation, as otherwise dropouts can cause
420
     * serious problems. */
421
2.28M
    if (in_pattern_accumulator) {
422
479
        double ome = ((double)(fixed_1 - fixed_epsilon)) / (double)fixed_1; /* One Minus Epsilon */
423
424
479
        if (orthogonal == 1) {
425
469
            if ((mat.xx > -ome && mat.xx < ome) || (mat.yy > -ome && mat.yy < ome)) {
426
317
                force_interpolation = true;
427
317
            }
428
469
        } else if (orthogonal == 2) {
429
0
            if ((mat.xy > -ome && mat.xy < ome) || (mat.yx > -ome && mat.yx < ome)) {
430
0
                force_interpolation = true;
431
0
            }
432
0
        }
433
479
    }
434
435
    /* Can we restrict the amount of image we need? */
436
2.28M
    while (!pim->imagematrices_are_untrustworthy) /* So we can break out of it */
437
2.28M
    {
438
2.28M
        gs_rect rect, rect_src;
439
2.28M
        gs_matrix mi;
440
2.28M
        const gs_matrix *m = pgs != NULL ? &ctm_only(pgs) : NULL;
441
2.28M
        gs_int_rect irect;
442
2.28M
        if (m == NULL || (code = gs_matrix_invert(m, &mi)) < 0 ||
443
2.28M
            (code = gs_matrix_multiply(&mi, &pic->ImageMatrix, &mi)) < 0) {
444
            /* Give up trying to shrink the render box, but continue processing */
445
4.17k
            break;
446
4.17k
        }
447
2.27M
        if (pcpath)
448
730k
        {
449
730k
            gs_fixed_rect obox;
450
730k
            gx_cpath_outer_box(pcpath, &obox);
451
730k
            rect.p.x = fixed2float(obox.p.x);
452
730k
            rect.p.y = fixed2float(obox.p.y);
453
730k
            rect.q.x = fixed2float(obox.q.x);
454
730k
            rect.q.y = fixed2float(obox.q.y);
455
730k
        }
456
1.54M
        else
457
1.54M
        {
458
1.54M
            rect.p.x = 0;
459
1.54M
            rect.p.y = 0;
460
1.54M
            rect.q.x = dev->width;
461
1.54M
            rect.q.y = dev->height;
462
1.54M
        }
463
        /* rect is in destination space. Calculate rect_src, in source space. */
464
2.27M
        code = gs_bbox_transform(&rect, &mi, &rect_src);
465
2.27M
        if (code < 0) {
466
            /* Give up trying to shrink the render/decode boxes, but continue processing */
467
0
            break;
468
0
        }
469
        /* Need to expand the region to allow for the fact that the mitchell
470
         * scaler reads multiple pixels in. */
471
        /* If mi.{xx,yy} > 1 then we are downscaling. During downscaling,
472
         * the support increases to ensure that we don't lose pixels contributions
473
         * entirely. */
474
2.27M
        if (pim->Interpolate)
475
37
        {
476
37
            float support = any_abs(mi.xx);
477
37
            int isupport;
478
37
            if (any_abs(mi.yy) > support)
479
0
                support = any_abs(mi.yy);
480
37
            if (any_abs(mi.xy) > support)
481
1
                support = any_abs(mi.xy);
482
37
            if (any_abs(mi.yx) > support)
483
0
                support = any_abs(mi.yx);
484
            /* If upscaling (support < 1) then we need 2 extra lines on each side of the source region
485
             * (2 being the maximum support for mitchell scaling).
486
             * If downscaling, then the number of lines is increased to avoid individual
487
             * contributions dropping out. */
488
37
            isupport = 2; /* Mitchell support. */
489
37
            if (support > 1)
490
1
                isupport = (int)ceil(isupport * support);
491
37
            rect_src.p.x -= isupport;
492
37
            rect_src.p.y -= isupport;
493
37
            rect_src.q.x += isupport;
494
37
            rect_src.q.y += isupport+1; /* +1 is a fudge! */
495
37
        }
496
2.27M
        irect.p.x = (int)floor(rect_src.p.x);
497
2.27M
        irect.p.y = (int)floor(rect_src.p.y);
498
2.27M
        irect.q.x = (int)ceil(rect_src.q.x);
499
2.27M
        irect.q.y = (int)ceil(rect_src.q.y);
500
        /* We therefore only need to render within irect. Restrict rrect to this. */
501
2.27M
        if (penum->rrect.x < irect.p.x) {
502
90.0k
            penum->rrect.w -= irect.p.x - penum->rrect.x;
503
90.0k
            if (penum->rrect.w < 0)
504
80.0k
               penum->rrect.w = 0;
505
90.0k
            penum->rrect.x = irect.p.x;
506
90.0k
        }
507
2.27M
        if (penum->rrect.x + penum->rrect.w > irect.q.x) {
508
206k
            penum->rrect.w = irect.q.x - penum->rrect.x;
509
206k
            if (penum->rrect.w < 0)
510
178k
                penum->rrect.w = 0;
511
206k
        }
512
2.27M
        if (penum->rrect.y < irect.p.y) {
513
256k
            penum->rrect.h -= irect.p.y - penum->rrect.y;
514
256k
            if (penum->rrect.h < 0)
515
89.9k
                penum->rrect.h = 0;
516
256k
            penum->rrect.y = irect.p.y;
517
256k
        }
518
2.27M
        if (penum->rrect.y + penum->rrect.h > irect.q.y) {
519
209k
            penum->rrect.h = irect.q.y - penum->rrect.y;
520
209k
            if (penum->rrect.h < 0)
521
37.9k
                penum->rrect.h = 0;
522
209k
        }
523
2.27M
        if (penum->drect.x < irect.p.x) {
524
90.0k
            penum->drect.w -= irect.p.x - penum->drect.x;
525
90.0k
            if (penum->drect.w < 0)
526
80.0k
               penum->drect.w = 0;
527
90.0k
            penum->drect.x = irect.p.x;
528
90.0k
        }
529
2.27M
        if (penum->drect.x + penum->drect.w > irect.q.x) {
530
206k
            penum->drect.w = irect.q.x - penum->drect.x;
531
206k
            if (penum->drect.w < 0)
532
178k
                penum->drect.w = 0;
533
206k
        }
534
2.27M
        if (penum->drect.y < irect.p.y) {
535
256k
            penum->drect.h -= irect.p.y - penum->drect.y;
536
256k
            if (penum->drect.h < 0)
537
89.9k
                penum->drect.h = 0;
538
256k
            penum->drect.y = irect.p.y;
539
256k
        }
540
2.27M
        if (penum->drect.y + penum->drect.h > irect.q.y) {
541
209k
            penum->drect.h = irect.q.y - penum->drect.y;
542
209k
            if (penum->drect.h < 0)
543
37.9k
                penum->drect.h = 0;
544
209k
        }
545
2.27M
        break; /* Out of the while */
546
2.27M
    }
547
    /* Check for the intersection being null */
548
2.28M
    if (penum->drect.x + penum->drect.w <= penum->rect.x  ||
549
2.28M
        penum->rect.x  + penum->rect.w  <= penum->drect.x ||
550
2.28M
        penum->drect.y + penum->drect.h <= penum->rect.y  ||
551
2.28M
        penum->rect.y  + penum->rect.h  <= penum->drect.y)
552
283k
    {
553
          /* Something may have gone wrong with the floating point above.
554
           * set the region to something sane. */
555
283k
        penum->drect.x = penum->rect.x;
556
283k
        penum->drect.y = penum->rect.y;
557
283k
        penum->drect.w = 0;
558
283k
        penum->drect.h = 0;
559
283k
    }
560
2.28M
    if (penum->rrect.x + penum->rrect.w <= penum->drect.x  ||
561
2.28M
        penum->drect.x + penum->drect.w  <= penum->rrect.x ||
562
2.28M
        penum->rrect.y + penum->rrect.h <= penum->drect.y  ||
563
2.28M
        penum->drect.y + penum->drect.h  <= penum->rrect.y)
564
283k
    {
565
          /* Something may have gone wrong with the floating point above.
566
           * set the region to something sane. */
567
283k
        penum->rrect.x = penum->drect.x;
568
283k
        penum->rrect.y = penum->drect.y;
569
283k
        penum->rrect.w = 0;
570
283k
        penum->rrect.h = 0;
571
283k
    }
572
573
    /*penum->matrix = mat;*/
574
2.28M
    penum->matrix.xx = mat.xx;
575
2.28M
    penum->matrix.xy = mat.xy;
576
2.28M
    penum->matrix.yx = mat.yx;
577
2.28M
    penum->matrix.yy = mat.yy;
578
2.28M
    penum->matrix.tx = mat.tx;
579
2.28M
    penum->matrix.ty = mat.ty;
580
2.28M
    if_debug6m('b', mem, " [%g %g %g %g %g %g]\n",
581
2.28M
              mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
582
    /* following works for 1, 2, 4, 8, 12, 16 */
583
2.28M
    index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
584
    /*
585
     * Compute extents with distance transformation.
586
     */
587
2.28M
    if (mat.tx > 0)
588
1.83M
        mtx = float2fixed(mat.tx);
589
446k
    else { /* Use positive values to ensure round down. */
590
446k
        int f = (int)-mat.tx + 1;
591
592
446k
        mtx = float2fixed(mat.tx + f) - int2fixed(f);
593
446k
    }
594
2.28M
    if (mat.ty > 0)
595
656k
        mty = float2fixed(mat.ty);
596
1.62M
    else {  /* Use positive values to ensure round down. */
597
1.62M
        int f = (int)-mat.ty + 1;
598
599
1.62M
        mty = float2fixed(mat.ty + f) - int2fixed(f);
600
1.62M
    }
601
602
2.28M
    row_extent.x = float2fixed_rounded_boxed(width * mat.xx);
603
2.28M
    row_extent.y =
604
2.28M
        (is_fzero(mat.xy) ? fixed_0 :
605
2.28M
         float2fixed_rounded_boxed(width * mat.xy));
606
2.28M
    col_extent.x =
607
2.28M
        (is_fzero(mat.yx) ? fixed_0 :
608
2.28M
         float2fixed_rounded_boxed(height * mat.yx));
609
2.28M
    col_extent.y = float2fixed_rounded_boxed(height * mat.yy);
610
2.28M
    gx_image_enum_common_init((gx_image_enum_common_t *)penum,
611
2.28M
                              (const gs_data_image_t *)pim,
612
2.28M
                              &image1_enum_procs, dev,
613
2.28M
                              (masked ? 1 : (penum->alpha ? cs_num_components(pcs)+1 : cs_num_components(pcs))),
614
2.28M
                              format);
615
2.28M
    if (penum->rect.w == width && penum->rect.h == height) {
616
1.64M
        x_extent = row_extent;
617
1.64M
        y_extent = col_extent;
618
1.64M
    } else {
619
636k
        int rw = penum->rect.w, rh = penum->rect.h;
620
621
636k
        x_extent.x = float2fixed_rounded_boxed(rw * mat.xx);
622
636k
        x_extent.y =
623
636k
            (is_fzero(mat.xy) ? fixed_0 :
624
636k
             float2fixed_rounded_boxed(rw * mat.xy));
625
636k
        y_extent.x =
626
636k
            (is_fzero(mat.yx) ? fixed_0 :
627
636k
             float2fixed_rounded_boxed(rh * mat.yx));
628
636k
        y_extent.y = float2fixed_rounded_boxed(rh * mat.yy);
629
636k
    }
630
    /* Set icolor0 and icolor1 to point to image clues locations if we have
631
       1spp or an imagemask, otherwise image clues is not used and
632
       we have these values point to other member variables */
633
2.28M
    if (masked || cs_num_components(pcs) == 1) {
634
        /* Go ahead and allocate now if not already done.  For a mask
635
           we really should only do 2 values. For now, the goal is to
636
           eliminate the 256 bytes for the >8bpp image enumerator */
637
992k
        penum->clues = (gx_image_clue*) gs_alloc_bytes(mem, sizeof(gx_image_clue)*256,
638
992k
                             "gx_image_enum_begin");
639
992k
        if (penum->clues == NULL) {
640
0
            code = gs_error_VMerror;
641
0
            goto fail;
642
0
        }
643
992k
        penum->icolor0 = &(penum->clues[0].dev_color);
644
992k
        penum->icolor1 = &(penum->clues[255].dev_color);
645
1.28M
    } else {
646
1.28M
        penum->icolor0 = &(penum->icolor0_val);
647
1.28M
        penum->icolor1 = &(penum->icolor1_val);
648
1.28M
    }
649
2.28M
    penum->icolor0->tag = penum->icolor1->tag = device_current_tag(dev);
650
651
2.28M
    if (masked) {       /* This is imagemask. */
652
429k
        if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
653
54
            code = gs_error_rangecheck;
654
54
            goto fail;
655
54
        }
656
        /* Initialize color entries 0 and 255. */
657
429k
        set_nonclient_dev_color(penum->icolor0, gx_no_color_index);
658
429k
        set_nonclient_dev_color(penum->icolor1, gx_no_color_index);
659
429k
        *(penum->icolor1) = *pdcolor;
660
429k
        memcpy(&penum->map[0].table.lookup4x1to32[0],
661
429k
               (decode[0] < decode[1] ? lookup4x1to32_inverted :
662
429k
                lookup4x1to32_identity),
663
429k
               16 * 4);
664
429k
        penum->map[0].decoding = sd_none;
665
429k
        spp = 1;
666
429k
        lop = rop3_know_S_0(lop);
667
1.85M
    } else {                    /* This is image, not imagemask. */
668
1.85M
        const gs_color_space_type *pcst = pcs->type;
669
1.85M
        int b_w_color;
670
671
1.85M
        spp = cs_num_components(pcs);
672
1.85M
        if (spp < 0) {          /* Pattern not allowed */
673
0
            code = gs_error_rangecheck;
674
0
            goto fail;
675
0
        }
676
1.85M
        if (penum->alpha)
677
0
            ++spp;
678
        /* Use a less expensive format if possible. */
679
1.85M
        switch (format) {
680
0
        case gs_image_format_bit_planar:
681
0
            if (bps > 1)
682
0
                break;
683
0
            format = gs_image_format_component_planar;
684
46.5k
        case gs_image_format_component_planar:
685
46.5k
            if (spp == 1)
686
0
                format = gs_image_format_chunky;
687
1.85M
        default:                /* chunky */
688
1.85M
            break;
689
1.85M
        }
690
691
1.85M
        if (pcs->cmm_icc_profile_data != NULL) {
692
1.82M
            device_color = false;
693
1.82M
        } else {
694
23.8k
            device_color = (*pcst->concrete_space) (pcs, pgs) == pcs;
695
23.8k
        }
696
697
1.85M
        code = image_init_colors(penum, bps, spp, format, decode, pgs, dev,
698
1.85M
                          pcs, &device_color);
699
1.85M
        if (code < 0) {
700
5
            gs_free_object(mem, penum->clues, "gx_image_enum_begin");
701
5
            gs_free_object(mem, penum, "gx_default_begin_image");
702
5
            return gs_throw(code, "Image colors initialization failed");
703
5
        }
704
        /* If we have a CIE based color space and the icc equivalent profile
705
           is not yet set, go ahead and handle that now.  It may already
706
           be done due to the above init_colors which may go through remap. */
707
1.85M
        if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent == NULL) {
708
0
            code = gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(penum->icc_setup.is_lab),
709
0
                                                pgs->memory);
710
0
            if (code < 0)
711
0
                goto fail;
712
0
            if (penum->icc_setup.is_lab) {
713
                /* Free what ever profile was created and use the icc manager's
714
                   cielab profile */
715
0
                gs_color_space *curr_pcs = (gs_color_space *)pcs;
716
0
                rc_decrement(curr_pcs->icc_equivalent,"gx_image_enum_begin");
717
0
                gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, -1,"gx_image_enum_begin");
718
0
                curr_pcs->cmm_icc_profile_data = pgs->icc_manager->lab_profile;
719
0
                gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, 1,"gx_image_enum_begin");
720
0
            }
721
0
        }
722
        /* Try to transform non-default RasterOps to something */
723
        /* that we implement less expensively. */
724
1.85M
        if (!pim->CombineWithColor)
725
1.85M
            lop = rop3_know_T_0(lop);
726
0
        else if ((rop3_uses_T(lop) && color_draws_b_w(dev, pdcolor) == 0))
727
0
            lop = rop3_know_T_0(lop);
728
729
1.85M
        if (lop != rop3_S &&    /* if best case, no more work needed */
730
1.85M
            !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
731
1.85M
            (b_w_color =
732
0
             color_draws_b_w(dev, penum->icolor0)) >= 0 &&
733
1.85M
            color_draws_b_w(dev, penum->icolor1) == (b_w_color ^ 1)
734
1.85M
            ) {
735
0
            if (b_w_color) {    /* Swap the colors and invert the RasterOp source. */
736
0
                gx_device_color dcolor;
737
738
0
                dcolor = *(penum->icolor0);
739
0
                *(penum->icolor0) = *(penum->icolor1);
740
0
                *(penum->icolor1) = dcolor;
741
0
                lop = rop3_invert_S(lop);
742
0
            }
743
            /*
744
             * At this point, we know that the source pixels
745
             * correspond directly to the S input for the raster op,
746
             * i.e., icolor0 is black and icolor1 is white.
747
             */
748
0
            switch (lop) {
749
0
                case rop3_D & rop3_S:
750
                    /* Implement this as an inverted mask writing 0s. */
751
0
                    *(penum->icolor1) = *(penum->icolor0);
752
                    /* (falls through) */
753
0
                case rop3_D | rop3_not(rop3_S):
754
                    /* Implement this as an inverted mask writing 1s. */
755
0
                    memcpy(&penum->map[0].table.lookup4x1to32[0],
756
0
                           lookup4x1to32_inverted, 16 * 4);
757
0
                  rmask:        /* Fill in the remaining parameters for a mask. */
758
0
                    penum->masked = masked = true;
759
0
                    set_nonclient_dev_color(penum->icolor0, gx_no_color_index);
760
0
                    penum->map[0].decoding = sd_none;
761
0
                    lop = rop3_T;
762
0
                    break;
763
0
                case rop3_D & rop3_not(rop3_S):
764
                    /* Implement this as a mask writing 0s. */
765
0
                    *(penum->icolor1) = *(penum->icolor0);
766
                    /* (falls through) */
767
0
                case rop3_D | rop3_S:
768
                    /* Implement this as a mask writing 1s. */
769
0
                    memcpy(&penum->map[0].table.lookup4x1to32[0],
770
0
                           lookup4x1to32_identity, 16 * 4);
771
0
                    goto rmask;
772
0
                default:
773
0
                    ;
774
0
            }
775
0
        }
776
1.85M
    }
777
2.28M
    penum->device_color = device_color;
778
    /*
779
     * Adjust width upward for unpacking up to 7 trailing bits in
780
     * the row, plus 1 byte for end-of-run, plus up to 7 leading
781
     * bits for data_x offset within a packed byte.
782
     */
783
2.28M
    bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
784
2.28M
    buffer = gs_alloc_bytes(mem, bsize, "image buffer");
785
2.28M
    if (buffer == 0) {
786
5
        code = gs_error_VMerror;
787
5
        goto fail;
788
5
    }
789
2.28M
    penum->bps = bps;
790
2.28M
    penum->unpack_bps = bps;
791
2.28M
    penum->log2_xbytes = log2_xbytes;
792
2.28M
    penum->spp = spp;
793
2.28M
    switch (format) {
794
2.23M
    case gs_image_format_chunky:
795
2.23M
        nplanes = 1;
796
2.23M
        spread = 1 << log2_xbytes;
797
2.23M
        break;
798
46.5k
    case gs_image_format_component_planar:
799
46.5k
        nplanes = spp;
800
46.5k
        spread = spp << log2_xbytes;
801
46.5k
        break;
802
0
    case gs_image_format_bit_planar:
803
0
        nplanes = spp * bps;
804
0
        spread = spp << log2_xbytes;
805
0
        break;
806
0
    default:
807
        /* No other cases are possible (checked by gx_image_enum_alloc). */
808
0
        return_error(gs_error_Fatal);
809
2.28M
    }
810
2.28M
    penum->num_planes = nplanes;
811
2.28M
    penum->spread = spread;
812
    /*
813
     * If we're asked to interpolate in a partial image, we have to
814
     * assume that the client either really only is interested in
815
     * the given sub-image, or else is constructing output out of
816
     * overlapping pieces.
817
     */
818
2.28M
    penum->interpolate = force_interpolation ? interp_force : pim->Interpolate ? interp_on : interp_off;
819
2.28M
    penum->x_extent = x_extent;
820
2.28M
    penum->y_extent = y_extent;
821
2.28M
    penum->posture =
822
2.28M
        ((x_extent.y | y_extent.x) == 0 ? image_portrait :
823
2.28M
         (x_extent.x | y_extent.y) == 0 ? image_landscape :
824
208k
         image_skewed);
825
2.28M
    penum->pgs = pgs;
826
2.28M
    if (pgs != NULL)
827
2.28M
        penum->pgs_level = pgs->level;
828
2.28M
    penum->pcs = pcs;
829
2.28M
    rc_increment_cs(pcs); /* Grab a ref (will decrement in gx_image1_end_image() */
830
2.28M
    penum->memory = mem;
831
2.28M
    penum->buffer = buffer;
832
2.28M
    penum->buffer_size = bsize;
833
2.28M
    penum->line = NULL;
834
2.28M
    penum->icc_link = NULL;
835
2.28M
    penum->color_cache = NULL;
836
2.28M
    penum->ht_buffer = NULL;
837
2.28M
    penum->thresh_buffer = NULL;
838
2.28M
    penum->use_cie_range = false;
839
2.28M
    penum->line_size = 0;
840
2.28M
    penum->use_rop = lop != (masked ? rop3_T : rop3_S);
841
#ifdef DEBUG
842
    if (gs_debug_c('*')) {
843
        if (penum->use_rop)
844
            dmprintf1(mem, "[%03x]", lop);
845
        dmprintf5(mem, "%c%d%c%dx%d ",
846
                 (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
847
                 bps,
848
                 (penum->posture == image_portrait ? ' ' :
849
                  penum->posture == image_landscape ? 'L' : 'T'),
850
                 width, height);
851
    }
852
#endif
853
2.28M
    penum->slow_loop = 0;
854
2.28M
    if (pcpath == 0) {
855
1.54M
        (*dev_proc(dev, get_clipping_box)) (dev, &obox);
856
1.54M
        cbox = obox;
857
1.54M
        penum->clip_image = 0;
858
1.54M
    } else
859
734k
        penum->clip_image =
860
734k
            (gx_cpath_outer_box(pcpath, &obox) |        /* not || */
861
734k
             gx_cpath_inner_box(pcpath, &cbox) ?
862
732k
             0 : image_clip_region);
863
2.28M
    penum->clip_outer = obox;
864
2.28M
    penum->clip_inner = cbox;
865
2.28M
    penum->log_op = rop3_T;     /* rop device takes care of this */
866
2.28M
    penum->clip_dev = 0;        /* in case we bail out */
867
2.28M
    penum->rop_dev = 0;         /* ditto */
868
2.28M
    penum->scaler = 0;          /* ditto */
869
    /*
870
     * If all four extrema of the image fall within the clipping
871
     * rectangle, clipping is never required.  When making this check,
872
     * we must carefully take into account the fact that we only care
873
     * about pixel centers.
874
     */
875
2.28M
    {
876
2.28M
        fixed
877
2.28M
            epx = min(row_extent.x, 0) + min(col_extent.x, 0),
878
2.28M
            eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
879
2.28M
            epy = min(row_extent.y, 0) + min(col_extent.y, 0),
880
2.28M
            eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
881
882
2.28M
        {
883
2.28M
            int hwx, hwy;
884
885
2.28M
            switch (penum->posture) {
886
2.07M
                case image_portrait:
887
2.07M
                    hwx = width, hwy = height;
888
2.07M
                    break;
889
92.8k
                case image_landscape:
890
92.8k
                    hwx = height, hwy = width;
891
92.8k
                    break;
892
115k
                default:
893
115k
                    hwx = hwy = 0;
894
2.28M
            }
895
            /*
896
             * If the image is only 1 sample wide or high,
897
             * and is less than 1 device pixel wide or high,
898
             * move it slightly so that it covers pixel centers.
899
             * This is a hack to work around a bug in some old
900
             * versions of TeX/dvips, which use 1-bit-high images
901
             * to draw horizontal and vertical lines without
902
             * positioning them properly.
903
             */
904
2.28M
            if (hwx == 1 && eqx - epx < fixed_1) {
905
22
                fixed diff =
906
22
                arith_rshift_1(row_extent.x + col_extent.x);
907
908
22
                mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
909
22
            }
910
2.28M
            if (hwy == 1 && eqy - epy < fixed_1) {
911
17
                fixed diff =
912
17
                arith_rshift_1(row_extent.y + col_extent.y);
913
914
17
                mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
915
17
            }
916
2.28M
        }
917
2.28M
        if_debug5m('b', mem, "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
918
2.28M
                   (masked? "masked, " : ""), spp, bps,
919
2.28M
                   fixed2float(mtx), fixed2float(mty));
920
2.28M
        if_debug9m('b', mem,
921
2.28M
                   "[b]   cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
922
2.28M
                   fixed2float(cbox.p.x), fixed2float(cbox.p.y),
923
2.28M
                   fixed2float(cbox.q.x), fixed2float(cbox.q.y),
924
2.28M
                   fixed2float(obox.p.x), fixed2float(obox.p.y),
925
2.28M
                   fixed2float(obox.q.x), fixed2float(obox.q.y),
926
2.28M
                   penum->clip_image);
927
        /* These DDAs enumerate the starting position of each source pixel
928
         * row in device space. */
929
2.28M
        dda_init(penum->dda.row.x, mtx, col_extent.x, height);
930
2.28M
        dda_init(penum->dda.row.y, mty, col_extent.y, height);
931
2.28M
        if (dda_will_overflow(penum->dda.row.x) ||
932
2.28M
            dda_will_overflow(penum->dda.row.y))
933
0
        {
934
0
            code = gs_error_rangecheck;
935
0
            goto fail;
936
0
        }
937
2.28M
        if (penum->posture == image_portrait) {
938
2.07M
            penum->dst_width = row_extent.x;
939
2.07M
            penum->dst_height = col_extent.y;
940
2.07M
        } else {
941
208k
            penum->dst_width = col_extent.x;
942
208k
            penum->dst_height = row_extent.y;
943
208k
        }
944
        /* For gs_image_class_0_interpolate. */
945
2.28M
        penum->yi0 = fixed2int_pixround_perfect(dda_current(penum->dda.row.y)); /* For gs_image_class_0_interpolate. */
946
2.28M
        if (penum->rect.y) {
947
574k
            int y = penum->rect.y;
948
949
78.6M
            while (y--) {
950
78.1M
                dda_next(penum->dda.row.x);
951
78.1M
                dda_next(penum->dda.row.y);
952
78.1M
            }
953
574k
        }
954
2.28M
        penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
955
2.28M
        penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
956
        /* These DDAs enumerate the starting positions of each row of our
957
         * source pixel data, in the subrectangle ('strip') that we are
958
         * actually rendering. */
959
2.28M
        dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
960
2.28M
        dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
961
2.28M
        if (dda_will_overflow(penum->dda.strip.x) ||
962
2.28M
            dda_will_overflow(penum->dda.strip.y))
963
0
        {
964
0
            code = gs_error_rangecheck;
965
0
            goto fail;
966
0
        }
967
2.28M
        if (penum->rect.x) {
968
8.24k
            dda_advance(penum->dda.strip.x, penum->rect.x);
969
8.24k
            dda_advance(penum->dda.strip.y, penum->rect.x);
970
8.24k
        }
971
2.28M
        {
972
2.28M
            fixed ox = dda_current(penum->dda.strip.x);
973
2.28M
            fixed oy = dda_current(penum->dda.strip.y);
974
975
2.28M
            if (!penum->clip_image)     /* i.e., not clip region */
976
2.27M
                penum->clip_image =
977
2.27M
                    (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
978
2.17M
                     image_clip_xmin : 0) +
979
2.27M
                    (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
980
1.62M
                     image_clip_xmax : 0) +
981
2.27M
                    (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
982
1.65M
                     image_clip_ymin : 0) +
983
2.27M
                    (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
984
1.84M
                     image_clip_ymax : 0);
985
2.28M
        }
986
2.28M
    }
987
0
    penum->y = 0;
988
2.28M
    penum->used.x = 0;
989
2.28M
    penum->used.y = 0;
990
2.28M
    if (penum->clip_image && pcpath) {  /* Set up the clipping device. */
991
583k
        gx_device_clip *cdev =
992
583k
            gs_alloc_struct(mem, gx_device_clip,
993
583k
                            &st_device_clip, "image clipper");
994
995
583k
        if (cdev == NULL) {
996
0
            code = gs_error_VMerror;
997
0
            goto fail;
998
0
        }
999
583k
        gx_make_clip_device_in_heap(cdev, pcpath, dev, mem);
1000
583k
        penum->clip_dev = cdev;
1001
583k
        penum->dev = (gx_device *)cdev; /* Will restore this in a mo. Hacky! */
1002
583k
    }
1003
2.28M
    if (penum->use_rop) {       /* Set up the RasterOp source device. */
1004
0
        gx_device_rop_texture *rtdev;
1005
1006
0
        code = gx_alloc_rop_texture_device(&rtdev, mem,
1007
0
                                           "image RasterOp");
1008
0
        if (code < 0)
1009
0
            goto fail;
1010
        /* The 'target' must not be NULL for gx_make_rop_texture_device */
1011
0
        if (!penum->clip_dev && !dev)
1012
0
            return_error(gs_error_undefined);
1013
1014
0
        gx_make_rop_texture_device(rtdev,
1015
0
                                   (penum->clip_dev != 0 ?
1016
0
                                    (gx_device *) penum->clip_dev :
1017
0
                                    dev), lop, pdcolor);
1018
0
        gx_device_retain((gx_device *)rtdev, true);
1019
0
        penum->rop_dev = rtdev;
1020
0
        penum->dev = (gx_device *)rtdev; /* Will restore this in a mo. Hacky! */
1021
0
    }
1022
2.28M
    {
1023
2.28M
        static sample_unpack_proc_t procs[2][6] = {
1024
2.28M
        {   sample_unpack_1, sample_unpack_2,
1025
2.28M
            sample_unpack_4, sample_unpack_8,
1026
2.28M
            sample_unpack_12, sample_unpack_16
1027
2.28M
        },
1028
2.28M
        {   sample_unpack_1_interleaved, sample_unpack_2_interleaved,
1029
2.28M
            sample_unpack_4_interleaved, sample_unpack_8_interleaved,
1030
2.28M
            sample_unpack_12, sample_unpack_16
1031
2.28M
        }};
1032
2.28M
        int num_planes = penum->num_planes;
1033
2.28M
        bool interleaved = (num_planes == 1 && penum->plane_depths[0] != penum->bps);
1034
2.28M
        irender_proc_t render_fn = NULL;
1035
2.28M
        int i;
1036
1037
2.28M
        if (interleaved) {
1038
1.24M
            int num_components = penum->plane_depths[0] / penum->bps;
1039
1040
3.77M
            for (i = 1; i < num_components; i++) {
1041
2.53M
                if (decode[0] != decode[i * 2 + 0] ||
1042
2.53M
                    decode[1] != decode[i * 2 + 1])
1043
8
                    break;
1044
2.53M
            }
1045
1.24M
            if (i == num_components)
1046
1.24M
                interleaved = false; /* Use single table. */
1047
1.24M
        }
1048
2.28M
        penum->unpack = procs[interleaved][index_bps];
1049
1050
2.28M
        if_debug1m('b', mem, "[b]unpack=%d\n", bps);
1051
        /* Set up pixel0 for image class procedures. */
1052
2.28M
        penum->dda.pixel0 = penum->dda.strip;
1053
2.28M
        penum->skip_next_line = NULL;
1054
9.84M
        for (i = 0; i < gx_image_class_table_count; ++i) {
1055
9.84M
            code = gx_image_class_table[i](penum, &render_fn);
1056
9.84M
            if (code < 0)
1057
0
                goto fail;
1058
1059
9.84M
            if (render_fn != NULL) {
1060
2.28M
                penum->render = render_fn;
1061
2.28M
                break;
1062
2.28M
            }
1063
9.84M
        }
1064
2.28M
        penum->dev = dev; /* Restore this (in case it was changed to cdev or rtdev) */
1065
2.28M
        if (i == gx_image_class_table_count) {
1066
            /* No available class can handle this image. */
1067
0
            return_error(gs_error_rangecheck);
1068
0
        }
1069
2.28M
    }
1070
2.28M
    return 0;
1071
1072
59
fail:
1073
59
    gs_free_object(mem, buffer, "image buffer");
1074
59
    gs_free_object(mem, penum->clues, "gx_image_enum_begin");
1075
59
    if (penum->clip_dev != NULL) {
1076
0
        rc_decrement(penum->clip_dev, "error in gx_begin_image1");
1077
0
        penum->clip_dev = NULL;
1078
0
    }
1079
59
    gs_free_object(mem, penum->clip_dev, "image clipper");
1080
59
    rc_decrement_cs(penum->pcs, "error in gx_begin_image1");
1081
59
    penum->pcs = NULL;
1082
59
    gs_free_object(mem, penum, "gx_begin_image1");
1083
59
    return code;
1084
2.28M
}
1085
1086
/* If a drawing color is black or white, return 0 or 1 respectively, */
1087
/* otherwise return -1. */
1088
static int
1089
color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
1090
0
{
1091
0
    if (color_is_pure(pdcolor)) {
1092
0
        gx_color_value rgb[3];
1093
1094
0
        (*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
1095
0
                                         rgb);
1096
0
        if (!(rgb[0] | rgb[1] | rgb[2]))
1097
0
            return 0;
1098
0
        if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
1099
0
            return 1;
1100
0
    }
1101
0
    return -1;
1102
0
}
1103
1104
1105
static void
1106
image_cache_decode(gx_image_enum *penum, byte input, byte *output, bool scale)
1107
0
{
1108
0
    float temp;
1109
1110
0
    switch ( penum->map[0].decoding ) {
1111
0
        case sd_none:
1112
0
            *output = input;
1113
0
            break;
1114
0
        case sd_lookup:
1115
0
            temp = penum->map[0].decode_lookup[input >> 4]*255.0f;
1116
0
            if (temp > 255) temp = 255;
1117
0
            if (temp < 0 ) temp = 0;
1118
0
            *output = (unsigned char) temp;
1119
0
            break;
1120
0
        case sd_compute:
1121
0
            temp = penum->map[0].decode_base +
1122
0
                (float) input * penum->map[0].decode_factor;
1123
0
            if (scale) {
1124
0
                temp = temp * 255.0;
1125
0
            }
1126
0
            if (temp > 255) temp = 255;
1127
0
            if (temp < 0 ) temp = 0;
1128
0
            *output = (unsigned char) temp;
1129
0
            break;
1130
0
        default:
1131
0
            *output = 0;
1132
0
            break;
1133
0
    }
1134
0
}
1135
1136
static bool
1137
decode_range_needed(gx_image_enum *penum)
1138
0
{
1139
0
    bool scale = true;
1140
1141
0
    if (penum->map[0].decoding == sd_compute) {
1142
0
        if (!(gs_color_space_is_ICC(penum->pcs) ||
1143
0
            gs_color_space_is_PSCIE(penum->pcs))) {
1144
0
            scale = false;
1145
0
        }
1146
0
    }
1147
0
    return scale;
1148
0
}
1149
1150
/* A special case where we go ahead and initialize the whole index cache with
1151
   contone.  Device colors.  If we are halftoning we will then go ahead and
1152
   apply the thresholds to the device contone values.  Only used for gray,
1153
   rgb or cmyk source colors (No DeviceN for now) */
1154
/* TO DO  Add in PSCIE decoder */
1155
int
1156
image_init_color_cache(gx_image_enum * penum, int bps, int spp)
1157
85.3k
{
1158
85.3k
    int num_des_comp = penum->dev->color_info.num_components;
1159
85.3k
    int num_src_comp;
1160
85.3k
    int num_entries = 1 << bps;
1161
85.3k
    bool need_decode = penum->icc_setup.need_decode;
1162
85.3k
    bool has_transfer = penum->icc_setup.has_transfer;
1163
85.3k
    byte value;
1164
85.3k
    bool decode_scale = true;
1165
85.3k
    int k, kk;
1166
85.3k
    byte psrc[4];
1167
85.3k
    byte *temp_buffer;
1168
85.3k
    byte *byte_ptr;
1169
85.3k
    bool is_indexed = (gs_color_space_get_index(penum->pcs) ==
1170
85.3k
                                            gs_color_space_index_Indexed);
1171
85.3k
    bool free_temp_buffer = true;
1172
85.3k
    gsicc_bufferdesc_t input_buff_desc;
1173
85.3k
    gsicc_bufferdesc_t output_buff_desc;
1174
85.3k
    gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
1175
85.3k
    int code;
1176
1177
85.3k
    if (penum->icc_link == NULL) {
1178
0
        return gs_rethrow(-1, "ICC Link not created during image render color");
1179
0
    }
1180
85.3k
    if (is_indexed) {
1181
1.77k
        num_src_comp = gs_color_space_num_components(penum->pcs->base_space);
1182
83.6k
    } else {
1183
        /* Detect case where cache is not needed.  Colors are already in the
1184
           device space.  Need to fast track this one and halftone row directly.
1185
           Detected in gximono.c by looking if penum->color_cache is NULL */
1186
83.6k
        if (penum->icc_link->is_identity && !need_decode && !has_transfer) {
1187
83.3k
            return 0;
1188
83.3k
        }
1189
227
        num_src_comp = 1;
1190
227
    }
1191
    /* Allocate cache of device contone values */
1192
2.00k
    penum->color_cache = gs_alloc_struct(penum->memory, gx_image_color_cache_t,
1193
2.00k
                                         &st_color_cache,
1194
2.00k
                                         "image_init_color_cache");
1195
2.00k
    if (penum->color_cache == NULL)
1196
0
        return_error(gs_error_VMerror);
1197
1198
2.00k
    penum->color_cache->device_contone = (byte*) gs_alloc_bytes(penum->memory,
1199
2.00k
                   num_des_comp * num_entries * sizeof(byte), "image_init_color_cache");
1200
2.00k
    penum->color_cache->is_transparent = (bool*) gs_alloc_bytes(penum->memory,
1201
2.00k
             num_entries * sizeof(bool), "image_init_color_cache");
1202
2.00k
    if (penum->color_cache->device_contone == NULL || penum->color_cache->is_transparent == NULL) {
1203
0
        gs_free_object(penum->memory, penum->color_cache->device_contone, "image_init_color_cache");
1204
0
        gs_free_object(penum->memory, penum->color_cache->is_transparent, "image_init_color_cache");
1205
0
        gs_free_object(penum->memory, penum->color_cache, "image_init_color_cache");
1206
0
        penum->color_cache = NULL;
1207
0
        return_error(gs_error_VMerror);
1208
0
    }
1209
    /* Initialize */
1210
2.00k
    memset(penum->color_cache->is_transparent,0,num_entries * sizeof(bool));
1211
    /* Depending upon if we need decode and ICC CM, fill the cache a couple
1212
       different ways. If the link is the identity, then we don't need to do any
1213
       color conversions except for potentially a decode.  This is written in
1214
       the manner shown below so that the common case of no decode and indexed
1215
       image with a look-up-table uses the table data directly or does as many
1216
       operations with memcpy as we can */
1217
    /* Need to check the decode output range so we know how we need to scale.
1218
       We want 8 bit output */
1219
2.00k
    if (need_decode) {
1220
0
        decode_scale = decode_range_needed(penum);
1221
0
    }
1222
2.00k
    if (penum->icc_link->is_identity) {
1223
        /* No CM needed.  */
1224
0
        if (need_decode || has_transfer) {
1225
            /* Slower case.  This could be sped up later to avoid the tests
1226
               within the loop by use of specialized loops.  */
1227
0
            for (k = 0; k < num_entries; k++) {
1228
                /* Data is in k */
1229
0
                if (need_decode) {
1230
0
                    image_cache_decode(penum, k, &value, decode_scale);
1231
0
                } else {
1232
0
                    value = k;
1233
0
                }
1234
                /* Data is in value */
1235
0
                if (is_indexed) {
1236
0
                    gs_cspace_indexed_lookup_bytes(penum->pcs, value, psrc);
1237
0
                } else {
1238
0
                    psrc[0] = value;
1239
0
                }
1240
                /* Data is in psrc */
1241
                /* These silly transforms need to go away. ToDo. */
1242
0
                if (has_transfer) {
1243
0
                    for (kk = 0; kk < num_des_comp; kk++) {
1244
0
                        conc[kk] = gx_color_value_from_byte(psrc[kk]);
1245
0
                    }
1246
0
                    cmap_transfer(&(conc[0]), penum->pgs, penum->dev);
1247
0
                    for (kk = 0; kk < num_des_comp; kk++) {
1248
0
                        psrc[kk] = gx_color_value_to_byte(conc[kk]);
1249
0
                    }
1250
0
                }
1251
0
                memcpy(&(penum->color_cache->device_contone[k * num_des_comp]),
1252
0
                               psrc, num_des_comp);
1253
0
            }
1254
0
        } else {
1255
            /* Indexing only.  No CM, decode or transfer functions. */
1256
0
            for (k = 0; k < num_entries; k++) {
1257
0
                gs_cspace_indexed_lookup_bytes(penum->pcs, (float)k, psrc);
1258
0
                memcpy(&(penum->color_cache->device_contone[k * num_des_comp]),
1259
0
                           psrc, num_des_comp);
1260
0
            }
1261
0
        }
1262
2.00k
    } else {
1263
        /* Need CM */
1264
        /* We need to worry about if the source is indexed and if we need
1265
           to decode first.  Then we can apply CM. Create a temp buffer in
1266
           the source space and then transform it with one call */
1267
2.00k
        temp_buffer = (byte*) gs_alloc_bytes(penum->memory,
1268
2.00k
                                             (size_t)num_entries * num_src_comp,
1269
2.00k
                                             "image_init_color_cache");
1270
2.00k
        if (temp_buffer == NULL)
1271
0
            return_error(gs_error_VMerror);
1272
1273
2.00k
        if (need_decode) {
1274
0
            if (is_indexed) {
1275
                /* Decode and lookup in index */
1276
0
                for (k = 0; k < num_entries; k++) {
1277
0
                    image_cache_decode(penum, k, &value, decode_scale);
1278
0
                    gs_cspace_indexed_lookup_bytes(penum->pcs, value, psrc);
1279
0
                    memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1280
0
                }
1281
0
            } else {
1282
                /* Decode only */
1283
0
                for (k = 0; k < num_entries; k++) {
1284
0
                    image_cache_decode(penum, k, &(temp_buffer[k]), decode_scale);
1285
0
                }
1286
0
            }
1287
2.00k
        } else {
1288
            /* No Decode */
1289
2.00k
            if (is_indexed) {
1290
                /* If index uses a num_entries sized table then just use its pointer */
1291
1.77k
                if (penum->pcs->params.indexed.use_proc ||
1292
1.77k
                    penum->pcs->params.indexed.hival < (num_entries - 1)) {
1293
                    /* Have to do the slow way */
1294
6.84k
                    for (k = 0; k <= penum->pcs->params.indexed.hival; k++) {
1295
6.66k
                        gs_cspace_indexed_lookup_bytes(penum->pcs, (float)k, psrc);
1296
6.66k
                        memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1297
6.66k
                    }
1298
                    /* just use psrc results from converting 'hival' to fill the remaining slots */
1299
40.1k
                    for (; k < num_entries; k++) {
1300
39.9k
                        memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1301
39.9k
                    }
1302
1.59k
                } else {
1303
                    /* Use the index table directly. */
1304
1.59k
                    gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1305
1.59k
                    free_temp_buffer = false;
1306
1.59k
                    temp_buffer = (byte *)(penum->pcs->params.indexed.lookup.table.data);
1307
1.59k
                }
1308
1.77k
            } else {
1309
                /* CM only */
1310
58.3k
                for (k = 0; k < num_entries; k++) {
1311
58.1k
                    temp_buffer[k] = k;
1312
58.1k
                }
1313
227
            }
1314
2.00k
        }
1315
        /* Set up the buffer descriptors. */
1316
2.00k
        gsicc_init_buffer(&input_buff_desc, num_src_comp, 1, false, false, false,
1317
2.00k
                          0, num_entries * num_src_comp, 1, num_entries);
1318
2.00k
        gsicc_init_buffer(&output_buff_desc, num_des_comp, 1, false, false, false,
1319
2.00k
                          0, num_entries * num_des_comp,
1320
2.00k
                      1, num_entries);
1321
2.00k
        code = (penum->icc_link->procs.map_buffer)(penum->dev, penum->icc_link,
1322
2.00k
                                            &input_buff_desc, &output_buff_desc,
1323
2.00k
                                            (void*) temp_buffer,
1324
2.00k
                                            (void*) penum->color_cache->device_contone);
1325
2.00k
        if (code < 0)
1326
0
            return gs_rethrow(code, "Failure to map color buffer");
1327
1328
        /* Check if we need to apply any transfer functions.  If so then do it now */
1329
2.00k
        if (has_transfer) {
1330
0
            for (k = 0; k < num_entries; k++) {
1331
0
                byte_ptr =
1332
0
                    &(penum->color_cache->device_contone[k * num_des_comp]);
1333
0
                for (kk = 0; kk < num_des_comp; kk++) {
1334
0
                    conc[kk] = gx_color_value_from_byte(byte_ptr[kk]);
1335
0
                }
1336
0
                cmap_transfer(&(conc[0]), penum->pgs, penum->dev);
1337
0
                for (kk = 0; kk < num_des_comp; kk++) {
1338
0
                    byte_ptr[kk] = gx_color_value_to_byte(conc[kk]);
1339
0
                }
1340
0
            }
1341
0
        }
1342
2.00k
        if (free_temp_buffer)
1343
409
            gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1344
2.00k
    }
1345
2.00k
    return 0;
1346
2.00k
}
1347
1348
/* Export this for use by image_render_ functions */
1349
void
1350
image_init_clues(gx_image_enum * penum, int bps, int spp)
1351
1.18M
{
1352
    /* Initialize the color table */
1353
1.18M
#define ictype(i)\
1354
1.18M
  penum->clues[i].dev_color.type
1355
1356
1.18M
    switch ((spp == 1 ? bps : 8)) {
1357
999k
        case 8:         /* includes all color images */
1358
999k
            {
1359
999k
                register gx_image_clue *pcht = &penum->clues[0];
1360
999k
                register int n = 64;    /* 8 bits means 256 clues, do   */
1361
                                        /* 4 at a time for efficiency   */
1362
63.9M
                do {
1363
63.9M
                    pcht[0].dev_color.type =
1364
63.9M
                        pcht[1].dev_color.type =
1365
63.9M
                        pcht[2].dev_color.type =
1366
63.9M
                        pcht[3].dev_color.type =
1367
63.9M
                        gx_dc_type_none;
1368
63.9M
                    pcht[0].key = pcht[1].key =
1369
63.9M
                        pcht[2].key = pcht[3].key = 0;
1370
63.9M
                    pcht += 4;
1371
63.9M
                }
1372
63.9M
                while (--n > 0);
1373
999k
                penum->clues[0].key = 1;        /* guarantee no hit */
1374
999k
                break;
1375
0
            }
1376
664
        case 4:
1377
664
            ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
1378
664
                ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
1379
664
                ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
1380
664
                ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
1381
664
                gx_dc_type_none;
1382
            /* falls through */
1383
1.80k
        case 2:
1384
1.80k
            ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
1385
1.18M
#undef ictype
1386
1.18M
    }
1387
1.18M
}
1388
1389
/* Initialize the color mapping tables for a non-mask image. */
1390
static int
1391
image_init_colors(gx_image_enum * penum, int bps, int spp,
1392
                  gs_image_format_t format, const float *decode /*[spp*2] */ ,
1393
                  const gs_gstate * pgs, gx_device * dev,
1394
                  const gs_color_space * pcs, bool * pdcb)
1395
1.85M
{
1396
1.85M
    int ci, decode_type, code;
1397
1.85M
    static const float default_decode[] = {
1398
1.85M
        0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
1399
1.85M
    };
1400
1401
    /* Clues are only used with image_mono_render */
1402
1.85M
    if (spp == 1) {
1403
563k
        image_init_clues(penum, bps, spp);
1404
563k
    }
1405
1.85M
    decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */
1406
4.99M
    for (ci = 0; ci < spp; ci +=2 ) {
1407
3.14M
        decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) |
1408
3.14M
                       (decode[ci] == 1. && decode[ci + 1] == 0.) << 1;
1409
3.14M
    }
1410
1411
    /* Initialize the maps from samples to intensities. */
1412
6.37M
    for (ci = 0; ci < spp; ci++) {
1413
4.52M
        sample_map *pmap = &penum->map[ci];
1414
1415
        /* If the decoding is [0 1] or [1 0], we can fold it */
1416
        /* into the expansion of the sample values; */
1417
        /* otherwise, we have to use the floating point method. */
1418
1419
4.52M
        const float *this_decode = &decode[ci * 2];
1420
4.52M
        const float *map_decode;        /* decoding used to */
1421
                                        /* construct the expansion map */
1422
4.52M
        const float *real_decode;       /* decoding for expanded samples */
1423
1424
4.52M
        map_decode = real_decode = this_decode;
1425
4.52M
        if (!(decode_type & 1)) {
1426
7.06k
            if ((decode_type & 2) && bps <= 8) {
1427
476
                real_decode = default_decode;
1428
6.58k
            } else {
1429
6.58k
                *pdcb = false;
1430
6.58k
                map_decode = default_decode;
1431
6.58k
            }
1432
7.06k
        }
1433
4.52M
        if (bps > 2 || format != gs_image_format_chunky) {
1434
4.50M
            if (bps <= 8)
1435
4.50M
                image_init_map(&pmap->table.lookup8[0], 1 << bps,
1436
4.50M
                               map_decode);
1437
4.50M
        } else {                /* The map index encompasses more than one pixel. */
1438
21.1k
            byte map[4];
1439
21.1k
            register int i;
1440
1441
21.1k
            image_init_map(&map[0], 1 << bps, map_decode);
1442
21.1k
            switch (bps) {
1443
20.5k
                case 1:
1444
20.5k
                    {
1445
20.5k
                        register bits32 *p = &pmap->table.lookup4x1to32[0];
1446
1447
20.5k
                        if (map[0] == 0 && map[1] == 0xff)
1448
20.5k
                            memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
1449
38
                        else if (map[0] == 0xff && map[1] == 0)
1450
38
                            memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
1451
0
                        else
1452
0
                            for (i = 0; i < 16; i++, p++)
1453
0
                                ((byte *) p)[0] = map[i >> 3],
1454
0
                                    ((byte *) p)[1] = map[(i >> 2) & 1],
1455
0
                                    ((byte *) p)[2] = map[(i >> 1) & 1],
1456
0
                                    ((byte *) p)[3] = map[i & 1];
1457
20.5k
                    }
1458
20.5k
                    break;
1459
574
                case 2:
1460
574
                    {
1461
574
                        register bits16 *p = &pmap->table.lookup2x2to16[0];
1462
1463
9.75k
                        for (i = 0; i < 16; i++, p++)
1464
9.18k
                            ((byte *) p)[0] = map[i >> 2],
1465
9.18k
                                ((byte *) p)[1] = map[i & 3];
1466
574
                    }
1467
574
                    break;
1468
21.1k
            }
1469
21.1k
        }
1470
4.52M
        pmap->decode_base /* = decode_lookup[0] */  = real_decode[0];
1471
4.52M
        pmap->decode_factor =
1472
4.52M
            (real_decode[1] - real_decode[0]) /
1473
4.52M
            (bps <= 8 ? 255.0 : (float)frac_1);
1474
4.52M
        pmap->decode_max /* = decode_lookup[15] */  = real_decode[1];
1475
4.52M
        if (decode_type) {
1476
4.52M
            pmap->decoding = sd_none;
1477
4.52M
            pmap->inverted = map_decode[0] != 0;
1478
4.52M
        } else if (bps <= 4) {
1479
633
            int step = 15 / ((1 << bps) - 1);
1480
633
            int i;
1481
1482
633
            pmap->decoding = sd_lookup;
1483
3.20k
            for (i = 15 - step; i > 0; i -= step)
1484
2.56k
                pmap->decode_lookup[i] = pmap->decode_base +
1485
2.56k
                    i * (255.0 / 15) * pmap->decode_factor;
1486
633
            pmap->inverted = 0;
1487
5.95k
        } else {
1488
5.95k
            pmap->decoding = sd_compute;
1489
5.95k
            pmap->inverted = 0;
1490
5.95k
        }
1491
4.52M
        if (spp == 1) {         /* and ci == 0 *//* Pre-map entries 0 and 255. */
1492
563k
            gs_client_color cc;
1493
1494
            /* Image clues are used in this case */
1495
563k
            cc.paint.values[0] = real_decode[0];
1496
563k
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0,
1497
563k
                                       pgs, dev, gs_color_select_source);
1498
563k
            if (code < 0)
1499
5
                return code;
1500
563k
            cc.paint.values[0] = real_decode[1];
1501
563k
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1,
1502
563k
                                       pgs, dev, gs_color_select_source);
1503
563k
            if (code < 0)
1504
0
                return code;
1505
563k
        }
1506
4.52M
    }
1507
1.85M
    return 0;
1508
1.85M
}
1509
/* Construct a mapping table for sample values. */
1510
/* map_size is 2, 4, 16, or 256.  Note that 255 % (map_size - 1) == 0, */
1511
/* so the division 0xffffL / (map_size - 1) is always exact. */
1512
void
1513
image_init_map(byte * map, int map_size, const float *decode)
1514
4.53M
{
1515
4.53M
    float min_v = decode[0];
1516
4.53M
    float diff_v = decode[1] - min_v;
1517
1518
4.53M
    if (diff_v == 1 || diff_v == -1) {  /* We can do the stepping with integers, without overflow. */
1519
4.53M
        byte *limit = map + map_size;
1520
4.53M
        uint value = (uint)(min_v * 0xffffL);
1521
4.53M
        int diff = (int)(diff_v * (0xffffL / (map_size - 1)));
1522
1523
1.15G
        for (; map != limit; map++, value += diff)
1524
1.15G
            *map = value >> 8;
1525
4.53M
    } else {                    /* Step in floating point, with clamping. */
1526
0
        int i;
1527
1528
0
        for (i = 0; i < map_size; ++i) {
1529
0
            int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
1530
1531
0
            map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
1532
0
        }
1533
0
    }
1534
4.53M
}
1535
1536
/*
1537
 * Scale a pair of mask_color values to match the scaling of each sample to
1538
 * a full byte, and complement and swap them if the map incorporates
1539
 * a Decode = [1 0] inversion.
1540
 */
1541
void
1542
gx_image_scale_mask_colors(gx_image_enum *penum, int component_index)
1543
500
{
1544
500
    uint scale = 255 / ((1 << penum->bps) - 1);
1545
500
    uint *values = &penum->mask_color.values[component_index * 2];
1546
500
    uint v0 = values[0] *= scale;
1547
500
    uint v1 = values[1] *= scale;
1548
1549
500
    if (penum->map[component_index].decoding == sd_none &&
1550
500
        penum->map[component_index].inverted
1551
500
        ) {
1552
0
        values[0] = 255 - v1;
1553
0
        values[1] = 255 - v0;
1554
0
    }
1555
500
}
1556
1557
/* Used to indicate for ICC procesing if we have decoding to do */
1558
bool
1559
gx_has_transfer(const gs_gstate *pgs, int num_comps)
1560
1.54M
{
1561
1.54M
    int k;
1562
1563
4.65M
    for (k = 0; k < num_comps; k++) {
1564
3.57M
        if (pgs->effective_transfer[k]->proc != gs_identity_transfer) {
1565
464k
            return(true);
1566
464k
        }
1567
3.57M
    }
1568
1.08M
    return(false);
1569
1.54M
}