Coverage Report

Created: 2025-06-10 06:56

/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
0
ENUM_PTRS_WITH(image_enum_enum_ptrs, gx_image_enum *eptr)
64
0
{
65
0
    int bps;
66
0
    gs_ptr_type_t ret;
67
68
    /* Enumerate the used members of clues.dev_color. */
69
0
    index -= gx_image_enum_num_ptrs;
70
0
    bps = eptr->unpack_bps;
71
0
    if (eptr->spp != 1)
72
0
        bps = 8;
73
0
    else if (bps > 8 || eptr->unpack == sample_unpack_copy)
74
0
        bps = 1;
75
0
    if (index >= (1 << bps) * st_device_color_max_ptrs)         /* done */
76
0
        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
0
    if (eptr->spp == 1) {
80
0
        if (eptr->clues != NULL) {
81
0
            if (eptr->clues[(index/st_device_color_max_ptrs) *
82
0
                (255 / ((1 << bps) - 1))].dev_color.type != 0) {
83
0
                ret = ENUM_USING(st_device_color,
84
0
                                 &eptr->clues[(index / st_device_color_max_ptrs) *
85
0
                                 (255 / ((1 << bps) - 1))].dev_color,
86
0
                                 sizeof(eptr->clues[0].dev_color),
87
0
                                 index % st_device_color_max_ptrs);
88
0
            } else {
89
0
                ret = 0;
90
0
            }
91
0
        } else {
92
0
            ret = 0;
93
0
        }
94
0
    } else {
95
0
        ret = 0;
96
0
    }
97
0
    if (ret == 0)               /* don't stop early */
98
0
        ENUM_RETURN(0);
99
0
    return ret;
100
0
}
101
102
0
#define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
103
0
gx_image_enum_do_ptrs(e1)
104
0
#undef e1
105
0
ENUM_PTRS_END
106
107
0
static RELOC_PTRS_WITH(image_enum_reloc_ptrs, gx_image_enum *eptr)
108
0
{
109
0
    int i;
110
111
0
#define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
112
0
    gx_image_enum_do_ptrs(r1)
113
0
#undef r1
114
0
    {
115
0
        int bps = eptr->unpack_bps;
116
117
0
        if (eptr->spp != 1)
118
0
            bps = 8;
119
0
        else if (bps > 8 || eptr->unpack == sample_unpack_copy)
120
0
            bps = 1;
121
0
        if (eptr->spp == 1) {
122
0
        for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
123
0
            RELOC_USING(st_device_color,
124
0
                        &eptr->clues[i].dev_color, sizeof(gx_device_color));
125
0
    }
126
0
}
127
0
}
128
0
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
123k
{
152
123k
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
153
123k
    int width = pim->Width, height = pim->Height;
154
123k
    int bpc = pim->BitsPerComponent;
155
123k
    gx_image_enum *penum;
156
157
123k
    if (width < 0 || height < 0)
158
0
        return_error(gs_error_rangecheck);
159
123k
    switch (pim->format) {
160
123k
    case gs_image_format_chunky:
161
123k
    case gs_image_format_component_planar:
162
123k
        switch (bpc) {
163
123k
        case 1: case 2: case 4: case 8: case 12: case 16: break;
164
0
        default: return_error(gs_error_rangecheck);
165
123k
        }
166
123k
        break;
167
123k
    case gs_image_format_bit_planar:
168
0
        if (bpc < 1 || bpc > 8)
169
0
            return_error(gs_error_rangecheck);
170
123k
    }
171
123k
    if (prect) {
172
45.0k
        if (prect->p.x < 0 || prect->p.y < 0 ||
173
45.0k
            prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
174
45.0k
            prect->q.x > width || prect->q.y > height
175
45.0k
            )
176
0
            return_error(gs_error_rangecheck);
177
45.0k
    }
178
123k
    *ppenum = NULL;   /* in case alloc fails and caller doesn't check code */
179
123k
    penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
180
123k
                            "gx_default_begin_image");
181
123k
    if (penum == 0)
182
0
        return_error(gs_error_VMerror);
183
123k
    memset(penum, 0, sizeof(gx_image_enum));  /* in case of failure, no dangling pointers */
184
123k
    if (prect) {
185
45.0k
        penum->rect.x = prect->p.x;
186
45.0k
        penum->rect.y = prect->p.y;
187
45.0k
        penum->rect.w = prect->q.x - prect->p.x;
188
45.0k
        penum->rect.h = prect->q.y - prect->p.y;
189
78.7k
    } else {
190
78.7k
        penum->rect.x = 0, penum->rect.y = 0;
191
78.7k
        penum->rect.w = width, penum->rect.h = height;
192
78.7k
    }
193
123k
    penum->rrect.x = penum->rect.x;
194
123k
    penum->rrect.y = penum->rect.y;
195
123k
    penum->rrect.w = penum->rect.w;
196
123k
    penum->rrect.h = penum->rect.h;
197
123k
    penum->drect.x = penum->rect.x;
198
123k
    penum->drect.y = penum->rect.y;
199
123k
    penum->drect.w = penum->rect.w;
200
123k
    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
123k
    *ppenum = penum;
210
123k
    return 0;
