Coverage Report

Created: 2026-08-08 08:00

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