Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises, 2001 Artifex Software.  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: gdevm64.c,v 1.4 2005/06/20 08:59:23 igor Exp $ */
18
/* 64-bit-per-pixel "memory" (stored bitmap) device */
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gxdevice.h"
22
#include "gxdevmem.h"		/* semi-public definitions */
23
#include "gdevmem.h"		/* private definitions */
24
 
25
/* Define debugging statistics. */
26
#ifdef DEBUG
27
struct stats_mem64_s {
28
    long
29
	fill, fwide, fgray[101], fsetc, fcolor[101], fnarrow[5],
30
	fprevc[257];
31
    double ftotal;
32
} stats_mem64;
33
static int prev_count = 0;
34
static gx_color_index prev_colors[256];
35
# define INCR(v) (++(stats_mem64.v))
36
#else
37
# define INCR(v) DO_NOTHING
38
#endif
39
 
40
 
41
/* ================ Standard (byte-oriented) device ================ */
42
 
43
#undef chunk
44
#define chunk byte
45
#define PIXEL_SIZE 2
46
 
47
/* Procedures */
48
declare_mem_procs(mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_rectangle);
49
 
50
/* The device descriptor. */
51
const gx_device_memory mem_true64_device =
52
mem_full_alpha_device("image64", 64, 0, mem_open,
53
		 gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
54
     mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_rectangle,
55
		      gx_default_map_cmyk_color, gx_default_copy_alpha,
56
		 gx_default_strip_tile_rectangle, mem_default_strip_copy_rop,
57
		      mem_get_bits_rectangle);
58
 
59
/* Convert x coordinate to byte offset in scan line. */
60
#undef x_to_byte
61
#define x_to_byte(x) ((x) << 3)
62
 
63
/* Put a 64-bit color into the bitmap. */
64
#define put8(ptr, abcd, efgh)\
65
	(ptr)[0] = abcd, (ptr)[1] = efgh
66
/* Free variables: [m]dev, abcd, degh. */
67
#if arch_is_big_endian
68
/* Unpack a color into 32 bit chunks. */
69
#  define declare_unpack_color(abcd, efgh, color)\
70
	bits32 abcd = (bits32)((color) >> 32);\
71
	bits32 efgh = (bits32)(color)
72
#else
73
/* Unpack a color into 32 bit chunks. */
74
#  define declare_unpack_color(abcd, efgh, color)\
75
	bits32 abcd = (bits32)((0x000000ff & ((color) >> 56)) |\
76
		               (0x0000ff00 & ((color) >> 40)) |\
77
		               (0x00ff0000 & ((color) >> 24)) |\
78
		               (0xff000000 & ((color) >> 8)));\
79
	bits32 efgh = (bits32)((0x000000ff & ((color) >> 24)) |\
80
		               (0x0000ff00 & ((color) >> 8)) |\
81
		               (0x00ff0000 & ((color) << 8)) |\
82
		               (0xff000000 & ((color) << 24)))
83
#endif
84
#define dest32 ((bits32 *)dest)
85
 
86
/* Fill a rectangle with a color. */
87
private int
88
mem_true64_fill_rectangle(gx_device * dev,
89
			  int x, int y, int w, int h, gx_color_index color)
