Coverage Report

Created: 2022-10-31 07:00

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