Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gxipixel.c,v 1.12 2005/07/21 19:32:06 alexcher Exp $ */
18
/* Common code for ImageType 1 and 4 initialization */
19
#include "gx.h"
20
#include "math_.h"
21
#include "memory_.h"
22
#include "gpcheck.h"
23
#include "gscdefs.h"		/* for image class table */
24
#include "gserrors.h"
25
#include "gsstruct.h"
26
#include "gsutil.h"
27
#include "gxfixed.h"
28
#include "gxfrac.h"
29
#include "gxarith.h"
30
#include "gxmatrix.h"
31
#include "gsccolor.h"
32
#include "gspaint.h"
33
#include "gzstate.h"
34
#include "gxdevice.h"
35
#include "gzpath.h"
36
#include "gzcpath.h"
37
#include "gxdevmem.h"
38
#include "gximage.h"
39
#include "gxiparam.h"
40
#include "gdevmrop.h"
41
 
42
/* Structure descriptors */
43
private_st_gx_image_enum();
44
 
45
/* Image class procedures */
46
extern_gx_image_class_table();
47
 
48
/* Enumerator procedures */
49
private const gx_image_enum_procs_t image1_enum_procs = {
50
    gx_image1_plane_data, gx_image1_end_image, gx_image1_flush
51
};
52
 
53
/* GC procedures */
54
private 
55
ENUM_PTRS_WITH(image_enum_enum_ptrs, gx_image_enum *eptr)
56
{
57
    int bps;
58
    gs_ptr_type_t ret;
59
 
60
    /* Enumerate the used members of clues.dev_color. */
61
    index -= gx_image_enum_num_ptrs;
62
    bps = eptr->unpack_bps;
63
    if (eptr->spp != 1)
64
	bps = 8;
65
    else if (bps > 8 || eptr->unpack == sample_unpack_copy)
66
	bps = 1;
67
    if (index >= (1 << bps) * st_device_color_max_ptrs)		/* done */
68
	return 0;
69
    ret = ENUM_USING(st_device_color,
70
		     &eptr->clues[(index / st_device_color_max_ptrs) *
71
				  (255 / ((1 << bps) - 1))].dev_color,
72
		     sizeof(eptr->clues[0].dev_color),
73
		     index % st_device_color_max_ptrs);
74
    if (ret == 0)		/* don't stop early */
75
	ENUM_RETURN(0);
76
    return ret;
77
}
78
#define e1(i,elt) ENUM_PTR(i,gx_image_enum,elt);
79
gx_image_enum_do_ptrs(e1)
80
#undef e1
81
ENUM_PTRS_END
82
private RELOC_PTRS_WITH(image_enum_reloc_ptrs, gx_image_enum *eptr)
83
{
84
    int i;
85
 
86
#define r1(i,elt) RELOC_PTR(gx_image_enum,elt);
87
    gx_image_enum_do_ptrs(r1)
88
#undef r1
89
    {
90
	int bps = eptr->unpack_bps;
91
 
92
	if (eptr->spp != 1)
93
	    bps = 8;
94
	else if (bps > 8 || eptr->unpack == sample_unpack_copy)
95
	    bps = 1;
96
	for (i = 0; i <= 255; i += 255 / ((1 << bps) - 1))
97
	    RELOC_USING(st_device_color,
98
			&eptr->clues[i].dev_color, sizeof(gx_device_color));
99
    }
100
}
101
RELOC_PTRS_END
102
 
103
/* Forward declarations */
104
private int color_draws_b_w(gx_device * dev,
105
			    const gx_drawing_color * pdcolor);
106
private void image_init_map(byte * map, int map_size, const float *decode);
107
private void image_init_colors(gx_image_enum * penum, int bps, int spp,
108
			       gs_image_format_t format,
109
			       const float *decode,
110
			       const gs_imager_state * pis, gx_device * dev,
111
			       const gs_color_space * pcs, bool * pdcb);
112
 
113
/* Procedures for unpacking the input data into bytes or fracs. */
114
/*extern SAMPLE_UNPACK_PROC(sample_unpack_copy); *//* declared above */
115
 
116
/*
117
 * Do common initialization for processing an ImageType 1 or 4 image.
118
 * Allocate the enumerator and fill in the following members:
119
 *	rect
120
 */
121
int
122
gx_image_enum_alloc(const gs_image_common_t * pic,
123
		    const gs_int_rect * prect, gs_memory_t * mem,
124
		    gx_image_enum **ppenum)
