rasops24.c revision 1.25 1 /* $NetBSD: rasops24.c,v 1.25 2008/04/28 20:23:56 martin Exp $ */
2
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.25 2008/04/28 20:23:56 martin Exp $");
34
35 #include "opt_rasops.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/time.h>
40
41 #include <machine/endian.h>
42 #include <sys/bswap.h>
43
44 #include <dev/wscons/wsdisplayvar.h>
45 #include <dev/wscons/wsconsio.h>
46 #include <dev/rasops/rasops.h>
47
48 static void rasops24_erasecols(void *, int, int, int, long);
49 static void rasops24_eraserows(void *, int, int, long);
50 static void rasops24_putchar(void *, int, int, u_int, long attr);
51 #ifndef RASOPS_SMALL
52 static void rasops24_putchar8(void *, int, int, u_int, long attr);
53 static void rasops24_putchar12(void *, int, int, u_int, long attr);
54 static void rasops24_putchar16(void *, int, int, u_int, long attr);
55 static void rasops24_makestamp(struct rasops_info *, long);
56 #endif
57
58 /*
59 * 4x1 stamp for optimized character blitting
60 */
61 static int32_t stamp[64];
62 static long stamp_attr;
63 static int stamp_mutex; /* XXX see note in readme */
64
65 /*
66 * XXX this confuses the hell out of gcc2 (not egcs) which always insists
67 * that the shift count is negative.
68 *
69 * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
70 * destination int32_t[0] = STAMP_READ(offset)
71 * destination int32_t[1] = STAMP_READ(offset + 4)
72 * destination int32_t[2] = STAMP_READ(offset + 8)
73 */
74 #define STAMP_SHIFT(fb,n) ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
75 #define STAMP_MASK (0xf << 4)
76 #define STAMP_READ(o) (*(int32_t *)((char *)stamp + (o)))
77
78 /*
79 * Initialize rasops_info struct for this colordepth.
80 */
81 void
82 rasops24_init(ri)
83 struct rasops_info *ri;
84 {
85
86 switch (ri->ri_font->fontwidth) {
87 #ifndef RASOPS_SMALL
88 case 8:
89 ri->ri_ops.putchar = rasops24_putchar8;
90 break;
91 case 12:
92 ri->ri_ops.putchar = rasops24_putchar12;
93 break;
94 case 16:
95 ri->ri_ops.putchar = rasops24_putchar16;
96 break;
97 #endif
98 default:
99 ri->ri_ops.putchar = rasops24_putchar;
100 break;
101 }
102
103 if (ri->ri_rnum == 0) {
104 ri->ri_rnum = 8;
105 ri->ri_rpos = 0;
106 ri->ri_gnum = 8;
107 ri->ri_gpos = 8;
108 ri->ri_bnum = 8;
109 ri->ri_bpos = 16;
110 }
111
112 ri->ri_ops.erasecols = rasops24_erasecols;
113 ri->ri_ops.eraserows = rasops24_eraserows;
114 }
115
116 /*
117 * Put a single character. This is the generic version.
118 * XXX this bites - we should use masks.
119 */
120 static void
121 rasops24_putchar(cookie, row, col, uc, attr)
122 void *cookie;
123 int row, col;
124 u_int uc;
125 long attr;
126 {
127 int fb, width, height, cnt, clr[2];
128 struct rasops_info *ri;
129 u_char *dp, *rp, *fr;
130
131 ri = (struct rasops_info *)cookie;
132
133 #ifdef RASOPS_CLIPPING
134 /* Catches 'row < 0' case too */
135 if ((unsigned)row >= (unsigned)ri->ri_rows)
136 return;
137
138 if ((unsigned)col >= (unsigned)ri->ri_cols)
139 return;
140 #endif
141
142 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
143 height = ri->ri_font->fontheight;
144 width = ri->ri_font->fontwidth;
145
146 clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
147 clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
148
149 if (uc == ' ') {
150 u_char c = clr[0];
151 while (height--) {
152 dp = rp;
153 rp += ri->ri_stride;
154
155 for (cnt = width; cnt; cnt--) {
156 *dp++ = c >> 16;
157 *dp++ = c >> 8;
158 *dp++ = c;
159 }
160 }
161 } else {
162 uc -= ri->ri_font->firstchar;
163 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
164
165 while (height--) {
166 dp = rp;
167 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
168 (fr[0] << 24);
169 fr += ri->ri_font->stride;
170 rp += ri->ri_stride;
171
172 for (cnt = width; cnt; cnt--, fb <<= 1) {
173 if ((fb >> 31) & 1) {
174 *dp++ = clr[1] >> 16;
175 *dp++ = clr[1] >> 8;
176 *dp++ = clr[1];
177 } else {
178 *dp++ = clr[0] >> 16;
179 *dp++ = clr[0] >> 8;
180 *dp++ = clr[0];
181 }
182 }
183 }
184 }
185
186 /* Do underline */
187 if ((attr & 1) != 0) {
188 u_char c = clr[1];
189
190 rp -= ri->ri_stride << 1;
191
192 while (width--) {
193 *rp++ = c >> 16;
194 *rp++ = c >> 8;
195 *rp++ = c;
196 }
197 }
198 }
199
200 #ifndef RASOPS_SMALL
201 /*
202 * Recompute the blitting stamp.
203 */
204 static void
205 rasops24_makestamp(ri, attr)
206 struct rasops_info *ri;
207 long attr;
208 {
209 u_int fg, bg, c1, c2, c3, c4;
210 int i;
211
212 fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
213 bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
214 stamp_attr = attr;
215
216 for (i = 0; i < 64; i += 4) {
217 #if BYTE_ORDER == LITTLE_ENDIAN
218 c1 = (i & 32 ? fg : bg);
219 c2 = (i & 16 ? fg : bg);
220 c3 = (i & 8 ? fg : bg);
221 c4 = (i & 4 ? fg : bg);
222 #else
223 c1 = (i & 8 ? fg : bg);
224 c2 = (i & 4 ? fg : bg);
225 c3 = (i & 16 ? fg : bg);
226 c4 = (i & 32 ? fg : bg);
227 #endif
228 stamp[i+0] = (c1 << 8) | (c2 >> 16);
229 stamp[i+1] = (c2 << 16) | (c3 >> 8);
230 stamp[i+2] = (c3 << 24) | c4;
231
232 #if BYTE_ORDER == LITTLE_ENDIAN
233 if ((ri->ri_flg & RI_BSWAP) == 0) {
234 #else
235 if ((ri->ri_flg & RI_BSWAP) != 0) {
236 #endif
237 stamp[i+0] = bswap32(stamp[i+0]);
238 stamp[i+1] = bswap32(stamp[i+1]);
239 stamp[i+2] = bswap32(stamp[i+2]);
240 }
241 }
242 }
243
244 /*
245 * Put a single character. This is for 8-pixel wide fonts.
246 */
247 static void
248 rasops24_putchar8(cookie, row, col, uc, attr)
249 void *cookie;
250 int row, col;
251 u_int uc;
252 long attr;
253 {
254 struct rasops_info *ri;
255 int height, so, fs;
256 int32_t *rp;
257 u_char *fr;
258
259 /* Can't risk remaking the stamp if it's already in use */
260 if (stamp_mutex++) {
261 stamp_mutex--;
262 rasops24_putchar(cookie, row, col, uc, attr);
263 return;
264 }
265
266 ri = (struct rasops_info *)cookie;
267
268 #ifdef RASOPS_CLIPPING
269 if ((unsigned)row >= (unsigned)ri->ri_rows) {
270 stamp_mutex--;
271 return;
272 }
273
274 if ((unsigned)col >= (unsigned)ri->ri_cols) {
275 stamp_mutex--;
276 return;
277 }
278 #endif
279
280 /* Recompute stamp? */
281 if (attr != stamp_attr)
282 rasops24_makestamp(ri, attr);
283
284 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
285 height = ri->ri_font->fontheight;
286
287 if (uc == (u_int)-1) {
288 int32_t c = stamp[0];
289 while (height--) {
290 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
291 DELTA(rp, ri->ri_stride, int32_t *);
292 }
293 } else {
294 uc -= ri->ri_font->firstchar;
295 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
296 fs = ri->ri_font->stride;
297
298 while (height--) {
299 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
300 rp[0] = STAMP_READ(so);
301 rp[1] = STAMP_READ(so + 4);
302 rp[2] = STAMP_READ(so + 8);
303
304 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
305 rp[3] = STAMP_READ(so);
306 rp[4] = STAMP_READ(so + 4);
307 rp[5] = STAMP_READ(so + 8);
308
309 fr += fs;
310 DELTA(rp, ri->ri_stride, int32_t *);
311 }
312 }
313
314 /* Do underline */
315 if ((attr & 1) != 0) {
316 int32_t c = STAMP_READ(52);
317
318 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
319 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
320 }
321
322 stamp_mutex--;
323 }
324
325 /*
326 * Put a single character. This is for 12-pixel wide fonts.
327 */
328 static void
329 rasops24_putchar12(cookie, row, col, uc, attr)
330 void *cookie;
331 int row, col;
332 u_int uc;
333 long attr;
334 {
335 struct rasops_info *ri;
336 int height, so, fs;
337 int32_t *rp;
338 u_char *fr;
339
340 /* Can't risk remaking the stamp if it's already in use */
341 if (stamp_mutex++) {
342 stamp_mutex--;
343 rasops24_putchar(cookie, row, col, uc, attr);
344 return;
345 }
346
347 ri = (struct rasops_info *)cookie;
348
349 #ifdef RASOPS_CLIPPING
350 if ((unsigned)row >= (unsigned)ri->ri_rows) {
351 stamp_mutex--;
352 return;
353 }
354
355 if ((unsigned)col >= (unsigned)ri->ri_cols) {
356 stamp_mutex--;
357 return;
358 }
359 #endif
360
361 /* Recompute stamp? */
362 if (attr != stamp_attr)
363 rasops24_makestamp(ri, attr);
364
365 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
366 height = ri->ri_font->fontheight;
367
368 if (uc == (u_int)-1) {
369 int32_t c = stamp[0];
370 while (height--) {
371 rp[0] = rp[1] = rp[2] = rp[3] =
372 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
373 DELTA(rp, ri->ri_stride, int32_t *);
374 }
375 } else {
376 uc -= ri->ri_font->firstchar;
377 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
378 fs = ri->ri_font->stride;
379
380 while (height--) {
381 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
382 rp[0] = STAMP_READ(so);
383 rp[1] = STAMP_READ(so + 4);
384 rp[2] = STAMP_READ(so + 8);
385
386 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
387 rp[3] = STAMP_READ(so);
388 rp[4] = STAMP_READ(so + 4);
389 rp[5] = STAMP_READ(so + 8);
390
391 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
392 rp[6] = STAMP_READ(so);
393 rp[7] = STAMP_READ(so + 4);
394 rp[8] = STAMP_READ(so + 8);
395
396 fr += fs;
397 DELTA(rp, ri->ri_stride, int32_t *);
398 }
399 }
400
401 /* Do underline */
402 if ((attr & 1) != 0) {
403 int32_t c = STAMP_READ(52);
404
405 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
406 rp[0] = rp[1] = rp[2] = rp[3] =
407 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
408 }
409
410 stamp_mutex--;
411 }
412
413 /*
414 * Put a single character. This is for 16-pixel wide fonts.
415 */
416 static void
417 rasops24_putchar16(cookie, row, col, uc, attr)
418 void *cookie;
419 int row, col;
420 u_int uc;
421 long attr;
422 {
423 struct rasops_info *ri;
424 int height, so, fs;
425 int32_t *rp;
426 u_char *fr;
427
428 /* Can't risk remaking the stamp if it's already in use */
429 if (stamp_mutex++) {
430 stamp_mutex--;
431 rasops24_putchar(cookie, row, col, uc, attr);
432 return;
433 }
434
435 ri = (struct rasops_info *)cookie;
436
437 #ifdef RASOPS_CLIPPING
438 if ((unsigned)row >= (unsigned)ri->ri_rows) {
439 stamp_mutex--;
440 return;
441 }
442
443 if ((unsigned)col >= (unsigned)ri->ri_cols) {
444 stamp_mutex--;
445 return;
446 }
447 #endif
448
449 /* Recompute stamp? */
450 if (attr != stamp_attr)
451 rasops24_makestamp(ri, attr);
452
453 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
454 height = ri->ri_font->fontheight;
455
456 if (uc == (u_int)-1) {
457 int32_t c = stamp[0];
458 while (height--) {
459 rp[0] = rp[1] = rp[2] = rp[3] =
460 rp[4] = rp[5] = rp[6] = rp[7] =
461 rp[8] = rp[9] = rp[10] = rp[11] = c;
462 DELTA(rp, ri->ri_stride, int32_t *);
463 }
464 } else {
465 uc -= ri->ri_font->firstchar;
466 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
467 fs = ri->ri_font->stride;
468
469 while (height--) {
470 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
471 rp[0] = STAMP_READ(so);
472 rp[1] = STAMP_READ(so + 4);
473 rp[2] = STAMP_READ(so + 8);
474
475 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
476 rp[3] = STAMP_READ(so);
477 rp[4] = STAMP_READ(so + 4);
478 rp[5] = STAMP_READ(so + 8);
479
480 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
481 rp[6] = STAMP_READ(so);
482 rp[7] = STAMP_READ(so + 4);
483 rp[8] = STAMP_READ(so + 8);
484
485 so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
486 rp[9] = STAMP_READ(so);
487 rp[10] = STAMP_READ(so + 4);
488 rp[11] = STAMP_READ(so + 8);
489
490 DELTA(rp, ri->ri_stride, int32_t *);
491 fr += fs;
492 }
493 }
494
495 /* Do underline */
496 if ((attr & 1) != 0) {
497 int32_t c = STAMP_READ(52);
498
499 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
500 rp[0] = rp[1] = rp[2] = rp[3] =
501 rp[4] = rp[5] = rp[6] = rp[7] =
502 rp[8] = rp[9] = rp[10] = rp[11] = c;
503 }
504
505 stamp_mutex--;
506 }
507 #endif /* !RASOPS_SMALL */
508
509 /*
510 * Erase rows. This is nice and easy due to alignment.
511 */
512 static void
513 rasops24_eraserows(cookie, row, num, attr)
514 void *cookie;
515 int row, num;
516 long attr;
517 {
518 int n9, n3, n1, cnt, stride, delta;
519 u_int32_t *dp, clr, xstamp[3];
520 struct rasops_info *ri;
521
522 /*
523 * If the color is gray, we can cheat and use the generic routines
524 * (which are faster, hopefully) since the r,g,b values are the same.
525 */
526 if ((attr & 4) != 0) {
527 rasops_eraserows(cookie, row, num, attr);
528 return;
529 }
530
531 ri = (struct rasops_info *)cookie;
532
533 #ifdef RASOPS_CLIPPING
534 if (row < 0) {
535 num += row;
536 row = 0;
537 }
538
539 if ((row + num) > ri->ri_rows)
540 num = ri->ri_rows - row;
541
542 if (num <= 0)
543 return;
544 #endif
545
546 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
547 xstamp[0] = (clr << 8) | (clr >> 16);
548 xstamp[1] = (clr << 16) | (clr >> 8);
549 xstamp[2] = (clr << 24) | clr;
550
551 #if BYTE_ORDER == LITTLE_ENDIAN
552 if ((ri->ri_flg & RI_BSWAP) == 0) {
553 #else
554 if ((ri->ri_flg & RI_BSWAP) != 0) {
555 #endif
556 xstamp[0] = bswap32(xstamp[0]);
557 xstamp[1] = bswap32(xstamp[1]);
558 xstamp[2] = bswap32(xstamp[2]);
559 }
560
561 /*
562 * XXX the wsdisplay_emulops interface seems a little deficient in
563 * that there is no way to clear the *entire* screen. We provide a
564 * workaround here: if the entire console area is being cleared, and
565 * the RI_FULLCLEAR flag is set, clear the entire display.
566 */
567 if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
568 stride = ri->ri_stride;
569 num = ri->ri_height;
570 dp = (int32_t *)ri->ri_origbits;
571 delta = 0;
572 } else {
573 stride = ri->ri_emustride;
574 num *= ri->ri_font->fontheight;
575 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
576 delta = ri->ri_delta;
577 }
578
579 n9 = stride / 36;
580 cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
581 n3 = (stride - cnt) / 12;
582 cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
583 n1 = (stride - cnt) >> 2;
584
585 while (num--) {
586 for (cnt = n9; cnt; cnt--) {
587 dp[0] = xstamp[0];
588 dp[1] = xstamp[1];
589 dp[2] = xstamp[2];
590 dp[3] = xstamp[0];
591 dp[4] = xstamp[1];
592 dp[5] = xstamp[2];
593 dp[6] = xstamp[0];
594 dp[7] = xstamp[1];
595 dp[8] = xstamp[2];
596 dp += 9;
597 }
598
599 for (cnt = n3; cnt; cnt--) {
600 dp[0] = xstamp[0];
601 dp[1] = xstamp[1];
602 dp[2] = xstamp[2];
603 dp += 3;
604 }
605
606 for (cnt = 0; cnt < n1; cnt++)
607 *dp++ = xstamp[cnt];
608
609 DELTA(dp, delta, int32_t *);
610 }
611 }
612
613 /*
614 * Erase columns.
615 */
616 static void
617 rasops24_erasecols(cookie, row, col, num, attr)
618 void *cookie;
619 int row, col, num;
620 long attr;
621 {
622 int n12, n4, height, cnt, slop, clr, xstamp[3];
623 struct rasops_info *ri;
624 int32_t *dp, *rp;
625 u_char *dbp;
626
627 /*
628 * If the color is gray, we can cheat and use the generic routines
629 * (which are faster, hopefully) since the r,g,b values are the same.
630 */
631 if ((attr & 4) != 0) {
632 rasops_erasecols(cookie, row, col, num, attr);
633 return;
634 }
635
636 ri = (struct rasops_info *)cookie;
637
638 #ifdef RASOPS_CLIPPING
639 /* Catches 'row < 0' case too */
640 if ((unsigned)row >= (unsigned)ri->ri_rows)
641 return;
642
643 if (col < 0) {
644 num += col;
645 col = 0;
646 }
647
648 if ((col + num) > ri->ri_cols)
649 num = ri->ri_cols - col;
650
651 if (num <= 0)
652 return;
653 #endif
654
655 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
656 num *= ri->ri_font->fontwidth;
657 height = ri->ri_font->fontheight;
658
659 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
660 xstamp[0] = (clr << 8) | (clr >> 16);
661 xstamp[1] = (clr << 16) | (clr >> 8);
662 xstamp[2] = (clr << 24) | clr;
663
664 #if BYTE_ORDER == LITTLE_ENDIAN
665 if ((ri->ri_flg & RI_BSWAP) == 0) {
666 #else
667 if ((ri->ri_flg & RI_BSWAP) != 0) {
668 #endif
669 xstamp[0] = bswap32(xstamp[0]);
670 xstamp[1] = bswap32(xstamp[1]);
671 xstamp[2] = bswap32(xstamp[2]);
672 }
673
674 /*
675 * The current byte offset mod 4 tells us the number of 24-bit pels
676 * we need to write for alignment to 32-bits. Once we're aligned on
677 * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
678 * the stamp does not need to be rotated. The following shows the
679 * layout of 4 pels in a 3 word region and illustrates this:
680 *
681 * aaab bbcc cddd
682 */
683 slop = (int)(long)rp & 3; num -= slop;
684 n12 = num / 12; num -= (n12 << 3) + (n12 << 2);
685 n4 = num >> 2; num &= 3;
686
687 while (height--) {
688 dbp = (u_char *)rp;
689 DELTA(rp, ri->ri_stride, int32_t *);
690
691 /* Align to 4 bytes */
692 /* XXX handle with masks, bring under control of RI_BSWAP */
693 for (cnt = slop; cnt; cnt--) {
694 *dbp++ = (clr >> 16);
695 *dbp++ = (clr >> 8);
696 *dbp++ = clr;
697 }
698
699 dp = (int32_t *)dbp;
700
701 /* 12 pels per loop */
702 for (cnt = n12; cnt; cnt--) {
703 dp[0] = xstamp[0];
704 dp[1] = xstamp[1];
705 dp[2] = xstamp[2];
706 dp[3] = xstamp[0];
707 dp[4] = xstamp[1];
708 dp[5] = xstamp[2];
709 dp[6] = xstamp[0];
710 dp[7] = xstamp[1];
711 dp[8] = xstamp[2];
712 dp += 9;
713 }
714
715 /* 4 pels per loop */
716 for (cnt = n4; cnt; cnt--) {
717 dp[0] = xstamp[0];
718 dp[1] = xstamp[1];
719 dp[2] = xstamp[2];
720 dp += 3;
721 }
722
723 /* Trailing slop */
724 /* XXX handle with masks, bring under control of RI_BSWAP */
725 dbp = (u_char *)dp;
726 for (cnt = num; cnt; cnt--) {
727 *dbp++ = (clr >> 16);
728 *dbp++ = (clr >> 8);
729 *dbp++ = clr;
730 }
731 }
732 }
733