211
123k
}
212
213
/* Convert and restrict to a valid range. */
214
332k
static inline fixed float2fixed_rounded_boxed(double src) {
215
332k
    float v = floor(src*fixed_scale + 0.5);
216
217
332k
    if (v <= min_fixed)
218
12
        return min_fixed;
219
332k
    else if (v >= max_fixed)
220
15
        return max_fixed;
221
332k
    else
222
332k
        return  (fixed)v;
223
332k
}
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
137k
{
230
137k
    int code = 0;
231
232
137k
    if (pmat == 0)
233
137k
        pmat = &ctm_only(pgs);
234
137k
    if (ImageMatrix->xx == pmat->xx && ImageMatrix->xy == pmat->xy &&
235
137k
        ImageMatrix->yx == pmat->yx && ImageMatrix->yy == pmat->yy) {
236
        /* Process common special case separately to accept singular matrix. */
237
75.7k
        rmat->xx = rmat->yy = 1.;
238
75.7k
        rmat->xy = rmat->yx = 0.;
239
75.7k
        rmat->tx = pmat->tx - ImageMatrix->tx;
240
75.7k
        rmat->ty = pmat->ty - ImageMatrix->ty;
241
75.7k
    } else {
242
61.4k
        if ((code = gs_matrix_invert_to_double(ImageMatrix, rmat)) < 0 ||
243
61.4k
            (code = gs_matrix_multiply_double(rmat, pmat, rmat)) < 0
244
61.4k
            ) {
245
4
            return code;
246
4
        }
247
61.4k
    }
248
137k
    return code;
249
137k
}
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
123k
{
264
123k
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
265
123k
    gs_image_format_t format = pim->format;
266
123k
    const int width = pim->Width;
267
123k
    const int height = pim->Height;
268
123k
    const int bps = pim->BitsPerComponent;
269
123k
    bool masked = penum->masked;
270
123k
    const float *decode = pim->Decode;
271
123k
    gs_matrix_double mat;
272
123k
    int index_bps;
273
123k
    gs_color_space *pcs = pim->ColorSpace;
274
123k
    gs_logical_operation_t lop = (pgs ? pgs->log_op : lop_default);
275
123k
    int code;
276
123k
    int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
277
123k
    int spp, nplanes, spread;
278
123k
    uint bsize;
279
123k
    byte *buffer = NULL;
280
123k
    fixed mtx, mty;
281
123k
    gs_fixed_point row_extent, col_extent, x_extent, y_extent;
282
123k
    bool device_color = true;
283
123k
    gs_fixed_rect obox, cbox;
284
123k
    bool gridfitimages = 0;
285
123k
    bool in_pattern_accumulator;
286
123k
    bool in_smask;
287
123k
    int orthogonal;
288
123k
    int force_interpolation = 0;
289
290
123k
    penum->pcs = NULL;
291
123k
    penum->clues = NULL;
292
123k
    penum->icc_setup.has_transfer = false;
293
123k
    penum->icc_setup.is_lab = false;
294
123k
    penum->icc_setup.must_halftone = false;
295
123k
    penum->icc_setup.need_decode = false;
296
123k
    penum->Width = width;
297
123k
    penum->Height = height;
298
299
123k
    if ((code = gx_image_compute_mat(pgs, pmat, &(pim->ImageMatrix), &mat)) < 0) {
300
3
        return code;
301
3
    }
302
123k
    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
123k
    in_pattern_accumulator = (dev_proc(dev, dev_spec_op)(dev, gxdso_in_pattern_accumulator, NULL, 0));
323
123k
    if (in_pattern_accumulator < 0)
324
86.9k
        in_pattern_accumulator = 0;
325
326
    /* Figure out if we are orthogonal */
327
123k
    if (mat.xy == 0 && mat.yx == 0)
328
116k
        orthogonal = 1;
329
7.59k
    else if (mat.xx == 0 && mat.yy == 0)
330
7.42k
        orthogonal = 2;
331
176
    else
332
176
        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
123k
    in_smask = (pim->override_in_smask ||
340
123k
                (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0);
341
123k
    gridfitimages = (in_smask || in_pattern_accumulator) && orthogonal;
342
343
123k
    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
120k
    } else if (!gridfitimages &&
347
120k
               (!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
80.4k
    } else if (gridfitimages && (penum->masked && penum->image_parent_type == 0)) {
351
        /* We don't gridfit imagemasks in a pattern accumulator */
352
40.5k
    } 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
40.5k
    } else if (orthogonal == 1) {
355
33.0k
        if (width == 1 || gridfitimages) {
356
30.3k
            if (mat.xx > 0) {
357
30.2k
                fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx)));
358
30.2k
                double x1 = mat.tx + mat.xx * width;
359
30.2k
                fixed ix1 = int2fixed(fixed2int_ceiling(float2fixed(x1)));
360
30.2k
                mat.tx = (double)fixed2float(ix0);
361
30.2k
                mat.xx = (double)(fixed2float(ix1 - ix0)/width);
362
30.2k
            } else if (mat.xx < 0) {
363
12
                fixed ix0 = int2fixed(fixed2int_ceiling(float2fixed(mat.tx)));
364
12
                double x1 = mat.tx + mat.xx * width;
365
12
                fixed ix1 = int2fixed(fixed2int(float2fixed(x1)));
366
12
                mat.tx = (double)fixed2float(ix0);
367
12
                mat.xx = (double)(fixed2float(ix1 - ix0)/width);
368
12
            }
369
30.3k
        }
370
33.0k
        if (height == 1 || gridfitimages) {
371
30.3k
            if (mat.yy > 0) {
372
30.2k
                fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty)));
373
30.2k
                double y1 = mat.ty + mat.yy * height;
374
30.2k
                fixed iy1 = int2fixed(fixed2int_ceiling(float2fixed(y1)));
375
30.2k
                mat.ty = (double)fixed2float(iy0);
376
30.2k
                mat.yy = (double)(fixed2float(iy1 - iy0)/height);
377
30.2k
            } else if (mat.yy < 0) {
378
52
                fixed iy0 = int2fixed(fixed2int_ceiling(float2fixed(mat.ty)));
379
52
                double y1 = mat.ty + mat.yy * height;
380
52
                fixed iy1 = int2fixed(fixed2int(float2fixed(y1)));
381
52
                mat.ty = (double)fixed2float(iy0);
382
52
                mat.yy = ((double)fixed2float(iy1 - iy0)/height);
383
52
            }
384
30.3k
        }
385
33.0k
    } else if (orthogonal == 2) {
386
7.35k
        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
7.35k
        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
7.35k
    }
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
123k
    if (in_pattern_accumulator) {
422
51
        double ome = ((double)(fixed_1 - fixed_epsilon)) / (double)fixed_1; /* One Minus Epsilon */
423
424
51
        if (orthogonal == 1) {
425
51
            if ((mat.xx > -ome && mat.xx < ome) || (mat.yy > -ome && mat.yy < ome)) {
426
41
                force_interpolation = true;
427
41
            }
428
51
        } 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
51
    }
434
435
    /* Can we restrict the amount of image we need? */
436
123k
    while (!pim->imagematrices_are_untrustworthy) /* So we can break out of it */