125
{
126
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
127
    int width = pim->Width, height = pim->Height;
128
    int bpc = pim->BitsPerComponent;
129
    gx_image_enum *penum;
130
 
131
    if (width < 0 || height < 0)
132
	return_error(gs_error_rangecheck);
133
    switch (pim->format) {
134
    case gs_image_format_chunky:
135
    case gs_image_format_component_planar:
136
	switch (bpc) {
137
	case 1: case 2: case 4: case 8: case 12: case 16: break;
138
	default: return_error(gs_error_rangecheck);
139
	}
140
	break;
141
    case gs_image_format_bit_planar:
142
	if (bpc < 1 || bpc > 8)
143
	    return_error(gs_error_rangecheck);
144
    }
145
    if (prect) {
146
	if (prect->p.x < 0 || prect->p.y < 0 ||
147
	    prect->q.x < prect->p.x || prect->q.y < prect->p.y ||
148
	    prect->q.x > width || prect->q.y > height
149
	    )
150
	    return_error(gs_error_rangecheck);
151
    }
152
    penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum,
153
			    "gx_default_begin_image");
154
    if (penum == 0)
155
	return_error(gs_error_VMerror);
156
    if (prect) {
157
	penum->rect.x = prect->p.x;
158
	penum->rect.y = prect->p.y;
159
	penum->rect.w = prect->q.x - prect->p.x;
160
	penum->rect.h = prect->q.y - prect->p.y;
161
    } else {
162
	penum->rect.x = 0, penum->rect.y = 0;
163
	penum->rect.w = width, penum->rect.h = height;
164
    }
165
#ifdef DEBUG
166
    if (gs_debug_c('b')) {
167
	dlprintf2("[b]Image: w=%d h=%d", width, height);
168
	if (prect)
169
	    dprintf4(" ((%d,%d),(%d,%d))",
170
		     prect->p.x, prect->p.y, prect->q.x, prect->q.y);
171
    }
172
#endif
173
    *ppenum = penum;
174
    return 0;
175
}
176
 
177
/*
178
 * Finish initialization for processing an ImageType 1 or 4 image.
179
 * Assumes the following members of *penum are set in addition to those
180
 * set by gx_image_enum_alloc:
181
 *	alpha, use_mask_color, mask_color (if use_mask_color is true),
182
 *	masked, adjust
183
 */
184
int
185
gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
186
		    const gs_matrix *pmat, const gs_image_common_t * pic,
187
		const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
188
		gs_memory_t * mem, gx_image_enum *penum)
189
{
190
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
191
    gs_image_format_t format = pim->format;
192
    const int width = pim->Width;
193
    const int height = pim->Height;
194
    const int bps = pim->BitsPerComponent;
195
    bool masked = penum->masked;
196
    const float *decode = pim->Decode;
197
    gs_matrix mat;
198
    int index_bps;
199
    const gs_color_space *pcs = pim->ColorSpace;
200
    gs_logical_operation_t lop = (pis ? pis->log_op : lop_default);
201
    int code;
202
    int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac);
203
    int spp, nplanes, spread;
204
    uint bsize;
205
    byte *buffer;
206
    fixed mtx, mty;
207
    gs_fixed_point row_extent, col_extent, x_extent, y_extent;
208
    bool device_color;
209
    gs_fixed_rect obox, cbox;
210
 
211
    if (pmat == 0)
212
	pmat = &ctm_only(pis);
213
    if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
214
	(code = gs_matrix_multiply(&mat, pmat, &mat)) < 0
215
	) {
216
	gs_free_object(mem, penum, "gx_default_begin_image");
217
	return code;
218
    }
219
    penum->matrix = mat;