90
{
91
    gx_device_memory * const mdev = (gx_device_memory *)dev;
92
    declare_scan_ptr(dest);
93
    declare_unpack_color(abcd, efgh, color);
94
 
95
    /*
96
     * In order to avoid testing w > 0 and h > 0 twice, we defer
97
     * executing setup_rect, and use fit_fill_xywh instead of
98
     * fit_fill.
99
     */
100
    fit_fill_xywh(dev, x, y, w, h);
101
    INCR(fill);
102
#ifdef DEBUG
103
    stats_mem64.ftotal += w;
104
#endif
105
    if (h <= 0)
106
	return 0;
107
    if (w >= 5) {
108
	INCR(fwide);
109
	setup_rect(dest);
110
#ifdef DEBUG
111
	{
112
	    int ci;
113
	    for (ci = 0; ci < prev_count; ++ci)
114
		if (prev_colors[ci] == color)
115
	    	    break;
116
	    INCR(fprevc[ci]);
117
	    if (ci == prev_count) {
118
		if (ci < countof(prev_colors))
119
	    	    ++prev_count;
120
		else
121
	    	    --ci;
122
	    }
123
	    if (ci) {
124
		memmove(&prev_colors[1], &prev_colors[0],
125
			ci * sizeof(prev_colors[0]));
126
		prev_colors[0] = color;
127
	    }
128
	}
129
#endif
130
	INCR(fcolor[min(w, 100)]);
131
	while (h-- > 0) {
132
	    register bits32 *pptr = dest32;
133
	    int w1 = w;
134
 
135
	    while (w1 >= 4) {
136
		put8(pptr, abcd, efgh);
137
		put8(pptr + 2, abcd, efgh);
138
		put8(pptr + 4, abcd, efgh);
139
		put8(pptr + 6, abcd, efgh);
140
		pptr += 4 * PIXEL_SIZE;
141
		w1 -= 4;
142
	    }
143
	    switch (w1) {
144
		case 1:
145
		    put8(pptr, abcd, efgh);
146
		    break;
147
		case 2:
148
		    put8(pptr, abcd, efgh);
149
		    put8(pptr + 2, abcd, efgh);
150
		    break;
151
		case 3:
152
		    put8(pptr, abcd, efgh);
153
		    put8(pptr + 2, abcd, efgh);
154
		    put8(pptr + 4, abcd, efgh);
155
		    break;
156
		case 0:
157
		    ;
158
	    }
159
	    inc_ptr(dest, draster);
160
	}
161
    } else {		/* w < 5 */
162
	INCR(fnarrow[max(w, 0)]);
163
	setup_rect(dest);
164
	switch (w) {
165
	    case 4:
166
		do {
167
		    put8(dest32, abcd, efgh);
168
		    put8(dest32 + 2, abcd, efgh);
169
		    put8(dest32 + 4, abcd, efgh);
170
		    put8(dest32 + 6, abcd, efgh);
171
		    inc_ptr(dest, draster);
172
		}
173
		while (--h);
174
		break;
175
	    case 3:
176
		do {
177
		    put8(dest32, abcd, efgh);
178
		    put8(dest32 + 2, abcd, efgh);
179
		    put8(dest32 + 4, abcd, efgh);
180
		    inc_ptr(dest, draster);
181
		}
182
		while (--h);
183
		break;
184
	    case 2:
185
		do {
186
		    put8(dest32, abcd, efgh);
187
		    put8(dest32 + 2, abcd, efgh);
188
		    inc_ptr(dest, draster);
189
		}
190
		while (--h);
191
		break;
192
	    case 1:
193
		do {
194
		    put8(dest32, abcd, efgh);
195
		    inc_ptr(dest, draster);
196
		}
197
		while (--h);
198
		break;
199
	    case 0:
200
	    default:
201
		;
202
	}
203
    }
204
    return 0;
205
}
206
 
