From 2744e12e38280c4877311f129d5a5db509b75026 Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 8 Aug 2010 19:26:38 +0000 Subject: pixman git update 10/8/2010 --- pixman/pixman/pixman-access.c | 40 ++-- pixman/pixman/pixman-bits-image.c | 401 +++++++++++++++++++++----------------- pixman/pixman/pixman-fast-path.c | 9 +- pixman/pixman/pixman-image.c | 36 +++- pixman/pixman/pixman-private.h | 51 +++-- pixman/pixman/pixman.c | 288 +++++++++++++++++++-------- pixman/test/scaling-crash-test.c | 193 +++++++++++++----- 7 files changed, 655 insertions(+), 363 deletions(-) (limited to 'pixman') diff --git a/pixman/pixman/pixman-access.c b/pixman/pixman/pixman-access.c index 33db7fd00..7ca856f3e 100644 --- a/pixman/pixman/pixman-access.c +++ b/pixman/pixman/pixman-access.c @@ -2732,7 +2732,7 @@ store_scanline_generic_64 (bits_image_t * image, */ pixman_contract (argb8_pixels, (uint64_t *)values, width); - image->store_scanline_raw_32 (image, x, y, width, argb8_pixels); + image->store_scanline_32 (image, x, y, width, argb8_pixels); free (argb8_pixels); } @@ -2753,7 +2753,7 @@ fetch_scanline_generic_64 (pixman_image_t *image, /* Fetch the pixels into the first half of buffer and then expand them in * place. */ - image->bits.fetch_scanline_raw_32 (image, x, y, width, buffer, NULL); + image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL); format = image->bits.format; if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR || @@ -2776,7 +2776,7 @@ fetch_pixel_generic_64 (bits_image_t *image, int offset, int line) { - uint32_t pixel32 = image->fetch_pixel_raw_32 (image, offset, line); + uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line); uint64_t result; pixman_format_code_t format; @@ -2808,7 +2808,7 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image, int offset, int line) { - uint64_t pixel64 = image->fetch_pixel_raw_64 (image, offset, line); + uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line); uint32_t result; pixman_contract (&result, &pixel64, 1); @@ -2819,12 +2819,12 @@ fetch_pixel_generic_lossy_32 (bits_image_t *image, typedef struct { pixman_format_code_t format; - fetch_scanline_t fetch_scanline_raw_32; - fetch_scanline_t fetch_scanline_raw_64; - fetch_pixel_32_t fetch_pixel_raw_32; - fetch_pixel_64_t fetch_pixel_raw_64; - store_scanline_t store_scanline_raw_32; - store_scanline_t store_scanline_raw_64; + fetch_scanline_t fetch_scanline_32; + fetch_scanline_t fetch_scanline_64; + fetch_pixel_32_t fetch_pixel_32; + fetch_pixel_64_t fetch_pixel_64; + store_scanline_t store_scanline_32; + store_scanline_t store_scanline_64; } format_info_t; #define FORMAT_INFO(format) \ @@ -2951,12 +2951,12 @@ setup_accessors (bits_image_t *image) { if (info->format == image->format) { - image->fetch_scanline_raw_32 = info->fetch_scanline_raw_32; - image->fetch_scanline_raw_64 = info->fetch_scanline_raw_64; - image->fetch_pixel_raw_32 = info->fetch_pixel_raw_32; - image->fetch_pixel_raw_64 = info->fetch_pixel_raw_64; - image->store_scanline_raw_32 = info->store_scanline_raw_32; - image->store_scanline_raw_64 = info->store_scanline_raw_64; + image->fetch_scanline_32 = info->fetch_scanline_32; + image->fetch_scanline_64 = info->fetch_scanline_64; + image->fetch_pixel_32 = info->fetch_pixel_32; + image->fetch_pixel_64 = info->fetch_pixel_64; + image->store_scanline_32 = info->store_scanline_32; + image->store_scanline_64 = info->store_scanline_64; return; } @@ -2967,13 +2967,13 @@ setup_accessors (bits_image_t *image) #ifndef PIXMAN_FB_ACCESSORS void -_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image); +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image); void -_pixman_bits_image_setup_raw_accessors (bits_image_t *image) +_pixman_bits_image_setup_accessors (bits_image_t *image) { if (image->read_func || image->write_func) - _pixman_bits_image_setup_raw_accessors_accessors (image); + _pixman_bits_image_setup_accessors_accessors (image); else setup_accessors (image); } @@ -2981,7 +2981,7 @@ _pixman_bits_image_setup_raw_accessors (bits_image_t *image) #else void -_pixman_bits_image_setup_raw_accessors_accessors (bits_image_t *image) +_pixman_bits_image_setup_accessors_accessors (bits_image_t *image) { setup_accessors (image); } diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c index f8a76a5a3..806c65e7a 100644 --- a/pixman/pixman/pixman-bits-image.c +++ b/pixman/pixman/pixman-bits-image.c @@ -36,43 +36,6 @@ #include "pixman-combine32.h" /* Store functions */ - -static void -bits_image_store_scanline_32 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ - image->store_scanline_raw_32 (image, x, y, width, buffer); - - if (image->common.alpha_map) - { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - bits_image_store_scanline_32 (image->common.alpha_map, x, y, width, buffer); - } -} - -static void -bits_image_store_scanline_64 (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *buffer) -{ - image->store_scanline_raw_64 (image, x, y, width, buffer); - - if (image->common.alpha_map) - { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - bits_image_store_scanline_64 (image->common.alpha_map, x, y, width, buffer); - } -} - void _pixman_image_store_scanline_32 (bits_image_t * image, int x, @@ -81,6 +44,15 @@ _pixman_image_store_scanline_32 (bits_image_t * image, const uint32_t *buffer) { image->store_scanline_32 (image, x, y, width, buffer); + + if (image->common.alpha_map) + { + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + image->common.alpha_map->store_scanline_32 ( + image->common.alpha_map, x, y, width, buffer); + } } void @@ -91,43 +63,22 @@ _pixman_image_store_scanline_64 (bits_image_t * image, const uint32_t *buffer) { image->store_scanline_64 (image, x, y, width, buffer); -} - -/* Fetch functions */ - -static uint32_t -bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y) -{ - uint32_t pixel; - uint32_t pixel_a; - - pixel = image->fetch_pixel_raw_32 (image, x, y); - assert (image->common.alpha_map); - - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - if (x < 0 || x >= image->common.alpha_map->width || - y < 0 || y >= image->common.alpha_map->height) - { - pixel_a = 0; - } - else + if (image->common.alpha_map) { - pixel_a = image->common.alpha_map->fetch_pixel_raw_32 ( - image->common.alpha_map, x, y); - pixel_a = ALPHA_8 (pixel_a); - } - - pixel &= 0x00ffffff; - pixel |= (pixel_a << 24); + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; - return pixel; + image->common.alpha_map->store_scanline_64 ( + image->common.alpha_map, x, y, width, buffer); + } } +/* Fetch functions */ + static force_inline uint32_t -get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) +fetch_pixel_no_alpha (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds) { if (check_bounds && (x < 0 || x >= image->width || y < 0 || y >= image->height)) @@ -138,6 +89,9 @@ get_pixel (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) return image->fetch_pixel_32 (image, x, y); } +typedef uint32_t (* get_pixel_t) (bits_image_t *image, + int x, int y, pixman_bool_t check_bounds); + static force_inline void repeat (pixman_repeat_t repeat, int size, int *coord) { @@ -169,7 +123,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord) static force_inline uint32_t bits_image_fetch_pixel_nearest (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { int x0 = pixman_fixed_to_int (x - pixman_fixed_e); int y0 = pixman_fixed_to_int (y - pixman_fixed_e); @@ -281,7 +236,8 @@ bilinear_interpolation (uint32_t tl, uint32_t tr, static force_inline uint32_t bits_image_fetch_pixel_bilinear (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { pixman_repeat_t repeat_mode = image->common.repeat; int width = image->width; @@ -538,7 +494,8 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, static force_inline uint32_t bits_image_fetch_pixel_convolution (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { pixman_fixed_t *params = image->common.filter_params; int x_off = (params[0] - pixman_fixed_1) >> 1; @@ -611,23 +568,24 @@ bits_image_fetch_pixel_convolution (bits_image_t *image, static force_inline uint32_t bits_image_fetch_pixel_filtered (bits_image_t *image, pixman_fixed_t x, - pixman_fixed_t y) + pixman_fixed_t y, + get_pixel_t get_pixel) { switch (image->common.filter) { case PIXMAN_FILTER_NEAREST: case PIXMAN_FILTER_FAST: - return bits_image_fetch_pixel_nearest (image, x, y); + return bits_image_fetch_pixel_nearest (image, x, y, get_pixel); break; case PIXMAN_FILTER_BILINEAR: case PIXMAN_FILTER_GOOD: case PIXMAN_FILTER_BEST: - return bits_image_fetch_pixel_bilinear (image, x, y); + return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel); break; case PIXMAN_FILTER_CONVOLUTION: - return bits_image_fetch_pixel_convolution (image, x, y); + return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); break; default: @@ -638,12 +596,101 @@ bits_image_fetch_pixel_filtered (bits_image_t *image, } static void -bits_image_fetch_transformed (pixman_image_t * image, - int offset, - int line, - int width, - uint32_t * buffer, - const uint32_t * mask) +bits_image_fetch_affine_no_alpha (pixman_image_t * image, + int offset, + int line, + int width, + uint32_t * buffer, + const uint32_t * mask) +{ + pixman_fixed_t x, y; + pixman_fixed_t ux, uy; + pixman_vector_t v; + int i; + + /* reference point is the center of the pixel */ + v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; + v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; + v.vector[2] = pixman_fixed_1; + + if (image->common.transform) + { + if (!pixman_transform_point_3d (image->common.transform, &v)) + return; + + ux = image->common.transform->matrix[0][0]; + uy = image->common.transform->matrix[1][0]; + } + else + { + ux = pixman_fixed_1; + uy = 0; + } + + x = v.vector[0]; + y = v.vector[1]; + + for (i = 0; i < width; ++i) + { + if (!mask || mask[i]) + { + buffer[i] = bits_image_fetch_pixel_filtered ( + &image->bits, x, y, fetch_pixel_no_alpha); + } + + x += ux; + y += uy; + } +} + +/* General fetcher */ +static force_inline uint32_t +fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) +{ + uint32_t pixel; + + if (check_bounds && + (x < 0 || x >= image->width || y < 0 || y >= image->height)) + { + return 0; + } + + pixel = image->fetch_pixel_32 (image, x, y); + + if (image->common.alpha_map) + { + uint32_t pixel_a; + + x -= image->common.alpha_origin_x; + y -= image->common.alpha_origin_y; + + if (x < 0 || x >= image->common.alpha_map->width || + y < 0 || y >= image->common.alpha_map->height) + { + pixel_a = 0; + } + else + { + pixel_a = image->common.alpha_map->fetch_pixel_32 ( + image->common.alpha_map, x, y); + + pixel_a = ALPHA_8 (pixel_a); + } + + pixel &= 0x00ffffff; + pixel |= (pixel_a << 24); + } + + return pixel; +} + +static void +bits_image_fetch_general (pixman_image_t * image, + int offset, + int line, + int width, + uint32_t * buffer, + const uint32_t * mask) { pixman_fixed_t x, y, w; pixman_fixed_t ux, uy, uw; @@ -655,8 +702,6 @@ bits_image_fetch_transformed (pixman_image_t * image, v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; v.vector[2] = pixman_fixed_1; - /* when using convolution filters or PIXMAN_REPEAT_PAD one - * might get here without a transform */ if (image->common.transform) { if (!pixman_transform_point_3d (image->common.transform, &v)) @@ -677,47 +722,30 @@ bits_image_fetch_transformed (pixman_image_t * image, y = v.vector[1]; w = v.vector[2]; - if (w == pixman_fixed_1 && uw == 0) /* Affine */ + for (i = 0; i < width; ++i) { - for (i = 0; i < width; ++i) + pixman_fixed_t x0, y0; + + if (!mask || mask[i]) { - if (!mask || mask[i]) + if (w != 0) { - buffer[i] = - bits_image_fetch_pixel_filtered (&image->bits, x, y); + x0 = ((pixman_fixed_48_16_t)x << 16) / w; + y0 = ((pixman_fixed_48_16_t)y << 16) / w; } - - x += ux; - y += uy; - } - } - else - { - for (i = 0; i < width; ++i) - { - if (!mask || mask[i]) + else { - pixman_fixed_t x0, y0; - - if (w != 0) - { - x0 = ((pixman_fixed_48_16_t)x << 16) / w; - y0 = ((pixman_fixed_48_16_t)y << 16) / w; - } - else - { - x0 = 0; - y0 = 0; - } - - buffer[i] = - bits_image_fetch_pixel_filtered (&image->bits, x0, y0); + x0 = 0; + y0 = 0; } - x += ux; - y += uy; - w += uw; + buffer[i] = bits_image_fetch_pixel_filtered ( + &image->bits, x0, y0, fetch_pixel_general); } + + x += ux; + y += uy; + w += uw; } } @@ -732,7 +760,7 @@ bits_image_fetch_solid_32 (pixman_image_t * image, uint32_t color; uint32_t *end; - color = image->bits.fetch_pixel_raw_32 (&image->bits, 0, 0); + color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); end = buffer + width; while (buffer < end) @@ -751,7 +779,7 @@ bits_image_fetch_solid_64 (pixman_image_t * image, uint64_t *buffer = (uint64_t *)b; uint64_t *end; - color = image->bits.fetch_pixel_raw_64 (&image->bits, 0, 0); + color = image->bits.fetch_pixel_64 (&image->bits, 0, 0); end = buffer + width; while (buffer < end) @@ -790,9 +818,9 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, w = MIN (width, image->width - x); if (wide) - image->fetch_scanline_raw_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); else - image->fetch_scanline_raw_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); width -= w; buffer += w * (wide? 2 : 1); @@ -828,9 +856,9 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, w = MIN (width, image->width - x); if (wide) - image->fetch_scanline_raw_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); else - image->fetch_scanline_raw_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); + image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); buffer += w * (wide? 2 : 1); x += w; @@ -878,68 +906,89 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image, } } +typedef struct +{ + pixman_format_code_t format; + uint32_t flags; + fetch_scanline_t fetch_32; + fetch_scanline_t fetch_64; +} fetcher_info_t; + +static const fetcher_info_t fetcher_info[] = +{ + { PIXMAN_solid, + FAST_PATH_NO_ALPHA_MAP, + bits_image_fetch_solid_32, + bits_image_fetch_solid_64 + }, + + { PIXMAN_any, + (FAST_PATH_NO_ALPHA_MAP | + FAST_PATH_ID_TRANSFORM | + FAST_PATH_NO_CONVOLUTION_FILTER | + FAST_PATH_NO_PAD_REPEAT | + FAST_PATH_NO_REFLECT_REPEAT), + bits_image_fetch_untransformed_32, + bits_image_fetch_untransformed_64 + }, + +#define FAST_BILINEAR_FLAGS \ + (FAST_PATH_NO_ALPHA_MAP | \ + FAST_PATH_NO_ACCESSORS | \ + FAST_PATH_HAS_TRANSFORM | \ + FAST_PATH_AFFINE_TRANSFORM | \ + FAST_PATH_X_UNIT_POSITIVE | \ + FAST_PATH_Y_UNIT_ZERO | \ + FAST_PATH_NONE_REPEAT | \ + FAST_PATH_BILINEAR_FILTER) + + { PIXMAN_a8r8g8b8, + FAST_BILINEAR_FLAGS, + bits_image_fetch_bilinear_no_repeat_8888, + _pixman_image_get_scanline_generic_64 + }, + + { PIXMAN_x8r8g8b8, + FAST_BILINEAR_FLAGS, + bits_image_fetch_bilinear_no_repeat_8888, + _pixman_image_get_scanline_generic_64 + }, + + { PIXMAN_any, + (FAST_PATH_NO_ALPHA_MAP | + FAST_PATH_HAS_TRANSFORM | + FAST_PATH_AFFINE_TRANSFORM), + bits_image_fetch_affine_no_alpha, + _pixman_image_get_scanline_generic_64 + }, + + { PIXMAN_any, 0, bits_image_fetch_general, _pixman_image_get_scanline_generic_64 }, + + { PIXMAN_null }, +}; + static void bits_image_property_changed (pixman_image_t *image) { - bits_image_t *bits = (bits_image_t *)image; + uint32_t flags = image->common.flags; + pixman_format_code_t format = image->common.extended_format_code; + const fetcher_info_t *info; - _pixman_bits_image_setup_raw_accessors (bits); + _pixman_bits_image_setup_accessors (&image->bits); - image->bits.fetch_pixel_32 = image->bits.fetch_pixel_raw_32; - - if (bits->common.alpha_map) + info = fetcher_info; + while (info->format != PIXMAN_null) { - image->common.get_scanline_64 = - _pixman_image_get_scanline_generic_64; - image->common.get_scanline_32 = - bits_image_fetch_transformed; + if ((info->format == format || info->format == PIXMAN_any) && + (info->flags & flags) == info->flags) + { + image->common.get_scanline_32 = info->fetch_32; + image->common.get_scanline_64 = info->fetch_64; + break; + } - image->bits.fetch_pixel_32 = bits_image_fetch_pixel_alpha; - } - else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) && - bits->width == 1 && - bits->height == 1) - { - image->common.get_scanline_64 = bits_image_fetch_solid_64; - image->common.get_scanline_32 = bits_image_fetch_solid_32; - } - else if (!bits->common.transform && - bits->common.filter != PIXMAN_FILTER_CONVOLUTION && - (bits->common.repeat == PIXMAN_REPEAT_NONE || - bits->common.repeat == PIXMAN_REPEAT_NORMAL)) - { - image->common.get_scanline_64 = bits_image_fetch_untransformed_64; - image->common.get_scanline_32 = bits_image_fetch_untransformed_32; - } - else if (bits->common.transform && - bits->common.transform->matrix[2][0] == 0 && - bits->common.transform->matrix[2][1] == 0 && - bits->common.transform->matrix[2][2] == pixman_fixed_1 && - bits->common.transform->matrix[0][0] > 0 && - bits->common.transform->matrix[1][0] == 0 && - !bits->read_func && - (bits->common.filter == PIXMAN_FILTER_BILINEAR || - bits->common.filter == PIXMAN_FILTER_GOOD || - bits->common.filter == PIXMAN_FILTER_BEST) && - bits->common.repeat == PIXMAN_REPEAT_NONE && - (bits->format == PIXMAN_a8r8g8b8 || - bits->format == PIXMAN_x8r8g8b8)) - { - image->common.get_scanline_64 = - _pixman_image_get_scanline_generic_64; - image->common.get_scanline_32 = - bits_image_fetch_bilinear_no_repeat_8888; + info++; } - else - { - image->common.get_scanline_64 = - _pixman_image_get_scanline_generic_64; - image->common.get_scanline_32 = - bits_image_fetch_transformed; - } - - bits->store_scanline_64 = bits_image_store_scanline_64; - bits->store_scanline_32 = bits_image_store_scanline_32; } static uint32_t * diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index cd39980fc..8165db4c7 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -1873,15 +1873,12 @@ static const pixman_fast_path_t c_fast_paths[] = FAST_PATH_NO_ACCESSORS | \ FAST_PATH_NO_WIDE_FORMAT) -#define HAS_NORMAL_REPEAT_FLAGS \ - (FAST_PATH_NO_REFLECT_REPEAT | \ - FAST_PATH_NO_PAD_REPEAT | \ - FAST_PATH_NO_NONE_REPEAT) - #define SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ { PIXMAN_OP_ ## op, \ PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | HAS_NORMAL_REPEAT_FLAGS | FAST_PATH_16BIT_SAFE | FAST_PATH_X_UNIT_POSITIVE, \ + (SCALED_NEAREST_FLAGS | \ + FAST_PATH_NORMAL_REPEAT | \ + FAST_PATH_X_UNIT_POSITIVE), \ PIXMAN_null, 0, \ PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \ diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 971859318..1cce9273d 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -297,21 +297,33 @@ compute_image_info (pixman_image_t *image) /* Transform */ if (!image->common.transform) { - flags |= (FAST_PATH_ID_TRANSFORM | FAST_PATH_X_UNIT_POSITIVE); + flags |= (FAST_PATH_ID_TRANSFORM | + FAST_PATH_X_UNIT_POSITIVE | + FAST_PATH_Y_UNIT_ZERO | + FAST_PATH_AFFINE_TRANSFORM); } else { - if (image->common.transform->matrix[0][1] == 0 && - image->common.transform->matrix[1][0] == 0 && - image->common.transform->matrix[2][0] == 0 && - image->common.transform->matrix[2][1] == 0 && + flags |= FAST_PATH_HAS_TRANSFORM; + + if (image->common.transform->matrix[2][0] == 0 && + image->common.transform->matrix[2][1] == 0 && image->common.transform->matrix[2][2] == pixman_fixed_1) { - flags |= FAST_PATH_SCALE_TRANSFORM; + flags |= FAST_PATH_AFFINE_TRANSFORM; + + if (image->common.transform->matrix[0][1] == 0 && + image->common.transform->matrix[1][0] == 0) + { + flags |= FAST_PATH_SCALE_TRANSFORM; + } } if (image->common.transform->matrix[0][0] > 0) flags |= FAST_PATH_X_UNIT_POSITIVE; + + if (image->common.transform->matrix[1][0] == 0) + flags |= FAST_PATH_Y_UNIT_ZERO; } /* Alpha map */ @@ -326,6 +338,12 @@ compute_image_info (pixman_image_t *image) flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); break; + case PIXMAN_FILTER_BILINEAR: + case PIXMAN_FILTER_GOOD: + case PIXMAN_FILTER_BEST: + flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); + break; + case PIXMAN_FILTER_CONVOLUTION: break; @@ -338,15 +356,15 @@ compute_image_info (pixman_image_t *image) switch (image->common.repeat) { case PIXMAN_REPEAT_NONE: - flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_PAD_REPEAT; + flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_PAD_REPEAT | FAST_PATH_NO_NORMAL_REPEAT; break; case PIXMAN_REPEAT_REFLECT: - flags |= FAST_PATH_NO_PAD_REPEAT | FAST_PATH_NO_NONE_REPEAT; + flags |= FAST_PATH_NO_PAD_REPEAT | FAST_PATH_NO_NONE_REPEAT | FAST_PATH_NO_NORMAL_REPEAT; break; case PIXMAN_REPEAT_PAD: - flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_NONE_REPEAT; + flags |= FAST_PATH_NO_REFLECT_REPEAT | FAST_PATH_NO_NONE_REPEAT | FAST_PATH_NO_NORMAL_REPEAT; break; default: diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index 450f7654e..6774b1514 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -175,24 +175,12 @@ struct bits_image uint32_t * free_me; int rowstride; /* in number of uint32_t's */ - /* Fetch a pixel, disregarding alpha maps, transformations etc. */ - fetch_pixel_32_t fetch_pixel_raw_32; - fetch_pixel_64_t fetch_pixel_raw_64; - - /* Fetch a pixel, taking alpha maps into account */ + fetch_scanline_t fetch_scanline_32; fetch_pixel_32_t fetch_pixel_32; - fetch_pixel_64_t fetch_pixel_64; - - /* Fetch raw scanlines, with no regard for transformations, alpha maps etc. */ - fetch_scanline_t fetch_scanline_raw_32; - fetch_scanline_t fetch_scanline_raw_64; - - /* Store scanlines with no regard for alpha maps */ - store_scanline_t store_scanline_raw_32; - store_scanline_t store_scanline_raw_64; - - /* Store a scanline, taking alpha maps into account */ store_scanline_t store_scanline_32; + + fetch_scanline_t fetch_scanline_64; + fetch_pixel_64_t fetch_pixel_64; store_scanline_t store_scanline_64; /* Used for indirect access to the bits */ @@ -213,9 +201,8 @@ union pixman_image solid_fill_t solid; }; - void -_pixman_bits_image_setup_raw_accessors (bits_image_t *image); +_pixman_bits_image_setup_accessors (bits_image_t *image); void _pixman_image_get_scanline_generic_64 (pixman_image_t *image, @@ -577,8 +564,32 @@ _pixman_choose_implementation (void); #define FAST_PATH_NEEDS_WORKAROUND (1 << 14) #define FAST_PATH_NO_NONE_REPEAT (1 << 15) #define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16) -#define FAST_PATH_16BIT_SAFE (1 << 17) -#define FAST_PATH_X_UNIT_POSITIVE (1 << 18) +#define FAST_PATH_X_UNIT_POSITIVE (1 << 17) +#define FAST_PATH_AFFINE_TRANSFORM (1 << 18) +#define FAST_PATH_Y_UNIT_ZERO (1 << 19) +#define FAST_PATH_BILINEAR_FILTER (1 << 20) +#define FAST_PATH_NO_NORMAL_REPEAT (1 << 21) +#define FAST_PATH_HAS_TRANSFORM (1 << 22) + +#define FAST_PATH_PAD_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_NORMAL_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_NONE_REPEAT \ + (FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT | \ + FAST_PATH_NO_REFLECT_REPEAT) + +#define FAST_PATH_REFLECT_REPEAT \ + (FAST_PATH_NO_NONE_REPEAT | \ + FAST_PATH_NO_NORMAL_REPEAT | \ + FAST_PATH_NO_PAD_REPEAT) #define _FAST_PATH_STANDARD_FLAGS \ (FAST_PATH_ID_TRANSFORM | \ diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c index a27e33b2c..1dbfd83f8 100644 --- a/pixman/pixman/pixman.c +++ b/pixman/pixman/pixman.c @@ -488,77 +488,6 @@ walk_region_internal (pixman_implementation_t *imp, } } -#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX)) - -static force_inline uint32_t -compute_src_extents_flags (pixman_image_t *image, - pixman_box32_t *extents, - int x, - int y) -{ - pixman_box16_t extents16; - uint32_t flags; - - flags = FAST_PATH_COVERS_CLIP; - - if (image->common.type != BITS) - return flags; - - if (image->common.repeat == PIXMAN_REPEAT_NONE && - (x > extents->x1 || y > extents->y1 || - x + image->bits.width < extents->x2 || - y + image->bits.height < extents->y2)) - { - flags &= ~FAST_PATH_COVERS_CLIP; - } - - if (IS_16BIT (extents->x1 - x) && - IS_16BIT (extents->y1 - y) && - IS_16BIT (extents->x2 - x) && - IS_16BIT (extents->y2 - y)) - { - extents16.x1 = extents->x1 - x; - extents16.y1 = extents->y1 - y; - extents16.x2 = extents->x2 - x; - extents16.y2 = extents->y2 - y; - - if (!image->common.transform || - pixman_transform_bounds (image->common.transform, &extents16)) - { - if (extents16.x1 >= 0 && extents16.y1 >= 0 && - extents16.x2 <= image->bits.width && - extents16.y2 <= image->bits.height) - { - flags |= FAST_PATH_SAMPLES_COVER_CLIP; - } - } - } - - if (IS_16BIT (extents->x1 - x - 1) && - IS_16BIT (extents->y1 - y - 1) && - IS_16BIT (extents->x2 - x + 1) && - IS_16BIT (extents->y2 - y + 1)) - { - extents16.x1 = extents->x1 - x - 1; - extents16.y1 = extents->y1 - y - 1; - extents16.x2 = extents->x2 - x + 1; - extents16.y2 = extents->y2 - y + 1; - - if (/* src space expanded by one in dest space fits in 16 bit */ - (!image->common.transform || - pixman_transform_bounds (image->common.transform, &extents16)) && - /* And src image size can be used as 16.16 fixed point */ - image->bits.width < 0x7fff && - image->bits.height < 0x7fff) - { - /* Then we're "16bit safe" */ - flags |= FAST_PATH_16BIT_SAFE; - } - } - - return flags; -} - #define N_CACHED_FAST_PATHS 8 typedef struct @@ -668,6 +597,208 @@ update_cache: } } +static pixman_bool_t +compute_sample_extents (pixman_transform_t *transform, + pixman_box32_t *extents, int x, int y, + pixman_fixed_t x_off, pixman_fixed_t y_off, + pixman_fixed_t width, pixman_fixed_t height) +{ + pixman_fixed_t x1, y1, x2, y2; + pixman_fixed_48_16_t tx1, ty1, tx2, ty2; + + /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */ + x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2; + y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2; + x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2; + y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2; + + if (!transform) + { + tx1 = (pixman_fixed_48_16_t)x1; + ty1 = (pixman_fixed_48_16_t)y1; + tx2 = (pixman_fixed_48_16_t)x2; + ty2 = (pixman_fixed_48_16_t)y2; + } + else + { + int i; + + for (i = 0; i < 4; ++i) + { + pixman_fixed_48_16_t tx, ty; + pixman_vector_t v; + + v.vector[0] = (i & 0x01)? x1 : x2; + v.vector[1] = (i & 0x02)? y1 : y2; + v.vector[2] = pixman_fixed_1; + + if (!pixman_transform_point (transform, &v)) + return FALSE; + + tx = (pixman_fixed_48_16_t)v.vector[0]; + ty = (pixman_fixed_48_16_t)v.vector[1]; + + if (i == 0) + { + tx1 = tx; + ty1 = ty; + tx2 = tx; + ty2 = ty; + } + else + { + if (tx < tx1) + tx1 = tx; + if (ty < ty1) + ty1 = ty; + if (tx > tx2) + tx2 = tx; + if (ty > ty2) + ty2 = ty; + } + } + } + + /* Expand the source area by a tiny bit so account of different rounding that + * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from + * 0.5 so this won't cause the area computed to be overly pessimistic. + */ + tx1 += x_off - 8 * pixman_fixed_e; + ty1 += y_off - 8 * pixman_fixed_e; + tx2 += x_off + width + 8 * pixman_fixed_e; + ty2 += y_off + height + 8 * pixman_fixed_e; + + if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 || + ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 || + tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 || + ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16) + { + return FALSE; + } + else + { + extents->x1 = pixman_fixed_to_int (tx1); + extents->y1 = pixman_fixed_to_int (ty1); + extents->x2 = pixman_fixed_to_int (tx2) + 1; + extents->y2 = pixman_fixed_to_int (ty2) + 1; + + return TRUE; + } +} + +#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX)) + +static pixman_bool_t +analyze_extent (pixman_image_t *image, int x, int y, + const pixman_box32_t *extents, uint32_t *flags) +{ + pixman_transform_t *transform; + pixman_fixed_t *params; + pixman_fixed_t x_off, y_off; + pixman_fixed_t width, height; + pixman_box32_t ex; + + *flags |= FAST_PATH_COVERS_CLIP; + if (!image) + return TRUE; + + transform = image->common.transform; + if (image->common.type == BITS) + { + /* During repeat mode calculations we might convert the + * width/height of an image to fixed 16.16, so we need + * them to be smaller than 16 bits. + */ + if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff) + return FALSE; + + if (image->common.repeat == PIXMAN_REPEAT_NONE && + (x > extents->x1 || y > extents->y1 || + x + image->bits.width < extents->x2 || + y + image->bits.height < extents->y2)) + { + (*flags) &= ~FAST_PATH_COVERS_CLIP; + } + } + + /* Some compositing functions walk one step + * outside the destination rectangle, so we + * check here that the expanded-by-one source + * extents in destination space fits in 16 bits + */ + if (!IS_16BIT (extents->x1 - x - 1) || + !IS_16BIT (extents->y1 - y - 1) || + !IS_16BIT (extents->x2 - x + 1) || + !IS_16BIT (extents->y2 - y + 1)) + { + return FALSE; + } + + if (image->common.type == BITS) + { + switch (image->common.filter) + { + case PIXMAN_FILTER_CONVOLUTION: + params = image->common.filter_params; + x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1); + y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1); + width = params[0]; + height = params[1]; + break; + + case PIXMAN_FILTER_GOOD: + case PIXMAN_FILTER_BEST: + case PIXMAN_FILTER_BILINEAR: + x_off = - pixman_fixed_1 / 2; + y_off = - pixman_fixed_1 / 2; + width = pixman_fixed_1; + height = pixman_fixed_1; + break; + + case PIXMAN_FILTER_FAST: + case PIXMAN_FILTER_NEAREST: + x_off = - pixman_fixed_e; + y_off = - pixman_fixed_e; + width = 0; + height = 0; + break; + + default: + return FALSE; + } + } + else + { + x_off = 0; + y_off = 0; + width = 0; + height = 0; + } + + /* Check that the extents expanded by one don't overflow. This ensures that + * compositing functions can simply walk the source space using 16.16 variables + * without worrying about overflow. + */ + ex.x1 = extents->x1 - 1; + ex.y1 = extents->y1 - 1; + ex.x2 = extents->x2 + 1; + ex.y2 = extents->y2 + 1; + + if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height)) + return FALSE; + + /* Check whether the non-expanded, transformed extent is entirely within + * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is. + */ + ex = *extents; + if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height)) + { + if (ex.x1 >= 0 && ex.y1 >= 0 && ex.x2 <= image->bits.width && ex.y2 <= image->bits.height) + *flags |= FAST_PATH_SAMPLES_COVER_CLIP; + } + + return TRUE; +} static void do_composite (pixman_op_t op, @@ -737,20 +868,21 @@ do_composite (pixman_op_t op, } pixman_region32_init (®ion); - + if (!pixman_compute_composite_region32 ( ®ion, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) { goto out; } - + extents = pixman_region32_extents (®ion); - - src_flags |= compute_src_extents_flags (src, extents, dest_x - src_x, dest_y - src_y); - if (mask) - mask_flags |= compute_src_extents_flags (mask, extents, dest_x - mask_x, dest_y - mask_y); + if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags)) + goto out; + + if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags)) + goto out; /* * Check if we can replace our operator by a simpler one @@ -765,7 +897,7 @@ do_composite (pixman_op_t op, src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags, - &imp, &func); + &imp, &func); walk_region_internal (imp, op, src, mask, dest, diff --git a/pixman/test/scaling-crash-test.c b/pixman/test/scaling-crash-test.c index 7e8b6d56b..0ce1fece9 100644 --- a/pixman/test/scaling-crash-test.c +++ b/pixman/test/scaling-crash-test.c @@ -8,117 +8,202 @@ * We have a source image filled with solid color, set NORMAL or PAD repeat, * and some transform which results in nearest neighbour scaling. * - * The expected result is the destination image filled with this solid - * color. + * The expected result is either that the destination image filled with this solid + * color or, if the transformation is such that we can't composite anything at + * all, that nothing has changed in the destination. + * + * The surrounding memory of the source image is a different solid color so that + * we are sure to get failures if we access it. */ static int -do_test (int32_t dst_size, - int32_t src_size, - int32_t src_offs, - int32_t scale_factor, - pixman_repeat_t repeat) +run_test (int32_t dst_width, + int32_t dst_height, + int32_t src_width, + int32_t src_height, + int32_t src_x, + int32_t src_y, + int32_t scale_x, + int32_t scale_y, + pixman_filter_t filter, + pixman_repeat_t repeat) { - int i; pixman_image_t * src_img; pixman_image_t * dst_img; pixman_transform_t transform; uint32_t * srcbuf; uint32_t * dstbuf; + pixman_box32_t box = { 0, 0, src_width, src_height }; + pixman_color_t color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc }; + int result; + int i; - srcbuf = (uint32_t *)malloc (src_size * 4); - dstbuf = (uint32_t *)malloc (dst_size * 4); + static const pixman_fixed_t kernel[] = + { +#define D(f) (pixman_double_to_fixed (f) + 0x0001) + + pixman_int_to_fixed (5), + pixman_int_to_fixed (5), + D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), + D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), + D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), + D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), + D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0) + }; + + result = 0; - /* horizontal test */ - memset (srcbuf, 0xCC, src_size * 4); - memset (dstbuf, 0x33, dst_size * 4); + srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4); + dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4); + + memset (srcbuf, 0x88, src_width * src_height * 4); + memset (dstbuf, 0x33, dst_width * dst_height * 4); src_img = pixman_image_create_bits ( - PIXMAN_a8r8g8b8, src_size, 1, srcbuf, src_size * 4); + PIXMAN_a8r8g8b8, src_width, src_height, + srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4); + + pixman_image_fill_boxes (PIXMAN_OP_SRC, src_img, &color_cc, 1, &box); + dst_img = pixman_image_create_bits ( - PIXMAN_a8r8g8b8, dst_size, 1, dstbuf, dst_size * 4); + PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4); - pixman_transform_init_scale (&transform, scale_factor, 65536); + pixman_transform_init_scale (&transform, scale_x, scale_y); pixman_image_set_transform (src_img, &transform); pixman_image_set_repeat (src_img, repeat); - pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); + if (filter == PIXMAN_FILTER_CONVOLUTION) + pixman_image_set_filter (src_img, filter, kernel, 27); + else + pixman_image_set_filter (src_img, filter, NULL, 0); pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, - src_offs, 0, 0, 0, 0, 0, dst_size, 1); + src_x, src_y, 0, 0, 0, 0, dst_width, dst_height); pixman_image_unref (src_img); pixman_image_unref (dst_img); - for (i = 0; i < dst_size; i++) + for (i = 0; i < dst_width * dst_height; i++) { - if (dstbuf[i] != 0xCCCCCCCC) + if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333) { - free (srcbuf); - free (dstbuf); - return 1; + result = 1; + break; } } - /* vertical test */ - memset (srcbuf, 0xCC, src_size * 4); - memset (dstbuf, 0x33, dst_size * 4); + free (srcbuf); + free (dstbuf); + return result; +} - src_img = pixman_image_create_bits ( - PIXMAN_a8r8g8b8, 1, src_size, srcbuf, 4); - dst_img = pixman_image_create_bits ( - PIXMAN_a8r8g8b8, 1, dst_size, dstbuf, 4); +typedef struct info_t info_t; +struct info_t +{ + int value; + char name[28]; +}; - pixman_transform_init_scale (&transform, 65536, scale_factor); - pixman_image_set_transform (src_img, &transform); - pixman_image_set_repeat (src_img, repeat); - pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); +static const info_t filters[] = +{ + { PIXMAN_FILTER_NEAREST, "NEAREST" }, + { PIXMAN_FILTER_BILINEAR, "BILINEAR" }, + { PIXMAN_FILTER_CONVOLUTION, "CONVOLUTION" }, +}; - pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, - 0, src_offs, 0, 0, 0, 0, 1, dst_size); +static const info_t repeats[] = +{ + { PIXMAN_REPEAT_PAD, "PAD" }, + { PIXMAN_REPEAT_REFLECT, "REFLECT" }, + { PIXMAN_REPEAT_NORMAL, "NORMAL" } +}; - pixman_image_unref (src_img); - pixman_image_unref (dst_img); +static int +do_test (int32_t dst_size, + int32_t src_size, + int32_t src_offs, + int32_t scale_factor) +{ +#define N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0])) + int i, j; - for (i = 0; i < dst_size; i++) + for (i = 0; i < N_ELEMENTS(filters); ++i) { - if (dstbuf[i] != 0xCCCCCCCC) + for (j = 0; j < N_ELEMENTS (repeats); ++j) { - free (srcbuf); - free (dstbuf); - return 1; + /* horizontal test */ + if (run_test (dst_size, 1, + src_size, 1, + src_offs, 0, + scale_factor, 65536, + filters[i].value, + repeats[j].value) != 0) + { + printf ("Vertical test failed with %s filter and repeat mode %s\n", + filters[i].name, repeats[j].name); + + return 1; + } + + /* vertical test */ + if (run_test (1, dst_size, + 1, src_size, + 0, src_offs, + 65536, scale_factor, + filters[i].value, + repeats[j].value) != 0) + { + printf ("Vertical test failed with %s filter and repeat mode %s\n", + filters[i].name, repeats[j].name); + + return 1; + } } } - free (srcbuf); - free (dstbuf); return 0; } int main (int argc, char *argv[]) { + int i; + pixman_disable_out_of_bounds_workaround (); /* can potentially crash */ assert (do_test ( - 48000, 32767, 1, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0); + 48000, 32767, 1, 65536 * 128) == 0); /* can potentially get into a deadloop */ assert (do_test ( - 16384, 65536, 32, 32768, PIXMAN_REPEAT_NORMAL) == 0); + 16384, 65536, 32, 32768) == 0); -#if 0 /* can potentially access memory outside source image buffer */ assert (do_test ( - 10, 10, 0, 1, PIXMAN_REPEAT_PAD) == 0); + 10, 10, 0, 1) == 0); assert (do_test ( - 10, 10, 0, 0, PIXMAN_REPEAT_PAD) == 0); -#endif + 10, 10, 0, 0) == 0); + + for (i = 0; i < 100; ++i) + { + pixman_fixed_t one_seventh = + (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (7 << 16); + + assert (do_test ( + 1, 7, 3, one_seventh + i - 50) == 0); + } + + for (i = 0; i < 100; ++i) + { + pixman_fixed_t scale = + (((pixman_fixed_48_16_t)pixman_fixed_1) << 16) / (32767 << 16); + + assert (do_test ( + 1, 32767, 16383, scale + i - 50) == 0); + } -#if 0 /* can potentially provide invalid results (out of range matrix stuff) */ assert (do_test ( - 48000, 32767, 16384, 65536 * 128, PIXMAN_REPEAT_NORMAL) == 0); -#endif + 48000, 32767, 16384, 65536 * 128) == 0); return 0; } -- cgit v1.2.3