/* Create random image for testing purposes */ static pixman_image_t * create_random_image (pixman_format_code_t *allowed_formats, int max_width, int max_height, int max_extra_stride, pixman_format_code_t *used_fmt) { int n = 0, i, width, height, stride; pixman_format_code_t fmt; uint32_t *buf; pixman_image_t *img; while (allowed_formats[n] != PIXMAN_null) n++; if (n > N_MOST_LIKELY_FORMATS && lcg_rand_n (4) != 0) n = N_MOST_LIKELY_FORMATS; fmt = allowed_formats[lcg_rand_n (n)]; width = lcg_rand_n (max_width) + 1; height = lcg_rand_n (max_height) + 1; stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + lcg_rand_n (max_extra_stride + 1); stride = (stride + 3) & ~3; /* do the allocation */ buf = aligned_malloc (64, stride * height); /* initialize image with random data */ for (i = 0; i < stride * height; i++) { /* generation is biased to having more 0 or 255 bytes as * they are more likely to be special-cased in code */ *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) : (lcg_rand_n (2) ? 0 : 255); } img = pixman_image_create_bits (fmt, width, height, buf, stride); if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) { pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)])); } else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) { pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); } image_endian_swap (img); if (used_fmt) *used_fmt = fmt; return img; }
/* Free random image, and optionally update crc32 based on its data */ static uint32_t free_random_image (uint32_t initcrc, pixman_image_t *img, pixman_format_code_t fmt) { uint32_t crc32 = 0; int stride = pixman_image_get_stride (img); uint32_t *data = pixman_image_get_data (img); int height = pixman_image_get_height (img); if (fmt != PIXMAN_null) { /* mask unused 'x' part */ if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) && PIXMAN_FORMAT_DEPTH (fmt) != 0) { int i; uint32_t *data = pixman_image_get_data (img); uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1; if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA || PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA) { mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt)); } for (i = 0; i < 32; i++) mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt)); for (i = 0; i < stride * height / 4; i++) data[i] &= mask; } /* swap endiannes in order to provide identical results on both big * and litte endian systems */ image_endian_swap (img); crc32 = compute_crc32 (initcrc, data, stride * height); } pixman_image_unref (img); free (data); return crc32; }
PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format) { PixelFormat pf; uint8_t bpp; bpp = pf.bits_per_pixel = PIXMAN_FORMAT_BPP(format); pf.bytes_per_pixel = PIXMAN_FORMAT_BPP(format) / 8; pf.depth = PIXMAN_FORMAT_DEPTH(format); pf.abits = PIXMAN_FORMAT_A(format); pf.rbits = PIXMAN_FORMAT_R(format); pf.gbits = PIXMAN_FORMAT_G(format); pf.bbits = PIXMAN_FORMAT_B(format); switch (PIXMAN_FORMAT_TYPE(format)) { case PIXMAN_TYPE_ARGB: pf.ashift = pf.bbits + pf.gbits + pf.rbits; pf.rshift = pf.bbits + pf.gbits; pf.gshift = pf.bbits; pf.bshift = 0; break; case PIXMAN_TYPE_ABGR: pf.ashift = pf.rbits + pf.gbits + pf.bbits; pf.bshift = pf.rbits + pf.gbits; pf.gshift = pf.rbits; pf.rshift = 0; break; case PIXMAN_TYPE_BGRA: pf.bshift = bpp - pf.bbits; pf.gshift = bpp - (pf.bbits + pf.gbits); pf.rshift = bpp - (pf.bbits + pf.gbits + pf.rbits); pf.ashift = 0; break; case PIXMAN_TYPE_RGBA: pf.rshift = bpp - pf.rbits; pf.gshift = bpp - (pf.rbits + pf.gbits); pf.bshift = bpp - (pf.rbits + pf.gbits + pf.bbits); pf.ashift = 0; break; default: g_assert_not_reached(); break; } pf.amax = (1 << pf.abits) - 1; pf.rmax = (1 << pf.rbits) - 1; pf.gmax = (1 << pf.gbits) - 1; pf.bmax = (1 << pf.bbits) - 1; pf.amask = pf.amax << pf.ashift; pf.rmask = pf.rmax << pf.rshift; pf.gmask = pf.gmax << pf.gshift; pf.bmask = pf.bmax << pf.bshift; return pf; }
cairo_bool_t _pixman_format_to_masks (pixman_format_code_t format, cairo_format_masks_t *masks) { int a, r, g, b; masks->bpp = PIXMAN_FORMAT_BPP (format); /* Number of bits in each channel */ a = PIXMAN_FORMAT_A (format); r = PIXMAN_FORMAT_R (format); g = PIXMAN_FORMAT_G (format); b = PIXMAN_FORMAT_B (format); switch (PIXMAN_FORMAT_TYPE (format)) { case PIXMAN_TYPE_ARGB: masks->alpha_mask = MASK (a) << (r + g + b); masks->red_mask = MASK (r) << (g + b); masks->green_mask = MASK (g) << (b); masks->blue_mask = MASK (b); return TRUE; case PIXMAN_TYPE_ABGR: masks->alpha_mask = MASK (a) << (b + g + r); masks->blue_mask = MASK (b) << (g + r); masks->green_mask = MASK (g) << (r); masks->red_mask = MASK (r); return TRUE; #ifdef PIXMAN_TYPE_BGRA case PIXMAN_TYPE_BGRA: masks->blue_mask = MASK (b) << (masks->bpp - b); masks->green_mask = MASK (g) << (masks->bpp - b - g); masks->red_mask = MASK (r) << (masks->bpp - b - g - r); masks->alpha_mask = MASK (a); return TRUE; #endif case PIXMAN_TYPE_A: masks->alpha_mask = MASK (a); masks->red_mask = 0; masks->green_mask = 0; masks->blue_mask = 0; return TRUE; case PIXMAN_TYPE_OTHER: case PIXMAN_TYPE_COLOR: case PIXMAN_TYPE_GRAY: case PIXMAN_TYPE_YUY2: case PIXMAN_TYPE_YV12: default: masks->alpha_mask = 0; masks->red_mask = 0; masks->green_mask = 0; masks->blue_mask = 0; return FALSE; } }
static force_inline void get_shifts (pixman_format_code_t format, int *a, int *r, int *g, int *b) { switch (PIXMAN_FORMAT_TYPE (format)) { case PIXMAN_TYPE_A: *b = 0; *g = 0; *r = 0; *a = 0; break; case PIXMAN_TYPE_ARGB: case PIXMAN_TYPE_ARGB_SRGB: *b = 0; *g = *b + PIXMAN_FORMAT_B (format); *r = *g + PIXMAN_FORMAT_G (format); *a = *r + PIXMAN_FORMAT_R (format); break; case PIXMAN_TYPE_ABGR: *r = 0; *g = *r + PIXMAN_FORMAT_R (format); *b = *g + PIXMAN_FORMAT_G (format); *a = *b + PIXMAN_FORMAT_B (format); break; case PIXMAN_TYPE_BGRA: /* With BGRA formats we start counting at the high end of the pixel */ *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format); *g = *b - PIXMAN_FORMAT_B (format); *r = *g - PIXMAN_FORMAT_G (format); *a = *r - PIXMAN_FORMAT_R (format); break; case PIXMAN_TYPE_RGBA: /* With BGRA formats we start counting at the high end of the pixel */ *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format); *g = *r - PIXMAN_FORMAT_R (format); *b = *g - PIXMAN_FORMAT_G (format); *a = *b - PIXMAN_FORMAT_B (format); break; default: assert (0); break; } }
/* Create random image for testing purposes */ static pixman_image_t * create_random_image (pixman_format_code_t *allowed_formats, int max_width, int max_height, int max_extra_stride, pixman_format_code_t *used_fmt) { int n = 0, width, height, stride; pixman_format_code_t fmt; uint32_t *buf; pixman_image_t *img; while (allowed_formats[n] != PIXMAN_null) n++; if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0) n = N_MOST_LIKELY_FORMATS; fmt = allowed_formats[prng_rand_n (n)]; width = prng_rand_n (max_width) + 1; height = prng_rand_n (max_height) + 1; stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + prng_rand_n (max_extra_stride + 1); stride = (stride + 3) & ~3; /* do the allocation */ buf = aligned_malloc (64, stride * height); if (prng_rand_n (4) == 0) { /* uniform distribution */ prng_randmemset (buf, stride * height, 0); } else { /* significantly increased probability for 0x00 and 0xFF */ prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF); } /* test negative stride */ if (prng_rand_n (4) == 0) { buf += (stride / 4) * (height - 1); stride = - stride; } img = pixman_image_create_bits (fmt, width, height, buf, stride); if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) { pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)])); } else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) { pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); } if (prng_rand_n (16) == 0) pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0); image_endian_swap (img); if (used_fmt) *used_fmt = fmt; return img; }
/* * pixman_composite_trapezoids() * * All the trapezoids are conceptually rendered to an infinitely big image. * The (0, 0) coordinates of this image are then aligned with the (x, y) * coordinates of the source image, and then both images are aligned with * the (x, y) coordinates of the destination. Then these three images are * composited across the entire destination. */ PIXMAN_EXPORT void pixman_composite_trapezoids (pixman_op_t op, pixman_image_t * src, pixman_image_t * dst, pixman_format_code_t mask_format, int x_src, int y_src, int x_dst, int y_dst, int n_traps, const pixman_trapezoid_t * traps) { int i; return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A); if (n_traps <= 0) return; _pixman_image_validate (src); _pixman_image_validate (dst); if (op == PIXMAN_OP_ADD && (src->common.flags & FAST_PATH_IS_OPAQUE) && (mask_format == dst->common.extended_format_code) && !(dst->common.have_clip_region)) { for (i = 0; i < n_traps; ++i) { const pixman_trapezoid_t *trap = &(traps[i]); if (!pixman_trapezoid_valid (trap)) continue; pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst); } } else { pixman_image_t *tmp; pixman_box32_t box; int i; if (!get_trap_extents (op, dst, traps, n_traps, &box)) return; if (!(tmp = pixman_image_create_bits ( mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1))) return; for (i = 0; i < n_traps; ++i) { const pixman_trapezoid_t *trap = &(traps[i]); if (!pixman_trapezoid_valid (trap)) continue; pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1); } pixman_image_composite (op, src, tmp, dst, x_src + box.x1, y_src + box.y1, 0, 0, x_dst + box.x1, y_dst + box.y1, box.x2 - box.x1, box.y2 - box.y1); pixman_image_unref (tmp); } }