437
123k
    {
438
123k
        gs_rect rect, rect_src;
439
123k
        gs_matrix mi;
440
123k
        const gs_matrix *m = pgs != NULL ? &ctm_only(pgs) : NULL;
441
123k
        gs_int_rect irect;
442
123k
        if (m == NULL || (code = gs_matrix_invert(m, &mi)) < 0 ||
443
123k
            (code = gs_matrix_multiply(&mi, &pic->ImageMatrix, &mi)) < 0) {
444
            /* Give up trying to shrink the render box, but continue processing */
445
190
            break;
446
190
        }
447
123k
        if (pcpath)
448
32.3k
        {
449
32.3k
            gs_fixed_rect obox;
450
32.3k
            gx_cpath_outer_box(pcpath, &obox);
451
32.3k
            rect.p.x = fixed2float(obox.p.x);
452
32.3k
            rect.p.y = fixed2float(obox.p.y);
453
32.3k
            rect.q.x = fixed2float(obox.q.x);
454
32.3k
            rect.q.y = fixed2float(obox.q.y);
455
32.3k
        }
456
91.1k
        else
457
91.1k
        {
458
91.1k
            rect.p.x = 0;
459
91.1k
            rect.p.y = 0;
460
91.1k
            rect.q.x = dev->width;
461
91.1k
            rect.q.y = dev->height;
462
91.1k
        }
463
        /* rect is in destination space. Calculate rect_src, in source space. */
464
123k
        code = gs_bbox_transform(&rect, &mi, &rect_src);
465
123k
        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
123k
        if (pim->Interpolate)
475
0
        {
476
0
            float support = any_abs(mi.xx);
477
0
            int isupport;
478
0
            if (any_abs(mi.yy) > support)
479
0
                support = any_abs(mi.yy);
480
0
            if (any_abs(mi.xy) > support)
481
0
                support = any_abs(mi.xy);
482
0
            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
0
            isupport = 2; /* Mitchell support. */
489
0
            if (support > 1)
490
0
                isupport = (int)ceil(isupport * support);
491
0
            rect_src.p.x -= isupport;
492
0
            rect_src.p.y -= isupport;
493
0
            rect_src.q.x += isupport;
494
0
            rect_src.q.y += isupport+1; /* +1 is a fudge! */
495
0
        }
496
123k
        irect.p.x = (int)floor(rect_src.p.x);
497
123k
        irect.p.y = (int)floor(rect_src.p.y);
498
123k
        irect.q.x = (int)ceil(rect_src.q.x);
499
123k
        irect.q.y = (int)ceil(rect_src.q.y);
500
        /* We therefore only need to render within irect. Restrict rrect to this. */
501
123k
        if (penum->rrect.x < irect.p.x) {
502
723
            penum->rrect.w -= irect.p.x - penum->rrect.x;
503
723
            if (penum->rrect.w < 0)
504
495
               penum->rrect.w = 0;
505
723
            penum->rrect.x = irect.p.x;
506
723
        }
507
123k
        if (penum->rrect.x + penum->rrect.w > irect.q.x) {
508
1.69k
            penum->rrect.w = irect.q.x - penum->rrect.x;
509
1.69k
            if (penum->rrect.w < 0)
510
1.27k
                penum->rrect.w = 0;
511
1.69k
        }
512
123k
        if (penum->rrect.y < irect.p.y) {
513
8.18k
            penum->rrect.h -= irect.p.y - penum->rrect.y;
514
8.18k
            if (penum->rrect.h < 0)
515
267
                penum->rrect.h = 0;
516
8.18k
            penum->rrect.y = irect.p.y;
517
8.18k
        }
518
123k
        if (penum->rrect.y + penum->rrect.h > irect.q.y) {
519
8.53k
            penum->rrect.h = irect.q.y - penum->rrect.y;
520
8.53k
            if (penum->rrect.h < 0)
521
848
                penum->rrect.h = 0;
522
8.53k
        }
523
123k
        if (penum->drect.x < irect.p.x) {
524
723
            penum->drect.w -= irect.p.x - penum->drect.x;
525
723
            if (penum->drect.w < 0)
526
495
               penum->drect.w = 0;
527
723
            penum->drect.x = irect.p.x;
528
723
        }
529
123k
        if (penum->drect.x + penum->drect.w > irect.q.x) {
530
1.69k
            penum->drect.w = irect.q.x - penum->drect.x;
531
1.69k
            if (penum->drect.w < 0)
532
1.27k
                penum->drect.w = 0;
533
1.69k
        }
534
123k
        if (penum->drect.y < irect.p.y) {
535
8.18k
            penum->drect.h -= irect.p.y - penum->drect.y;
536
8.18k
            if (penum->drect.h < 0)
537
267
                penum->drect.h = 0;
538
8.18k
            penum->drect.y = irect.p.y;
539
8.18k
        }
540
123k
        if (penum->drect.y + penum->drect.h > irect.q.y) {
541
8.53k
            penum->drect.h = irect.q.y - penum->drect.y;
542
8.53k
            if (penum->drect.h < 0)
543
848
                penum->drect.h = 0;
544
8.53k
        }
545
123k
        break; /* Out of the while */
546
123k
    }
547
    /* Check for the intersection being null */
548
123k
    if (penum->drect.x + penum->drect.w <= penum->rect.x  ||
549
123k
        penum->rect.x  + penum->rect.w  <= penum->drect.x ||
550
123k
        penum->drect.y + penum->drect.h <= penum->rect.y  ||
551
123k
        penum->rect.y  + penum->rect.h  <= penum->drect.y)
552
2.04k
    {
553
          /* Something may have gone wrong with the floating point above.
554
           * set the region to something sane. */
555
2.04k
        penum->drect.x = penum->rect.x;
556
2.04k
        penum->drect.y = penum->rect.y;
557
2.04k
        penum->drect.w = 0;
558
2.04k
        penum->drect.h = 0;
559
2.04k
    }
560
123k
    if (penum->rrect.x + penum->rrect.w <= penum->drect.x  ||
561
123k
        penum->drect.x + penum->drect.w  <= penum->rrect.x ||
562
123k
        penum->rrect.y + penum->rrect.h <= penum->drect.y  ||
563
123k
        penum->drect.y + penum->drect.h  <= penum->rrect.y)
