pixman-bits-image.c (35925B)
1 /* 2 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 3 * 2005 Lars Knoll & Zack Rusin, Trolltech 4 * 2008 Aaron Plattner, NVIDIA Corporation 5 * Copyright © 2000 SuSE, Inc. 6 * Copyright © 2007, 2009 Red Hat, Inc. 7 * Copyright © 2008 André Tupinambá <andrelrt@gmail.com> 8 * 9 * Permission to use, copy, modify, distribute, and sell this software and its 10 * documentation for any purpose is hereby granted without fee, provided that 11 * the above copyright notice appear in all copies and that both that 12 * copyright notice and this permission notice appear in supporting 13 * documentation, and that the name of Keith Packard not be used in 14 * advertising or publicity pertaining to distribution of the software without 15 * specific, written prior permission. Keith Packard makes no 16 * representations about the suitability of this software for any purpose. It 17 * is provided "as is" without express or implied warranty. 18 * 19 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 20 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 24 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 25 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 26 * SOFTWARE. 27 */ 28 29 #ifdef HAVE_CONFIG_H 30 #include <pixman-config.h> 31 #endif 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include "pixman-private.h" 36 #include "pixman-combine32.h" 37 #include "pixman-inlines.h" 38 #include "dither/blue-noise-64x64.h" 39 40 /* Fetch functions */ 41 42 static force_inline void 43 fetch_pixel_no_alpha_32 (bits_image_t *image, 44 int x, int y, pixman_bool_t check_bounds, 45 void *out) 46 { 47 uint32_t *ret = out; 48 49 if (check_bounds && 50 (x < 0 || x >= image->width || y < 0 || y >= image->height)) 51 *ret = 0; 52 else 53 *ret = image->fetch_pixel_32 (image, x, y); 54 } 55 56 static force_inline void 57 fetch_pixel_no_alpha_float (bits_image_t *image, 58 int x, int y, pixman_bool_t check_bounds, 59 void *out) 60 { 61 argb_t *ret = out; 62 63 if (check_bounds && 64 (x < 0 || x >= image->width || y < 0 || y >= image->height)) 65 ret->a = ret->r = ret->g = ret->b = 0.f; 66 else 67 *ret = image->fetch_pixel_float (image, x, y); 68 } 69 70 typedef void (* get_pixel_t) (bits_image_t *image, 71 int x, int y, pixman_bool_t check_bounds, void *out); 72 73 static force_inline void 74 bits_image_fetch_pixel_nearest (bits_image_t *image, 75 pixman_fixed_t x, 76 pixman_fixed_t y, 77 get_pixel_t get_pixel, 78 void *out) 79 { 80 int x0 = pixman_fixed_to_int (x - pixman_fixed_e); 81 int y0 = pixman_fixed_to_int (y - pixman_fixed_e); 82 83 if (image->common.repeat != PIXMAN_REPEAT_NONE) 84 { 85 repeat (image->common.repeat, &x0, image->width); 86 repeat (image->common.repeat, &y0, image->height); 87 88 get_pixel (image, x0, y0, FALSE, out); 89 } 90 else 91 { 92 get_pixel (image, x0, y0, TRUE, out); 93 } 94 } 95 96 static force_inline void 97 bits_image_fetch_pixel_bilinear_32 (bits_image_t *image, 98 pixman_fixed_t x, 99 pixman_fixed_t y, 100 get_pixel_t get_pixel, 101 void *out) 102 { 103 pixman_repeat_t repeat_mode = image->common.repeat; 104 int width = image->width; 105 int height = image->height; 106 int x1, y1, x2, y2; 107 uint32_t tl, tr, bl, br; 108 int32_t distx, disty; 109 uint32_t *ret = out; 110 111 x1 = x - pixman_fixed_1 / 2; 112 y1 = y - pixman_fixed_1 / 2; 113 114 distx = pixman_fixed_to_bilinear_weight (x1); 115 disty = pixman_fixed_to_bilinear_weight (y1); 116 117 x1 = pixman_fixed_to_int (x1); 118 y1 = pixman_fixed_to_int (y1); 119 x2 = x1 + 1; 120 y2 = y1 + 1; 121 122 if (repeat_mode != PIXMAN_REPEAT_NONE) 123 { 124 repeat (repeat_mode, &x1, width); 125 repeat (repeat_mode, &y1, height); 126 repeat (repeat_mode, &x2, width); 127 repeat (repeat_mode, &y2, height); 128 129 get_pixel (image, x1, y1, FALSE, &tl); 130 get_pixel (image, x2, y1, FALSE, &tr); 131 get_pixel (image, x1, y2, FALSE, &bl); 132 get_pixel (image, x2, y2, FALSE, &br); 133 } 134 else 135 { 136 get_pixel (image, x1, y1, TRUE, &tl); 137 get_pixel (image, x2, y1, TRUE, &tr); 138 get_pixel (image, x1, y2, TRUE, &bl); 139 get_pixel (image, x2, y2, TRUE, &br); 140 } 141 142 *ret = bilinear_interpolation (tl, tr, bl, br, distx, disty); 143 } 144 145 static force_inline void 146 bits_image_fetch_pixel_bilinear_float (bits_image_t *image, 147 pixman_fixed_t x, 148 pixman_fixed_t y, 149 get_pixel_t get_pixel, 150 void *out) 151 { 152 pixman_repeat_t repeat_mode = image->common.repeat; 153 int width = image->width; 154 int height = image->height; 155 int x1, y1, x2, y2; 156 argb_t tl, tr, bl, br; 157 float distx, disty; 158 argb_t *ret = out; 159 160 x1 = x - pixman_fixed_1 / 2; 161 y1 = y - pixman_fixed_1 / 2; 162 163 distx = ((float)pixman_fixed_fraction(x1)) / 65536.f; 164 disty = ((float)pixman_fixed_fraction(y1)) / 65536.f; 165 166 x1 = pixman_fixed_to_int (x1); 167 y1 = pixman_fixed_to_int (y1); 168 x2 = x1 + 1; 169 y2 = y1 + 1; 170 171 if (repeat_mode != PIXMAN_REPEAT_NONE) 172 { 173 repeat (repeat_mode, &x1, width); 174 repeat (repeat_mode, &y1, height); 175 repeat (repeat_mode, &x2, width); 176 repeat (repeat_mode, &y2, height); 177 178 get_pixel (image, x1, y1, FALSE, &tl); 179 get_pixel (image, x2, y1, FALSE, &tr); 180 get_pixel (image, x1, y2, FALSE, &bl); 181 get_pixel (image, x2, y2, FALSE, &br); 182 } 183 else 184 { 185 get_pixel (image, x1, y1, TRUE, &tl); 186 get_pixel (image, x2, y1, TRUE, &tr); 187 get_pixel (image, x1, y2, TRUE, &bl); 188 get_pixel (image, x2, y2, TRUE, &br); 189 } 190 191 *ret = bilinear_interpolation_float (tl, tr, bl, br, distx, disty); 192 } 193 194 static force_inline void accum_32(unsigned int *satot, unsigned int *srtot, 195 unsigned int *sgtot, unsigned int *sbtot, 196 const void *p, pixman_fixed_t f) 197 { 198 uint32_t pixel = *(uint32_t *)p; 199 200 *srtot += (int)RED_8 (pixel) * f; 201 *sgtot += (int)GREEN_8 (pixel) * f; 202 *sbtot += (int)BLUE_8 (pixel) * f; 203 *satot += (int)ALPHA_8 (pixel) * f; 204 } 205 206 static force_inline void reduce_32(unsigned int satot, unsigned int srtot, 207 unsigned int sgtot, unsigned int sbtot, 208 void *p) 209 { 210 uint32_t *ret = p; 211 212 satot = (int32_t)(satot + 0x8000) / 65536; 213 srtot = (int32_t)(srtot + 0x8000) / 65536; 214 sgtot = (int32_t)(sgtot + 0x8000) / 65536; 215 sbtot = (int32_t)(sbtot + 0x8000) / 65536; 216 217 satot = CLIP ((int32_t)satot, 0, 0xff); 218 srtot = CLIP ((int32_t)srtot, 0, 0xff); 219 sgtot = CLIP ((int32_t)sgtot, 0, 0xff); 220 sbtot = CLIP ((int32_t)sbtot, 0, 0xff); 221 222 *ret = ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); 223 } 224 225 static force_inline void accum_float(unsigned int *satot, unsigned int *srtot, 226 unsigned int *sgtot, unsigned int *sbtot, 227 const void *p, pixman_fixed_t f) 228 { 229 const argb_t *pixel = p; 230 231 *satot += pixel->a * f; 232 *srtot += pixel->r * f; 233 *sgtot += pixel->g * f; 234 *sbtot += pixel->b * f; 235 } 236 237 static force_inline void reduce_float(unsigned int satot, unsigned int srtot, 238 unsigned int sgtot, unsigned int sbtot, 239 void *p) 240 { 241 argb_t *ret = p; 242 243 ret->a = CLIP ((int32_t)satot / 65536.f, 0.f, 1.f); 244 ret->r = CLIP ((int32_t)srtot / 65536.f, 0.f, 1.f); 245 ret->g = CLIP ((int32_t)sgtot / 65536.f, 0.f, 1.f); 246 ret->b = CLIP ((int32_t)sbtot / 65536.f, 0.f, 1.f); 247 } 248 249 typedef void (* accumulate_pixel_t) (unsigned int *satot, unsigned int *srtot, 250 unsigned int *sgtot, unsigned int *sbtot, 251 const void *pixel, pixman_fixed_t f); 252 253 typedef void (* reduce_pixel_t) (unsigned int satot, unsigned int srtot, 254 unsigned int sgtot, unsigned int sbtot, 255 void *out); 256 257 static force_inline void 258 bits_image_fetch_pixel_convolution (bits_image_t *image, 259 pixman_fixed_t x, 260 pixman_fixed_t y, 261 get_pixel_t get_pixel, 262 void *out, 263 accumulate_pixel_t accum, 264 reduce_pixel_t reduce) 265 { 266 pixman_fixed_t *params = image->common.filter_params; 267 int x_off = (params[0] - pixman_fixed_1) >> 1; 268 int y_off = (params[1] - pixman_fixed_1) >> 1; 269 int32_t cwidth = pixman_fixed_to_int (params[0]); 270 int32_t cheight = pixman_fixed_to_int (params[1]); 271 int32_t i, j, x1, x2, y1, y2; 272 pixman_repeat_t repeat_mode = image->common.repeat; 273 int width = image->width; 274 int height = image->height; 275 unsigned int srtot, sgtot, sbtot, satot; 276 277 params += 2; 278 279 x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); 280 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); 281 x2 = x1 + cwidth; 282 y2 = y1 + cheight; 283 284 srtot = sgtot = sbtot = satot = 0; 285 286 for (i = y1; i < y2; ++i) 287 { 288 for (j = x1; j < x2; ++j) 289 { 290 int rx = j; 291 int ry = i; 292 293 pixman_fixed_t f = *params; 294 295 if (f) 296 { 297 /* Must be big enough to hold a argb_t */ 298 argb_t pixel; 299 300 if (repeat_mode != PIXMAN_REPEAT_NONE) 301 { 302 repeat (repeat_mode, &rx, width); 303 repeat (repeat_mode, &ry, height); 304 305 get_pixel (image, rx, ry, FALSE, &pixel); 306 } 307 else 308 { 309 get_pixel (image, rx, ry, TRUE, &pixel); 310 } 311 312 accum (&satot, &srtot, &sgtot, &sbtot, &pixel, f); 313 } 314 315 params++; 316 } 317 } 318 319 reduce (satot, srtot, sgtot, sbtot, out); 320 } 321 322 static void 323 bits_image_fetch_pixel_separable_convolution (bits_image_t *image, 324 pixman_fixed_t x, 325 pixman_fixed_t y, 326 get_pixel_t get_pixel, 327 void *out, 328 accumulate_pixel_t accum, 329 reduce_pixel_t reduce) 330 { 331 pixman_fixed_t *params = image->common.filter_params; 332 pixman_repeat_t repeat_mode = image->common.repeat; 333 int width = image->width; 334 int height = image->height; 335 int cwidth = pixman_fixed_to_int (params[0]); 336 int cheight = pixman_fixed_to_int (params[1]); 337 int x_phase_bits = pixman_fixed_to_int (params[2]); 338 int y_phase_bits = pixman_fixed_to_int (params[3]); 339 int x_phase_shift = 16 - x_phase_bits; 340 int y_phase_shift = 16 - y_phase_bits; 341 int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; 342 int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; 343 pixman_fixed_t *y_params; 344 unsigned int srtot, sgtot, sbtot, satot; 345 int32_t x1, x2, y1, y2; 346 int32_t px, py; 347 int i, j; 348 349 /* Round x and y to the middle of the closest phase before continuing. This 350 * ensures that the convolution matrix is aligned right, since it was 351 * positioned relative to a particular phase (and not relative to whatever 352 * exact fraction we happen to get here). 353 */ 354 x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); 355 y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); 356 357 px = (x & 0xffff) >> x_phase_shift; 358 py = (y & 0xffff) >> y_phase_shift; 359 360 y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; 361 362 x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); 363 y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); 364 x2 = x1 + cwidth; 365 y2 = y1 + cheight; 366 367 srtot = sgtot = sbtot = satot = 0; 368 369 for (i = y1; i < y2; ++i) 370 { 371 pixman_fixed_48_16_t fy = *y_params++; 372 pixman_fixed_t *x_params = params + 4 + px * cwidth; 373 374 if (fy) 375 { 376 for (j = x1; j < x2; ++j) 377 { 378 pixman_fixed_t fx = *x_params++; 379 int rx = j; 380 int ry = i; 381 382 if (fx) 383 { 384 /* Must be big enough to hold a argb_t */ 385 argb_t pixel; 386 pixman_fixed_t f; 387 388 if (repeat_mode != PIXMAN_REPEAT_NONE) 389 { 390 repeat (repeat_mode, &rx, width); 391 repeat (repeat_mode, &ry, height); 392 393 get_pixel (image, rx, ry, FALSE, &pixel); 394 } 395 else 396 { 397 get_pixel (image, rx, ry, TRUE, &pixel); 398 } 399 400 f = (fy * fx + 0x8000) >> 16; 401 402 accum(&satot, &srtot, &sgtot, &sbtot, &pixel, f); 403 } 404 } 405 } 406 } 407 408 409 reduce(satot, srtot, sgtot, sbtot, out); 410 } 411 412 static force_inline void 413 bits_image_fetch_pixel_filtered (bits_image_t *image, 414 pixman_bool_t wide, 415 pixman_fixed_t x, 416 pixman_fixed_t y, 417 get_pixel_t get_pixel, 418 void *out) 419 { 420 switch (image->common.filter) 421 { 422 case PIXMAN_FILTER_NEAREST: 423 case PIXMAN_FILTER_FAST: 424 bits_image_fetch_pixel_nearest (image, x, y, get_pixel, out); 425 break; 426 427 case PIXMAN_FILTER_BILINEAR: 428 case PIXMAN_FILTER_GOOD: 429 case PIXMAN_FILTER_BEST: 430 if (wide) 431 bits_image_fetch_pixel_bilinear_float (image, x, y, get_pixel, out); 432 else 433 bits_image_fetch_pixel_bilinear_32 (image, x, y, get_pixel, out); 434 break; 435 436 case PIXMAN_FILTER_CONVOLUTION: 437 if (wide) 438 { 439 bits_image_fetch_pixel_convolution (image, x, y, 440 get_pixel, out, 441 accum_float, 442 reduce_float); 443 } 444 else 445 { 446 bits_image_fetch_pixel_convolution (image, x, y, 447 get_pixel, out, 448 accum_32, reduce_32); 449 } 450 break; 451 452 case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: 453 if (wide) 454 { 455 bits_image_fetch_pixel_separable_convolution (image, x, y, 456 get_pixel, out, 457 accum_float, 458 reduce_float); 459 } 460 else 461 { 462 bits_image_fetch_pixel_separable_convolution (image, x, y, 463 get_pixel, out, 464 accum_32, reduce_32); 465 } 466 break; 467 468 default: 469 assert (0); 470 break; 471 } 472 } 473 474 static uint32_t * 475 __bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, 476 pixman_bool_t wide, 477 const uint32_t * mask) 478 { 479 pixman_image_t *image = iter->image; 480 int offset = iter->x; 481 int line = iter->y++; 482 int width = iter->width; 483 uint32_t * buffer = iter->buffer; 484 485 const uint32_t wide_zero[4] = {0}; 486 pixman_fixed_t x, y; 487 pixman_fixed_t ux, uy; 488 pixman_vector_t v; 489 int i; 490 get_pixel_t get_pixel = 491 wide ? fetch_pixel_no_alpha_float : fetch_pixel_no_alpha_32; 492 493 /* reference point is the center of the pixel */ 494 v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 495 v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 496 v.vector[2] = pixman_fixed_1; 497 498 if (image->common.transform) 499 { 500 if (!pixman_transform_point_3d (image->common.transform, &v)) 501 return iter->buffer; 502 503 ux = image->common.transform->matrix[0][0]; 504 uy = image->common.transform->matrix[1][0]; 505 } 506 else 507 { 508 ux = pixman_fixed_1; 509 uy = 0; 510 } 511 512 x = v.vector[0]; 513 y = v.vector[1]; 514 515 for (i = 0; i < width; ++i) 516 { 517 if (!mask || (!wide && mask[i]) || 518 (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0)) 519 { 520 bits_image_fetch_pixel_filtered ( 521 &image->bits, wide, x, y, get_pixel, buffer); 522 } 523 524 x += ux; 525 y += uy; 526 buffer += wide ? 4 : 1; 527 } 528 529 return iter->buffer; 530 } 531 532 static uint32_t * 533 bits_image_fetch_affine_no_alpha_32 (pixman_iter_t *iter, 534 const uint32_t *mask) 535 { 536 return __bits_image_fetch_affine_no_alpha(iter, FALSE, mask); 537 } 538 539 static uint32_t * 540 bits_image_fetch_affine_no_alpha_float (pixman_iter_t *iter, 541 const uint32_t *mask) 542 { 543 return __bits_image_fetch_affine_no_alpha(iter, TRUE, mask); 544 } 545 546 /* General fetcher */ 547 static force_inline void 548 fetch_pixel_general_32 (bits_image_t *image, 549 int x, int y, pixman_bool_t check_bounds, 550 void *out) 551 { 552 uint32_t pixel, *ret = out; 553 554 if (check_bounds && 555 (x < 0 || x >= image->width || y < 0 || y >= image->height)) 556 { 557 *ret = 0; 558 return; 559 } 560 561 pixel = image->fetch_pixel_32 (image, x, y); 562 563 if (image->common.alpha_map) 564 { 565 uint32_t pixel_a; 566 567 x -= image->common.alpha_origin_x; 568 y -= image->common.alpha_origin_y; 569 570 if (x < 0 || x >= image->common.alpha_map->width || 571 y < 0 || y >= image->common.alpha_map->height) 572 { 573 pixel_a = 0; 574 } 575 else 576 { 577 pixel_a = image->common.alpha_map->fetch_pixel_32 ( 578 image->common.alpha_map, x, y); 579 580 pixel_a = ALPHA_8 (pixel_a); 581 } 582 583 pixel &= 0x00ffffff; 584 pixel |= (pixel_a << 24); 585 } 586 587 *ret = pixel; 588 } 589 590 static force_inline void 591 fetch_pixel_general_float (bits_image_t *image, 592 int x, int y, pixman_bool_t check_bounds, 593 void *out) 594 { 595 argb_t *ret = out; 596 597 if (check_bounds && 598 (x < 0 || x >= image->width || y < 0 || y >= image->height)) 599 { 600 ret->a = ret->r = ret->g = ret->b = 0; 601 return; 602 } 603 604 *ret = image->fetch_pixel_float (image, x, y); 605 606 if (image->common.alpha_map) 607 { 608 x -= image->common.alpha_origin_x; 609 y -= image->common.alpha_origin_y; 610 611 if (x < 0 || x >= image->common.alpha_map->width || 612 y < 0 || y >= image->common.alpha_map->height) 613 { 614 ret->a = 0.f; 615 } 616 else 617 { 618 argb_t alpha; 619 620 alpha = image->common.alpha_map->fetch_pixel_float ( 621 image->common.alpha_map, x, y); 622 623 ret->a = alpha.a; 624 } 625 } 626 } 627 628 static uint32_t * 629 __bits_image_fetch_general (pixman_iter_t *iter, 630 pixman_bool_t wide, 631 const uint32_t *mask) 632 { 633 pixman_image_t *image = iter->image; 634 int offset = iter->x; 635 int line = iter->y++; 636 int width = iter->width; 637 uint32_t * buffer = iter->buffer; 638 get_pixel_t get_pixel = 639 wide ? fetch_pixel_general_float : fetch_pixel_general_32; 640 641 const uint32_t wide_zero[4] = {0}; 642 pixman_fixed_t x, y, w; 643 pixman_fixed_t ux, uy, uw; 644 pixman_vector_t v; 645 int i; 646 647 /* reference point is the center of the pixel */ 648 v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 649 v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 650 v.vector[2] = pixman_fixed_1; 651 652 if (image->common.transform) 653 { 654 if (!pixman_transform_point_3d (image->common.transform, &v)) 655 return buffer; 656 657 ux = image->common.transform->matrix[0][0]; 658 uy = image->common.transform->matrix[1][0]; 659 uw = image->common.transform->matrix[2][0]; 660 } 661 else 662 { 663 ux = pixman_fixed_1; 664 uy = 0; 665 uw = 0; 666 } 667 668 x = v.vector[0]; 669 y = v.vector[1]; 670 w = v.vector[2]; 671 672 for (i = 0; i < width; ++i) 673 { 674 pixman_fixed_t x0, y0; 675 676 if (!mask || (!wide && mask[i]) || 677 (wide && memcmp(&mask[4 * i], wide_zero, 16) != 0)) 678 { 679 if (w != 0) 680 { 681 x0 = ((uint64_t)x << 16) / w; 682 y0 = ((uint64_t)y << 16) / w; 683 } 684 else 685 { 686 x0 = 0; 687 y0 = 0; 688 } 689 690 bits_image_fetch_pixel_filtered ( 691 &image->bits, wide, x0, y0, get_pixel, buffer); 692 } 693 694 x += ux; 695 y += uy; 696 w += uw; 697 buffer += wide ? 4 : 1; 698 } 699 700 return iter->buffer; 701 } 702 703 static uint32_t * 704 bits_image_fetch_general_32 (pixman_iter_t *iter, 705 const uint32_t *mask) 706 { 707 return __bits_image_fetch_general(iter, FALSE, mask); 708 } 709 710 static uint32_t * 711 bits_image_fetch_general_float (pixman_iter_t *iter, 712 const uint32_t *mask) 713 { 714 return __bits_image_fetch_general(iter, TRUE, mask); 715 } 716 717 static void 718 replicate_pixel_32 (bits_image_t * bits, 719 int x, 720 int y, 721 int width, 722 uint32_t * buffer) 723 { 724 uint32_t color; 725 uint32_t *end; 726 727 color = bits->fetch_pixel_32 (bits, x, y); 728 729 end = buffer + width; 730 while (buffer < end) 731 *(buffer++) = color; 732 } 733 734 static void 735 replicate_pixel_float (bits_image_t * bits, 736 int x, 737 int y, 738 int width, 739 uint32_t * b) 740 { 741 argb_t color; 742 argb_t *buffer = (argb_t *)b; 743 argb_t *end; 744 745 color = bits->fetch_pixel_float (bits, x, y); 746 747 end = buffer + width; 748 while (buffer < end) 749 *(buffer++) = color; 750 } 751 752 static void 753 bits_image_fetch_untransformed_repeat_none (bits_image_t *image, 754 pixman_bool_t wide, 755 int x, 756 int y, 757 int width, 758 uint32_t * buffer) 759 { 760 uint32_t w; 761 762 if (y < 0 || y >= image->height) 763 { 764 memset (buffer, 0, width * (wide? sizeof (argb_t) : 4)); 765 return; 766 } 767 768 if (x < 0) 769 { 770 w = MIN (width, -x); 771 772 memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4)); 773 774 width -= w; 775 buffer += w * (wide? 4 : 1); 776 x += w; 777 } 778 779 if (x < image->width) 780 { 781 w = MIN (width, image->width - x); 782 783 if (wide) 784 image->fetch_scanline_float (image, x, y, w, buffer, NULL); 785 else 786 image->fetch_scanline_32 (image, x, y, w, buffer, NULL); 787 788 width -= w; 789 buffer += w * (wide? 4 : 1); 790 x += w; 791 } 792 793 memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4)); 794 } 795 796 static void 797 bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, 798 pixman_bool_t wide, 799 int x, 800 int y, 801 int width, 802 uint32_t * buffer) 803 { 804 uint32_t w; 805 806 while (y < 0) 807 y += image->height; 808 809 while (y >= image->height) 810 y -= image->height; 811 812 if (image->width == 1) 813 { 814 if (wide) 815 replicate_pixel_float (image, 0, y, width, buffer); 816 else 817 replicate_pixel_32 (image, 0, y, width, buffer); 818 819 return; 820 } 821 822 while (width) 823 { 824 while (x < 0) 825 x += image->width; 826 while (x >= image->width) 827 x -= image->width; 828 829 w = MIN (width, image->width - x); 830 831 if (wide) 832 image->fetch_scanline_float (image, x, y, w, buffer, NULL); 833 else 834 image->fetch_scanline_32 (image, x, y, w, buffer, NULL); 835 836 buffer += w * (wide? 4 : 1); 837 x += w; 838 width -= w; 839 } 840 } 841 842 static uint32_t * 843 bits_image_fetch_untransformed_32 (pixman_iter_t * iter, 844 const uint32_t *mask) 845 { 846 pixman_image_t *image = iter->image; 847 int x = iter->x; 848 int y = iter->y; 849 int width = iter->width; 850 uint32_t * buffer = iter->buffer; 851 852 if (image->common.repeat == PIXMAN_REPEAT_NONE) 853 { 854 bits_image_fetch_untransformed_repeat_none ( 855 &image->bits, FALSE, x, y, width, buffer); 856 } 857 else 858 { 859 bits_image_fetch_untransformed_repeat_normal ( 860 &image->bits, FALSE, x, y, width, buffer); 861 } 862 863 iter->y++; 864 return buffer; 865 } 866 867 static uint32_t * 868 bits_image_fetch_untransformed_float (pixman_iter_t * iter, 869 const uint32_t *mask) 870 { 871 pixman_image_t *image = iter->image; 872 int x = iter->x; 873 int y = iter->y; 874 int width = iter->width; 875 uint32_t * buffer = iter->buffer; 876 877 if (image->common.repeat == PIXMAN_REPEAT_NONE) 878 { 879 bits_image_fetch_untransformed_repeat_none ( 880 &image->bits, TRUE, x, y, width, buffer); 881 } 882 else 883 { 884 bits_image_fetch_untransformed_repeat_normal ( 885 &image->bits, TRUE, x, y, width, buffer); 886 } 887 888 iter->y++; 889 return buffer; 890 } 891 892 typedef struct 893 { 894 pixman_format_code_t format; 895 uint32_t flags; 896 pixman_iter_get_scanline_t get_scanline_32; 897 pixman_iter_get_scanline_t get_scanline_float; 898 } fetcher_info_t; 899 900 static const fetcher_info_t fetcher_info[] = 901 { 902 { PIXMAN_any, 903 (FAST_PATH_NO_ALPHA_MAP | 904 FAST_PATH_ID_TRANSFORM | 905 FAST_PATH_NO_CONVOLUTION_FILTER | 906 FAST_PATH_NO_PAD_REPEAT | 907 FAST_PATH_NO_REFLECT_REPEAT), 908 bits_image_fetch_untransformed_32, 909 bits_image_fetch_untransformed_float 910 }, 911 912 /* Affine, no alpha */ 913 { PIXMAN_any, 914 (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM), 915 bits_image_fetch_affine_no_alpha_32, 916 bits_image_fetch_affine_no_alpha_float, 917 }, 918 919 /* General */ 920 { PIXMAN_any, 921 0, 922 bits_image_fetch_general_32, 923 bits_image_fetch_general_float, 924 }, 925 926 { PIXMAN_null }, 927 }; 928 929 static void 930 bits_image_property_changed (pixman_image_t *image) 931 { 932 _pixman_bits_image_setup_accessors (&image->bits); 933 } 934 935 void 936 _pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) 937 { 938 pixman_format_code_t format = image->common.extended_format_code; 939 uint32_t flags = image->common.flags; 940 const fetcher_info_t *info; 941 942 for (info = fetcher_info; info->format != PIXMAN_null; ++info) 943 { 944 if ((info->format == format || info->format == PIXMAN_any) && 945 (info->flags & flags) == info->flags) 946 { 947 if (iter->iter_flags & ITER_NARROW) 948 { 949 iter->get_scanline = info->get_scanline_32; 950 } 951 else 952 { 953 iter->get_scanline = info->get_scanline_float; 954 } 955 return; 956 } 957 } 958 959 /* Just in case we somehow didn't find a scanline function */ 960 iter->get_scanline = _pixman_iter_get_scanline_noop; 961 } 962 963 static uint32_t * 964 dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) 965 { 966 pixman_image_t *image = iter->image; 967 int x = iter->x; 968 int y = iter->y; 969 int width = iter->width; 970 uint32_t * buffer = iter->buffer; 971 972 image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask); 973 if (image->common.alpha_map) 974 { 975 uint32_t *alpha; 976 977 if ((alpha = malloc (width * sizeof (uint32_t)))) 978 { 979 int i; 980 981 x -= image->common.alpha_origin_x; 982 y -= image->common.alpha_origin_y; 983 984 image->common.alpha_map->fetch_scanline_32 ( 985 image->common.alpha_map, x, y, width, alpha, mask); 986 987 for (i = 0; i < width; ++i) 988 { 989 buffer[i] &= ~0xff000000; 990 buffer[i] |= (alpha[i] & 0xff000000); 991 } 992 993 free (alpha); 994 } 995 } 996 997 return iter->buffer; 998 } 999 1000 static uint32_t * 1001 dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) 1002 { 1003 bits_image_t * image = &iter->image->bits; 1004 int x = iter->x; 1005 int y = iter->y; 1006 int width = iter->width; 1007 argb_t * buffer = (argb_t *)iter->buffer; 1008 1009 image->fetch_scanline_float ( 1010 image, x, y, width, (uint32_t *)buffer, mask); 1011 if (image->common.alpha_map) 1012 { 1013 argb_t *alpha; 1014 1015 if ((alpha = malloc (width * sizeof (argb_t)))) 1016 { 1017 int i; 1018 1019 x -= image->common.alpha_origin_x; 1020 y -= image->common.alpha_origin_y; 1021 1022 image->common.alpha_map->fetch_scanline_float ( 1023 image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask); 1024 1025 for (i = 0; i < width; ++i) 1026 buffer[i].a = alpha[i].a; 1027 1028 free (alpha); 1029 } 1030 } 1031 1032 return iter->buffer; 1033 } 1034 1035 static void 1036 dest_write_back_narrow (pixman_iter_t *iter) 1037 { 1038 bits_image_t * image = &iter->image->bits; 1039 int x = iter->x; 1040 int y = iter->y; 1041 int width = iter->width; 1042 const uint32_t *buffer = iter->buffer; 1043 1044 image->store_scanline_32 (image, x, y, width, buffer); 1045 1046 if (image->common.alpha_map) 1047 { 1048 x -= image->common.alpha_origin_x; 1049 y -= image->common.alpha_origin_y; 1050 1051 image->common.alpha_map->store_scanline_32 ( 1052 image->common.alpha_map, x, y, width, buffer); 1053 } 1054 1055 iter->y++; 1056 } 1057 1058 static float 1059 dither_factor_blue_noise_64 (int x, int y) 1060 { 1061 float m = dither_blue_noise_64x64[((y & 0x3f) << 6) | (x & 0x3f)]; 1062 return m * (1. / 4096.f) + (1. / 8192.f); 1063 } 1064 1065 static float 1066 dither_factor_bayer_8 (int x, int y) 1067 { 1068 uint32_t m; 1069 1070 y ^= x; 1071 1072 /* Compute reverse(interleave(xor(x mod n, y mod n), x mod n)) 1073 * Here n = 8 and `mod n` is the bottom 3 bits. 1074 */ 1075 m = ((y & 0x1) << 5) | ((x & 0x1) << 4) | 1076 ((y & 0x2) << 2) | ((x & 0x2) << 1) | 1077 ((y & 0x4) >> 1) | ((x & 0x4) >> 2); 1078 1079 /* m is in range [0, 63]. We scale it to [0, 63.0f/64.0f], then 1080 * shift it to to [1.0f/128.0f, 127.0f/128.0f] so that 0 < d < 1. 1081 * This ensures exact values are not changed by dithering. 1082 */ 1083 return (float)(m) * (1 / 64.0f) + (1.0f / 128.0f); 1084 } 1085 1086 typedef float (* dither_factor_t)(int x, int y); 1087 1088 static force_inline float 1089 dither_apply_channel (float f, float d, float s) 1090 { 1091 /* float_to_unorm splits the [0, 1] segment in (1 << n_bits) 1092 * subsections of equal length; however unorm_to_float does not 1093 * map to the center of those sections. In fact, pixel value u is 1094 * mapped to: 1095 * 1096 * u u u 1 1097 * -------------- = ---------- + -------------- * ---------- 1098 * 2^n_bits - 1 2^n_bits 2^n_bits - 1 2^n_bits 1099 * 1100 * Hence if f = u / (2^n_bits - 1) is exactly representable on a 1101 * n_bits palette, all the numbers between 1102 * 1103 * u 1104 * ---------- = f - f * 2^n_bits = f + (0 - f) * 2^n_bits 1105 * 2^n_bits 1106 * 1107 * and 1108 * 1109 * u + 1 1110 * ---------- = f - (f - 1) * 2^n_bits = f + (1 - f) * 2^n_bits 1111 * 2^n_bits 1112 * 1113 * are also mapped back to u. 1114 * 1115 * Hence the following calculation ensures that we add as much 1116 * noise as possible without perturbing values which are exactly 1117 * representable in the target colorspace. Note that this corresponds to 1118 * mixing the original color with noise with a ratio of `1 / 2^n_bits`. 1119 */ 1120 return f + (d - f) * s; 1121 } 1122 1123 static force_inline float 1124 dither_compute_scale (int n_bits) 1125 { 1126 // No dithering for wide formats 1127 if (n_bits == 0 || n_bits >= 32) 1128 return 0.f; 1129 1130 return 1.f / (float)(1 << n_bits); 1131 } 1132 1133 static const uint32_t * 1134 dither_apply_ordered (pixman_iter_t *iter, dither_factor_t factor) 1135 { 1136 bits_image_t *image = &iter->image->bits; 1137 int x = iter->x + image->dither_offset_x; 1138 int y = iter->y + image->dither_offset_y; 1139 int width = iter->width; 1140 argb_t *buffer = (argb_t *)iter->buffer; 1141 1142 pixman_format_code_t format = image->format; 1143 int a_size = PIXMAN_FORMAT_A (format); 1144 int r_size = PIXMAN_FORMAT_R (format); 1145 int g_size = PIXMAN_FORMAT_G (format); 1146 int b_size = PIXMAN_FORMAT_B (format); 1147 1148 float a_scale = dither_compute_scale (a_size); 1149 float r_scale = dither_compute_scale (r_size); 1150 float g_scale = dither_compute_scale (g_size); 1151 float b_scale = dither_compute_scale (b_size); 1152 1153 int i; 1154 float d; 1155 1156 for (i = 0; i < width; ++i) 1157 { 1158 d = factor (x + i, y); 1159 1160 buffer->a = dither_apply_channel (buffer->a, d, a_scale); 1161 buffer->r = dither_apply_channel (buffer->r, d, r_scale); 1162 buffer->g = dither_apply_channel (buffer->g, d, g_scale); 1163 buffer->b = dither_apply_channel (buffer->b, d, b_scale); 1164 1165 buffer++; 1166 } 1167 1168 return iter->buffer; 1169 } 1170 1171 static void 1172 dest_write_back_wide (pixman_iter_t *iter) 1173 { 1174 bits_image_t * image = &iter->image->bits; 1175 int x = iter->x; 1176 int y = iter->y; 1177 int width = iter->width; 1178 const uint32_t *buffer = iter->buffer; 1179 1180 switch (image->dither) 1181 { 1182 case PIXMAN_DITHER_NONE: 1183 break; 1184 1185 case PIXMAN_DITHER_GOOD: 1186 case PIXMAN_DITHER_BEST: 1187 case PIXMAN_DITHER_ORDERED_BLUE_NOISE_64: 1188 buffer = dither_apply_ordered (iter, dither_factor_blue_noise_64); 1189 break; 1190 1191 case PIXMAN_DITHER_FAST: 1192 case PIXMAN_DITHER_ORDERED_BAYER_8: 1193 buffer = dither_apply_ordered (iter, dither_factor_bayer_8); 1194 break; 1195 } 1196 1197 image->store_scanline_float (image, x, y, width, buffer); 1198 1199 if (image->common.alpha_map) 1200 { 1201 x -= image->common.alpha_origin_x; 1202 y -= image->common.alpha_origin_y; 1203 1204 image->common.alpha_map->store_scanline_float ( 1205 image->common.alpha_map, x, y, width, buffer); 1206 } 1207 1208 iter->y++; 1209 } 1210 1211 void 1212 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) 1213 { 1214 if (iter->iter_flags & ITER_NARROW) 1215 { 1216 if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == 1217 (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) 1218 { 1219 iter->get_scanline = _pixman_iter_get_scanline_noop; 1220 } 1221 else 1222 { 1223 iter->get_scanline = dest_get_scanline_narrow; 1224 } 1225 1226 iter->write_back = dest_write_back_narrow; 1227 } 1228 else 1229 { 1230 iter->get_scanline = dest_get_scanline_wide; 1231 iter->write_back = dest_write_back_wide; 1232 } 1233 } 1234 1235 static uint32_t * 1236 create_bits (pixman_format_code_t format, 1237 int width, 1238 int height, 1239 int * rowstride_bytes, 1240 pixman_bool_t clear) 1241 { 1242 int stride; 1243 size_t buf_size; 1244 int bpp; 1245 1246 /* what follows is a long-winded way, avoiding any possibility of integer 1247 * overflows, of saying: 1248 * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t); 1249 */ 1250 1251 bpp = PIXMAN_FORMAT_BPP (format); 1252 if (_pixman_multiply_overflows_int (width, bpp)) 1253 return NULL; 1254 1255 stride = width * bpp; 1256 if (_pixman_addition_overflows_int (stride, 0x1f)) 1257 return NULL; 1258 1259 stride += 0x1f; 1260 stride >>= 5; 1261 1262 stride *= sizeof (uint32_t); 1263 1264 if (_pixman_multiply_overflows_size (height, stride)) 1265 return NULL; 1266 1267 buf_size = (size_t)height * stride; 1268 1269 if (rowstride_bytes) 1270 *rowstride_bytes = stride; 1271 1272 if (clear) 1273 return calloc (1, buf_size); 1274 else 1275 return malloc (buf_size); 1276 } 1277 1278 pixman_bool_t 1279 _pixman_bits_image_init (pixman_image_t * image, 1280 pixman_format_code_t format, 1281 int width, 1282 int height, 1283 uint32_t * bits, 1284 int rowstride, 1285 pixman_bool_t clear) 1286 { 1287 uint32_t *free_me = NULL; 1288 1289 if (PIXMAN_FORMAT_BPP (format) == 128) 1290 return_val_if_fail(!(rowstride % 4), FALSE); 1291 1292 if (!bits && width && height) 1293 { 1294 int rowstride_bytes; 1295 1296 free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); 1297 1298 if (!bits) 1299 return FALSE; 1300 1301 rowstride = rowstride_bytes / (int) sizeof (uint32_t); 1302 } 1303 1304 _pixman_image_init (image); 1305 1306 image->type = BITS; 1307 image->bits.format = format; 1308 image->bits.width = width; 1309 image->bits.height = height; 1310 image->bits.bits = bits; 1311 image->bits.free_me = free_me; 1312 image->bits.dither = PIXMAN_DITHER_NONE; 1313 image->bits.dither_offset_x = 0; 1314 image->bits.dither_offset_y = 0; 1315 image->bits.read_func = NULL; 1316 image->bits.write_func = NULL; 1317 image->bits.rowstride = rowstride; 1318 image->bits.indexed = NULL; 1319 1320 image->common.property_changed = bits_image_property_changed; 1321 1322 _pixman_image_reset_clip_region (image); 1323 1324 return TRUE; 1325 } 1326 1327 static pixman_image_t * 1328 create_bits_image_internal (pixman_format_code_t format, 1329 int width, 1330 int height, 1331 uint32_t * bits, 1332 int rowstride_bytes, 1333 pixman_bool_t clear) 1334 { 1335 pixman_image_t *image; 1336 1337 /* must be a whole number of uint32_t's 1338 */ 1339 return_val_if_fail ( 1340 bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); 1341 1342 return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL); 1343 1344 image = _pixman_image_allocate (); 1345 1346 if (!image) 1347 return NULL; 1348 1349 if (!_pixman_bits_image_init (image, format, width, height, bits, 1350 rowstride_bytes / (int) sizeof (uint32_t), 1351 clear)) 1352 { 1353 free (image); 1354 return NULL; 1355 } 1356 1357 return image; 1358 } 1359 1360 /* If bits is NULL, a buffer will be allocated and initialized to 0 */ 1361 PIXMAN_EXPORT pixman_image_t * 1362 pixman_image_create_bits (pixman_format_code_t format, 1363 int width, 1364 int height, 1365 uint32_t * bits, 1366 int rowstride_bytes) 1367 { 1368 return create_bits_image_internal ( 1369 format, width, height, bits, rowstride_bytes, TRUE); 1370 } 1371 1372 1373 /* If bits is NULL, a buffer will be allocated and _not_ initialized */ 1374 PIXMAN_EXPORT pixman_image_t * 1375 pixman_image_create_bits_no_clear (pixman_format_code_t format, 1376 int width, 1377 int height, 1378 uint32_t * bits, 1379 int rowstride_bytes) 1380 { 1381 return create_bits_image_internal ( 1382 format, width, height, bits, rowstride_bytes, FALSE); 1383 }