220
    if_debug6('b', " [%g %g %g %g %g %g]\n",
221
	      mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
222
    /* following works for 1, 2, 4, 8, 12, 16 */
223
    index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
224
    mtx = float2fixed(mat.tx);
225
    mty = float2fixed(mat.ty);
226
    row_extent.x = float2fixed(width * mat.xx + mat.tx) - mtx;
227
    row_extent.y =
228
	(is_fzero(mat.xy) ? fixed_0 :
229
	 float2fixed(width * mat.xy + mat.ty) - mty);
230
    col_extent.x =
231
	(is_fzero(mat.yx) ? fixed_0 :
232
	 float2fixed(height * mat.yx + mat.tx) - mtx);
233
    col_extent.y = float2fixed(height * mat.yy + mat.ty) - mty;
234
    gx_image_enum_common_init((gx_image_enum_common_t *)penum,
235
			      (const gs_data_image_t *)pim,
236
			      &image1_enum_procs, dev,
237
			      (masked ? 1 : cs_num_components(pcs)),
238
			      format);
239
    if (penum->rect.w == width && penum->rect.h == height) {
240
	x_extent = row_extent;
241
	y_extent = col_extent;
242
    } else {
243
	int rw = penum->rect.w, rh = penum->rect.h;
244
 
245
	x_extent.x = float2fixed(rw * mat.xx + mat.tx) - mtx;
246
	x_extent.y =
247
	    (is_fzero(mat.xy) ? fixed_0 :
248
	     float2fixed(rw * mat.xy + mat.ty) - mty);
249
	y_extent.x =
250
	    (is_fzero(mat.yx) ? fixed_0 :
251
	     float2fixed(rh * mat.yx + mat.tx) - mtx);
252
	y_extent.y = float2fixed(rh * mat.yy + mat.ty) - mty;
253
    }
254
    if (masked) {	/* This is imagemask. */
255
	if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
256
	    gs_free_object(mem, penum, "gx_default_begin_image");
257
	    return_error(gs_error_rangecheck);
258
	}
259
	/* Initialize color entries 0 and 255. */
260
	set_nonclient_dev_color(&penum->icolor0, gx_no_color_index);
261
	penum->icolor1 = *pdcolor;
262
	memcpy(&penum->map[0].table.lookup4x1to32[0],
263
	       (decode[0] < decode[1] ? lookup4x1to32_inverted :
264
		lookup4x1to32_identity),
265
	       16 * 4);
266
	penum->map[0].decoding = sd_none;
267
	spp = 1;
268
	lop = rop3_know_S_0(lop);
269
    } else {			/* This is image, not imagemask. */
270
	const gs_color_space_type *pcst = pcs->type;
271
	int b_w_color;
272
 
273
	spp = cs_num_components(pcs);
274
	if (spp < 0) {		/* Pattern not allowed */
275
	    gs_free_object(mem, penum, "gx_default_begin_image");
276
	    return_error(gs_error_rangecheck);
277
	}
278
	if (penum->alpha)
279
	    ++spp;
280
	/* Use a less expensive format if possible. */
281
	switch (format) {
282
	case gs_image_format_bit_planar:
283
	    if (bps > 1)
284
		break;
285
	    format = gs_image_format_component_planar;
286
	case gs_image_format_component_planar:
287
	    if (spp == 1)
288
		format = gs_image_format_chunky;
289
	default:		/* chunky */
290
	    break;
291
	}
292
	device_color = (*pcst->concrete_space) (pcs, pis) == pcs;
293
	image_init_colors(penum, bps, spp, format, decode, pis, dev,
294
			  pcs, &device_color);
295
	/* Try to transform non-default RasterOps to something */
296
	/* that we implement less expensively. */
297
	if (!pim->CombineWithColor)
298
	    lop = rop3_know_T_0(lop) & ~lop_T_transparent;
299
	else {
300
	    if (rop3_uses_T(lop))
301
		switch (color_draws_b_w(dev, pdcolor)) {
302
		    case 0:
303
			lop = rop3_know_T_0(lop);
304
			break;
305
		    case 1:
306
			lop = rop3_know_T_1(lop);
307
			break;
308
		    default:
309
			;
310
		}
311
	}
312
	if (lop != rop3_S &&	/* if best case, no more work needed */
313
	    !rop3_uses_T(lop) && bps == 1 && spp == 1 &&
314
	    (b_w_color =
315
	     color_draws_b_w(dev, &penum->icolor0)) >= 0 &&
316
	    color_draws_b_w(dev, &penum->icolor1) == (b_w_color ^ 1)
317
	    ) {
318
	    if (b_w_color) {	/* Swap the colors and invert the RasterOp source. */
319
		gx_device_color dcolor;
320
 
321
		dcolor = penum->icolor0;
322
		penum->icolor0 = penum->icolor1;
323
		penum->icolor1 = dcolor;
324
		lop = rop3_invert_S(lop);
325
	    }
326
	    /*
327
	     * At this point, we know that the source pixels
328
	     * correspond directly to the S input for the raster op,
329
	     * i.e., icolor0 is black and icolor1 is white.
330
	     */
331
	    switch (lop) {
332
		case rop3_D & rop3_S:
333
		    /* Implement this as an inverted mask writing 0s. */
334
		    penum->icolor1 = penum->icolor0;
335
		    /* (falls through) */
336
		case rop3_D | rop3_not(rop3_S):
337
		    /* Implement this as an inverted mask writing 1s. */
338
		    memcpy(&penum->map[0].table.lookup4x1to32[0],
339
			   lookup4x1to32_inverted, 16 * 4);
340
		  rmask:	/* Fill in the remaining parameters for a mask. */
341
		    penum->masked = masked = true;
342
		    set_nonclient_dev_color(&penum->icolor0, gx_no_color_index);
343
		    penum->map[0].decoding = sd_none;
344
		    lop = rop3_T;
345
		    break;
346
		case rop3_D & rop3_not(rop3_S):
347
		    /* Implement this as a mask writing 0s. */
348
		    penum->icolor1 = penum->icolor0;
349
		    /* (falls through) */
350
		case rop3_D | rop3_S:
351
		    /* Implement this as a mask writing 1s. */
352
		    memcpy(&penum->map[0].table.lookup4x1to32[0],
353
			   lookup4x1to32_identity, 16 * 4);
354
		    goto rmask;
355
		default:
356
		    ;
357
	    }
358
	}
359
    }
