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