Coverage Report

Created: 2025-06-10 06:58

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