207
/* Copy a monochrome bitmap. */
208
private int
209
mem_true64_copy_mono(gx_device * dev,
210
	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
211
	int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
212
{
213
    gx_device_memory * const mdev = (gx_device_memory *)dev;
214
    const byte *line;
215
    int sbit;
216
    int first_bit;
217
 
218
    declare_scan_ptr(dest);
219
 
220
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
221
    setup_rect(dest);
222
    line = base + (sourcex >> 3);
223
    sbit = sourcex & 7;
224
    first_bit = 0x80 >> sbit;
225
    if (zero != gx_no_color_index) {	/* Loop for halftones or inverted masks */
226
	/* (never used). */
227
	declare_unpack_color(abcd0, efgh0, zero);
228
	declare_unpack_color(abcd1, efgh1, one);
229
	while (h-- > 0) {
230
	    register bits32 *pptr = dest32;
231
	    const byte *sptr = line;
232
	    register int sbyte = *sptr++;
233
	    register int bit = first_bit;
234
	    int count = w;
235
 
236
	    do {
237
		if (sbyte & bit) {
238
		    if (one != gx_no_color_index)
239
			put8(pptr, abcd1, efgh1);
240
		} else
241
		    put8(pptr, abcd0, efgh0);
242
		pptr += PIXEL_SIZE;
243
		if ((bit >>= 1) == 0)
244
		    bit = 0x80, sbyte = *sptr++;
245
	    }
246
	    while (--count > 0);
247
	    line += sraster;
248
	    inc_ptr(dest, draster);
249
	}
250
    } else if (one != gx_no_color_index) {	/* Loop for character and pattern masks. */
251
	/* This is used heavily. */
252
	declare_unpack_color(abcd1, efgh1, one);
253
	int first_mask = first_bit << 1;
254
	int first_count, first_skip;
255
 
256
	if (sbit + w > 8)
257
	    first_mask -= 1,
258
		first_count = 8 - sbit;
259
	else
260
	    first_mask -= first_mask >> w,
261
		first_count = w;
262
	first_skip = first_count * PIXEL_SIZE;
263
	while (h-- > 0) {
264
	    register bits32 *pptr = dest32;
265
	    const byte *sptr = line;
266
	    register int sbyte = *sptr++ & first_mask;
267
	    int count = w - first_count;
268
 
269
	    if (sbyte) {
270
		register int bit = first_bit;
271
 
272
		do {
273
		    if (sbyte & bit)
274
			put8(pptr, abcd1, efgh1);
275
		    pptr += PIXEL_SIZE;
276
		}
277
		while ((bit >>= 1) & first_mask);
278
	    } else
279
		pptr += first_skip;
280
	    while (count >= 8) {
281
		sbyte = *sptr++;
282
		if (sbyte & 0xf0) {
283
		    if (sbyte & 0x80)
284
			put8(pptr, abcd1, efgh1);
285
		    if (sbyte & 0x40)
286
			put8(pptr + 2, abcd1, efgh1);
287
		    if (sbyte & 0x20)
288
			put8(pptr + 4, abcd1, efgh1);
289
		    if (sbyte & 0x10)
290
			put8(pptr + 6, abcd1, efgh1);
291
		}
292
		if (sbyte & 0xf) {
293
		    if (sbyte & 8)
294
			put8(pptr + 8, abcd1, efgh1);
295
		    if (sbyte & 4)
296
			put8(pptr + 10, abcd1, efgh1);
297
		    if (sbyte & 2)
298
			put8(pptr + 12, abcd1, efgh1);
299
		    if (sbyte & 1)
300
			put8(pptr + 14, abcd1, efgh1);
301
		}
302
		pptr += 8 * PIXEL_SIZE;
303
		count -= 8;
304
	    }
305
	    if (count > 0) {
306
		register int bit = 0x80;
307
 
308
		sbyte = *sptr++;
309
		do {
310
		    if (sbyte & bit)
311
			put8(pptr, abcd1, efgh1);
312
		    pptr += PIXEL_SIZE;
313
		    bit >>= 1;
314
		}
315
		while (--count > 0);
316
	    }
317
	    line += sraster;
318
	    inc_ptr(dest, draster);
319
	}
320
    }
321
    return 0;
322
}
323
 
324
/* Copy a color bitmap. */
325
private int
326
mem_true64_copy_color(gx_device * dev,
327
	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
328
		      int x, int y, int w, int h)
329
{
330
    gx_device_memory * const mdev = (gx_device_memory *)dev;
331
 
332
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
333
    mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
334
    return 0;
335
}
336
 
337
/* ================ "Word"-oriented device ================ */
338
 
339
/* Note that on a big-endian machine, this is the same as the */
340
/* standard byte-oriented-device. */
341
 
342
#if !arch_is_big_endian
343
 
344
/* Procedures */
345
declare_mem_procs(mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle);
346
 
347
/* Here is the device descriptor. */
348
const gx_device_memory mem_true64_word_device =
349
mem_full_device("image64w", 64, 0, mem_open,
350
		gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
351
     mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle,
352
		gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,
353
		gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
354
 
355
/* Fill a rectangle with a color. */
356
private int
357
mem64_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
358
			  gx_color_index color)
359
{
360
    gx_device_memory * const mdev = (gx_device_memory *)dev;
361
    byte *base;
362
    uint raster;
363
 
364
    fit_fill(dev, x, y, w, h);
365
    base = scan_line_base(mdev, y);
366
    raster = mdev->raster;
367
    mem_swap_byte_rect(base, raster, x * 64, w * 64, h, true);
368
    mem_true64_fill_rectangle(dev, x, y, w, h, color);
369
    mem_swap_byte_rect(base, raster, x * 64, w * 64, h, false);
370
    return 0;
371
}
372
 
373
/* Copy a bitmap. */
374
private int
375
mem64_word_copy_mono(gx_device * dev,
376
	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
377
	int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
378
{
379
    gx_device_memory * const mdev = (gx_device_memory *)dev;
380
    byte *row;
381
    uint raster;
382
    bool store;
383
 
384
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
385
    row = scan_line_base(mdev, y);
386
    raster = mdev->raster;
387
    store = (zero != gx_no_color_index && one != gx_no_color_index);
388
    mem_swap_byte_rect(row, raster, x * 64, w * 64, h, store);
389
    mem_true64_copy_mono(dev, base, sourcex, sraster, id,
390
			 x, y, w, h, zero, one);
391
    mem_swap_byte_rect(row, raster, x * 64, w * 64, h, false);
392
    return 0;
393
}
394
 
395
/* Copy a color bitmap. */
396
private int
397
mem64_word_copy_color(gx_device * dev,
398
	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
399
		      int x, int y, int w, int h)
400
{
401
    gx_device_memory * const mdev = (gx_device_memory *)dev;
402
    byte *row;
403
    uint raster;
404
 
405
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
406
    row = scan_line_base(mdev, y);
407
    raster = mdev->raster;
408
    mem_swap_byte_rect(row, raster, x * 64, w * 64, h, true);
409
    bytes_copy_rectangle(row + x * PIXEL_SIZE, raster, base + sourcex * PIXEL_SIZE,
410
    				sraster, w * PIXEL_SIZE, h);
411
    mem_swap_byte_rect(row, raster, x * 64, w * 64, h, false);
412
    return 0;
413
}
414
 
415
#endif /* !arch_is_big_endian */