564
2.04k
    {
565
          /* Something may have gone wrong with the floating point above.
566
           * set the region to something sane. */
567
2.04k
        penum->rrect.x = penum->drect.x;
568
2.04k
        penum->rrect.y = penum->drect.y;
569
2.04k
        penum->rrect.w = 0;
570
2.04k
        penum->rrect.h = 0;
571
2.04k
    }
572
573
    /*penum->matrix = mat;*/
574
123k
    penum->matrix.xx = mat.xx;
575
123k
    penum->matrix.xy = mat.xy;
576
123k
    penum->matrix.yx = mat.yx;
577
123k
    penum->matrix.yy = mat.yy;
578
123k
    penum->matrix.tx = mat.tx;
579
123k
    penum->matrix.ty = mat.ty;
580
123k
    if_debug6m('b', mem, " [%g %g %g %g %g %g]\n",
581
123k
              mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
582
    /* following works for 1, 2, 4, 8, 12, 16 */
583
123k
    index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
584
    /*
585
     * Compute extents with distance transformation.
586
     */
587
123k
    if (mat.tx > 0)
588
106k
        mtx = float2fixed(mat.tx);
589
16.7k
    else { /* Use positive values to ensure round down. */
590
16.7k
        int f = (int)-mat.tx + 1;
591
592
16.7k
        mtx = float2fixed(mat.tx + f) - int2fixed(f);
593
16.7k
    }
594
123k
    if (mat.ty > 0)
595
24.8k
        mty = float2fixed(mat.ty);
596
98.9k
    else {  /* Use positive values to ensure round down. */
597
98.9k
        int f = (int)-mat.ty + 1;
598
599
98.9k
        mty = float2fixed(mat.ty + f) - int2fixed(f);
600
98.9k
    }
601
602
123k
    row_extent.x = float2fixed_rounded_boxed(width * mat.xx);
603
123k
    row_extent.y =
604
123k
        (is_fzero(mat.xy) ? fixed_0 :
605
123k
         float2fixed_rounded_boxed(width * mat.xy));
606
123k
    col_extent.x =
607
123k
        (is_fzero(mat.yx) ? fixed_0 :
608
123k
         float2fixed_rounded_boxed(height * mat.yx));
609
123k
    col_extent.y = float2fixed_rounded_boxed(height * mat.yy);
610
123k
    gx_image_enum_common_init((gx_image_enum_common_t *)penum,
611
123k
                              (const gs_data_image_t *)pim,
612
123k
                              &image1_enum_procs, dev,
613
123k
                              (masked ? 1 : (penum->alpha ? cs_num_components(pcs)+1 : cs_num_components(pcs))),
614
123k
                              format);
615
123k
    if (penum->rect.w == width && penum->rect.h == height) {
616
89.0k
        x_extent = row_extent;
617
89.0k
        y_extent = col_extent;
618
89.0k
    } else {
619
34.7k
        int rw = penum->rect.w, rh = penum->rect.h;
620
621
34.7k
        x_extent.x = float2fixed_rounded_boxed(rw * mat.xx);
622
34.7k
        x_extent.y =
623
34.7k
            (is_fzero(mat.xy) ? fixed_0 :
624
34.7k
             float2fixed_rounded_boxed(rw * mat.xy));
625
34.7k
        y_extent.x =
626
34.7k
            (is_fzero(mat.yx) ? fixed_0 :
627
34.7k
             float2fixed_rounded_boxed(rh * mat.yx));
628
34.7k
        y_extent.y = float2fixed_rounded_boxed(rh * mat.yy);
629
34.7k
    }
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
123k
    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
79.3k
        penum->clues = (gx_image_clue*) gs_alloc_bytes(mem, sizeof(gx_image_clue)*256,
638
79.3k
                             "gx_image_enum_begin");
639
79.3k
        if (penum->clues == NULL) {
640
0
            code = gs_error_VMerror;
641
0
            goto fail;
642
0
        }
643
79.3k
        penum->icolor0 = &(penum->clues[0].dev_color);
644
79.3k
        penum->icolor1 = &(penum->clues[255].dev_color);
645
79.3k
    } else {
646
44.4k
        penum->icolor0 = &(penum->icolor0_val);
647
44.4k
        penum->icolor1 = &(penum->icolor1_val);
648
44.4k
    }
649
123k
    penum->icolor0->tag = penum->icolor1->tag = device_current_tag(dev);
650
651
123k
    if (masked) {       /* This is imagemask. */
652
13.0k
        if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
653
1
            code = gs_error_rangecheck;
654
1
            goto fail;
655
1
        }
656
        /* Initialize color entries 0 and 255. */
657
13.0k
        set_nonclient_dev_color(penum->icolor0, gx_no_color_index);
658
13.0k
        set_nonclient_dev_color(penum->icolor1, gx_no_color_index);
659
13.0k
        *(penum->icolor1) = *pdcolor;
660
13.0k
        memcpy(&penum->map[0].table.lookup4x1to32[0],
661
13.0k
               (decode[0] < decode[1] ? lookup4x1to32_inverted :
662
13.0k
                lookup4x1to32_identity),
663
13.0k
               16 * 4);
664
13.0k
        penum->map[0].decoding = sd_none;
665
13.0k
        spp = 1;
666
13.0k
        lop = rop3_know_S_0(lop);
667
110k
    } else {                    /* This is image, not imagemask. */
668
110k
        const gs_color_space_type *pcst = pcs->type;
669
110k
        int b_w_color;
670
671
110k
        spp = cs_num_components(pcs);
672
110k
        if (spp < 0) {          /* Pattern not allowed */
673
0
            code = gs_error_rangecheck;
674
0
            goto fail;
675
0
        }
676
110k
        if (penum->alpha)
677
0
            ++spp;
678
        /* Use a less expensive format if possible. */
679
110k
        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
0
        case gs_image_format_component_planar:
685
0
            if (spp == 1)
686
0
                format = gs_image_format_chunky;
687
110k
        default:                /* chunky */
688
110k
            break;
689
110k
        }
690
691
110k
        if (pcs->cmm_icc_profile_data != NULL) {
692
108k
            device_color = false;
693
108k
        } else {
694
2.23k
            device_color = (*pcst->concrete_space) (pcs, pgs) == pcs;
695
2.23k
        }
696
697
110k
        code = image_init_colors(penum, bps, spp, format, decode, pgs, dev,
698
110k
                          pcs, &device_color);
