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