34,45 → 34,21 |
#include <string.h> |
#include "pixman-private.h" |
#include "pixman-combine32.h" |
#include "pixman-inlines.h" |
|
/* Store functions */ |
void |
_pixman_image_store_scanline_32 (bits_image_t * image, |
int x, |
int y, |
int width, |
const uint32_t *buffer) |
static uint32_t * |
_pixman_image_get_scanline_generic_float (pixman_iter_t * iter, |
const uint32_t *mask) |
{ |
image->store_scanline_32 (image, x, y, width, buffer); |
pixman_iter_get_scanline_t fetch_32 = iter->data; |
uint32_t *buffer = iter->buffer; |
|
if (image->common.alpha_map) |
{ |
x -= image->common.alpha_origin_x; |
y -= image->common.alpha_origin_y; |
fetch_32 (iter, NULL); |
|
image->common.alpha_map->store_scanline_32 ( |
image->common.alpha_map, x, y, width, buffer); |
} |
} |
pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); |
|
void |
_pixman_image_store_scanline_64 (bits_image_t * image, |
int x, |
int y, |
int width, |
const uint32_t *buffer) |
{ |
image->store_scanline_64 (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_64 ( |
image->common.alpha_map, x, y, width, buffer); |
return iter->buffer; |
} |
} |
|
/* Fetch functions */ |
|
92,34 → 68,6 |
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) |
{ |
switch (repeat) |
{ |
case PIXMAN_REPEAT_NORMAL: |
*coord = MOD (*coord, size); |
break; |
|
case PIXMAN_REPEAT_PAD: |
*coord = CLIP (*coord, 0, size - 1); |
break; |
|
case PIXMAN_REPEAT_REFLECT: |
*coord = MOD (*coord, size * 2); |
|
if (*coord >= size) |
*coord = size * 2 - *coord - 1; |
break; |
|
case PIXMAN_REPEAT_NONE: |
break; |
|
default: |
break; |
} |
} |
|
static force_inline uint32_t |
bits_image_fetch_pixel_nearest (bits_image_t *image, |
pixman_fixed_t x, |
131,8 → 79,8 |
|
if (image->common.repeat != PIXMAN_REPEAT_NONE) |
{ |
repeat (image->common.repeat, image->width, &x0); |
repeat (image->common.repeat, image->height, &y0); |
repeat (image->common.repeat, &x0, image->width); |
repeat (image->common.repeat, &y0, image->height); |
|
return get_pixel (image, x0, y0, FALSE); |
} |
142,98 → 90,7 |
} |
} |
|
#if SIZEOF_LONG > 4 |
|
static force_inline uint32_t |
bilinear_interpolation (uint32_t tl, uint32_t tr, |
uint32_t bl, uint32_t br, |
int distx, int disty) |
{ |
uint64_t distxy, distxiy, distixy, distixiy; |
uint64_t tl64, tr64, bl64, br64; |
uint64_t f, r; |
|
distxy = distx * disty; |
distxiy = distx * (256 - disty); |
distixy = (256 - distx) * disty; |
distixiy = (256 - distx) * (256 - disty); |
|
/* Alpha and Blue */ |
tl64 = tl & 0xff0000ff; |
tr64 = tr & 0xff0000ff; |
bl64 = bl & 0xff0000ff; |
br64 = br & 0xff0000ff; |
|
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; |
r = f & 0x0000ff0000ff0000ull; |
|
/* Red and Green */ |
tl64 = tl; |
tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); |
|
tr64 = tr; |
tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); |
|
bl64 = bl; |
bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); |
|
br64 = br; |
br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); |
|
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; |
r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); |
|
return (uint32_t)(r >> 16); |
} |
|
#else |
|
static force_inline uint32_t |
bilinear_interpolation (uint32_t tl, uint32_t tr, |
uint32_t bl, uint32_t br, |
int distx, int disty) |
{ |
int distxy, distxiy, distixy, distixiy; |
uint32_t f, r; |
|
distxy = distx * disty; |
distxiy = (distx << 8) - distxy; /* distx * (256 - disty) */ |
distixy = (disty << 8) - distxy; /* disty * (256 - distx) */ |
distixiy = |
256 * 256 - (disty << 8) - |
(distx << 8) + distxy; /* (256 - distx) * (256 - disty) */ |
|
/* Blue */ |
r = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy |
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy; |
|
/* Green */ |
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy |
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy; |
r |= f & 0xff000000; |
|
tl >>= 16; |
tr >>= 16; |
bl >>= 16; |
br >>= 16; |
r >>= 16; |
|
/* Red */ |
f = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy |
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy; |
r |= f & 0x00ff0000; |
|
/* Alpha */ |
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy |
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy; |
r |= f & 0xff000000; |
|
return r; |
} |
|
#endif |
|
static force_inline uint32_t |
bits_image_fetch_pixel_bilinear (bits_image_t *image, |
pixman_fixed_t x, |
pixman_fixed_t y, |
249,8 → 106,8 |
x1 = x - pixman_fixed_1 / 2; |
y1 = y - pixman_fixed_1 / 2; |
|
distx = (x1 >> 8) & 0xff; |
disty = (y1 >> 8) & 0xff; |
distx = pixman_fixed_to_bilinear_weight (x1); |
disty = pixman_fixed_to_bilinear_weight (y1); |
|
x1 = pixman_fixed_to_int (x1); |
y1 = pixman_fixed_to_int (y1); |
259,10 → 116,10 |
|
if (repeat_mode != PIXMAN_REPEAT_NONE) |
{ |
repeat (repeat_mode, width, &x1); |
repeat (repeat_mode, height, &y1); |
repeat (repeat_mode, width, &x2); |
repeat (repeat_mode, height, &y2); |
repeat (repeat_mode, &x1, width); |
repeat (repeat_mode, &y1, height); |
repeat (repeat_mode, &x2, width); |
repeat (repeat_mode, &y2, height); |
|
tl = get_pixel (image, x1, y1, FALSE); |
bl = get_pixel (image, x1, y2, FALSE); |
280,14 → 137,17 |
return bilinear_interpolation (tl, tr, bl, br, distx, disty); |
} |
|
static void |
bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, |
int offset, |
int line, |
int width, |
uint32_t * buffer, |
static uint32_t * |
bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter, |
const uint32_t * mask) |
{ |
|
pixman_image_t * ima = iter->image; |
int offset = iter->x; |
int line = iter->y++; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
bits_image_t *bits = &ima->bits; |
pixman_fixed_t x_top, x_bottom, x; |
pixman_fixed_t ux_top, ux_bottom, ux; |
309,13 → 169,13 |
v.vector[2] = pixman_fixed_1; |
|
if (!pixman_transform_point_3d (bits->common.transform, &v)) |
return; |
return iter->buffer; |
|
ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0]; |
x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2; |
|
y = v.vector[1] - pixman_fixed_1/2; |
disty = (y >> 8) & 0xff; |
disty = pixman_fixed_to_bilinear_weight (y); |
|
/* Load the pointers to the first and second lines from the source |
* image that bilinear code must read. |
376,7 → 236,7 |
if (top_row == zero && bottom_row == zero) |
{ |
memset (buffer, 0, width * sizeof (uint32_t)); |
return; |
return iter->buffer; |
} |
else if (bits->format == PIXMAN_x8r8g8b8) |
{ |
424,7 → 284,7 |
tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask; |
br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; |
|
distx = (x >> 8) & 0xff; |
distx = pixman_fixed_to_bilinear_weight (x); |
|
*buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty); |
|
449,7 → 309,7 |
bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; |
br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; |
|
distx = (x >> 8) & 0xff; |
distx = pixman_fixed_to_bilinear_weight (x); |
|
*buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty); |
} |
473,7 → 333,7 |
tl = top_row [pixman_fixed_to_int (x_top)] | top_mask; |
bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; |
|
distx = (x >> 8) & 0xff; |
distx = pixman_fixed_to_bilinear_weight (x); |
|
*buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty); |
} |
488,6 → 348,8 |
/* Zero fill to the left of the image */ |
while (buffer < end) |
*buffer++ = 0; |
|
return iter->buffer; |
} |
|
static force_inline uint32_t |
501,11 → 363,11 |
int y_off = (params[1] - pixman_fixed_1) >> 1; |
int32_t cwidth = pixman_fixed_to_int (params[0]); |
int32_t cheight = pixman_fixed_to_int (params[1]); |
int32_t srtot, sgtot, sbtot, satot; |
int32_t i, j, x1, x2, y1, y2; |
pixman_repeat_t repeat_mode = image->common.repeat; |
int width = image->width; |
int height = image->height; |
int srtot, sgtot, sbtot, satot; |
|
params += 2; |
|
531,8 → 393,8 |
|
if (repeat_mode != PIXMAN_REPEAT_NONE) |
{ |
repeat (repeat_mode, width, &rx); |
repeat (repeat_mode, height, &ry); |
repeat (repeat_mode, &rx, width); |
repeat (repeat_mode, &ry, height); |
|
pixel = get_pixel (image, rx, ry, FALSE); |
} |
541,10 → 403,10 |
pixel = get_pixel (image, rx, ry, TRUE); |
} |
|
srtot += RED_8 (pixel) * f; |
sgtot += GREEN_8 (pixel) * f; |
sbtot += BLUE_8 (pixel) * f; |
satot += ALPHA_8 (pixel) * f; |
srtot += (int)RED_8 (pixel) * f; |
sgtot += (int)GREEN_8 (pixel) * f; |
sbtot += (int)BLUE_8 (pixel) * f; |
satot += (int)ALPHA_8 (pixel) * f; |
} |
|
params++; |
551,10 → 413,10 |
} |
} |
|
satot >>= 16; |
srtot >>= 16; |
sgtot >>= 16; |
sbtot >>= 16; |
satot = (satot + 0x8000) >> 16; |
srtot = (srtot + 0x8000) >> 16; |
sgtot = (sgtot + 0x8000) >> 16; |
sbtot = (sbtot + 0x8000) >> 16; |
|
satot = CLIP (satot, 0, 0xff); |
srtot = CLIP (srtot, 0, 0xff); |
564,6 → 426,104 |
return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); |
} |
|
static uint32_t |
bits_image_fetch_pixel_separable_convolution (bits_image_t *image, |
pixman_fixed_t x, |
pixman_fixed_t y, |
get_pixel_t get_pixel) |
{ |
pixman_fixed_t *params = image->common.filter_params; |
pixman_repeat_t repeat_mode = image->common.repeat; |
int width = image->width; |
int height = image->height; |
int cwidth = pixman_fixed_to_int (params[0]); |
int cheight = pixman_fixed_to_int (params[1]); |
int x_phase_bits = pixman_fixed_to_int (params[2]); |
int y_phase_bits = pixman_fixed_to_int (params[3]); |
int x_phase_shift = 16 - x_phase_bits; |
int y_phase_shift = 16 - y_phase_bits; |
int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; |
int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; |
pixman_fixed_t *y_params; |
int srtot, sgtot, sbtot, satot; |
int32_t x1, x2, y1, y2; |
int32_t px, py; |
int i, j; |
|
/* Round x and y to the middle of the closest phase before continuing. This |
* ensures that the convolution matrix is aligned right, since it was |
* positioned relative to a particular phase (and not relative to whatever |
* exact fraction we happen to get here). |
*/ |
x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); |
y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); |
|
px = (x & 0xffff) >> x_phase_shift; |
py = (y & 0xffff) >> y_phase_shift; |
|
y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; |
|
x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); |
y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); |
x2 = x1 + cwidth; |
y2 = y1 + cheight; |
|
srtot = sgtot = sbtot = satot = 0; |
|
for (i = y1; i < y2; ++i) |
{ |
pixman_fixed_48_16_t fy = *y_params++; |
pixman_fixed_t *x_params = params + 4 + px * cwidth; |
|
if (fy) |
{ |
for (j = x1; j < x2; ++j) |
{ |
pixman_fixed_t fx = *x_params++; |
int rx = j; |
int ry = i; |
|
if (fx) |
{ |
pixman_fixed_t f; |
uint32_t pixel; |
|
if (repeat_mode != PIXMAN_REPEAT_NONE) |
{ |
repeat (repeat_mode, &rx, width); |
repeat (repeat_mode, &ry, height); |
|
pixel = get_pixel (image, rx, ry, FALSE); |
} |
else |
{ |
pixel = get_pixel (image, rx, ry, TRUE); |
} |
|
f = (fy * fx + 0x8000) >> 16; |
|
srtot += (int)RED_8 (pixel) * f; |
sgtot += (int)GREEN_8 (pixel) * f; |
sbtot += (int)BLUE_8 (pixel) * f; |
satot += (int)ALPHA_8 (pixel) * f; |
} |
} |
} |
} |
|
satot = (satot + 0x8000) >> 16; |
srtot = (srtot + 0x8000) >> 16; |
sgtot = (sgtot + 0x8000) >> 16; |
sbtot = (sbtot + 0x8000) >> 16; |
|
satot = CLIP (satot, 0, 0xff); |
srtot = CLIP (srtot, 0, 0xff); |
sgtot = CLIP (sgtot, 0, 0xff); |
sbtot = CLIP (sbtot, 0, 0xff); |
|
return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); |
} |
|
static force_inline uint32_t |
bits_image_fetch_pixel_filtered (bits_image_t *image, |
pixman_fixed_t x, |
587,6 → 547,10 |
return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); |
break; |
|
case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: |
return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel); |
break; |
|
default: |
break; |
} |
594,14 → 558,16 |
return 0; |
} |
|
static void |
bits_image_fetch_affine_no_alpha (pixman_image_t * image, |
int offset, |
int line, |
int width, |
uint32_t * buffer, |
static uint32_t * |
bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, |
const uint32_t * mask) |
{ |
pixman_image_t *image = iter->image; |
int offset = iter->x; |
int line = iter->y++; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
pixman_fixed_t x, y; |
pixman_fixed_t ux, uy; |
pixman_vector_t v; |
615,7 → 581,7 |
if (image->common.transform) |
{ |
if (!pixman_transform_point_3d (image->common.transform, &v)) |
return; |
return iter->buffer; |
|
ux = image->common.transform->matrix[0][0]; |
uy = image->common.transform->matrix[1][0]; |
640,6 → 606,8 |
x += ux; |
y += uy; |
} |
|
return buffer; |
} |
|
/* General fetcher */ |
683,14 → 651,16 |
return pixel; |
} |
|
static void |
bits_image_fetch_general (pixman_image_t * image, |
int offset, |
int line, |
int width, |
uint32_t * buffer, |
static uint32_t * |
bits_image_fetch_general (pixman_iter_t *iter, |
const uint32_t * mask) |
{ |
pixman_image_t *image = iter->image; |
int offset = iter->x; |
int line = iter->y++; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
pixman_fixed_t x, y, w; |
pixman_fixed_t ux, uy, uw; |
pixman_vector_t v; |
704,7 → 674,7 |
if (image->common.transform) |
{ |
if (!pixman_transform_point_3d (image->common.transform, &v)) |
return; |
return buffer; |
|
ux = image->common.transform->matrix[0][0]; |
uy = image->common.transform->matrix[1][0]; |
746,13 → 716,159 |
y += uy; |
w += uw; |
} |
|
return buffer; |
} |
|
static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
|
typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x); |
|
static force_inline void |
bits_image_fetch_separable_convolution_affine (pixman_image_t * image, |
int offset, |
int line, |
int width, |
uint32_t * buffer, |
const uint32_t * mask, |
|
convert_pixel_t convert_pixel, |
pixman_format_code_t format, |
pixman_repeat_t repeat_mode) |
{ |
bits_image_t *bits = &image->bits; |
pixman_fixed_t *params = image->common.filter_params; |
int cwidth = pixman_fixed_to_int (params[0]); |
int cheight = pixman_fixed_to_int (params[1]); |
int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; |
int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; |
int x_phase_bits = pixman_fixed_to_int (params[2]); |
int y_phase_bits = pixman_fixed_to_int (params[3]); |
int x_phase_shift = 16 - x_phase_bits; |
int y_phase_shift = 16 - y_phase_bits; |
pixman_fixed_t vx, vy; |
pixman_fixed_t ux, uy; |
pixman_vector_t v; |
int k; |
|
/* 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 (!pixman_transform_point_3d (image->common.transform, &v)) |
return; |
|
ux = image->common.transform->matrix[0][0]; |
uy = image->common.transform->matrix[1][0]; |
|
vx = v.vector[0]; |
vy = v.vector[1]; |
|
for (k = 0; k < width; ++k) |
{ |
pixman_fixed_t *y_params; |
int satot, srtot, sgtot, sbtot; |
pixman_fixed_t x, y; |
int32_t x1, x2, y1, y2; |
int32_t px, py; |
int i, j; |
|
if (mask && !mask[k]) |
goto next; |
|
/* Round x and y to the middle of the closest phase before continuing. This |
* ensures that the convolution matrix is aligned right, since it was |
* positioned relative to a particular phase (and not relative to whatever |
* exact fraction we happen to get here). |
*/ |
x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); |
y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); |
|
px = (x & 0xffff) >> x_phase_shift; |
py = (y & 0xffff) >> y_phase_shift; |
|
x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); |
y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); |
x2 = x1 + cwidth; |
y2 = y1 + cheight; |
|
satot = srtot = sgtot = sbtot = 0; |
|
y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; |
|
for (i = y1; i < y2; ++i) |
{ |
pixman_fixed_t fy = *y_params++; |
|
if (fy) |
{ |
pixman_fixed_t *x_params = params + 4 + px * cwidth; |
|
for (j = x1; j < x2; ++j) |
{ |
pixman_fixed_t fx = *x_params++; |
int rx = j; |
int ry = i; |
|
if (fx) |
{ |
pixman_fixed_t f; |
uint32_t pixel, mask; |
uint8_t *row; |
|
mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; |
|
if (repeat_mode != PIXMAN_REPEAT_NONE) |
{ |
repeat (repeat_mode, &rx, bits->width); |
repeat (repeat_mode, &ry, bits->height); |
|
row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; |
pixel = convert_pixel (row, rx) | mask; |
} |
else |
{ |
if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height) |
{ |
pixel = 0; |
} |
else |
{ |
row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; |
pixel = convert_pixel (row, rx) | mask; |
} |
} |
|
f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16; |
srtot += (int)RED_8 (pixel) * f; |
sgtot += (int)GREEN_8 (pixel) * f; |
sbtot += (int)BLUE_8 (pixel) * f; |
satot += (int)ALPHA_8 (pixel) * f; |
} |
} |
} |
} |
|
satot = (satot + 0x8000) >> 16; |
srtot = (srtot + 0x8000) >> 16; |
sgtot = (sgtot + 0x8000) >> 16; |
sbtot = (sbtot + 0x8000) >> 16; |
|
satot = CLIP (satot, 0, 0xff); |
srtot = CLIP (srtot, 0, 0xff); |
sgtot = CLIP (sgtot, 0, 0xff); |
sbtot = CLIP (sbtot, 0, 0xff); |
|
buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0); |
|
next: |
vx += ux; |
vy += uy; |
} |
} |
|
static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
|
static force_inline void |
bits_image_fetch_bilinear_affine (pixman_image_t * image, |
int offset, |
int line, |
800,8 → 916,8 |
x1 = x - pixman_fixed_1 / 2; |
y1 = y - pixman_fixed_1 / 2; |
|
distx = (x1 >> 8) & 0xff; |
disty = (y1 >> 8) & 0xff; |
distx = pixman_fixed_to_bilinear_weight (x1); |
disty = pixman_fixed_to_bilinear_weight (y1); |
|
y1 = pixman_fixed_to_int (y1); |
y2 = y1 + 1; |
814,10 → 930,10 |
|
mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; |
|
repeat (repeat_mode, width, &x1); |
repeat (repeat_mode, height, &y1); |
repeat (repeat_mode, width, &x2); |
repeat (repeat_mode, height, &y2); |
repeat (repeat_mode, &x1, width); |
repeat (repeat_mode, &y1, height); |
repeat (repeat_mode, &x2, width); |
repeat (repeat_mode, &y2, height); |
|
row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; |
row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; |
906,6 → 1022,77 |
} |
} |
|
static force_inline void |
bits_image_fetch_nearest_affine (pixman_image_t * image, |
int offset, |
int line, |
int width, |
uint32_t * buffer, |
const uint32_t * mask, |
|
convert_pixel_t convert_pixel, |
pixman_format_code_t format, |
pixman_repeat_t repeat_mode) |
{ |
pixman_fixed_t x, y; |
pixman_fixed_t ux, uy; |
pixman_vector_t v; |
bits_image_t *bits = &image->bits; |
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 (!pixman_transform_point_3d (image->common.transform, &v)) |
return; |
|
ux = image->common.transform->matrix[0][0]; |
uy = image->common.transform->matrix[1][0]; |
|
x = v.vector[0]; |
y = v.vector[1]; |
|
for (i = 0; i < width; ++i) |
{ |
int width, height, x0, y0; |
const uint8_t *row; |
|
if (mask && !mask[i]) |
goto next; |
|
width = image->bits.width; |
height = image->bits.height; |
x0 = pixman_fixed_to_int (x - pixman_fixed_e); |
y0 = pixman_fixed_to_int (y - pixman_fixed_e); |
|
if (repeat_mode == PIXMAN_REPEAT_NONE && |
(y0 < 0 || y0 >= height || x0 < 0 || x0 >= width)) |
{ |
buffer[i] = 0; |
} |
else |
{ |
uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; |
|
if (repeat_mode != PIXMAN_REPEAT_NONE) |
{ |
repeat (repeat_mode, &x0, width); |
repeat (repeat_mode, &y0, height); |
} |
|
row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0; |
|
buffer[i] = convert_pixel (row, x0) | mask; |
} |
|
next: |
x += ux; |
y += uy; |
} |
} |
|
static force_inline uint32_t |
convert_a8r8g8b8 (const uint8_t *row, int x) |
{ |
927,54 → 1114,89 |
static force_inline uint32_t |
convert_r5g6b5 (const uint8_t *row, int x) |
{ |
return CONVERT_0565_TO_0888 (*((uint16_t *)row + x)); |
return convert_0565_to_0888 (*((uint16_t *)row + x)); |
} |
|
#define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode) \ |
static uint32_t * \ |
bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t *iter, \ |
const uint32_t * mask) \ |
{ \ |
bits_image_fetch_separable_convolution_affine ( \ |
iter->image, \ |
iter->x, iter->y++, \ |
iter->width, \ |
iter->buffer, mask, \ |
convert_ ## format, \ |
PIXMAN_ ## format, \ |
repeat_mode); \ |
\ |
return iter->buffer; \ |
} |
|
#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode) \ |
static void \ |
bits_image_fetch_bilinear_affine_ ## name (pixman_image_t *image, \ |
int offset, \ |
int line, \ |
int width, \ |
uint32_t * buffer, \ |
static uint32_t * \ |
bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \ |
const uint32_t * mask) \ |
{ \ |
bits_image_fetch_bilinear_affine (image, offset, line, width, buffer, mask, \ |
bits_image_fetch_bilinear_affine (iter->image, \ |
iter->x, iter->y++, \ |
iter->width, \ |
iter->buffer, mask, \ |
convert_ ## format, \ |
PIXMAN_ ## format, \ |
repeat_mode); \ |
} \ |
extern int no_such_variable |
return iter->buffer; \ |
} |
|
MAKE_BILINEAR_FETCHER (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD); |
MAKE_BILINEAR_FETCHER (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE); |
MAKE_BILINEAR_FETCHER (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT); |
MAKE_BILINEAR_FETCHER (normal_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NORMAL); |
MAKE_BILINEAR_FETCHER (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD); |
MAKE_BILINEAR_FETCHER (none_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NONE); |
MAKE_BILINEAR_FETCHER (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT); |
MAKE_BILINEAR_FETCHER (normal_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NORMAL); |
MAKE_BILINEAR_FETCHER (pad_a8, a8, PIXMAN_REPEAT_PAD); |
MAKE_BILINEAR_FETCHER (none_a8, a8, PIXMAN_REPEAT_NONE); |
MAKE_BILINEAR_FETCHER (reflect_a8, a8, PIXMAN_REPEAT_REFLECT); |
MAKE_BILINEAR_FETCHER (normal_a8, a8, PIXMAN_REPEAT_NORMAL); |
MAKE_BILINEAR_FETCHER (pad_r5g6b5, r5g6b5, PIXMAN_REPEAT_PAD); |
MAKE_BILINEAR_FETCHER (none_r5g6b5, r5g6b5, PIXMAN_REPEAT_NONE); |
MAKE_BILINEAR_FETCHER (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT); |
MAKE_BILINEAR_FETCHER (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL); |
#define MAKE_NEAREST_FETCHER(name, format, repeat_mode) \ |
static uint32_t * \ |
bits_image_fetch_nearest_affine_ ## name (pixman_iter_t *iter, \ |
const uint32_t * mask) \ |
{ \ |
bits_image_fetch_nearest_affine (iter->image, \ |
iter->x, iter->y++, \ |
iter->width, \ |
iter->buffer, mask, \ |
convert_ ## format, \ |
PIXMAN_ ## format, \ |
repeat_mode); \ |
return iter->buffer; \ |
} |
|
#define MAKE_FETCHERS(name, format, repeat_mode) \ |
MAKE_NEAREST_FETCHER (name, format, repeat_mode) \ |
MAKE_BILINEAR_FETCHER (name, format, repeat_mode) \ |
MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode) |
|
MAKE_FETCHERS (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD) |
MAKE_FETCHERS (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE) |
MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT) |
MAKE_FETCHERS (normal_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NORMAL) |
MAKE_FETCHERS (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD) |
MAKE_FETCHERS (none_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NONE) |
MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT) |
MAKE_FETCHERS (normal_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NORMAL) |
MAKE_FETCHERS (pad_a8, a8, PIXMAN_REPEAT_PAD) |
MAKE_FETCHERS (none_a8, a8, PIXMAN_REPEAT_NONE) |
MAKE_FETCHERS (reflect_a8, a8, PIXMAN_REPEAT_REFLECT) |
MAKE_FETCHERS (normal_a8, a8, PIXMAN_REPEAT_NORMAL) |
MAKE_FETCHERS (pad_r5g6b5, r5g6b5, PIXMAN_REPEAT_PAD) |
MAKE_FETCHERS (none_r5g6b5, r5g6b5, PIXMAN_REPEAT_NONE) |
MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT) |
MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL) |
|
static void |
bits_image_fetch_solid_32 (pixman_image_t * image, |
replicate_pixel_32 (bits_image_t * bits, |
int x, |
int y, |
int width, |
uint32_t * buffer, |
const uint32_t * mask) |
uint32_t * buffer) |
{ |
uint32_t color; |
uint32_t *end; |
|
color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); |
color = bits->fetch_pixel_32 (bits, x, y); |
|
end = buffer + width; |
while (buffer < end) |
982,18 → 1204,17 |
} |
|
static void |
bits_image_fetch_solid_64 (pixman_image_t * image, |
replicate_pixel_float (bits_image_t * bits, |
int x, |
int y, |
int width, |
uint32_t * b, |
const uint32_t * unused) |
uint32_t * b) |
{ |
uint64_t color; |
uint64_t *buffer = (uint64_t *)b; |
uint64_t *end; |
argb_t color; |
argb_t *buffer = (argb_t *)b; |
argb_t *end; |
|
color = image->bits.fetch_pixel_64 (&image->bits, 0, 0); |
color = bits->fetch_pixel_float (bits, x, y); |
|
end = buffer + width; |
while (buffer < end) |
1012,7 → 1233,7 |
|
if (y < 0 || y >= image->height) |
{ |
memset (buffer, 0, width * (wide? 8 : 4)); |
memset (buffer, 0, width * (wide? sizeof (argb_t) : 4)); |
return; |
} |
|
1020,10 → 1241,10 |
{ |
w = MIN (width, -x); |
|
memset (buffer, 0, w * (wide ? 8 : 4)); |
memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4)); |
|
width -= w; |
buffer += w * (wide? 2 : 1); |
buffer += w * (wide? 4 : 1); |
x += w; |
} |
|
1032,16 → 1253,16 |
w = MIN (width, image->width - x); |
|
if (wide) |
image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); |
image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); |
else |
image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); |
|
width -= w; |
buffer += w * (wide? 2 : 1); |
buffer += w * (wide? 4 : 1); |
x += w; |
} |
|
memset (buffer, 0, width * (wide ? 8 : 4)); |
memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4)); |
} |
|
static void |
1060,6 → 1281,16 |
while (y >= image->height) |
y -= image->height; |
|
if (image->width == 1) |
{ |
if (wide) |
replicate_pixel_float (image, 0, y, width, buffer); |
else |
replicate_pixel_32 (image, 0, y, width, buffer); |
|
return; |
} |
|
while (width) |
{ |
while (x < 0) |
1070,24 → 1301,26 |
w = MIN (width, image->width - x); |
|
if (wide) |
image->fetch_scanline_64 ((pixman_image_t *)image, x, y, w, buffer, NULL); |
image->fetch_scanline_float ((pixman_image_t *)image, x, y, w, buffer, NULL); |
else |
image->fetch_scanline_32 ((pixman_image_t *)image, x, y, w, buffer, NULL); |
|
buffer += w * (wide? 2 : 1); |
buffer += w * (wide? 4 : 1); |
x += w; |
width -= w; |
} |
} |
|
static void |
bits_image_fetch_untransformed_32 (pixman_image_t * image, |
int x, |
int y, |
int width, |
uint32_t * buffer, |
static uint32_t * |
bits_image_fetch_untransformed_32 (pixman_iter_t * iter, |
const uint32_t * mask) |
{ |
pixman_image_t *image = iter->image; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
if (image->common.repeat == PIXMAN_REPEAT_NONE) |
{ |
bits_image_fetch_untransformed_repeat_none ( |
1098,16 → 1331,21 |
bits_image_fetch_untransformed_repeat_normal ( |
&image->bits, FALSE, x, y, width, buffer); |
} |
|
iter->y++; |
return buffer; |
} |
|
static void |
bits_image_fetch_untransformed_64 (pixman_image_t * image, |
int x, |
int y, |
int width, |
uint32_t * buffer, |
const uint32_t * unused) |
static uint32_t * |
bits_image_fetch_untransformed_float (pixman_iter_t * iter, |
const uint32_t *mask) |
{ |
pixman_image_t *image = iter->image; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
if (image->common.repeat == PIXMAN_REPEAT_NONE) |
{ |
bits_image_fetch_untransformed_repeat_none ( |
1118,6 → 1356,9 |
bits_image_fetch_untransformed_repeat_normal ( |
&image->bits, TRUE, x, y, width, buffer); |
} |
|
iter->y++; |
return buffer; |
} |
|
typedef struct |
1124,18 → 1365,12 |
{ |
pixman_format_code_t format; |
uint32_t flags; |
fetch_scanline_t fetch_32; |
fetch_scanline_t fetch_64; |
pixman_iter_get_scanline_t get_scanline_32; |
pixman_iter_get_scanline_t get_scanline_float; |
} 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 | |
1143,7 → 1378,7 |
FAST_PATH_NO_PAD_REPEAT | |
FAST_PATH_NO_REFLECT_REPEAT), |
bits_image_fetch_untransformed_32, |
bits_image_fetch_untransformed_64 |
bits_image_fetch_untransformed_float |
}, |
|
#define FAST_BILINEAR_FLAGS \ |
1159,13 → 1394,13 |
{ PIXMAN_a8r8g8b8, |
FAST_BILINEAR_FLAGS, |
bits_image_fetch_bilinear_no_repeat_8888, |
_pixman_image_get_scanline_generic_64 |
_pixman_image_get_scanline_generic_float |
}, |
|
{ PIXMAN_x8r8g8b8, |
FAST_BILINEAR_FLAGS, |
bits_image_fetch_bilinear_no_repeat_8888, |
_pixman_image_get_scanline_generic_64 |
_pixman_image_get_scanline_generic_float |
}, |
|
#define GENERAL_BILINEAR_FLAGS \ |
1175,39 → 1410,76 |
FAST_PATH_AFFINE_TRANSFORM | \ |
FAST_PATH_BILINEAR_FILTER) |
|
#define GENERAL_NEAREST_FLAGS \ |
(FAST_PATH_NO_ALPHA_MAP | \ |
FAST_PATH_NO_ACCESSORS | \ |
FAST_PATH_HAS_TRANSFORM | \ |
FAST_PATH_AFFINE_TRANSFORM | \ |
FAST_PATH_NEAREST_FILTER) |
|
#define GENERAL_SEPARABLE_CONVOLUTION_FLAGS \ |
(FAST_PATH_NO_ALPHA_MAP | \ |
FAST_PATH_NO_ACCESSORS | \ |
FAST_PATH_HAS_TRANSFORM | \ |
FAST_PATH_AFFINE_TRANSFORM | \ |
FAST_PATH_SEPARABLE_CONVOLUTION_FILTER) |
|
#define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ |
{ PIXMAN_ ## format, \ |
GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ |
bits_image_fetch_separable_convolution_affine_ ## name, \ |
_pixman_image_get_scanline_generic_float \ |
}, |
|
#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ |
{ PIXMAN_ ## format, \ |
GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ |
bits_image_fetch_bilinear_affine_ ## name, \ |
_pixman_image_get_scanline_generic_64 \ |
_pixman_image_get_scanline_generic_float \ |
}, |
|
BILINEAR_AFFINE_FAST_PATH (pad_a8r8g8b8, a8r8g8b8, PAD) |
BILINEAR_AFFINE_FAST_PATH (none_a8r8g8b8, a8r8g8b8, NONE) |
BILINEAR_AFFINE_FAST_PATH (reflect_a8r8g8b8, a8r8g8b8, REFLECT) |
BILINEAR_AFFINE_FAST_PATH (normal_a8r8g8b8, a8r8g8b8, NORMAL) |
BILINEAR_AFFINE_FAST_PATH (pad_x8r8g8b8, x8r8g8b8, PAD) |
BILINEAR_AFFINE_FAST_PATH (none_x8r8g8b8, x8r8g8b8, NONE) |
BILINEAR_AFFINE_FAST_PATH (reflect_x8r8g8b8, x8r8g8b8, REFLECT) |
BILINEAR_AFFINE_FAST_PATH (normal_x8r8g8b8, x8r8g8b8, NORMAL) |
BILINEAR_AFFINE_FAST_PATH (pad_a8, a8, PAD) |
BILINEAR_AFFINE_FAST_PATH (none_a8, a8, NONE) |
BILINEAR_AFFINE_FAST_PATH (reflect_a8, a8, REFLECT) |
BILINEAR_AFFINE_FAST_PATH (normal_a8, a8, NORMAL) |
BILINEAR_AFFINE_FAST_PATH (pad_r5g6b5, r5g6b5, PAD) |
BILINEAR_AFFINE_FAST_PATH (none_r5g6b5, r5g6b5, NONE) |
BILINEAR_AFFINE_FAST_PATH (reflect_r5g6b5, r5g6b5, REFLECT) |
BILINEAR_AFFINE_FAST_PATH (normal_r5g6b5, r5g6b5, NORMAL) |
#define NEAREST_AFFINE_FAST_PATH(name, format, repeat) \ |
{ PIXMAN_ ## format, \ |
GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ |
bits_image_fetch_nearest_affine_ ## name, \ |
_pixman_image_get_scanline_generic_float \ |
}, |
|
#define AFFINE_FAST_PATHS(name, format, repeat) \ |
SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ |
BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ |
NEAREST_AFFINE_FAST_PATH(name, format, repeat) |
|
AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD) |
AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE) |
AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT) |
AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL) |
AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD) |
AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE) |
AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT) |
AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL) |
AFFINE_FAST_PATHS (pad_a8, a8, PAD) |
AFFINE_FAST_PATHS (none_a8, a8, NONE) |
AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT) |
AFFINE_FAST_PATHS (normal_a8, a8, NORMAL) |
AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD) |
AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE) |
AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT) |
AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL) |
|
/* Affine, no alpha */ |
{ 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_image_get_scanline_generic_float |
}, |
|
/* General */ |
{ PIXMAN_any, 0, bits_image_fetch_general, _pixman_image_get_scanline_generic_64 }, |
{ PIXMAN_any, |
0, |
bits_image_fetch_general, |
_pixman_image_get_scanline_generic_float |
}, |
|
{ PIXMAN_null }, |
}; |
1215,35 → 1487,191 |
static void |
bits_image_property_changed (pixman_image_t *image) |
{ |
_pixman_bits_image_setup_accessors (&image->bits); |
} |
|
void |
_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) |
{ |
pixman_format_code_t format = image->common.extended_format_code; |
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_accessors (&image->bits); |
|
info = fetcher_info; |
while (info->format != PIXMAN_null) |
for (info = fetcher_info; info->format != PIXMAN_null; ++info) |
{ |
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; |
if (iter->iter_flags & ITER_NARROW) |
{ |
iter->get_scanline = info->get_scanline_32; |
} |
else |
{ |
iter->data = info->get_scanline_32; |
iter->get_scanline = info->get_scanline_float; |
} |
return; |
} |
} |
|
info++; |
/* Just in case we somehow didn't find a scanline function */ |
iter->get_scanline = _pixman_iter_get_scanline_noop; |
} |
|
static uint32_t * |
dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) |
{ |
pixman_image_t *image = iter->image; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
uint32_t * buffer = iter->buffer; |
|
image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask); |
if (image->common.alpha_map) |
{ |
uint32_t *alpha; |
|
if ((alpha = malloc (width * sizeof (uint32_t)))) |
{ |
int i; |
|
x -= image->common.alpha_origin_x; |
y -= image->common.alpha_origin_y; |
|
image->common.alpha_map->fetch_scanline_32 ( |
(pixman_image_t *)image->common.alpha_map, |
x, y, width, alpha, mask); |
|
for (i = 0; i < width; ++i) |
{ |
buffer[i] &= ~0xff000000; |
buffer[i] |= (alpha[i] & 0xff000000); |
} |
|
free (alpha); |
} |
} |
|
return iter->buffer; |
} |
|
static uint32_t * |
dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) |
{ |
bits_image_t * image = &iter->image->bits; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
argb_t * buffer = (argb_t *)iter->buffer; |
|
image->fetch_scanline_float ( |
(pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask); |
if (image->common.alpha_map) |
{ |
argb_t *alpha; |
|
if ((alpha = malloc (width * sizeof (argb_t)))) |
{ |
int i; |
|
x -= image->common.alpha_origin_x; |
y -= image->common.alpha_origin_y; |
|
image->common.alpha_map->fetch_scanline_float ( |
(pixman_image_t *)image->common.alpha_map, |
x, y, width, (uint32_t *)alpha, mask); |
|
for (i = 0; i < width; ++i) |
buffer[i].a = alpha[i].a; |
|
free (alpha); |
} |
} |
|
return iter->buffer; |
} |
|
static void |
dest_write_back_narrow (pixman_iter_t *iter) |
{ |
bits_image_t * image = &iter->image->bits; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
const uint32_t *buffer = iter->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); |
} |
|
iter->y++; |
} |
|
static void |
dest_write_back_wide (pixman_iter_t *iter) |
{ |
bits_image_t * image = &iter->image->bits; |
int x = iter->x; |
int y = iter->y; |
int width = iter->width; |
const uint32_t *buffer = iter->buffer; |
|
image->store_scanline_float (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_float ( |
image->common.alpha_map, x, y, width, buffer); |
} |
|
iter->y++; |
} |
|
void |
_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) |
{ |
if (iter->iter_flags & ITER_NARROW) |
{ |
if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == |
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) |
{ |
iter->get_scanline = _pixman_iter_get_scanline_noop; |
} |
else |
{ |
iter->get_scanline = dest_get_scanline_narrow; |
} |
|
iter->write_back = dest_write_back_narrow; |
} |
else |
{ |
iter->get_scanline = dest_get_scanline_wide; |
iter->write_back = dest_write_back_wide; |
} |
} |
|
static uint32_t * |
create_bits (pixman_format_code_t format, |
int width, |
int height, |
int * rowstride_bytes) |
int * rowstride_bytes, |
pixman_bool_t clear) |
{ |
int stride; |
int buf_size; |
size_t buf_size; |
int bpp; |
|
/* what follows is a long-winded way, avoiding any possibility of integer |
1252,11 → 1680,11 |
*/ |
|
bpp = PIXMAN_FORMAT_BPP (format); |
if (pixman_multiply_overflows_int (width, bpp)) |
if (_pixman_multiply_overflows_int (width, bpp)) |
return NULL; |
|
stride = width * bpp; |
if (pixman_addition_overflows_int (stride, 0x1f)) |
if (_pixman_addition_overflows_int (stride, 0x1f)) |
return NULL; |
|
stride += 0x1f; |
1264,7 → 1692,7 |
|
stride *= sizeof (uint32_t); |
|
if (pixman_multiply_overflows_int (height, stride)) |
if (_pixman_multiply_overflows_size (height, stride)) |
return NULL; |
|
buf_size = height * stride; |
1272,43 → 1700,37 |
if (rowstride_bytes) |
*rowstride_bytes = stride; |
|
if (clear) |
return calloc (buf_size, 1); |
else |
return malloc (buf_size); |
} |
|
PIXMAN_EXPORT pixman_image_t * |
pixman_image_create_bits (pixman_format_code_t format, |
pixman_bool_t |
_pixman_bits_image_init (pixman_image_t * image, |
pixman_format_code_t format, |
int width, |
int height, |
uint32_t * bits, |
int rowstride_bytes) |
int rowstride, |
pixman_bool_t clear) |
{ |
pixman_image_t *image; |
uint32_t *free_me = NULL; |
|
/* must be a whole number of uint32_t's |
*/ |
return_val_if_fail ( |
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); |
|
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL); |
|
if (!bits && width && height) |
{ |
free_me = bits = create_bits (format, width, height, &rowstride_bytes); |
if (!bits) |
return NULL; |
} |
int rowstride_bytes; |
|
image = _pixman_image_allocate (); |
free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); |
|
if (!image) |
{ |
if (free_me) |
free (free_me); |
if (!bits) |
return FALSE; |
|
return NULL; |
rowstride = rowstride_bytes / (int) sizeof (uint32_t); |
} |
|
_pixman_image_init (image); |
|
image->type = BITS; |
image->bits.format = format; |
image->bits.width = width; |
1317,10 → 1739,7 |
image->bits.free_me = free_me; |
image->bits.read_func = NULL; |
image->bits.write_func = NULL; |
|
/* The rowstride is stored in number of uint32_t */ |
image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t); |
|
image->bits.rowstride = rowstride; |
image->bits.indexed = NULL; |
|
image->common.property_changed = bits_image_property_changed; |
1327,5 → 1746,63 |
|
_pixman_image_reset_clip_region (image); |
|
return TRUE; |
} |
|
static pixman_image_t * |
create_bits_image_internal (pixman_format_code_t format, |
int width, |
int height, |
uint32_t * bits, |
int rowstride_bytes, |
pixman_bool_t clear) |
{ |
pixman_image_t *image; |
|
/* must be a whole number of uint32_t's |
*/ |
return_val_if_fail ( |
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); |
|
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL); |
|
image = _pixman_image_allocate (); |
|
if (!image) |
return NULL; |
|
if (!_pixman_bits_image_init (image, format, width, height, bits, |
rowstride_bytes / (int) sizeof (uint32_t), |
clear)) |
{ |
free (image); |
return NULL; |
} |
|
return image; |
} |
|
/* If bits is NULL, a buffer will be allocated and initialized to 0 */ |
PIXMAN_EXPORT pixman_image_t * |
pixman_image_create_bits (pixman_format_code_t format, |
int width, |
int height, |
uint32_t * bits, |
int rowstride_bytes) |
{ |
return create_bits_image_internal ( |
format, width, height, bits, rowstride_bytes, TRUE); |
} |
|
|
/* If bits is NULL, a buffer will be allocated and _not_ initialized */ |
PIXMAN_EXPORT pixman_image_t * |
pixman_image_create_bits_no_clear (pixman_format_code_t format, |
int width, |
int height, |
uint32_t * bits, |
int rowstride_bytes) |
{ |
return create_bits_image_internal ( |
format, width, height, bits, rowstride_bytes, FALSE); |
} |