699
110k
        if (code < 0) {
700
0
            gs_free_object(mem, penum->clues, "gx_image_enum_begin");
701
0
            gs_free_object(mem, penum, "gx_default_begin_image");
702
0
            return gs_throw(code, "Image colors initialization failed");
703
0
        }
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
110k
        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
110k
        if (!pim->CombineWithColor)
725
110k
            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
110k
        if (lop != rop3_S &&    /* if best case, no more work needed */
730
110k
            !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
731
110k
            (b_w_color =
732
0
             color_draws_b_w(dev, penum->icolor0)) >= 0 &&
733
110k
            color_draws_b_w(dev, penum->icolor1) == (b_w_color ^ 1)
734
110k
            ) {
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
110k
    }
777
123k
    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
123k
    bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
784
123k
    buffer = gs_alloc_bytes(mem, bsize, "image buffer");
785
123k
    if (buffer == 0) {
786
1
        code = gs_error_VMerror;
787
1
        goto fail;
788
1
    }
789
123k
    penum->bps = bps;
790
123k
    penum->unpack_bps = bps;
791
123k
    penum->log2_xbytes = log2_xbytes;
792
123k
    penum->spp = spp;
793
123k
    switch (format) {
794
123k
    case gs_image_format_chunky:
795
123k
        nplanes = 1;
796
123k
        spread = 1 << log2_xbytes;
797
123k
        break;
798
0
    case gs_image_format_component_planar:
799
0
        nplanes = spp;
800
0
        spread = spp << log2_xbytes;
801
0
        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
123k
    }
810
123k
    penum->num_planes = nplanes;
811
123k
    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
123k
    penum->interpolate = force_interpolation ? interp_force : pim->Interpolate ? interp_on : interp_off;
819
123k
    penum->x_extent = x_extent;
820
123k
    penum->y_extent = y_extent;
821
123k
    penum->posture =
822
123k
        ((x_extent.y | y_extent.x) == 0 ? image_portrait :
823
123k
         (x_extent.x | y_extent.y) == 0 ? image_landscape :
824
7.59k
         image_skewed);
825
123k
    penum->pgs = pgs;
826
123k
    if (pgs != NULL)
827
123k
        penum->pgs_level = pgs->level;
828
123k
    penum->pcs = pcs;
829
123k
    rc_increment_cs(pcs); /* Grab a ref (will decrement in gx_image1_end_image() */
830
123k
    penum->memory = mem;
831
123k
    penum->buffer = buffer;
832
123k
    penum->buffer_size = bsize;
833
123k
    penum->line = NULL;
834
123k
    penum->icc_link = NULL;
835
123k
    penum->color_cache = NULL;
836
123k
    penum->ht_buffer = NULL;
837
123k
    penum->thresh_buffer = NULL;
838
123k
    penum->use_cie_range = false;
839
123k
    penum->line_size = 0;
840
123k
    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
123k
    penum->slow_loop = 0;
854
123k
    if (pcpath == 0) {
855
91.2k
        (*dev_proc(dev, get_clipping_box)) (dev, &obox);
856
91.2k
        cbox = obox;
857
91.2k
        penum->clip_image = 0;
858
91.2k
    } else
859
32.5k
        penum->clip_image =
860
32.5k
            (gx_cpath_outer_box(pcpath, &obox) |        /* not || */
861
32.5k
             gx_cpath_inner_box(pcpath, &cbox) ?
862
32.3k
             0 : image_clip_region);
863
123k
    penum->clip_outer = obox;
864
123k
    penum->clip_inner = cbox;
865
123k
    penum->log_op = rop3_T;     /* rop device takes care of this */
866
123k
    penum->clip_dev = 0;        /* in case we bail out */
867
123k
    penum->rop_dev = 0;         /* ditto */
868
123k
    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
123k
    {
876
123k
        fixed
877
123k
            epx = min(row_extent.x, 0) + min(col_extent.x, 0),
878
123k
            eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
879
123k
            epy = min(row_extent.y, 0) + min(col_extent.y, 0),
880
123k
            eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
881
882
123k
        {
883
123k
            int hwx, hwy;
884
885
123k
            switch (penum->posture) {
886
116k
                case image_portrait:
887
116k
                    hwx = width, hwy = height;
888
116k
                    break;
889
7.42k
                case image_landscape:
890
7.42k
                    hwx = height, hwy = width;
891
7.42k
                    break;
892
173
                default:
893
173
                    hwx = hwy = 0;
894
123k
            }
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
123k
            if (hwx == 1 && eqx - epx < fixed_1) {
905
1
                fixed diff =
906
1
                arith_rshift_1(row_extent.x + col_extent.x);
907
908
1
                mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
909
1
            }
910
123k
            if (hwy == 1 && eqy - epy < fixed_1) {
911
1
                fixed diff =
912
1
                arith_rshift_1(row_extent.y + col_extent.y);
913
914
1
                mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
915
1
            }
916
123k
        }
917
123k
        if_debug5m('b', mem, "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
918
123k
                   (masked? "masked, " : ""), spp, bps,
919
123k
                   fixed2float(mtx), fixed2float(mty));
920
123k
        if_debug9m('b', mem,
921
123k
                   "[b]   cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
922
123k
                   fixed2float(cbox.p.x), fixed2float(cbox.p.y),
923
123k
                   fixed2float(cbox.q.x), fixed2float(cbox.q.y),
924
123k
                   fixed2float(obox.p.x), fixed2float(obox.p.y),
925
123k
                   fixed2float(obox.q.x), fixed2float(obox.q.y),
926
123k
                   penum->clip_image);
927
        /* These DDAs enumerate the starting position of each source pixel
928
         * row in device space. */
929
123k
        dda_init(penum->dda.row.x, mtx, col_extent.x, height);
930
123k
        dda_init(penum->dda.row.y, mty, col_extent.y, height);
931
123k
        if (dda_will_overflow(penum->dda.row.x) ||
932
123k
            dda_will_overflow(penum->dda.row.y))
933
0
        {
934
0
            code = gs_error_rangecheck;
935
0
            goto fail;
936
0
        }
937
123k
        if (penum->posture == image_portrait) {
938
116k
            penum->dst_width = row_extent.x;
939
116k
            penum->dst_height = col_extent.y;
940
116k
        } else {
941
7.59k
            penum->dst_width = col_extent.x;
942
7.59k
            penum->dst_height = row_extent.y;
943
7.59k
        }
944
        /* For gs_image_class_0_interpolate. */
945
123k
        penum->yi0 = fixed2int_pixround_perfect(dda_current(penum->dda.row.y)); /* For gs_image_class_0_interpolate. */
946
123k
        if (penum->rect.y) {
947
30.9k
            int y = penum->rect.y;
948
949
3.96M
            while (y--) {
950
3.93M
                dda_next(penum->dda.row.x);
951
3.93M
                dda_next(penum->dda.row.y);
952
3.93M
            }
953
30.9k
        }
954
123k
        penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
955
123k
        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
123k
        dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
960
123k
        dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
961
123k
        if (dda_will_overflow(penum->dda.strip.x) ||
962
123k
            dda_will_overflow(penum->dda.strip.y))
963
0
        {
964
0
            code = gs_error_rangecheck;
965
0
            goto fail;
966
0
        }
967
123k
        if (penum->rect.x) {
968
75
            dda_advance(penum->dda.strip.x, penum->rect.x);
969
75
            dda_advance(penum->dda.strip.y, penum->rect.x);
970
75
        }
971
123k
        {
972
123k
            fixed ox = dda_current(penum->dda.strip.x);
973
123k
            fixed oy = dda_current(penum->dda.strip.y);
974
975
123k
            if (!penum->clip_image)     /* i.e., not clip region */
976
123k
                penum->clip_image =
977
123k
                    (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
978
122k
                     image_clip_xmin : 0) +
979
123k
                    (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
980
92.3k
                     image_clip_xmax : 0) +
981
123k
                    (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
982
93.4k
                     image_clip_ymin : 0) +
983
123k
                    (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
984
103k
                     image_clip_ymax : 0);
985
123k
        }
986
123k
    }
