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; } }
cairo_content_t _cairo_content_from_pixman_format (pixman_format_code_t pixman_format) { cairo_content_t content; content = 0; if (PIXMAN_FORMAT_RGB (pixman_format)) content |= CAIRO_CONTENT_COLOR; if (PIXMAN_FORMAT_A (pixman_format)) content |= CAIRO_CONTENT_ALPHA; return content; }
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 void bits_image_fetch_bilinear_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 x1, y1, x2, y2; uint32_t tl, tr, bl, br; int32_t distx, disty; int width = image->bits.width; int height = image->bits.height; const uint8_t *row1; const uint8_t *row2; if (mask && !mask[i]) goto next; x1 = x - pixman_fixed_1 / 2; y1 = y - pixman_fixed_1 / 2; distx = pixman_fixed_to_bilinear_weight (x1); disty = pixman_fixed_to_bilinear_weight (y1); y1 = pixman_fixed_to_int (y1); y2 = y1 + 1; x1 = pixman_fixed_to_int (x1); x2 = x1 + 1; if (repeat_mode != PIXMAN_REPEAT_NONE) { uint32_t mask; mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; 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; tl = convert_pixel (row1, x1) | mask; tr = convert_pixel (row1, x2) | mask; bl = convert_pixel (row2, x1) | mask; br = convert_pixel (row2, x2) | mask; } else { uint32_t mask1, mask2; int bpp; /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value, * which means if you use it in expressions, those * expressions become unsigned themselves. Since * the variables below can be negative in some cases, * that will lead to crashes on 64 bit architectures. * * So this line makes sure bpp is signed */ bpp = PIXMAN_FORMAT_BPP (format); if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0) { buffer[i] = 0; goto next; } if (y2 == 0) { row1 = zero; mask1 = 0; } else { row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; row1 += bpp / 8 * x1; mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; } if (y1 == height - 1) { row2 = zero; mask2 = 0; } else { row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; row2 += bpp / 8 * x1; mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; } if (x2 == 0) { tl = 0; bl = 0; } else { tl = convert_pixel (row1, 0) | mask1; bl = convert_pixel (row2, 0) | mask2; } if (x1 == width - 1) { tr = 0; br = 0; } else { tr = convert_pixel (row1, 1) | mask1; br = convert_pixel (row2, 1) | mask2; } } buffer[i] = bilinear_interpolation ( tl, tr, bl, br, distx, disty); next: x += ux; y += uy; } }