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