360
    penum->device_color = device_color;
361
    /*
362
     * Adjust width upward for unpacking up to 7 trailing bits in
363
     * the row, plus 1 byte for end-of-run, plus up to 7 leading
364
     * bits for data_x offset within a packed byte.
365
     */
366
    bsize = ((bps > 8 ? width * 2 : width) + 15) * spp;
367
    buffer = gs_alloc_bytes(mem, bsize, "image buffer");
368
    if (buffer == 0) {
369
	gs_free_object(mem, penum, "gx_default_begin_image");
370
	return_error(gs_error_VMerror);
371
    }
372
    penum->bps = bps;
373
    penum->unpack_bps = bps;
374
    penum->log2_xbytes = log2_xbytes;
375
    penum->spp = spp;
376
    switch (format) {
377
    case gs_image_format_chunky:
378
	nplanes = 1;
379
	spread = 1 << log2_xbytes;
380
	break;
381
    case gs_image_format_component_planar:
382
	nplanes = spp;
383
	spread = spp << log2_xbytes;
384
	break;
385
    case gs_image_format_bit_planar:
386
	nplanes = spp * bps;
387
	spread = spp << log2_xbytes;
388
	break;
389
    default:
390
	/* No other cases are possible (checked by gx_image_enum_alloc). */
391
	return_error(gs_error_Fatal);
392
    }
393
    penum->num_planes = nplanes;
394
    penum->spread = spread;
395
    /*
396
     * If we're asked to interpolate in a partial image, we have to
397
     * assume that the client either really only is interested in
398
     * the given sub-image, or else is constructing output out of
399
     * overlapping pieces.
400
     */
401
    penum->interpolate = pim->Interpolate;
402
    penum->x_extent = x_extent;
403
    penum->y_extent = y_extent;
404
    penum->posture =
405
	((x_extent.y | y_extent.x) == 0 ? image_portrait :
406
	 (x_extent.x | y_extent.y) == 0 ? image_landscape :
407
	 image_skewed);
408
    penum->pis = pis;
409
    penum->pcs = pcs;
410
    penum->memory = mem;
411
    penum->buffer = buffer;
412
    penum->buffer_size = bsize;
413
    penum->line = 0;
414
    penum->line_size = 0;
415
    penum->use_rop = lop != (masked ? rop3_T : rop3_S);
416
#ifdef DEBUG
417
    if (gs_debug_c('*')) {
418
	if (penum->use_rop)
419
	    dprintf1("[%03x]", lop);
420
	dprintf5("%c%d%c%dx%d ",
421
		 (masked ? (color_is_pure(pdcolor) ? 'm' : 'h') : 'i'),
422
		 bps,
423
		 (penum->posture == image_portrait ? ' ' :
424
		  penum->posture == image_landscape ? 'L' : 'T'),
425
		 width, height);
426
    }
427
#endif
428
    penum->slow_loop = 0;
429
    if (pcpath == 0) {
430
	(*dev_proc(dev, get_clipping_box)) (dev, &obox);
431
	cbox = obox;
432
	penum->clip_image = 0;
433
    } else
