1 From deef1daf5896062f47fa61b94e1e77c7c0041820 Mon Sep 17 00:00:00 2001
2 From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
3 Date: Fri, 04 Dec 2009 16:49:19 +0000
4 Subject: A copy-paste version of 16bpp bilinear scanline fetcher
7 diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
8 index 3d78ff0..1656975 100644
9 --- a/pixman/pixman-bits-image.c
10 +++ b/pixman/pixman-bits-image.c
11 @@ -535,6 +535,212 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
16 +bits_image_fetch_bilinear_no_repeat_0565 (pixman_image_t * ima,
21 + const uint32_t * mask,
24 + bits_image_t *bits = &ima->bits;
25 + pixman_fixed_t x_top, x_bottom, x;
26 + pixman_fixed_t ux_top, ux_bottom, ux;
28 + uint32_t top_mask, bottom_mask;
30 + uint16_t *bottom_row;
32 + uint16_t zero[2] = { 0, 0 };
38 + /* reference point is the center of the pixel */
39 + v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
40 + v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
41 + v.vector[2] = pixman_fixed_1;
43 + if (!pixman_transform_point_3d (bits->common.transform, &v))
46 + ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
47 + x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
49 + y = v.vector[1] - pixman_fixed_1/2;
50 + disty = (y >> 8) & 0xff;
52 + /* Load the pointers to the first and second lines from the source
53 + * image that bilinear code must read.
55 + * The main trick in this code is about the check if any line are
56 + * outside of the image;
58 + * When I realize that a line (any one) is outside, I change
59 + * the pointer to a dummy area with zeros. Once I change this, I
60 + * must be sure the pointer will not change, so I set the
61 + * variables to each pointer increments inside the loop.
63 + y1 = pixman_fixed_to_int (y);
66 + if (y1 < 0 || y1 >= bits->height)
74 + top_row = bits->bits + y1 * bits->rowstride;
79 + if (y2 < 0 || y2 >= bits->height)
87 + bottom_row = bits->bits + y2 * bits->rowstride;
92 + /* Instead of checking whether the operation uses the mast in
93 + * each loop iteration, verify this only once and prepare the
94 + * variables to make the code smaller inside the loop.
104 + /* If have a mask, prepare the variables to check it */
108 + /* If both are zero, then the whole thing is zero */
109 + if (top_row == zero && bottom_row == zero)
111 + memset (buffer, 0, width * sizeof (uint32_t));
116 + if (top_row == zero)
119 + bottom_mask = 0xff000000;
121 + else if (bottom_row == zero)
123 + top_mask = 0xff000000;
128 + top_mask = 0xff000000;
129 + bottom_mask = 0xff000000;
133 + end = buffer + width;
135 + /* Zero fill to the left of the image */
136 + while (buffer < end && x < pixman_fixed_minus_1)
141 + x_bottom += ux_bottom;
147 + while (buffer < end && x < 0)
152 + tr = CONVERT_0565_TO_0888 (top_row[pixman_fixed_to_int (x_top) + 1]) | top_mask;
153 + br = CONVERT_0565_TO_0888 (bottom_row[pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask;
155 + distx = (x >> 8) & 0xff;
157 + *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty);
161 + x_bottom += ux_bottom;
166 + w = pixman_int_to_fixed (bits->width - 1);
168 + while (buffer < end && x < w)
172 + uint32_t tl, tr, bl, br;
175 + tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask;
176 + tr = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top) + 1]) | top_mask;
177 + bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask;
178 + br = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask;
180 + distx = (x >> 8) & 0xff;
182 + *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty);
188 + x_bottom += ux_bottom;
193 + w = pixman_int_to_fixed (bits->width);
194 + while (buffer < end && x < w)
201 + tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask;
202 + bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask;
204 + distx = (x >> 8) & 0xff;
206 + *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty);
212 + x_bottom += ux_bottom;
216 + /* Zero fill to the left of the image */
217 + while (buffer < end)
221 static force_inline uint32_t
222 bits_image_fetch_pixel_convolution (bits_image_t *image,
224 @@ -917,14 +1123,26 @@ bits_image_property_changed (pixman_image_t *image)
225 (bits->common.filter == PIXMAN_FILTER_BILINEAR ||
226 bits->common.filter == PIXMAN_FILTER_GOOD ||
227 bits->common.filter == PIXMAN_FILTER_BEST) &&
228 - bits->common.repeat == PIXMAN_REPEAT_NONE &&
229 - (bits->format == PIXMAN_a8r8g8b8 ||
230 - bits->format == PIXMAN_x8r8g8b8))
231 + bits->common.repeat == PIXMAN_REPEAT_NONE)
233 image->common.get_scanline_64 =
234 _pixman_image_get_scanline_generic_64;
235 - image->common.get_scanline_32 =
236 - bits_image_fetch_bilinear_no_repeat_8888;
238 + if (bits->format == PIXMAN_a8r8g8b8 || bits->format == PIXMAN_x8r8g8b8)
240 + image->common.get_scanline_32 =
241 + bits_image_fetch_bilinear_no_repeat_8888;
243 + else if (bits->format == PIXMAN_r5g6b5)
245 + image->common.get_scanline_32 =
246 + bits_image_fetch_bilinear_no_repeat_0565;
250 + image->common.get_scanline_32 =
251 + bits_image_fetch_transformed;