11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* 21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 2005 Lars Knoll & Zack Rusin, Trolltech 41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 2008 Aaron Plattner, NVIDIA Corporation 51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2000 SuSE, Inc. 61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2007, 2009 Red Hat, Inc. 71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2008 André Tupinambá <andrelrt@gmail.com> 81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Permission to use, copy, modify, distribute, and sell this software and its 101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation for any purpose is hereby granted without fee, provided that 111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the above copyright notice appear in all copies and that both that 121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copyright notice and this permission notice appear in supporting 131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation, and that the name of Keith Packard not be used in 141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * advertising or publicity pertaining to distribution of the software without 151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * specific, written prior permission. Keith Packard makes no 161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * representations about the suitability of this software for any purpose. It 171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * is provided "as is" without express or implied warranty. 181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * SOFTWARE. 271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef HAVE_CONFIG_H 301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <config.h> 311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdio.h> 331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h> 341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <string.h> 351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-private.h" 361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-combine32.h" 371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman-inlines.h" 381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 391176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_image_get_scanline_generic_float (pixman_iter_t * iter, 411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *mask) 421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_iter_get_scanline_t fetch_32 = iter->data; 441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *buffer = iter->buffer; 451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck fetch_32 (iter, NULL); 471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); 491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Fetch functions */ 541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 551176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 561176bdada62cabc6ec4b0308a930e83b679d5d36John Reckfetch_pixel_no_alpha (bits_image_t *image, 571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, int y, pixman_bool_t check_bounds) 581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (check_bounds && 601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (x < 0 || x >= image->width || y < 0 || y >= image->height)) 611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 0; 631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return image->fetch_pixel_32 (image, x, y); 661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 681176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef uint32_t (* get_pixel_t) (bits_image_t *image, 691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, int y, pixman_bool_t check_bounds); 701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 711176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 721176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_pixel_nearest (bits_image_t *image, 731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, 741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y, 751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck get_pixel_t get_pixel) 761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x0 = pixman_fixed_to_int (x - pixman_fixed_e); 781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y0 = pixman_fixed_to_int (y - pixman_fixed_e); 791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.repeat != PIXMAN_REPEAT_NONE) 811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (image->common.repeat, &x0, image->width); 831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (image->common.repeat, &y0, image->height); 841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return get_pixel (image, x0, y0, FALSE); 861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return get_pixel (image, x0, y0, TRUE); 901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 931176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 941176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_pixel_bilinear (bits_image_t *image, 951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, 961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y, 971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck get_pixel_t get_pixel) 981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode = image->common.repeat; 1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = image->width; 1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height = image->height; 1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x1, y1, x2, y2; 1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t tl, tr, bl, br; 1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t distx, disty; 1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = x - pixman_fixed_1 / 2; 1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = y - pixman_fixed_1 / 2; 1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck distx = pixman_fixed_to_bilinear_weight (x1); 1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck disty = pixman_fixed_to_bilinear_weight (y1); 1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = pixman_fixed_to_int (x1); 1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y1); 1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x2 = x1 + 1; 1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + 1; 1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &x1, width); 1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &y1, height); 1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &x2, width); 1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &y2, height); 1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = get_pixel (image, x1, y1, FALSE); 1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = get_pixel (image, x1, y2, FALSE); 1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = get_pixel (image, x2, y1, FALSE); 1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = get_pixel (image, x2, y2, FALSE); 1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = get_pixel (image, x1, y1, TRUE); 1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = get_pixel (image, x2, y1, TRUE); 1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = get_pixel (image, x1, y2, TRUE); 1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = get_pixel (image, x2, y2, TRUE); 1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return bilinear_interpolation (tl, tr, bl, br, distx, disty); 1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter, 1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *mask) 1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t * ima = iter->image; 1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset = iter->x; 1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line = iter->y++; 1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t *bits = &ima->bits; 1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x_top, x_bottom, x; 1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux_top, ux_bottom, ux; 1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t top_mask, bottom_mask; 1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *top_row; 1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *bottom_row; 1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *end; 1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t zero[2] = { 0, 0 }; 1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t one = 1; 1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y, y1, y2; 1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int disty; 1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int mask_inc; 1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int w; 1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (bits->common.transform, &v)) 1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0]; 1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2; 1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = v.vector[1] - pixman_fixed_1/2; 1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck disty = pixman_fixed_to_bilinear_weight (y); 1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Load the pointers to the first and second lines from the source 1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * image that bilinear code must read. 1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The main trick in this code is about the check if any line are 1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * outside of the image; 1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * When I realize that a line (any one) is outside, I change 1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the pointer to a dummy area with zeros. Once I change this, I 1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * must be sure the pointer will not change, so I set the 1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * variables to each pointer increments inside the loop. 1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y); 1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + 1; 1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y1 < 0 || y1 >= bits->height) 1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_row = zero; 1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top = 0; 1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux_top = 0; 1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_row = bits->bits + y1 * bits->rowstride; 2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top = x; 2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux_top = ux; 2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y2 < 0 || y2 >= bits->height) 2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_row = zero; 2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom = 0; 2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux_bottom = 0; 2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_row = bits->bits + y2 * bits->rowstride; 2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom = x; 2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux_bottom = ux; 2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Instead of checking whether the operation uses the mast in 2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * each loop iteration, verify this only once and prepare the 2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * variables to make the code smaller inside the loop. 2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!mask) 2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask_inc = 0; 2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask = &one; 2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* If have a mask, prepare the variables to check it */ 2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask_inc = 1; 2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* If both are zero, then the whole thing is zero */ 2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (top_row == zero && bottom_row == zero) 2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (buffer, 0, width * sizeof (uint32_t)); 2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else if (bits->format == PIXMAN_x8r8g8b8) 2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (top_row == zero) 2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_mask = 0; 2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_mask = 0xff000000; 2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else if (bottom_row == zero) 2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_mask = 0xff000000; 2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_mask = 0; 2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_mask = 0xff000000; 2561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_mask = 0xff000000; 2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck top_mask = 0; 2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bottom_mask = 0; 2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck end = buffer + width; 2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Zero fill to the left of the image */ 2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end && x < pixman_fixed_minus_1) 2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *buffer++ = 0; 2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top += ux_top; 2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom += ux_bottom; 2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask += mask_inc; 2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Left edge 2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end && x < 0) 2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t tr, br; 2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t distx; 2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask; 2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; 2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck distx = pixman_fixed_to_bilinear_weight (x); 2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty); 2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top += ux_top; 2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom += ux_bottom; 2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask += mask_inc; 2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Main part */ 2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = pixman_int_to_fixed (bits->width - 1); 2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end && x < w) 3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (*mask) 3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t tl, tr, bl, br; 3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t distx; 3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = top_row [pixman_fixed_to_int (x_top)] | top_mask; 3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask; 3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; 3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; 3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck distx = pixman_fixed_to_bilinear_weight (x); 3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty); 3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer++; 3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top += ux_top; 3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom += ux_bottom; 3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask += mask_inc; 3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Right Edge */ 3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = pixman_int_to_fixed (bits->width); 3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end && x < w) 3271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (*mask) 3291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t tl, bl; 3311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t distx; 3321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = top_row [pixman_fixed_to_int (x_top)] | top_mask; 3341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; 3351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck distx = pixman_fixed_to_bilinear_weight (x); 3371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty); 3391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 3401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer++; 3421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 3431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_top += ux_top; 3441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x_bottom += ux_bottom; 3451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask += mask_inc; 3461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 3471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Zero fill to the left of the image */ 3491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end) 3501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *buffer++ = 0; 3511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 3531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 3541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3551176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 3561176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_pixel_convolution (bits_image_t *image, 3571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, 3581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y, 3591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck get_pixel_t get_pixel) 3601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 3611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *params = image->common.filter_params; 3621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_off = (params[0] - pixman_fixed_1) >> 1; 3631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_off = (params[1] - pixman_fixed_1) >> 1; 3641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t cwidth = pixman_fixed_to_int (params[0]); 3651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t cheight = pixman_fixed_to_int (params[1]); 3661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t i, j, x1, x2, y1, y2; 3671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode = image->common.repeat; 3681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = image->width; 3691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height = image->height; 3701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int srtot, sgtot, sbtot, satot; 3711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck params += 2; 3731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); 3751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); 3761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x2 = x1 + cwidth; 3771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + cheight; 3781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = sgtot = sbtot = satot = 0; 3801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = y1; i < y2; ++i) 3821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (j = x1; j < x2; ++j) 3841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rx = j; 3861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int ry = i; 3871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t f = *params; 3891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (f) 3911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t pixel; 3931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 3951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 3961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &rx, width); 3971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &ry, height); 3981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 3991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = get_pixel (image, rx, ry, FALSE); 4001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 4021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = get_pixel (image, rx, ry, TRUE); 4041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot += (int)RED_8 (pixel) * f; 4071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot += (int)GREEN_8 (pixel) * f; 4081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot += (int)BLUE_8 (pixel) * f; 4091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot += (int)ALPHA_8 (pixel) * f; 4101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck params++; 4131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = (satot + 0x8000) >> 16; 4171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = (srtot + 0x8000) >> 16; 4181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = (sgtot + 0x8000) >> 16; 4191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = (sbtot + 0x8000) >> 16; 4201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = CLIP (satot, 0, 0xff); 4221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = CLIP (srtot, 0, 0xff); 4231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = CLIP (sgtot, 0, 0xff); 4241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = CLIP (sbtot, 0, 0xff); 4251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); 4271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 4281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4291176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t 4301176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_pixel_separable_convolution (bits_image_t *image, 4311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, 4321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y, 4331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck get_pixel_t get_pixel) 4341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 4351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *params = image->common.filter_params; 4361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode = image->common.repeat; 4371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = image->width; 4381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height = image->height; 4391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int cwidth = pixman_fixed_to_int (params[0]); 4401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int cheight = pixman_fixed_to_int (params[1]); 4411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_phase_bits = pixman_fixed_to_int (params[2]); 4421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_phase_bits = pixman_fixed_to_int (params[3]); 4431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_phase_shift = 16 - x_phase_bits; 4441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_phase_shift = 16 - y_phase_bits; 4451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; 4461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; 4471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *y_params; 4481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int srtot, sgtot, sbtot, satot; 4491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t x1, x2, y1, y2; 4501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t px, py; 4511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i, j; 4521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Round x and y to the middle of the closest phase before continuing. This 4541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * ensures that the convolution matrix is aligned right, since it was 4551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * positioned relative to a particular phase (and not relative to whatever 4561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * exact fraction we happen to get here). 4571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 4581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); 4591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); 4601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck px = (x & 0xffff) >> x_phase_shift; 4621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck py = (y & 0xffff) >> y_phase_shift; 4631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; 4651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); 4671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); 4681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x2 = x1 + cwidth; 4691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + cheight; 4701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = sgtot = sbtot = satot = 0; 4721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = y1; i < y2; ++i) 4741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_48_16_t fy = *y_params++; 4761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *x_params = params + 4 + px * cwidth; 4771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (fy) 4791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (j = x1; j < x2; ++j) 4811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t fx = *x_params++; 4831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rx = j; 4841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int ry = i; 4851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (fx) 4871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t f; 4891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t pixel; 4901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 4921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 4931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &rx, width); 4941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &ry, height); 4951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 4961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = get_pixel (image, rx, ry, FALSE); 4971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 4981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 4991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 5001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = get_pixel (image, rx, ry, TRUE); 5011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck f = (fy * fx + 0x8000) >> 16; 5041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot += (int)RED_8 (pixel) * f; 5061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot += (int)GREEN_8 (pixel) * f; 5071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot += (int)BLUE_8 (pixel) * f; 5081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot += (int)ALPHA_8 (pixel) * f; 5091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = (satot + 0x8000) >> 16; 5151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = (srtot + 0x8000) >> 16; 5161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = (sgtot + 0x8000) >> 16; 5171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = (sbtot + 0x8000) >> 16; 5181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = CLIP (satot, 0, 0xff); 5201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = CLIP (srtot, 0, 0xff); 5211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = CLIP (sgtot, 0, 0xff); 5221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = CLIP (sbtot, 0, 0xff); 5231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); 5251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 5261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5271176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 5281176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_pixel_filtered (bits_image_t *image, 5291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, 5301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y, 5311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck get_pixel_t get_pixel) 5321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 5331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck switch (image->common.filter) 5341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 5351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_NEAREST: 5361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_FAST: 5371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return bits_image_fetch_pixel_nearest (image, x, y, get_pixel); 5381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 5391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_BILINEAR: 5411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_GOOD: 5421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_BEST: 5431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel); 5441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 5451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_CONVOLUTION: 5471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); 5481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 5491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: 5511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel); 5521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 5531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck default: 5551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 5561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 0; 5591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 5601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5611176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 5621176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_affine_no_alpha (pixman_iter_t * iter, 5631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask) 5641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 5651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image = iter->image; 5661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset = iter->x; 5671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line = iter->y++; 5681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 5691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 5701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, y; 5721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux, uy; 5731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 5741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 5751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 5771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 5781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 5791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 5801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.transform) 5821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 5831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (image->common.transform, &v)) 5841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 5851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = image->common.transform->matrix[0][0]; 5871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = image->common.transform->matrix[1][0]; 5881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 5901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 5911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = pixman_fixed_1; 5921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = 0; 5931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 5941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = v.vector[0]; 5961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = v.vector[1]; 5971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 5981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 5991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!mask || mask[i]) 6011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = bits_image_fetch_pixel_filtered ( 6031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, x, y, fetch_pixel_no_alpha); 6041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 6071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += uy; 6081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return buffer; 6111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 6121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* General fetcher */ 6141176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 6151176bdada62cabc6ec4b0308a930e83b679d5d36John Reckfetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) 6161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 6171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t pixel; 6181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (check_bounds && 6201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (x < 0 || x >= image->width || y < 0 || y >= image->height)) 6211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return 0; 6231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = image->fetch_pixel_32 (image, x, y); 6261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.alpha_map) 6281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t pixel_a; 6301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->common.alpha_origin_x; 6321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->common.alpha_origin_y; 6331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x < 0 || x >= image->common.alpha_map->width || 6351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y < 0 || y >= image->common.alpha_map->height) 6361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel_a = 0; 6381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 6401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel_a = image->common.alpha_map->fetch_pixel_32 ( 6421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map, x, y); 6431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel_a = ALPHA_8 (pixel_a); 6451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel &= 0x00ffffff; 6481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel |= (pixel_a << 24); 6491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return pixel; 6521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 6531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6541176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 6551176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_general (pixman_iter_t *iter, 6561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *mask) 6571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 6581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image = iter->image; 6591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset = iter->x; 6601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line = iter->y++; 6611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 6621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 6631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, y, w; 6651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux, uy, uw; 6661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 6671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 6681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 6701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 6711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 6721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 6731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.transform) 6751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (image->common.transform, &v)) 6771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return buffer; 6781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = image->common.transform->matrix[0][0]; 6801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = image->common.transform->matrix[1][0]; 6811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uw = image->common.transform->matrix[2][0]; 6821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 6841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = pixman_fixed_1; 6861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = 0; 6871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uw = 0; 6881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 6891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = v.vector[0]; 6911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = v.vector[1]; 6921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = v.vector[2]; 6931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 6951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 6961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x0, y0; 6971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 6981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!mask || mask[i]) 6991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 7001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (w != 0) 7011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 7021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x0 = ((pixman_fixed_48_16_t)x << 16) / w; 7031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y0 = ((pixman_fixed_48_16_t)y << 16) / w; 7041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 7051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 7061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 7071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x0 = 0; 7081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y0 = 0; 7091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 7101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = bits_image_fetch_pixel_filtered ( 7121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, x0, y0, fetch_pixel_general); 7131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 7141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 7161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += uy; 7171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w += uw; 7181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 7191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return buffer; 7211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 7221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7231176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x); 7241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7251176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline void 7261176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_separable_convolution_affine (pixman_image_t * image, 7271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset, 7281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line, 7291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 7301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer, 7311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask, 7321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_pixel_t convert_pixel, 7341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format, 7351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode) 7361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 7371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t *bits = &image->bits; 7381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *params = image->common.filter_params; 7391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int cwidth = pixman_fixed_to_int (params[0]); 7401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int cheight = pixman_fixed_to_int (params[1]); 7411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; 7421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; 7431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_phase_bits = pixman_fixed_to_int (params[2]); 7441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_phase_bits = pixman_fixed_to_int (params[3]); 7451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x_phase_shift = 16 - x_phase_bits; 7461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y_phase_shift = 16 - y_phase_bits; 7471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t vx, vy; 7481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux, uy; 7491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 7501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int k; 7511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 7531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 7541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 7551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 7561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (image->common.transform, &v)) 7581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 7591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = image->common.transform->matrix[0][0]; 7611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = image->common.transform->matrix[1][0]; 7621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck vx = v.vector[0]; 7641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck vy = v.vector[1]; 7651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (k = 0; k < width; ++k) 7671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 7681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *y_params; 7691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int satot, srtot, sgtot, sbtot; 7701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, y; 7711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t x1, x2, y1, y2; 7721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t px, py; 7731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i, j; 7741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (mask && !mask[k]) 7761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck goto next; 7771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Round x and y to the middle of the closest phase before continuing. This 7791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * ensures that the convolution matrix is aligned right, since it was 7801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * positioned relative to a particular phase (and not relative to whatever 7811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * exact fraction we happen to get here). 7821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 7831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); 7841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); 7851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck px = (x & 0xffff) >> x_phase_shift; 7871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck py = (y & 0xffff) >> y_phase_shift; 7881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); 7901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); 7911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x2 = x1 + cwidth; 7921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + cheight; 7931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = srtot = sgtot = sbtot = 0; 7951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; 7971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 7981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = y1; i < y2; ++i) 7991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t fy = *y_params++; 8011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (fy) 8031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t *x_params = params + 4 + px * cwidth; 8051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (j = x1; j < x2; ++j) 8071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t fx = *x_params++; 8091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rx = j; 8101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int ry = i; 8111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (fx) 8131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t f; 8151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t pixel, mask; 8161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint8_t *row; 8171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 8191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 8211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &rx, bits->width); 8231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &ry, bits->height); 8241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; 8261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = convert_pixel (row, rx) | mask; 8271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 8291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height) 8311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = 0; 8331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 8351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 8361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; 8371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixel = convert_pixel (row, rx) | mask; 8381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16; 8421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot += (int)RED_8 (pixel) * f; 8431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot += (int)GREEN_8 (pixel) * f; 8441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot += (int)BLUE_8 (pixel) * f; 8451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot += (int)ALPHA_8 (pixel) * f; 8461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = (satot + 0x8000) >> 16; 8521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = (srtot + 0x8000) >> 16; 8531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = (sgtot + 0x8000) >> 16; 8541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = (sbtot + 0x8000) >> 16; 8551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck satot = CLIP (satot, 0, 0xff); 8571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck srtot = CLIP (srtot, 0, 0xff); 8581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sgtot = CLIP (sgtot, 0, 0xff); 8591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck sbtot = CLIP (sbtot, 0, 0xff); 8601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0); 8621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck next: 8641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck vx += ux; 8651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck vy += uy; 8661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 8671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 8681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8691176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 8701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8711176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline void 8721176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_bilinear_affine (pixman_image_t * image, 8731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset, 8741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line, 8751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 8761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer, 8771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask, 8781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_pixel_t convert_pixel, 8801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format, 8811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode) 8821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 8831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, y; 8841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux, uy; 8851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 8861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t *bits = &image->bits; 8871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 8881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 8901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 8911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 8921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 8931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (image->common.transform, &v)) 8951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 8961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 8971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = image->common.transform->matrix[0][0]; 8981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = image->common.transform->matrix[1][0]; 8991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = v.vector[0]; 9011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = v.vector[1]; 9021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 9041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x1, y1, x2, y2; 9061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t tl, tr, bl, br; 9071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int32_t distx, disty; 9081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = image->bits.width; 9091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height = image->bits.height; 9101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint8_t *row1; 9111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint8_t *row2; 9121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (mask && !mask[i]) 9141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck goto next; 9151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = x - pixman_fixed_1 / 2; 9171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = y - pixman_fixed_1 / 2; 9181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck distx = pixman_fixed_to_bilinear_weight (x1); 9201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck disty = pixman_fixed_to_bilinear_weight (y1); 9211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y1 = pixman_fixed_to_int (y1); 9231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y2 = y1 + 1; 9241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x1 = pixman_fixed_to_int (x1); 9251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x2 = x1 + 1; 9261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 9281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t mask; 9301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 9321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &x1, width); 9341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &y1, height); 9351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &x2, width); 9361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &y2, height); 9371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; 9391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; 9401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = convert_pixel (row1, x1) | mask; 9421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = convert_pixel (row1, x2) | mask; 9431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = convert_pixel (row2, x1) | mask; 9441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = convert_pixel (row2, x2) | mask; 9451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 9471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t mask1, mask2; 9491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int bpp; 9501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value, 9521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * which means if you use it in expressions, those 9531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * expressions become unsigned themselves. Since 9541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the variables below can be negative in some cases, 9551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * that will lead to crashes on 64 bit architectures. 9561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 9571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * So this line makes sure bpp is signed 9581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 9591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bpp = PIXMAN_FORMAT_BPP (format); 9601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0) 9621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = 0; 9641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck goto next; 9651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y2 == 0) 9681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row1 = zero; 9701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask1 = 0; 9711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 9731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; 9751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row1 += bpp / 8 * x1; 9761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 9781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y1 == height - 1) 9811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row2 = zero; 9831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask2 = 0; 9841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 9861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; 9881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row2 += bpp / 8 * x1; 9891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 9911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 9931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x2 == 0) 9941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 9951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = 0; 9961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = 0; 9971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 9981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 9991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl = convert_pixel (row1, 0) | mask1; 10011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bl = convert_pixel (row2, 0) | mask2; 10021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x1 == width - 1) 10051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = 0; 10071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = 0; 10081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 10101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tr = convert_pixel (row1, 1) | mask1; 10121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck br = convert_pixel (row2, 1) | mask2; 10131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = bilinear_interpolation ( 10171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tl, tr, bl, br, distx, disty); 10181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck next: 10201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 10211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += uy; 10221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 10241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10251176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline void 10261176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_nearest_affine (pixman_image_t * image, 10271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int offset, 10281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int line, 10291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 10301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer, 10311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask, 10321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_pixel_t convert_pixel, 10341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format, 10351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_repeat_t repeat_mode) 10361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 10371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t x, y; 10381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t ux, uy; 10391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_vector_t v; 10401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t *bits = &image->bits; 10411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 10421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* reference point is the center of the pixel */ 10441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; 10451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; 10461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck v.vector[2] = pixman_fixed_1; 10471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!pixman_transform_point_3d (image->common.transform, &v)) 10491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 10501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ux = image->common.transform->matrix[0][0]; 10521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uy = image->common.transform->matrix[1][0]; 10531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x = v.vector[0]; 10551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y = v.vector[1]; 10561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 10581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, height, x0, y0; 10601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint8_t *row; 10611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (mask && !mask[i]) 10631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck goto next; 10641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck width = image->bits.width; 10661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck height = image->bits.height; 10671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x0 = pixman_fixed_to_int (x - pixman_fixed_e); 10681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y0 = pixman_fixed_to_int (y - pixman_fixed_e); 10691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode == PIXMAN_REPEAT_NONE && 10711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width)) 10721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = 0; 10741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 10761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 10781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (repeat_mode != PIXMAN_REPEAT_NONE) 10801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 10811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &x0, width); 10821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat (repeat_mode, &y0, height); 10831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0; 10861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] = convert_pixel (row, x0) | mask; 10881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck next: 10911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += ux; 10921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += uy; 10931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 10941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 10951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 10961176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 10971176bdada62cabc6ec4b0308a930e83b679d5d36John Reckconvert_a8r8g8b8 (const uint8_t *row, int x) 10981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 10991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return *(((uint32_t *)row) + x); 11001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 11011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11021176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 11031176bdada62cabc6ec4b0308a930e83b679d5d36John Reckconvert_x8r8g8b8 (const uint8_t *row, int x) 11041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 11051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return *(((uint32_t *)row) + x); 11061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 11071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11081176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 11091176bdada62cabc6ec4b0308a930e83b679d5d36John Reckconvert_a8 (const uint8_t *row, int x) 11101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 11111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return *(row + x) << 24; 11121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 11131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11141176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic force_inline uint32_t 11151176bdada62cabc6ec4b0308a930e83b679d5d36John Reckconvert_r5g6b5 (const uint8_t *row, int x) 11161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 11171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return convert_0565_to_0888 (*((uint16_t *)row + x)); 11181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 11191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode) \ 11211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static uint32_t * \ 11221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t *iter, \ 11231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask) \ 11241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 11251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_separable_convolution_affine ( \ 11261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->image, \ 11271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->x, iter->y++, \ 11281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->width, \ 11291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->buffer, mask, \ 11301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_ ## format, \ 11311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck PIXMAN_ ## format, \ 11321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat_mode); \ 11331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 11341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; \ 11351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 11361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode) \ 11381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static uint32_t * \ 11391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \ 11401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask) \ 11411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 11421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_bilinear_affine (iter->image, \ 11431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->x, iter->y++, \ 11441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->width, \ 11451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->buffer, mask, \ 11461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_ ## format, \ 11471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck PIXMAN_ ## format, \ 11481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat_mode); \ 11491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; \ 11501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 11511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAKE_NEAREST_FETCHER(name, format, repeat_mode) \ 11531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static uint32_t * \ 11541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_nearest_affine_ ## name (pixman_iter_t *iter, \ 11551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t * mask) \ 11561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 11571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_nearest_affine (iter->image, \ 11581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->x, iter->y++, \ 11591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->width, \ 11601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->buffer, mask, \ 11611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck convert_ ## format, \ 11621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck PIXMAN_ ## format, \ 11631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck repeat_mode); \ 11641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; \ 11651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 11661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAKE_FETCHERS(name, format, repeat_mode) \ 11681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck MAKE_NEAREST_FETCHER (name, format, repeat_mode) \ 11691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck MAKE_BILINEAR_FETCHER (name, format, repeat_mode) \ 11701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode) 11711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11721176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD) 11731176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE) 11741176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT) 11751176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (normal_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NORMAL) 11761176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD) 11771176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (none_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NONE) 11781176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT) 11791176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (normal_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NORMAL) 11801176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (pad_a8, a8, PIXMAN_REPEAT_PAD) 11811176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (none_a8, a8, PIXMAN_REPEAT_NONE) 11821176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (reflect_a8, a8, PIXMAN_REPEAT_REFLECT) 11831176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (normal_a8, a8, PIXMAN_REPEAT_NORMAL) 11841176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (pad_r5g6b5, r5g6b5, PIXMAN_REPEAT_PAD) 11851176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (none_r5g6b5, r5g6b5, PIXMAN_REPEAT_NONE) 11861176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT) 11871176bdada62cabc6ec4b0308a930e83b679d5d36John ReckMAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL) 11881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11891176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 11901176bdada62cabc6ec4b0308a930e83b679d5d36John Reckreplicate_pixel_32 (bits_image_t * bits, 11911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, 11921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y, 11931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 11941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer) 11951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 11961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t color; 11971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *end; 11981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 11991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck color = bits->fetch_pixel_32 (bits, x, y); 12001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck end = buffer + width; 12021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end) 12031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *(buffer++) = color; 12041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 12051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12061176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 12071176bdada62cabc6ec4b0308a930e83b679d5d36John Reckreplicate_pixel_float (bits_image_t * bits, 12081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, 12091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y, 12101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 12111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * b) 12121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 12131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck argb_t color; 12141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck argb_t *buffer = (argb_t *)b; 12151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck argb_t *end; 12161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck color = bits->fetch_pixel_float (bits, x, y); 12181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck end = buffer + width; 12201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (buffer < end) 12211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *(buffer++) = color; 12221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 12231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12241176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 12251176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_untransformed_repeat_none (bits_image_t *image, 12261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_bool_t wide, 12271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, 12281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y, 12291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 12301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer) 12311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 12321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t w; 12331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y < 0 || y >= image->height) 12351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 12361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (buffer, 0, width * (wide? sizeof (argb_t) : 4)); 12371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 12381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 12391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x < 0) 12411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 12421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = MIN (width, -x); 12431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4)); 12451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck width -= w; 12471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer += w * (wide? 4 : 1); 12481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += w; 12491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 12501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (x < image->width) 12521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 12531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = MIN (width, image->width - x); 12541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (wide) 12561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); 12571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 12581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); 12591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck width -= w; 12611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer += w * (wide? 4 : 1); 12621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += w; 12631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 12641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4)); 12661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 12671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12681176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 12691176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_untransformed_repeat_normal (bits_image_t *image, 12701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_bool_t wide, 12711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x, 12721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y, 12731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 12741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer) 12751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 12761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t w; 12771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (y < 0) 12791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += image->height; 12801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (y >= image->height) 12821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->height; 12831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->width == 1) 12851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 12861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (wide) 12871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck replicate_pixel_float (image, 0, y, width, buffer); 12881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 12891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck replicate_pixel_32 (image, 0, y, width, buffer); 12901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 12921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 12931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 12941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (width) 12951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 12961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (x < 0) 12971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += image->width; 12981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (x >= image->width) 12991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->width; 13001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck w = MIN (width, image->width - x); 13021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (wide) 13041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); 13051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 13061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); 13071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer += w * (wide? 4 : 1); 13091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x += w; 13101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck width -= w; 13111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 13121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 13131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13141176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 13151176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_untransformed_32 (pixman_iter_t * iter, 13161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *mask) 13171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 13181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image = iter->image; 13191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 13201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 13211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 13221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 13231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.repeat == PIXMAN_REPEAT_NONE) 13251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 13261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_repeat_none ( 13271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, FALSE, x, y, width, buffer); 13281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 13291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 13301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 13311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_repeat_normal ( 13321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, FALSE, x, y, width, buffer); 13331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 13341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->y++; 13361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return buffer; 13371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 13381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13391176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 13401176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_fetch_untransformed_float (pixman_iter_t * iter, 13411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *mask) 13421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 13431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image = iter->image; 13441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 13451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 13461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 13471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 13481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.repeat == PIXMAN_REPEAT_NONE) 13501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 13511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_repeat_none ( 13521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, TRUE, x, y, width, buffer); 13531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 13541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 13551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 13561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_repeat_normal ( 13571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &image->bits, TRUE, x, y, width, buffer); 13581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 13591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->y++; 13611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return buffer; 13621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 13631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13641176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct 13651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 13661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format; 13671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t flags; 13681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_iter_get_scanline_t get_scanline_32; 13691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_iter_get_scanline_t get_scanline_float; 13701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} fetcher_info_t; 13711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13721176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const fetcher_info_t fetcher_info[] = 13731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 13741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_any, 13751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | 13761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_ID_TRANSFORM | 13771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_CONVOLUTION_FILTER | 13781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_PAD_REPEAT | 13791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_REFLECT_REPEAT), 13801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_32, 13811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_untransformed_float 13821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 13831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define FAST_BILINEAR_FLAGS \ 13851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | \ 13861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_ACCESSORS | \ 13871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_HAS_TRANSFORM | \ 13881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_AFFINE_TRANSFORM | \ 13891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_X_UNIT_POSITIVE | \ 13901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_Y_UNIT_ZERO | \ 13911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NONE_REPEAT | \ 13921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_BILINEAR_FILTER) 13931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 13941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_a8r8g8b8, 13951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_BILINEAR_FLAGS, 13961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_bilinear_no_repeat_8888, 13971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float 13981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 13991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_x8r8g8b8, 14011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_BILINEAR_FLAGS, 14021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_bilinear_no_repeat_8888, 14031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float 14041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define GENERAL_BILINEAR_FLAGS \ 14071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | \ 14081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_ACCESSORS | \ 14091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_HAS_TRANSFORM | \ 14101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_AFFINE_TRANSFORM | \ 14111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_BILINEAR_FILTER) 14121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define GENERAL_NEAREST_FLAGS \ 14141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | \ 14151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_ACCESSORS | \ 14161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_HAS_TRANSFORM | \ 14171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_AFFINE_TRANSFORM | \ 14181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NEAREST_FILTER) 14191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define GENERAL_SEPARABLE_CONVOLUTION_FLAGS \ 14211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | \ 14221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_NO_ACCESSORS | \ 14231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_HAS_TRANSFORM | \ 14241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_AFFINE_TRANSFORM | \ 14251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck FAST_PATH_SEPARABLE_CONVOLUTION_FILTER) 14261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ 14281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_ ## format, \ 14291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ 14301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_separable_convolution_affine_ ## name, \ 14311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float \ 14321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ 14351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_ ## format, \ 14361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ 14371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_bilinear_affine_ ## name, \ 14381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float \ 14391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define NEAREST_AFFINE_FAST_PATH(name, format, repeat) \ 14421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_ ## format, \ 14431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ 14441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_nearest_affine_ ## name, \ 14451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float \ 14461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define AFFINE_FAST_PATHS(name, format, repeat) \ 14491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ 14501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ 14511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck NEAREST_AFFINE_FAST_PATH(name, format, repeat) 14521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD) 14541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE) 14551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT) 14561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL) 14571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD) 14581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE) 14591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT) 14601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL) 14611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (pad_a8, a8, PAD) 14621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (none_a8, a8, NONE) 14631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT) 14641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (normal_a8, a8, NORMAL) 14651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD) 14661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE) 14671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT) 14681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL) 14691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Affine, no alpha */ 14711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_any, 14721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM), 14731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_affine_no_alpha, 14741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float 14751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* General */ 14781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_any, 14791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 0, 14801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_fetch_general, 14811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_get_scanline_generic_float 14821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck }, 14831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { PIXMAN_null }, 14851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}; 14861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14871176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 14881176bdada62cabc6ec4b0308a930e83b679d5d36John Reckbits_image_property_changed (pixman_image_t *image) 14891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 14901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_bits_image_setup_accessors (&image->bits); 14911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 14921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 14931176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid 14941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) 14951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 14961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format = image->common.extended_format_code; 14971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t flags = image->common.flags; 14981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const fetcher_info_t *info; 14991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (info = fetcher_info; info->format != PIXMAN_null; ++info) 15011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if ((info->format == format || info->format == PIXMAN_any) && 15031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (info->flags & flags) == info->flags) 15041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (iter->iter_flags & ITER_NARROW) 15061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = info->get_scanline_32; 15081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 15101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->data = info->get_scanline_32; 15121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = info->get_scanline_float; 15131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return; 15151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Just in case we somehow didn't find a scanline function */ 15191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = _pixman_iter_get_scanline_noop; 15201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 15211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15221176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 15231176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) 15241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 15251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image = iter->image; 15261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 15271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 15281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 15291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * buffer = iter->buffer; 15301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask); 15321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.alpha_map) 15331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *alpha; 15351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if ((alpha = malloc (width * sizeof (uint32_t)))) 15371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 15391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->common.alpha_origin_x; 15411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->common.alpha_origin_y; 15421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map->fetch_scanline_32 ( 15441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (pixman_image_t *)image->common.alpha_map, 15451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x, y, width, alpha, mask); 15461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 15481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] &= ~0xff000000; 15501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i] |= (alpha[i] & 0xff000000); 15511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (alpha); 15541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 15581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 15591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15601176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 15611176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) 15621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 15631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t * image = &iter->image->bits; 15641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 15651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 15661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 15671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck argb_t * buffer = (argb_t *)iter->buffer; 15681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->fetch_scanline_float ( 15701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask); 15711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.alpha_map) 15721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck argb_t *alpha; 15741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if ((alpha = malloc (width * sizeof (argb_t)))) 15761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 15771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int i; 15781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->common.alpha_origin_x; 15801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->common.alpha_origin_y; 15811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map->fetch_scanline_float ( 15831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (pixman_image_t *)image->common.alpha_map, 15841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x, y, width, (uint32_t *)alpha, mask); 15851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (i = 0; i < width; ++i) 15871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buffer[i].a = alpha[i].a; 15881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (alpha); 15901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 15921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return iter->buffer; 15941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 15951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 15961176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 15971176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdest_write_back_narrow (pixman_iter_t *iter) 15981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 15991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t * image = &iter->image->bits; 16001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 16011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 16021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 16031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *buffer = iter->buffer; 16041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->store_scanline_32 (image, x, y, width, buffer); 16061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.alpha_map) 16081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->common.alpha_origin_x; 16101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->common.alpha_origin_y; 16111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map->store_scanline_32 ( 16131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map, x, y, width, buffer); 16141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->y++; 16171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 16181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16191176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 16201176bdada62cabc6ec4b0308a930e83b679d5d36John Reckdest_write_back_wide (pixman_iter_t *iter) 16211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 16221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits_image_t * image = &iter->image->bits; 16231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = iter->x; 16241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int y = iter->y; 16251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = iter->width; 16261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck const uint32_t *buffer = iter->buffer; 16271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->store_scanline_float (image, x, y, width, buffer); 16291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (image->common.alpha_map) 16311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x -= image->common.alpha_origin_x; 16331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y -= image->common.alpha_origin_y; 16341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map->store_scanline_float ( 16361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.alpha_map, x, y, width, buffer); 16371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->y++; 16401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 16411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16421176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid 16431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) 16441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 16451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (iter->iter_flags & ITER_NARROW) 16461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == 16481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) 16491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = _pixman_iter_get_scanline_noop; 16511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 16531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = dest_get_scanline_narrow; 16551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->write_back = dest_write_back_narrow; 16581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 16601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 16611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->get_scanline = dest_get_scanline_wide; 16621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck iter->write_back = dest_write_back_wide; 16631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 16641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 16651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16661176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t * 16671176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcreate_bits (pixman_format_code_t format, 16681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 16691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height, 16701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int * rowstride_bytes, 16711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_bool_t clear) 16721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 16731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int stride; 16741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck size_t buf_size; 16751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int bpp; 16761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* what follows is a long-winded way, avoiding any possibility of integer 16781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * overflows, of saying: 16791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t); 16801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 16811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bpp = PIXMAN_FORMAT_BPP (format); 16831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (_pixman_multiply_overflows_int (width, bpp)) 16841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; 16851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck stride = width * bpp; 16871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (_pixman_addition_overflows_int (stride, 0x1f)) 16881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; 16891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck stride += 0x1f; 16911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck stride >>= 5; 16921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck stride *= sizeof (uint32_t); 16941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (_pixman_multiply_overflows_size (height, stride)) 16961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; 16971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 16981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck buf_size = height * stride; 16991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (rowstride_bytes) 17011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *rowstride_bytes = stride; 17021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (clear) 17041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return calloc (buf_size, 1); 17051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 17061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return malloc (buf_size); 17071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 17081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17091176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_bool_t 17101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck_pixman_bits_image_init (pixman_image_t * image, 17111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_format_code_t format, 17121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 17131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height, 17141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * bits, 17151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rowstride, 17161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_bool_t clear) 17171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 17181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *free_me = NULL; 17191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!bits && width && height) 17211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 17221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rowstride_bytes; 17231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); 17251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!bits) 17271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return FALSE; 17281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rowstride = rowstride_bytes / (int) sizeof (uint32_t); 17301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 17311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_init (image); 17331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->type = BITS; 17351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.format = format; 17361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.width = width; 17371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.height = height; 17381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.bits = bits; 17391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.free_me = free_me; 17401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.read_func = NULL; 17411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.write_func = NULL; 17421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.rowstride = rowstride; 17431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->bits.indexed = NULL; 17441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image->common.property_changed = bits_image_property_changed; 17461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck _pixman_image_reset_clip_region (image); 17481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return TRUE; 17501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 17511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17521176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic pixman_image_t * 17531176bdada62cabc6ec4b0308a930e83b679d5d36John Reckcreate_bits_image_internal (pixman_format_code_t format, 17541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 17551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height, 17561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * bits, 17571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rowstride_bytes, 17581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_bool_t clear) 17591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 17601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_image_t *image; 17611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* must be a whole number of uint32_t's 17631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 17641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return_val_if_fail ( 17651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); 17661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL); 17681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck image = _pixman_image_allocate (); 17701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!image) 17721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; 17731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!_pixman_bits_image_init (image, format, width, height, bits, 17751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rowstride_bytes / (int) sizeof (uint32_t), 17761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck clear)) 17771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 17781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (image); 17791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; 17801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 17811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return image; 17831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 17841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* If bits is NULL, a buffer will be allocated and initialized to 0 */ 17861176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_image_t * 17871176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_create_bits (pixman_format_code_t format, 17881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 17891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height, 17901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * bits, 17911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rowstride_bytes) 17921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 17931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return create_bits_image_internal ( 17941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck format, width, height, bits, rowstride_bytes, TRUE); 17951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 17961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 17981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* If bits is NULL, a buffer will be allocated and _not_ initialized */ 17991176bdada62cabc6ec4b0308a930e83b679d5d36John ReckPIXMAN_EXPORT pixman_image_t * 18001176bdada62cabc6ec4b0308a930e83b679d5d36John Reckpixman_image_create_bits_no_clear (pixman_format_code_t format, 18011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width, 18021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int height, 18031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t * bits, 18041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rowstride_bytes) 18051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 18061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return create_bits_image_internal ( 18071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck format, width, height, bits, rowstride_bytes, FALSE); 18081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 1809