434
	penum->clip_image =
435
	    (gx_cpath_outer_box(pcpath, &obox) |	/* not || */
436
	     gx_cpath_inner_box(pcpath, &cbox) ?
437
 
438
    penum->clip_outer = obox;
439
    penum->clip_inner = cbox;
440
    penum->log_op = rop3_T;	/* rop device takes care of this */
441
    penum->clip_dev = 0;	/* in case we bail out */
442
    penum->rop_dev = 0;		/* ditto */
443
    penum->scaler = 0;		/* ditto */
444
    /*
445
     * If all four extrema of the image fall within the clipping
446
     * rectangle, clipping is never required.  When making this check,
447
     * we must carefully take into account the fact that we only care
448
     * about pixel centers.
449
     */
450
    {
451
	fixed
452
	    epx = min(row_extent.x, 0) + min(col_extent.x, 0),
453
	    eqx = max(row_extent.x, 0) + max(col_extent.x, 0),
454
	    epy = min(row_extent.y, 0) + min(col_extent.y, 0),
455
	    eqy = max(row_extent.y, 0) + max(col_extent.y, 0);
456
 
457
	{
458
	    int hwx, hwy;
459
 
460
	    switch (penum->posture) {
461
		case image_portrait:
462
		    hwx = width, hwy = height;
463
		    break;
464
		case image_landscape:
465
		    hwx = height, hwy = width;
466
		    break;
467
		default:
468
		    hwx = hwy = 0;
469
	    }
470
	    /*
471
	     * If the image is only 1 sample wide or high,
472
	     * and is less than 1 device pixel wide or high,
473
	     * move it slightly so that it covers pixel centers.
474
	     * This is a hack to work around a bug in some old
475
	     * versions of TeX/dvips, which use 1-bit-high images
476
	     * to draw horizontal and vertical lines without
477
	     * positioning them properly.
478
	     */
479
	    if (hwx == 1 && eqx - epx < fixed_1) {
480
		fixed diff =
481
		arith_rshift_1(row_extent.x + col_extent.x);
482
 
483
		mtx = (((mtx + diff) | fixed_half) & -fixed_half) - diff;
484
	    }
485
	    if (hwy == 1 && eqy - epy < fixed_1) {
486
		fixed diff =
487
		arith_rshift_1(row_extent.y + col_extent.y);
488
 
489
		mty = (((mty + diff) | fixed_half) & -fixed_half) - diff;
490
	    }
491
	}
492
	if_debug5('b', "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n",
493
		  (masked? "masked, " : ""), spp, bps,
494
		  fixed2float(mtx), fixed2float(mty));
495
	if_debug9('b',
496
		  "[b]   cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n",
497
		  fixed2float(cbox.p.x), fixed2float(cbox.p.y),
498
		  fixed2float(cbox.q.x), fixed2float(cbox.q.y),
499
		  fixed2float(obox.p.x), fixed2float(obox.p.y),
500
		  fixed2float(obox.q.x), fixed2float(obox.q.y),
501
		  penum->clip_image);
502
	dda_init(penum->dda.row.x, mtx, col_extent.x, height);
503
	dda_init(penum->dda.row.y, mty, col_extent.y, height);
504
	if (penum->rect.y) {
505
	    dda_advance(penum->dda.row.x, penum->rect.y);
506
	    dda_advance(penum->dda.row.y, penum->rect.y);
507
	}
508
	penum->cur.x = penum->prev.x = dda_current(penum->dda.row.x);
509
	penum->cur.y = penum->prev.y = dda_current(penum->dda.row.y);
510
	dda_init(penum->dda.strip.x, penum->cur.x, row_extent.x, width);
511
	dda_init(penum->dda.strip.y, penum->cur.y, row_extent.y, width);
512
	if (penum->rect.x) {
513
	    dda_advance(penum->dda.strip.x, penum->rect.x);
514
	    dda_advance(penum->dda.strip.y, penum->rect.x);
515
	} {
516
	    fixed ox = dda_current(penum->dda.strip.x);
517
	    fixed oy = dda_current(penum->dda.strip.y);
518
 
519
	    if (!penum->clip_image)	/* i.e., not clip region */
520
		penum->clip_image =
521
		    (fixed_pixround(ox + epx) < fixed_pixround(cbox.p.x) ?
522
		     image_clip_xmin : 0) +
523
		    (fixed_pixround(ox + eqx) >= fixed_pixround(cbox.q.x) ?
524
		     image_clip_xmax : 0) +
525
		    (fixed_pixround(oy + epy) < fixed_pixround(cbox.p.y) ?
526
		     image_clip_ymin : 0) +
527
		    (fixed_pixround(oy + eqy) >= fixed_pixround(cbox.q.y) ?
528
		     image_clip_ymax : 0);
529
	}
530
    }
531
    penum->y = 0;
532
    penum->used.x = 0;
533
    penum->used.y = 0;
534
    {
535
	static sample_unpack_proc_t procs[2][6] = {
536
	{   sample_unpack_1, sample_unpack_2,
537
	    sample_unpack_4, sample_unpack_8,
538
	    0, 0
539
	}, 
540
	{   sample_unpack_1_interleaved, sample_unpack_2_interleaved,
541
	    sample_unpack_4_interleaved, sample_unpack_8_interleaved,
542
	    0, 0
543
	}};
544
	int num_planes = penum->num_planes;
545
	bool interleaved = (num_planes == 1 && penum->plane_depths[0] != penum->bps);
546
	int i;
547
 
548
	procs[0][4] = procs[1][4] = sample_unpack_12_proc;
549
	procs[0][5] = procs[1][5] = sample_unpack_16_proc;
550
	if (interleaved) {
551
	    int num_components = penum->plane_depths[0] / penum->bps;
552
 
553
	    for (i = 1; i < num_components; i++) {
554
		if (decode[0] != decode[i * 2 + 0] ||
555
		    decode[1] != decode[i * 2 + 1])
556
		    break;
557
	    }
558
	    if (i == num_components)
559
		interleaved = false; /* Use single table. */
560
	}
561
	if (index_bps >= 4) {
562
	    if ((penum->unpack = procs[interleaved][index_bps]) == 0) {		/* bps case not supported. */
563
		gx_default_end_image(dev,
564
				     (gx_image_enum_common_t *) penum,
565
				     false);
566
		return_error(gs_error_rangecheck);
567
	    }
568
	} else {
569
	    penum->unpack = procs[interleaved][index_bps];
570
	}
571
	if_debug1('b', "[b]unpack=%d\n", bps);
572
	/* Set up pixel0 for image class procedures. */
573
	penum->dda.pixel0 = penum->dda.strip;
574
	for (i = 0; i < gx_image_class_table_count; ++i)
575
	    if ((penum->render = gx_image_class_table[i](penum)) != 0)
576
		break;
577
	if (i == gx_image_class_table_count) {
578
	    /* No available class can handle this image. */
579
	    gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
580
				 false);
581
	    return_error(gs_error_rangecheck);
582
	}
583
    }