987
0
    penum->y = 0;
988
123k
    penum->used.x = 0;
989
123k
    penum->used.y = 0;
990
123k
    if (penum->clip_image && pcpath) {  /* Set up the clipping device. */
991
21.6k
        gx_device_clip *cdev =
992
21.6k
            gs_alloc_struct(mem, gx_device_clip,
993
21.6k
                            &st_device_clip, "image clipper");
994
995
21.6k
        if (cdev == NULL) {
996
0
            code = gs_error_VMerror;
997
0
            goto fail;
998
0
        }
999
21.6k
        gx_make_clip_device_in_heap(cdev, pcpath, dev, mem);
1000
21.6k
        penum->clip_dev = cdev;
1001
21.6k
        penum->dev = (gx_device *)cdev; /* Will restore this in a mo. Hacky! */
1002
21.6k
    }
1003
123k
    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
123k
    {
1023
123k
        static sample_unpack_proc_t procs[2][6] = {
1024
123k
        {   sample_unpack_1, sample_unpack_2,
1025
123k
            sample_unpack_4, sample_unpack_8,
1026
123k
            sample_unpack_12, sample_unpack_16
1027
123k
        },
1028
123k
        {   sample_unpack_1_interleaved, sample_unpack_2_interleaved,
1029
123k
            sample_unpack_4_interleaved, sample_unpack_8_interleaved,
1030
123k
            sample_unpack_12, sample_unpack_16
1031
123k
        }};
1032
123k
        int num_planes = penum->num_planes;
1033
123k
        bool interleaved = (num_planes == 1 && penum->plane_depths[0] != penum->bps);
1034
123k
        irender_proc_t render_fn = NULL;
1035
123k
        int i;
1036
1037
123k
        if (interleaved) {
1038
44.4k
            int num_components = penum->plane_depths[0] / penum->bps;
1039
1040
136k
            for (i = 1; i < num_components; i++) {
1041
92.1k
                if (decode[0] != decode[i * 2 + 0] ||
1042
92.1k
                    decode[1] != decode[i * 2 + 1])
1043
0
                    break;
1044
92.1k
            }
1045
44.4k
            if (i == num_components)
1046
44.4k
                interleaved = false; /* Use single table. */
1047
44.4k
        }
1048
123k
        penum->unpack = procs[interleaved][index_bps];
1049
1050
123k
        if_debug1m('b', mem, "[b]unpack=%d\n", bps);
1051
        /* Set up pixel0 for image class procedures. */
1052
123k
        penum->dda.pixel0 = penum->dda.strip;
1053
123k
        penum->skip_next_line = NULL;
1054
510k
        for (i = 0; i < gx_image_class_table_count; ++i) {
1055
510k
            code = gx_image_class_table[i](penum, &render_fn);
1056
510k
            if (code < 0)
1057
0
                goto fail;
1058
1059
510k
            if (render_fn != NULL) {
1060
123k
                penum->render = render_fn;
1061
123k
                break;
1062
123k
            }
1063
510k
        }
1064
123k
        penum->dev = dev; /* Restore this (in case it was changed to cdev or rtdev) */
1065
123k
        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
123k
    }
1070
123k
    return 0;
1071
1072
2
fail:
1073
2
    gs_free_object(mem, buffer, "image buffer");
1074
2
    gs_free_object(mem, penum->clues, "gx_image_enum_begin");
1075
2
    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
2
    gs_free_object(mem, penum->clip_dev, "image clipper");
1080
2
    rc_decrement_cs(penum->pcs, "error in gx_begin_image1");
1081
2
    penum->pcs = NULL;
1082
2
    gs_free_object(mem, penum, "gx_begin_image1");
1083
2
    return code;
