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) 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: gdevmr8n.c,v 1.4 2002/02/21 22:24:51 giles Exp $ */
18
/* RasterOp implementation for 8N-bit memory devices */
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gsbittab.h"
22
#include "gserrors.h"
23
#include "gsropt.h"
24
#include "gxcindex.h"
25
#include "gxdcolor.h"
26
#include "gxdevice.h"
27
#include "gxdevmem.h"
28
#include "gxdevrop.h"
29
#include "gdevmem.h"
30
#include "gdevmrop.h"
31
 
32
/*
33
 * NOTE: The 16- and 32-bit cases aren't implemented: they just fall back to
34
 * the default implementation.  This is very slow and will be fixed someday.
35
 */
36
 
37
#define chunk byte
38
 
39
/* Calculate the X offset for a given Y value, */
40
/* taking shift into account if necessary. */
41
#define x_offset(px, ty, textures)\
42
  ((textures)->shift == 0 ? (px) :\
43
   (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
44
 
45
/* ---------------- RasterOp with 8-bit gray / 24-bit RGB ---------------- */
46
 
47
int
48
mem_gray8_rgb24_strip_copy_rop(gx_device * dev,
49
	     const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
50
			       const gx_color_index * scolors,
51
	   const gx_strip_bitmap * textures, const gx_color_index * tcolors,
52
			       int x, int y, int width, int height,
53
		       int phase_x, int phase_y, gs_logical_operation_t lop)
54
{
55
    gx_device_memory *mdev = (gx_device_memory *) dev;
56
    gs_rop3_t rop = lop_rop(lop);
57
    gx_color_index const_source = gx_no_color_index;
58
    gx_color_index const_texture = gx_no_color_index;
59
    uint draster = mdev->raster;
60
    int line_count;
61
    byte *drow;
62
    int depth = dev->color_info.depth;
63
    int bpp = depth >> 3;	/* bytes per pixel, 1 or 3 */
64
    gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1;
65
    gx_color_index strans =
66
	(lop & lop_S_transparent ? all_ones : gx_no_color_index);
67
    gx_color_index ttrans =
68
	(lop & lop_T_transparent ? all_ones : gx_no_color_index);
69
 
70
    /* Check for constant source. */
71
    if (!rop3_uses_S(rop))
72
	const_source = 0;	/* arbitrary */
73
    else if (scolors != 0 && scolors[0] == scolors[1]) {
74
	/* Constant source */
75
	const_source = scolors[0];
76
	if (const_source == gx_device_black(dev))
77
	    rop = rop3_know_S_0(rop);
78
	else if (const_source == gx_device_white(dev))
79
	    rop = rop3_know_S_1(rop);
80
    }
81
 
82
    /* Check for constant texture. */
83
    if (!rop3_uses_T(rop))
84
	const_texture = 0;	/* arbitrary */
85
    else if (tcolors != 0 && tcolors[0] == tcolors[1]) {
86
	/* Constant texture */
87
	const_texture = tcolors[0];
88
	if (const_texture == gx_device_black(dev))
89
	    rop = rop3_know_T_0(rop);
90
	else if (const_texture == gx_device_white(dev))
91
	    rop = rop3_know_T_1(rop);
92
    }
93
 
94
    if (bpp == 1 &&
95
	(gx_device_has_color(dev) ||
96
	 (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones))
97
	) {
98
	/*
99
	 * This is an 8-bit device but not gray-scale.  Except in a few
100
	 * simple cases, we have to use the slow algorithm that converts
101
	 * values to and from RGB.
102
	 */
103
	gx_color_index bw_pixel;
104
 
105
	switch (rop) {
106
	case rop3_0:
107
	    bw_pixel = gx_device_black(dev);
108
	    goto bw;
109
	case rop3_1:
110
	    bw_pixel = gx_device_white(dev);
111
bw:	    if (bw_pixel == 0x00)
112
		rop = rop3_0;
113
	    else if (bw_pixel == 0xff)
114
		rop = rop3_1;
115
	    else
116
		goto df;
117
	    break;
118
	case rop3_D:
119
	    break;
120
	case rop3_S:
121
	    if (lop & lop_S_transparent)
122
		goto df;
123
	    break;
124
	case rop3_T:
125
	    if (lop & lop_T_transparent)
126
		goto df;
127
	    break;
128
	default:
129
df:	    return mem_default_strip_copy_rop(dev,
130
					      sdata, sourcex, sraster, id,
131
					      scolors, textures, tcolors,
132
					      x, y, width, height,
133
					      phase_x, phase_y, lop);
134
	}
135
    }
136
 
137
    /* Adjust coordinates to be in bounds. */
138
    if (const_source == gx_no_color_index) {
139
	fit_copy(dev, sdata, sourcex, sraster, id,
140
		 x, y, width, height);
141
    } else {
142
	fit_fill(dev, x, y, width, height);
143
    }
144
 
145
    /* Set up transfer parameters. */
146
    line_count = height;
147
    drow = scan_line_base(mdev, y) + x * bpp;
148
 
149
    /*
150
     * There are 18 cases depending on whether each of the source and
151
     * texture is constant, 1-bit, or multi-bit, and on whether the
152
     * depth is 8 or 24 bits.  We divide first according to constant
153
     * vs. non-constant, and then according to 1- vs. multi-bit, and
154
     * finally according to pixel depth.  This minimizes source code,
155
     * but not necessarily time, since we do some of the divisions
156
     * within 1 or 2 levels of loop.
157
     */
158
 
159
#define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7)))
160
/* 8-bit */
161
#define cbit8(base, i, colors)\
162
  (dbit(base, i) ? (byte)colors[1] : (byte)colors[0])
163
#define rop_body_8(s_pixel, t_pixel)\
164
  if ( (s_pixel) == strans ||	/* So = 0, s_tr = 1 */\
165
       (t_pixel) == ttrans	/* Po = 0, p_tr = 1 */\
166
     )\
167
    continue;\
168
  *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel)
169
/* 24-bit */
170
#define get24(ptr)\
171
  (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2])
172
#define put24(ptr, pixel)\
173
  (ptr)[0] = (byte)((pixel) >> 16),\
174
  (ptr)[1] = (byte)((uint)(pixel) >> 8),\
175
  (ptr)[2] = (byte)(pixel)
176
#define cbit24(base, i, colors)\
177
  (dbit(base, i) ? colors[1] : colors[0])
178
#define rop_body_24(s_pixel, t_pixel)\
179
  if ( (s_pixel) == strans ||	/* So = 0, s_tr = 1 */\
180
       (t_pixel) == ttrans	/* Po = 0, p_tr = 1 */\
181
     )\
182
    continue;\
183
  { gx_color_index d_pixel = get24(dptr);\
184
    d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\
185
    put24(dptr, d_pixel);\
186
  }
187
 
188
    if (const_texture != gx_no_color_index) {
189
/**** Constant texture ****/
190
	if (const_source != gx_no_color_index) {
191
/**** Constant source & texture ****/
192
	    for (; line_count-- > 0; drow += draster) {
193
		byte *dptr = drow;
194
		int left = width;
195
 
196
		if (bpp == 1)
197
/**** 8-bit destination ****/
198
		    for (; left > 0; ++dptr, --left) {
199
			rop_body_8((byte)const_source, (byte)const_texture);
200
		    }
201
		else
202
/**** 24-bit destination ****/
203
		    for (; left > 0; dptr += 3, --left) {
204
			rop_body_24(const_source, const_texture);
205
		    }
206
	    }
207
	} else {
208
/**** Data source, const texture ****/
209
	    const byte *srow = sdata;
210
 
211
	    for (; line_count-- > 0; drow += draster, srow += sraster) {
212
		byte *dptr = drow;
213
		int left = width;
214
 
215
		if (scolors) {
216
/**** 1-bit source ****/
217
		    int sx = sourcex;
218
 
219
		    if (bpp == 1)
220
/**** 8-bit destination ****/
221
			for (; left > 0; ++dptr, ++sx, --left) {
222
			    byte s_pixel = cbit8(srow, sx, scolors);
223
 
224
			    rop_body_8(s_pixel, (byte)const_texture);
225
			}
226
		    else
227
/**** 24-bit destination ****/
228
			for (; left > 0; dptr += 3, ++sx, --left) {
229
			    bits32 s_pixel = cbit24(srow, sx, scolors);
230
 
231
			    rop_body_24(s_pixel, const_texture);
232
			}
233
		} else if (bpp == 1) {
234
/**** 8-bit source & dest ****/
235
		    const byte *sptr = srow + sourcex;
236
 
237
		    for (; left > 0; ++dptr, ++sptr, --left) {
238
			byte s_pixel = *sptr;
239
 
240
			rop_body_8(s_pixel, (byte)const_texture);
241
		    }
242
		} else {
243
/**** 24-bit source & dest ****/
244
		    const byte *sptr = srow + sourcex * 3;
245
 
246
		    for (; left > 0; dptr += 3, sptr += 3, --left) {
247
			bits32 s_pixel = get24(sptr);
248
 
249
			rop_body_24(s_pixel, const_texture);
250
		    }
251
		}
252
	    }
253
	}
254
    } else if (const_source != gx_no_color_index) {
255
/**** Const source, data texture ****/
256
	uint traster = textures->raster;
257
	int ty = y + phase_y;
258
 
259
	for (; line_count-- > 0; drow += draster, ++ty) {	/* Loop over copies of the tile. */
260
	    int dx = x, w = width, nw;
261
	    byte *dptr = drow;
262
	    const byte *trow =
263
	    textures->data + (ty % textures->size.y) * traster;
264
	    int xoff = x_offset(phase_x, ty, textures);
265
 
266
	    for (; w > 0; dx += nw, w -= nw) {
267
		int tx = (dx + xoff) % textures->rep_width;
268
		int left = nw = min(w, textures->size.x - tx);
269
		const byte *tptr = trow;
270
 
271
		if (tcolors) {
272
/**** 1-bit texture ****/
273
		    if (bpp == 1)
274
/**** 8-bit dest ****/
275
			for (; left > 0; ++dptr, ++tx, --left) {
276
			    byte t_pixel = cbit8(tptr, tx, tcolors);
277
 
278
			    rop_body_8((byte)const_source, t_pixel);
279
			}
280
		    else
281
/**** 24-bit dest ****/
282
			for (; left > 0; dptr += 3, ++tx, --left) {
283
			    bits32 t_pixel = cbit24(tptr, tx, tcolors);
284
 
285
			    rop_body_24(const_source, t_pixel);
286
			}
287
		} else if (bpp == 1) {
288
/**** 8-bit T & D ****/
289
		    tptr += tx;
290
		    for (; left > 0; ++dptr, ++tptr, --left) {
291
			byte t_pixel = *tptr;
292
 
293
			rop_body_8((byte)const_source, t_pixel);
294
		    }
295
		} else {
296
/**** 24-bit T & D ****/
297
		    tptr += tx * 3;
298
		    for (; left > 0; dptr += 3, tptr += 3, --left) {
299
			bits32 t_pixel = get24(tptr);
300
 
301
			rop_body_24(const_source, t_pixel);
302
		    }
303
		}
304
	    }
305
	}
306
    } else {
307
/**** Data source & texture ****/
308
	uint traster = textures->raster;
309
	int ty = y + phase_y;
310
	const byte *srow = sdata;
311
 
312
	/* Loop over scan lines. */
313
	for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) {	/* Loop over copies of the tile. */
314
	    int sx = sourcex;
315
	    int dx = x;
316
	    int w = width;
317
	    int nw;
318
	    byte *dptr = drow;
319
	    const byte *trow =
320
	    textures->data + (ty % textures->size.y) * traster;
321
	    int xoff = x_offset(phase_x, ty, textures);
322
 
323
	    for (; w > 0; dx += nw, w -= nw) {	/* Loop over individual pixels. */
324
		int tx = (dx + xoff) % textures->rep_width;
325
		int left = nw = min(w, textures->size.x - tx);
326
		const byte *tptr = trow;
327
 
328
		/*
329
		 * For maximum speed, we should split this loop
330
		 * into 7 cases depending on source & texture
331
		 * depth: (1,1), (1,8), (1,24), (8,1), (8,8),
332
		 * (24,1), (24,24).  But since we expect these
333
		 * cases to be relatively uncommon, we just
334
		 * divide on the destination depth.
335
		 */
336
		if (bpp == 1) {
337
/**** 8-bit destination ****/
338
		    const byte *sptr = srow + sx;
339
 
340
		    tptr += tx;
341
		    for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) {
342
			byte s_pixel =
343
			    (scolors ? cbit8(srow, sx, scolors) : *sptr);
344
			byte t_pixel =
345
			    (tcolors ? cbit8(tptr, tx, tcolors) : *tptr);
346
 
347
			rop_body_8(s_pixel, t_pixel);
348
		    }
349
		} else {
350
/**** 24-bit destination ****/
351
		    const byte *sptr = srow + sx * 3;
352
 
353
		    tptr += tx * 3;
354
		    for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) {
355
			bits32 s_pixel =
356
			    (scolors ? cbit24(srow, sx, scolors) :
357
			     get24(sptr));
358
			bits32 t_pixel =
359
			    (tcolors ? cbit24(tptr, tx, tcolors) :
360
			     get24(tptr));
361
 
362
			rop_body_24(s_pixel, t_pixel);
363
		    }
364
		}
365
	    }
366
	}
367
    }
368
#undef rop_body_8
369
#undef rop_body_24
370
#undef dbit
371
#undef cbit8
372
#undef cbit24
373
    return 0;
374
}