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