1084
123k
}
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
44.1k
{
1158
44.1k
    int num_des_comp = penum->dev->color_info.num_components;
1159
44.1k
    int num_src_comp;
1160
44.1k
    int num_entries = 1 << bps;
1161
44.1k
    bool need_decode = penum->icc_setup.need_decode;
1162
44.1k
    bool has_transfer = penum->icc_setup.has_transfer;
1163
44.1k
    byte value;
1164
44.1k
    bool decode_scale = true;
1165
44.1k
    int k, kk;
1166
44.1k
    byte psrc[4];
1167
44.1k
    byte *temp_buffer;
1168
44.1k
    byte *byte_ptr;
1169
44.1k
    bool is_indexed = (gs_color_space_get_index(penum->pcs) ==
1170
44.1k
                                            gs_color_space_index_Indexed);
1171
44.1k
    bool free_temp_buffer = true;
1172
44.1k
    gsicc_bufferdesc_t input_buff_desc;
1173
44.1k
    gsicc_bufferdesc_t output_buff_desc;
1174
44.1k
    gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
1175
44.1k
    int code;
1176
1177
44.1k
    if (penum->icc_link == NULL) {
1178
0
        return gs_rethrow(-1, "ICC Link not created during image render color");
1179
0
    }
1180
44.1k
    if (is_indexed) {
1181
914
        num_src_comp = gs_color_space_num_components(penum->pcs->base_space);
1182
43.2k
    } 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
43.2k
        if (penum->icc_link->is_identity && !need_decode && !has_transfer) {
1187
43.2k
            return 0;
1188
43.2k
        }
1189
25
        num_src_comp = 1;
1190
25
    }
1191
    /* Allocate cache of device contone values */
1192
939
    penum->color_cache = gs_alloc_struct(penum->memory, gx_image_color_cache_t,
1193
939
                                         &st_color_cache,
1194
939
                                         "image_init_color_cache");
1195
939
    if (penum->color_cache == NULL)
1196
0
        return_error(gs_error_VMerror);
1197
1198
939
    penum->color_cache->device_contone = (byte*) gs_alloc_bytes(penum->memory,
1199
939
                   num_des_comp * num_entries * sizeof(byte), "image_init_color_cache");
1200
939
    penum->color_cache->is_transparent = (bool*) gs_alloc_bytes(penum->memory,
1201
939
             num_entries * sizeof(bool), "image_init_color_cache");
1202
939
    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
939
    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
939
    if (need_decode) {
1220
0
        decode_scale = decode_range_needed(penum);
1221
0
    }
1222
939
    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
939
    } 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
939
        temp_buffer = (byte*) gs_alloc_bytes(penum->memory,
1268
939
                                             (size_t)num_entries * num_src_comp,
1269
939
                                             "image_init_color_cache");
1270
939
        if (temp_buffer == NULL)
1271
0
            return_error(gs_error_VMerror);
1272
1273
939
        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
939
        } else {
1288
            /* No Decode */
1289
939
            if (is_indexed) {
1290
                /* If index uses a num_entries sized table then just use its pointer */
1291
914
                if (penum->pcs->params.indexed.use_proc ||
1292
914
                    penum->pcs->params.indexed.hival < (num_entries - 1)) {
1293
                    /* Have to do the slow way */
1294
3.33k
                    for (k = 0; k <= penum->pcs->params.indexed.hival; k++) {
1295
3.23k
                        gs_cspace_indexed_lookup_bytes(penum->pcs, (float)k, psrc);
1296
3.23k
                        memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1297
3.23k
                    }
1298
                    /* just use psrc results from converting 'hival' to fill the remaining slots */
1299
21.6k
                    for (; k < num_entries; k++) {
1300
21.5k
                        memcpy(&(temp_buffer[k * num_src_comp]), psrc, num_src_comp);
1301
21.5k
                    }
1302
817
                } else {
1303
                    /* Use the index table directly. */
1304
817
                    gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1305
817
                    free_temp_buffer = false;
1306
817
                    temp_buffer = (byte *)(penum->pcs->params.indexed.lookup.table.data);
1307
817
                }
1308
914
            } else {
1309
                /* CM only */
1310
6.42k
                for (k = 0; k < num_entries; k++) {
1311
6.40k
                    temp_buffer[k] = k;
1312
6.40k
                }
1313
25
            }
1314
939
        }
1315
        /* Set up the buffer descriptors. */
1316
939
        gsicc_init_buffer(&input_buff_desc, num_src_comp, 1, false, false, false,
1317
939
                          0, num_entries * num_src_comp, 1, num_entries);
1318
939
        gsicc_init_buffer(&output_buff_desc, num_des_comp, 1, false, false, false,
1319
939
                          0, num_entries * num_des_comp,
1320
939
                      1, num_entries);
1321
939
        code = (penum->icc_link->procs.map_buffer)(penum->dev, penum->icc_link,
1322
939
                                            &input_buff_desc, &output_buff_desc,
1323
939
                                            (void*) temp_buffer,
1324
939
                                            (void*) penum->color_cache->device_contone);
1325
939
        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
939
        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
939
        if (free_temp_buffer)
1343
122
            gs_free_object(penum->memory, temp_buffer, "image_init_color_cache");
1344
939
    }
1345
939
    return 0;
1346
939
}
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
87.1k
{
1352
    /* Initialize the color table */
1353
87.1k
#define ictype(i)\
1354
87.1k
  penum->clues[i].dev_color.type
1355
1356
87.1k
    switch ((spp == 1 ? bps : 8)) {
1357
85.3k
        case 8:         /* includes all color images */
1358
85.3k
            {
1359
85.3k
                register gx_image_clue *pcht = &penum->clues[0];
1360
85.3k
                register int n = 64;    /* 8 bits means 256 clues, do   */
1361
                                        /* 4 at a time for efficiency   */
1362
5.45M
                do {
1363
5.45M
                    pcht[0].dev_color.type =
1364
5.45M
                        pcht[1].dev_color.type =
1365
5.45M
                        pcht[2].dev_color.type =
1366
5.45M
                        pcht[3].dev_color.type =
1367
5.45M
                        gx_dc_type_none;
1368
5.45M
                    pcht[0].key = pcht[1].key =
1369
5.45M
                        pcht[2].key = pcht[3].key = 0;
1370
5.45M
                    pcht += 4;
1371
5.45M
                }
1372
5.45M
                while (--n > 0);
1373
85.3k
                penum->clues[0].key = 1;        /* guarantee no hit */
1374
85.3k
                break;
1375
0
            }
1376
44
        case 4:
1377
44
            ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
1378
44
                ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
1379
44
                ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
1380
44
                ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
1381
44
                gx_dc_type_none;
1382
            /* falls through */
1383
208
        case 2:
1384
208
            ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
1385
87.1k
#undef ictype
1386
87.1k
    }
1387
87.1k
}
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
110k
{
1396
110k
    int ci, decode_type, code;
1397
110k
    static const float default_decode[] = {
1398
110k
        0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
1399
110k
    };
1400
1401
    /* Clues are only used with image_mono_render */
1402
110k
    if (spp == 1) {
1403
66.2k
        image_init_clues(penum, bps, spp);
1404
66.2k
    }
1405
110k
    decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */
1406
265k
    for (ci = 0; ci < spp; ci +=2 ) {
1407
155k
        decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) |
1408
155k
                       (decode[ci] == 1. && decode[ci + 1] == 0.) << 1;
1409
155k
    }