584
    if (penum->clip_image && pcpath) {	/* Set up the clipping device. */
585
	gx_device_clip *cdev =
586
	    gs_alloc_struct(mem, gx_device_clip,
587
			    &st_device_clip, "image clipper");
588
 
589
	if (cdev == 0) {
590
	    gx_default_end_image(dev,
591
				 (gx_image_enum_common_t *) penum,
592
				 false);
593
	    return_error(gs_error_VMerror);
594
	}
595
	gx_make_clip_translate_device(cdev, gx_cpath_list(pcpath), 0, 0, mem);
596
	gx_device_retain((gx_device *)cdev, true); /* will free explicitly */
597
	gx_device_set_target((gx_device_forward *)cdev, dev);
598
	(*dev_proc(cdev, open_device)) ((gx_device *) cdev);
599
	penum->clip_dev = cdev;
600
    }
601
    if (penum->use_rop) {	/* Set up the RasterOp source device. */
602
	gx_device_rop_texture *rtdev;
603
 
604
	code = gx_alloc_rop_texture_device(&rtdev, mem,
605
					   "image RasterOp");
606
	if (code < 0) {
607
	    gx_default_end_image(dev, (gx_image_enum_common_t *) penum,
608
				 false);
609
	    return code;
610
	}
611
	gx_make_rop_texture_device(rtdev,
612
				   (penum->clip_dev != 0 ?
613
				    (gx_device *) penum->clip_dev :
614
				    dev), lop, pdcolor);
615
	penum->rop_dev = rtdev;
616
    }
617
    return 0;
618
}
619
 
