rasops24.c revision 1.30
1/* $NetBSD: rasops24.c,v 1.30 2018/12/04 09:27:59 mlelstv 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.30 2018/12/04 09:27:59 mlelstv 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 48static void rasops24_erasecols(void *, int, int, int, long); 49static void rasops24_eraserows(void *, int, int, long); 50static void rasops24_putchar(void *, int, int, u_int, long attr); 51#ifndef RASOPS_SMALL 52static void rasops24_putchar8(void *, int, int, u_int, long attr); 53static void rasops24_putchar12(void *, int, int, u_int, long attr); 54static void rasops24_putchar16(void *, int, int, u_int, long attr); 55static void rasops24_makestamp(struct rasops_info *, long); 56 57/* 58 * 4x1 stamp for optimized character blitting 59 */ 60static int32_t stamp[64]; 61static long stamp_attr; 62static int stamp_mutex; /* XXX see note in readme */ 63#endif 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 */ 81void 82rasops24_init(struct rasops_info *ri) 83{ 84 85 switch (ri->ri_font->fontwidth) { 86#ifndef RASOPS_SMALL 87 case 8: 88 ri->ri_ops.putchar = rasops24_putchar8; 89 break; 90 case 12: 91 ri->ri_ops.putchar = rasops24_putchar12; 92 break; 93 case 16: 94 ri->ri_ops.putchar = rasops24_putchar16; 95 break; 96#endif 97 default: 98 ri->ri_ops.putchar = rasops24_putchar; 99 break; 100 } 101 102 if (ri->ri_rnum == 0) { 103 ri->ri_rnum = 8; 104 ri->ri_rpos = 0; 105 ri->ri_gnum = 8; 106 ri->ri_gpos = 8; 107 ri->ri_bnum = 8; 108 ri->ri_bpos = 16; 109 } 110 111 ri->ri_ops.erasecols = rasops24_erasecols; 112 ri->ri_ops.eraserows = rasops24_eraserows; 113} 114 115/* 116 * Put a single character. This is the generic version. 117 * XXX this bites - we should use masks. 118 */ 119static void 120rasops24_putchar(void *cookie, int row, int col, u_int uc, long attr) 121{ 122 int fb, width, height, cnt, clr[2]; 123 struct rasops_info *ri = (struct rasops_info *)cookie; 124 struct wsdisplay_font *font = PICK_FONT(ri, uc); 125 u_char *dp, *rp, *fr; 126 127#ifdef RASOPS_CLIPPING 128 /* Catches 'row < 0' case too */ 129 if ((unsigned)row >= (unsigned)ri->ri_rows) 130 return; 131 132 if ((unsigned)col >= (unsigned)ri->ri_cols) 133 return; 134#endif 135 136 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; 137 height = font->fontheight; 138 width = font->fontwidth; 139 140 clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf]; 141 clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf]; 142 143 if (uc == ' ') { 144 u_char c = clr[0]; 145 while (height--) { 146 dp = rp; 147 rp += ri->ri_stride; 148 149 for (cnt = width; cnt; cnt--) { 150 *dp++ = c >> 16; 151 *dp++ = c >> 8; 152 *dp++ = c; 153 } 154 } 155 } else { 156 uc -= font->firstchar; 157 fr = (u_char *)font->data + uc * ri->ri_fontscale; 158 159 while (height--) { 160 dp = rp; 161 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | 162 (fr[0] << 24); 163 fr += font->stride; 164 rp += ri->ri_stride; 165 166 for (cnt = width; cnt; cnt--, fb <<= 1) { 167 if ((fb >> 31) & 1) { 168 *dp++ = clr[1] >> 16; 169 *dp++ = clr[1] >> 8; 170 *dp++ = clr[1]; 171 } else { 172 *dp++ = clr[0] >> 16; 173 *dp++ = clr[0] >> 8; 174 *dp++ = clr[0]; 175 } 176 } 177 } 178 } 179 180 /* Do underline */ 181 if ((attr & WSATTR_UNDERLINE) != 0) { 182 u_char c = clr[1]; 183 184 rp -= ri->ri_stride << 1; 185 186 while (width--) { 187 *rp++ = c >> 16; 188 *rp++ = c >> 8; 189 *rp++ = c; 190 } 191 } 192} 193 194#ifndef RASOPS_SMALL 195/* 196 * Recompute the blitting stamp. 197 */ 198static void 199rasops24_makestamp(struct rasops_info *ri, long attr) 200{ 201 u_int fg, bg, c1, c2, c3, c4; 202 int i; 203 204 fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff; 205 bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff; 206 stamp_attr = attr; 207 208 for (i = 0; i < 64; i += 4) { 209#if BYTE_ORDER == LITTLE_ENDIAN 210 c1 = (i & 32 ? fg : bg); 211 c2 = (i & 16 ? fg : bg); 212 c3 = (i & 8 ? fg : bg); 213 c4 = (i & 4 ? fg : bg); 214#else 215 c1 = (i & 8 ? fg : bg); 216 c2 = (i & 4 ? fg : bg); 217 c3 = (i & 16 ? fg : bg); 218 c4 = (i & 32 ? fg : bg); 219#endif 220 stamp[i+0] = (c1 << 8) | (c2 >> 16); 221 stamp[i+1] = (c2 << 16) | (c3 >> 8); 222 stamp[i+2] = (c3 << 24) | c4; 223 224#if BYTE_ORDER == LITTLE_ENDIAN 225 if ((ri->ri_flg & RI_BSWAP) == 0) { 226#else 227 if ((ri->ri_flg & RI_BSWAP) != 0) { 228#endif 229 stamp[i+0] = bswap32(stamp[i+0]); 230 stamp[i+1] = bswap32(stamp[i+1]); 231 stamp[i+2] = bswap32(stamp[i+2]); 232 } 233 } 234} 235 236/* 237 * Put a single character. This is for 8-pixel wide fonts. 238 */ 239static void 240rasops24_putchar8(void *cookie, int row, int col, u_int uc, long attr) 241{ 242 struct rasops_info *ri = (struct rasops_info *)cookie; 243 struct wsdisplay_font *font = PICK_FONT(ri, uc); 244 int height, so, fs; 245 int32_t *rp; 246 u_char *fr; 247 248 /* Can't risk remaking the stamp if it's already in use */ 249 if (stamp_mutex++) { 250 stamp_mutex--; 251 rasops24_putchar(cookie, row, col, uc, attr); 252 return; 253 } 254 255#ifdef RASOPS_CLIPPING 256 if ((unsigned)row >= (unsigned)ri->ri_rows) { 257 stamp_mutex--; 258 return; 259 } 260 261 if ((unsigned)col >= (unsigned)ri->ri_cols) { 262 stamp_mutex--; 263 return; 264 } 265#endif 266 267 /* Recompute stamp? */ 268 if (attr != stamp_attr) 269 rasops24_makestamp(ri, attr); 270 271 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 272 height = font->fontheight; 273 274 if (uc == (u_int)-1) { 275 int32_t c = stamp[0]; 276 while (height--) { 277 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c; 278 DELTA(rp, ri->ri_stride, int32_t *); 279 } 280 } else { 281 uc -= font->firstchar; 282 fr = (u_char *)font->data + uc*ri->ri_fontscale; 283 fs = font->stride; 284 285 while (height--) { 286 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 287 rp[0] = STAMP_READ(so); 288 rp[1] = STAMP_READ(so + 4); 289 rp[2] = STAMP_READ(so + 8); 290 291 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 292 rp[3] = STAMP_READ(so); 293 rp[4] = STAMP_READ(so + 4); 294 rp[5] = STAMP_READ(so + 8); 295 296 fr += fs; 297 DELTA(rp, ri->ri_stride, int32_t *); 298 } 299 } 300 301 /* Do underline */ 302 if ((attr & WSATTR_UNDERLINE) != 0) { 303 int32_t c = STAMP_READ(52); 304 305 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 306 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c; 307 } 308 309 stamp_mutex--; 310} 311 312/* 313 * Put a single character. This is for 12-pixel wide fonts. 314 */ 315static void 316rasops24_putchar12(void *cookie, int row, int col, u_int uc, long attr) 317{ 318 struct rasops_info *ri = (struct rasops_info *)cookie; 319 struct wsdisplay_font *font = PICK_FONT(ri, uc); 320 int height, so, fs; 321 int32_t *rp; 322 u_char *fr; 323 324 /* Can't risk remaking the stamp if it's already in use */ 325 if (stamp_mutex++) { 326 stamp_mutex--; 327 rasops24_putchar(cookie, row, col, uc, attr); 328 return; 329 } 330 331#ifdef RASOPS_CLIPPING 332 if ((unsigned)row >= (unsigned)ri->ri_rows) { 333 stamp_mutex--; 334 return; 335 } 336 337 if ((unsigned)col >= (unsigned)ri->ri_cols) { 338 stamp_mutex--; 339 return; 340 } 341#endif 342 343 /* Recompute stamp? */ 344 if (attr != stamp_attr) 345 rasops24_makestamp(ri, attr); 346 347 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 348 height = font->fontheight; 349 350 if (uc == (u_int)-1) { 351 int32_t c = stamp[0]; 352 while (height--) { 353 rp[0] = rp[1] = rp[2] = rp[3] = 354 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c; 355 DELTA(rp, ri->ri_stride, int32_t *); 356 } 357 } else { 358 uc -= font->firstchar; 359 fr = (u_char *)font->data + uc*ri->ri_fontscale; 360 fs = font->stride; 361 362 while (height--) { 363 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 364 rp[0] = STAMP_READ(so); 365 rp[1] = STAMP_READ(so + 4); 366 rp[2] = STAMP_READ(so + 8); 367 368 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 369 rp[3] = STAMP_READ(so); 370 rp[4] = STAMP_READ(so + 4); 371 rp[5] = STAMP_READ(so + 8); 372 373 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK; 374 rp[6] = STAMP_READ(so); 375 rp[7] = STAMP_READ(so + 4); 376 rp[8] = STAMP_READ(so + 8); 377 378 fr += fs; 379 DELTA(rp, ri->ri_stride, int32_t *); 380 } 381 } 382 383 /* Do underline */ 384 if ((attr & WSATTR_UNDERLINE) != 0) { 385 int32_t c = STAMP_READ(52); 386 387 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 388 rp[0] = rp[1] = rp[2] = rp[3] = 389 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c; 390 } 391 392 stamp_mutex--; 393} 394 395/* 396 * Put a single character. This is for 16-pixel wide fonts. 397 */ 398static void 399rasops24_putchar16(void *cookie, int row, int col, u_int uc, long attr) 400{ 401 struct rasops_info *ri = (struct rasops_info *)cookie; 402 struct wsdisplay_font *font = PICK_FONT(ri, uc); 403 int height, so, fs; 404 int32_t *rp; 405 u_char *fr; 406 407 /* Can't risk remaking the stamp if it's already in use */ 408 if (stamp_mutex++) { 409 stamp_mutex--; 410 rasops24_putchar(cookie, row, col, uc, attr); 411 return; 412 } 413 414#ifdef RASOPS_CLIPPING 415 if ((unsigned)row >= (unsigned)ri->ri_rows) { 416 stamp_mutex--; 417 return; 418 } 419 420 if ((unsigned)col >= (unsigned)ri->ri_cols) { 421 stamp_mutex--; 422 return; 423 } 424#endif 425 426 /* Recompute stamp? */ 427 if (attr != stamp_attr) 428 rasops24_makestamp(ri, attr); 429 430 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 431 height = font->fontheight; 432 433 if (uc == (u_int)-1) { 434 int32_t c = stamp[0]; 435 while (height--) { 436 rp[0] = rp[1] = rp[2] = rp[3] = 437 rp[4] = rp[5] = rp[6] = rp[7] = 438 rp[8] = rp[9] = rp[10] = rp[11] = c; 439 DELTA(rp, ri->ri_stride, int32_t *); 440 } 441 } else { 442 uc -= font->firstchar; 443 fr = (u_char *)font->data + uc*ri->ri_fontscale; 444 fs = font->stride; 445 446 while (height--) { 447 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 448 rp[0] = STAMP_READ(so); 449 rp[1] = STAMP_READ(so + 4); 450 rp[2] = STAMP_READ(so + 8); 451 452 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 453 rp[3] = STAMP_READ(so); 454 rp[4] = STAMP_READ(so + 4); 455 rp[5] = STAMP_READ(so + 8); 456 457 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK; 458 rp[6] = STAMP_READ(so); 459 rp[7] = STAMP_READ(so + 4); 460 rp[8] = STAMP_READ(so + 8); 461 462 so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK; 463 rp[9] = STAMP_READ(so); 464 rp[10] = STAMP_READ(so + 4); 465 rp[11] = STAMP_READ(so + 8); 466 467 DELTA(rp, ri->ri_stride, int32_t *); 468 fr += fs; 469 } 470 } 471 472 /* Do underline */ 473 if ((attr & WSATTR_UNDERLINE) != 0) { 474 int32_t c = STAMP_READ(52); 475 476 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 477 rp[0] = rp[1] = rp[2] = rp[3] = 478 rp[4] = rp[5] = rp[6] = rp[7] = 479 rp[8] = rp[9] = rp[10] = rp[11] = c; 480 } 481 482 stamp_mutex--; 483} 484#endif /* !RASOPS_SMALL */ 485 486/* 487 * Erase rows. This is nice and easy due to alignment. 488 */ 489static void 490rasops24_eraserows(void *cookie, int row, int num, long attr) 491{ 492 int n9, n3, n1, cnt, stride, delta; 493 u_int32_t *dp, clr, xstamp[3]; 494 struct rasops_info *ri; 495 496 /* 497 * If the color is gray, we can cheat and use the generic routines 498 * (which are faster, hopefully) since the r,g,b values are the same. 499 */ 500 if ((attr & WSATTR_PRIVATE2) != 0) { 501 rasops_eraserows(cookie, row, num, attr); 502 return; 503 } 504 505 ri = (struct rasops_info *)cookie; 506 507#ifdef RASOPS_CLIPPING 508 if (row < 0) { 509 num += row; 510 row = 0; 511 } 512 513 if ((row + num) > ri->ri_rows) 514 num = ri->ri_rows - row; 515 516 if (num <= 0) 517 return; 518#endif 519 520 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff; 521 xstamp[0] = (clr << 8) | (clr >> 16); 522 xstamp[1] = (clr << 16) | (clr >> 8); 523 xstamp[2] = (clr << 24) | clr; 524 525#if BYTE_ORDER == LITTLE_ENDIAN 526 if ((ri->ri_flg & RI_BSWAP) == 0) { 527#else 528 if ((ri->ri_flg & RI_BSWAP) != 0) { 529#endif 530 xstamp[0] = bswap32(xstamp[0]); 531 xstamp[1] = bswap32(xstamp[1]); 532 xstamp[2] = bswap32(xstamp[2]); 533 } 534 535 /* 536 * XXX the wsdisplay_emulops interface seems a little deficient in 537 * that there is no way to clear the *entire* screen. We provide a 538 * workaround here: if the entire console area is being cleared, and 539 * the RI_FULLCLEAR flag is set, clear the entire display. 540 */ 541 if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) { 542 stride = ri->ri_stride; 543 num = ri->ri_height; 544 dp = (int32_t *)ri->ri_origbits; 545 delta = 0; 546 } else { 547 stride = ri->ri_emustride; 548 num *= ri->ri_font->fontheight; 549 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale); 550 delta = ri->ri_delta; 551 } 552 553 n9 = stride / 36; 554 cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */ 555 n3 = (stride - cnt) / 12; 556 cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */ 557 n1 = (stride - cnt) >> 2; 558 559 while (num--) { 560 for (cnt = n9; cnt; cnt--) { 561 dp[0] = xstamp[0]; 562 dp[1] = xstamp[1]; 563 dp[2] = xstamp[2]; 564 dp[3] = xstamp[0]; 565 dp[4] = xstamp[1]; 566 dp[5] = xstamp[2]; 567 dp[6] = xstamp[0]; 568 dp[7] = xstamp[1]; 569 dp[8] = xstamp[2]; 570 dp += 9; 571 } 572 573 for (cnt = n3; cnt; cnt--) { 574 dp[0] = xstamp[0]; 575 dp[1] = xstamp[1]; 576 dp[2] = xstamp[2]; 577 dp += 3; 578 } 579 580 for (cnt = 0; cnt < n1; cnt++) 581 *dp++ = xstamp[cnt]; 582 583 DELTA(dp, delta, int32_t *); 584 } 585} 586 587/* 588 * Erase columns. 589 */ 590static void 591rasops24_erasecols(void *cookie, int row, int col, int num, long attr) 592{ 593 int n12, n4, height, cnt, slop, clr, xstamp[3]; 594 struct rasops_info *ri; 595 int32_t *dp, *rp; 596 u_char *dbp; 597 598 /* 599 * If the color is gray, we can cheat and use the generic routines 600 * (which are faster, hopefully) since the r,g,b values are the same. 601 */ 602 if ((attr & WSATTR_PRIVATE2) != 0) { 603 rasops_erasecols(cookie, row, col, num, attr); 604 return; 605 } 606 607 ri = (struct rasops_info *)cookie; 608 609#ifdef RASOPS_CLIPPING 610 /* Catches 'row < 0' case too */ 611 if ((unsigned)row >= (unsigned)ri->ri_rows) 612 return; 613 614 if (col < 0) { 615 num += col; 616 col = 0; 617 } 618 619 if ((col + num) > ri->ri_cols) 620 num = ri->ri_cols - col; 621 622 if (num <= 0) 623 return; 624#endif 625 626 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 627 num *= ri->ri_font->fontwidth; 628 height = ri->ri_font->fontheight; 629 630 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff; 631 xstamp[0] = (clr << 8) | (clr >> 16); 632 xstamp[1] = (clr << 16) | (clr >> 8); 633 xstamp[2] = (clr << 24) | clr; 634 635#if BYTE_ORDER == LITTLE_ENDIAN 636 if ((ri->ri_flg & RI_BSWAP) == 0) { 637#else 638 if ((ri->ri_flg & RI_BSWAP) != 0) { 639#endif 640 xstamp[0] = bswap32(xstamp[0]); 641 xstamp[1] = bswap32(xstamp[1]); 642 xstamp[2] = bswap32(xstamp[2]); 643 } 644 645 /* 646 * The current byte offset mod 4 tells us the number of 24-bit pels 647 * we need to write for alignment to 32-bits. Once we're aligned on 648 * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so 649 * the stamp does not need to be rotated. The following shows the 650 * layout of 4 pels in a 3 word region and illustrates this: 651 * 652 * aaab bbcc cddd 653 */ 654 slop = (int)(long)rp & 3; num -= slop; 655 n12 = num / 12; num -= (n12 << 3) + (n12 << 2); 656 n4 = num >> 2; num &= 3; 657 658 while (height--) { 659 dbp = (u_char *)rp; 660 DELTA(rp, ri->ri_stride, int32_t *); 661 662 /* Align to 4 bytes */ 663 /* XXX handle with masks, bring under control of RI_BSWAP */ 664 for (cnt = slop; cnt; cnt--) { 665 *dbp++ = (clr >> 16); 666 *dbp++ = (clr >> 8); 667 *dbp++ = clr; 668 } 669 670 dp = (int32_t *)dbp; 671 672 /* 12 pels per loop */ 673 for (cnt = n12; cnt; cnt--) { 674 dp[0] = xstamp[0]; 675 dp[1] = xstamp[1]; 676 dp[2] = xstamp[2]; 677 dp[3] = xstamp[0]; 678 dp[4] = xstamp[1]; 679 dp[5] = xstamp[2]; 680 dp[6] = xstamp[0]; 681 dp[7] = xstamp[1]; 682 dp[8] = xstamp[2]; 683 dp += 9; 684 } 685 686 /* 4 pels per loop */ 687 for (cnt = n4; cnt; cnt--) { 688 dp[0] = xstamp[0]; 689 dp[1] = xstamp[1]; 690 dp[2] = xstamp[2]; 691 dp += 3; 692 } 693 694 /* Trailing slop */ 695 /* XXX handle with masks, bring under control of RI_BSWAP */ 696 dbp = (u_char *)dp; 697 for (cnt = num; cnt; cnt--) { 698 *dbp++ = (clr >> 16); 699 *dbp++ = (clr >> 8); 700 *dbp++ = clr; 701 } 702 } 703} 704