1410
1411
    /* Initialize the maps from samples to intensities. */
1412
313k
    for (ci = 0; ci < spp; ci++) {
1413
202k
        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
202k
        const float *this_decode = &decode[ci * 2];
1420
202k
        const float *map_decode;        /* decoding used to */
1421
                                        /* construct the expansion map */
1422
202k
        const float *real_decode;       /* decoding for expanded samples */
1423
1424
202k
        map_decode = real_decode = this_decode;
1425
202k
        if (!(decode_type & 1)) {
1426
1.08k
            if ((decode_type & 2) && bps <= 8) {
1427
34
                real_decode = default_decode;
1428
1.04k
            } else {
1429
1.04k
                *pdcb = false;
1430
1.04k
                map_decode = default_decode;
1431
1.04k
            }
1432
1.08k
        }
1433
202k
        if (bps > 2 || format != gs_image_format_chunky) {
1434
201k
            if (bps <= 8)
1435
201k
                image_init_map(&pmap->table.lookup8[0], 1 << bps,
1436
201k
                               map_decode);
1437
201k
        } else {                /* The map index encompasses more than one pixel. */
1438
1.54k
            byte map[4];
1439
1.54k
            register int i;
1440
1441
1.54k
            image_init_map(&map[0], 1 << bps, map_decode);
1442
1.54k
            switch (bps) {
1443
1.46k
                case 1:
1444
1.46k
                    {
1445
1.46k
                        register bits32 *p = &pmap->table.lookup4x1to32[0];
1446
1447
1.46k
                        if (map[0] == 0 && map[1] == 0xff)
1448
1.46k
                            memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
1449
2
                        else if (map[0] == 0xff && map[1] == 0)
1450
2
                            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
1.46k
                    }
1458
1.46k
                    break;
1459
82
                case 2:
1460
82
                    {
1461
82
                        register bits16 *p = &pmap->table.lookup2x2to16[0];
1462
1463
1.39k
                        for (i = 0; i < 16; i++, p++)
1464
1.31k
                            ((byte *) p)[0] = map[i >> 2],
1465
1.31k
                                ((byte *) p)[1] = map[i & 3];
1466
82
                    }
1467
82
                    break;
1468
1.54k
            }
1469
1.54k
        }
1470
202k
        pmap->decode_base /* = decode_lookup[0] */  = real_decode[0];
1471
202k
        pmap->decode_factor =
1472
202k
            (real_decode[1] - real_decode[0]) /
1473
202k
            (bps <= 8 ? 255.0 : (float)frac_1);
1474
202k
        pmap->decode_max /* = decode_lookup[15] */  = real_decode[1];
1475
202k
        if (decode_type) {
1476
201k
            pmap->decoding = sd_none;
1477
201k
            pmap->inverted = map_decode[0] != 0;
1478
201k
        } else if (bps <= 4) {
1479
81
            int step = 15 / ((1 << bps) - 1);
1480
81
            int i;
1481
1482
81
            pmap->decoding = sd_lookup;
1483
255
            for (i = 15 - step; i > 0; i -= step)
1484
174
                pmap->decode_lookup[i] = pmap->decode_base +
1485
174
                    i * (255.0 / 15) * pmap->decode_factor;
1486
81
            pmap->inverted = 0;
1487
966
        } else {
1488
966
            pmap->decoding = sd_compute;
1489
966
            pmap->inverted = 0;
1490
966
        }
1491
202k
        if (spp == 1) {         /* and ci == 0 *//* Pre-map entries 0 and 255. */
1492
66.2k
            gs_client_color cc;
1493
1494
            /* Image clues are used in this case */
1495
66.2k
            cc.paint.values[0] = real_decode[0];
1496
66.2k
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0,
1497
66.2k
                                       pgs, dev, gs_color_select_source);
1498
66.2k
            if (code < 0)
1499
0
                return code;
1500
66.2k
            cc.paint.values[0] = real_decode[1];
1501
66.2k
            code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1,
1502
66.2k
                                       pgs, dev, gs_color_select_source);
1503
66.2k
            if (code < 0)
1504
0
                return code;
1505
66.2k
        }
1506
202k
    }
1507
110k
    return 0;
1508
110k
}
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
202k
{
1515
202k
    float min_v = decode[0];
1516
202k
    float diff_v = decode[1] - min_v;
1517
1518
202k
    if (diff_v == 1 || diff_v == -1) {  /* We can do the stepping with integers, without overflow. */
1519
202k
        byte *limit = map + map_size;
1520
202k
        uint value = (uint)(min_v * 0xffffL);
1521
202k
        int diff = (int)(diff_v * (0xffffL / (map_size - 1)));
1522
1523
51.7M
        for (; map != limit; map++, value += diff)
1524
51.5M
            *map = value >> 8;
1525
202k
    } 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
202k
}
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
57
{
1544
57
    uint scale = 255 / ((1 << penum->bps) - 1);
1545
57
    uint *values = &penum->mask_color.values[component_index * 2];
1546
57
    uint v0 = values[0] *= scale;
1547
57
    uint v1 = values[1] *= scale;
1548
1549
57
    if (penum->map[component_index].decoding == sd_none &&
1550
57
        penum->map[component_index].inverted
1551
57
        ) {
1552
0
        values[0] = 255 - v1;
1553
0
        values[1] = 255 - v0;
1554
0
    }
1555
57
}
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
47.4k
{
1561
47.4k
    int k;
1562
1563
47.4k
    for (k = 0; k < num_comps; k++) {
1564
47.4k
        if (pgs->effective_transfer[k]->proc != gs_identity_transfer) {
1565
47.4k
            return(true);
1566
47.4k
        }
1567
47.4k
    }
1568
0
    return(false);
1569
47.4k
}