620
/* If a drawing color is black or white, return 0 or 1 respectively, */
621
/* otherwise return -1. */
622
private int
623
color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor)
624
{
625
    if (color_is_pure(pdcolor)) {
626
	gx_color_value rgb[3];
627
 
628
	(*dev_proc(dev, map_color_rgb)) (dev, gx_dc_pure_color(pdcolor),
629
					 rgb);
630
	if (!(rgb[0] | rgb[1] | rgb[2]))
631
	    return 0;
632
	if ((rgb[0] & rgb[1] & rgb[2]) == gx_max_color_value)
633
	    return 1;
634
    }
635
    return -1;
636
}
637
 
638
/* Export this for use by image_render_ functions */
639
void
640
image_init_clues(gx_image_enum * penum, int bps, int spp)
641
{
642
    /* Initialize the color table */
643
#define ictype(i)\
644
  penum->clues[i].dev_color.type
645
 
646
    switch ((spp == 1 ? bps : 8)) {
647
	case 8:		/* includes all color images */
648
	    {
649
		register gx_image_clue *pcht = &penum->clues[0];
650
		register int n = 64;	/* 8 bits means 256 clues, do	*/
651
					/* 4 at a time for efficiency	*/
652
		do {
653
		    pcht[0].dev_color.type =
654
			pcht[1].dev_color.type =
655
			pcht[2].dev_color.type =
656
			pcht[3].dev_color.type =
657
			gx_dc_type_none;
658
		    pcht[0].key = pcht[1].key =
659
			pcht[2].key = pcht[3].key = 0;
660
		    pcht += 4;
661
		}
662
		while (--n > 0);
663
		penum->clues[0].key = 1;	/* guarantee no hit */
664
		break;
665
	    }
666
	case 4:
667
	    ictype(17) = ictype(2 * 17) = ictype(3 * 17) =
668
		ictype(4 * 17) = ictype(6 * 17) = ictype(7 * 17) =
669
		ictype(8 * 17) = ictype(9 * 17) = ictype(11 * 17) =
670
		ictype(12 * 17) = ictype(13 * 17) = ictype(14 * 17) =
671
		gx_dc_type_none;
672
	    /* falls through */
673
	case 2:
674
	    ictype(5 * 17) = ictype(10 * 17) = gx_dc_type_none;
675
#undef ictype
676
    }
677
}
678
 
679
/* Initialize the color mapping tables for a non-mask image. */
680
private void
681
image_init_colors(gx_image_enum * penum, int bps, int spp,
682
		  gs_image_format_t format, const float *decode /*[spp*2] */ ,
683
		  const gs_imager_state * pis, gx_device * dev,
684
		  const gs_color_space * pcs, bool * pdcb)
685
{
686
    int ci;
687
    static const float default_decode[] = {
688
	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
689
    };
690
 
691
    image_init_clues(penum, bps, spp);
692
 
693
    /* Initialize the maps from samples to intensities. */
694
    for (ci = 0; ci < spp; ci++) {
695
	sample_map *pmap = &penum->map[ci];
696
 
697
	/* If the decoding is [0 1] or [1 0], we can fold it */
698
	/* into the expansion of the sample values; */
699
	/* otherwise, we have to use the floating point method. */
700
 
701
	const float *this_decode = &decode[ci * 2];
702
	const float *map_decode;	/* decoding used to */
703
					/* construct the expansion map */
704
	const float *real_decode;	/* decoding for expanded samples */
705
 
706
	bool no_decode;
707
 
708
	map_decode = real_decode = this_decode;
709
	if (map_decode[0] == 0.0 && map_decode[1] == 1.0)
710
	    no_decode = true;
711
	else if (map_decode[0] == 1.0 && map_decode[1] == 0.0 && bps <= 8) {
712
	    no_decode = true;
713
	    real_decode = default_decode;
714
	} else {
715
	    no_decode = false;
716
	    *pdcb = false;
717
	    map_decode = default_decode;
718
	}
719
	if (bps > 2 || format != gs_image_format_chunky) {
720
	    if (bps <= 8)
721
		image_init_map(&pmap->table.lookup8[0], 1 << bps,
722
			       map_decode);
723
	} else {		/* The map index encompasses more than one pixel. */
724
	    byte map[4];
725
	    register int i;
726
 
727
	    image_init_map(&map[0], 1 << bps, map_decode);
728
	    switch (bps) {
729
		case 1:
730
		    {
731
			register bits32 *p = &pmap->table.lookup4x1to32[0];
732
 
733
			if (map[0] == 0 && map[1] == 0xff)
734
			    memcpy((byte *) p, lookup4x1to32_identity, 16 * 4);
735
			else if (map[0] == 0xff && map[1] == 0)
736
			    memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4);
737
			else
738
			    for (i = 0; i < 16; i++, p++)
739
				((byte *) p)[0] = map[i >> 3],
740
				    ((byte *) p)[1] = map[(i >> 2) & 1],
741
				    ((byte *) p)[2] = map[(i >> 1) & 1],
742
				    ((byte *) p)[3] = map[i & 1];
743
		    }
744
		    break;
745
		case 2:
746
		    {
747
			register bits16 *p = &pmap->table.lookup2x2to16[0];
748
 
749
			for (i = 0; i < 16; i++, p++)
750
			    ((byte *) p)[0] = map[i >> 2],
751
				((byte *) p)[1] = map[i & 3];
752
		    }
753
		    break;
754
	    }
755
	}
756
	pmap->decode_base /* = decode_lookup[0] */  = real_decode[0];
757
	pmap->decode_factor =
758
	    (real_decode[1] - real_decode[0]) /
759
	    (bps <= 8 ? 255.0 : (float)frac_1);
760
	pmap->decode_max /* = decode_lookup[15] */  = real_decode[1];
761
	if (no_decode) {
762
	    pmap->decoding = sd_none;
763
	    pmap->inverted = map_decode[0] != 0;
764
	} else if (bps <= 4) {
765
	    int step = 15 / ((1 << bps) - 1);
766
	    int i;
767
 
768
	    pmap->decoding = sd_lookup;
769
	    for (i = 15 - step; i > 0; i -= step)
770
		pmap->decode_lookup[i] = pmap->decode_base +
771
		    i * (255.0 / 15) * pmap->decode_factor;
772
	} else
773
	    pmap->decoding = sd_compute;
774
	if (spp == 1) {		/* and ci == 0 *//* Pre-map entries 0 and 255. */
775
	    gs_client_color cc;
776
 
777
	    cc.paint.values[0] = real_decode[0];
778
	    (*pcs->type->remap_color) (&cc, pcs, &penum->icolor0,
779
				       pis, dev, gs_color_select_source);
780
	    cc.paint.values[0] = real_decode[1];
781
	    (*pcs->type->remap_color) (&cc, pcs, &penum->icolor1,
782
				       pis, dev, gs_color_select_source);
783
	}
784
    }
785
 
786
}
787
/* Construct a mapping table for sample values. */
788
/* map_size is 2, 4, 16, or 256.  Note that 255 % (map_size - 1) == 0, */
789
/* so the division 0xffffL / (map_size - 1) is always exact. */
790
private void
791
image_init_map(byte * map, int map_size, const float *decode)
792
{
793
    float min_v = decode[0];
794
    float diff_v = decode[1] - min_v;
795
 
796
    if (diff_v == 1 || diff_v == -1) {	/* We can do the stepping with integers, without overflow. */
797
	byte *limit = map + map_size;
798
	uint value = (uint)(min_v * 0xffffL);
799
	int diff = (int)(diff_v * (0xffffL / (map_size - 1)));
800
 
801
	for (; map != limit; map++, value += diff)
802
	    *map = value >> 8;
803
    } else {			/* Step in floating point, with clamping. */
804
	int i;
805
 
806
	for (i = 0; i < map_size; ++i) {
807
	    int value = (int)((min_v + diff_v * i / (map_size - 1)) * 255);
808
 
809
	    map[i] = (value < 0 ? 0 : value > 255 ? 255 : value);
810
	}
811
    }
812
}
813
 
814
/*
815
 * Scale a pair of mask_color values to match the scaling of each sample to
816
 * a full byte, and complement and swap them if the map incorporates
817
 * a Decode = [1 0] inversion.
818
 */
819
void
820
gx_image_scale_mask_colors(gx_image_enum *penum, int component_index)
821
{
822
    uint scale = 255 / ((1 << penum->bps) - 1);
823
    uint *values = &penum->mask_color.values[component_index * 2];
824
    uint v0 = values[0] *= scale;
825
    uint v1 = values[1] *= scale;
826
 
827
    if (penum->map[component_index].decoding == sd_none &&
828
	penum->map[component_index].inverted
829
	) {
830
	values[0] = 255 - v1;
831
	values[1] = 255 - v0;
832
    }
833
}