static void fill (pixman_image_t *image, uint32_t pixel) { uint8_t *data = (uint8_t *)pixman_image_get_data (image); int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8; int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image); int i; switch (bytes_per_pixel) { case 4: for (i = 0; i < n_bytes / 4; ++i) ((uint32_t *)data)[i] = pixel; break; case 2: pixel &= 0xffff; for (i = 0; i < n_bytes / 2; ++i) ((uint16_t *)data)[i] = pixel; break; case 1: pixel &= 0xff; for (i = 0; i < n_bytes; ++i) ((uint8_t *)data)[i] = pixel; break; default: assert (0); break; } }
cairo_surface_t * _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, cairo_format_t format) { cairo_image_surface_t *surface; surface = malloc (sizeof (cairo_image_surface_t)); if (surface == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } _cairo_surface_init (&surface->base, &cairo_image_surface_backend); surface->pixman_image = pixman_image; surface->format = format; surface->data = (unsigned char *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; surface->has_clip = FALSE; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); return &surface->base; }
cairo_surface_t * _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, pixman_format_code_t pixman_format) { cairo_image_surface_t *surface; surface = malloc (sizeof (cairo_image_surface_t)); if (surface == NULL) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, &_cairo_image_surface_backend, _cairo_content_from_pixman_format (pixman_format)); surface->pixman_image = pixman_image; surface->pixman_format = pixman_format; surface->format = _cairo_format_from_pixman_format (pixman_format); surface->data = (unsigned char *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; surface->has_clip = FALSE; surface->transparency = CAIRO_IMAGE_UNKNOWN; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); return &surface->base; }
static void on_destroy (pixman_image_t *image, void *data) { uint32_t *bits = pixman_image_get_data (image); fence_free (bits); }
struct texture_t * sw_render_alloc_texture(struct render_t * render, void * pixels, u32_t w, u32_t h, enum pixel_format_t format) { struct texture_t * texture; pixman_image_t * img; u32_t pitch; if(!render) return NULL; if( (w <= 0) && (h <= 0) ) return NULL; texture = (struct texture_t *)malloc(sizeof(struct texture_t)); if(! texture) return NULL; switch(format) { case PIXEL_FORMAT_ARGB32: pitch = w * 4; break; case PIXEL_FORMAT_RGB24: pitch = w * 3; break; case PIXEL_FORMAT_A8: pitch = w * 1; break; case PIXEL_FORMAT_A1: pitch = (w + 7) / 8; break; case PIXEL_FORMAT_RGB16_565: pitch = w * 2; break; case PIXEL_FORMAT_RGB30: pitch = w * 4; break; default: pitch = w * 4; break; } pitch = (pitch + 0x3) & ~0x3; img = pixman_image_create_bits_no_clear(pixel_format_to_pixman_format_code(format), w, h, pixels, pitch); if(!img) { free(texture); return NULL; } texture->width = w; texture->height = h; texture->pitch = pitch; texture->format = format; texture->pixels = pixman_image_get_data(img); texture->priv = img; return texture; }
/* 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; }
static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) { static const int blksize = 32; int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize; int dirty_top[blocks]; int y, yoff, x, xoff, blk, bw; int bpp = surface_bytes_per_pixel(ssd->ds); uint8_t *guest, *mirror; if (qemu_spice_rect_is_empty(&ssd->dirty)) { return; }; if (ssd->surface == NULL) { ssd->surface = pixman_image_ref(ssd->ds->image); ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format, ssd->ds->image); } for (blk = 0; blk < blocks; blk++) { dirty_top[blk] = -1; } guest = surface_data(ssd->ds); mirror = (void *)pixman_image_get_data(ssd->mirror); for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) { yoff = y * surface_stride(ssd->ds); for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { xoff = x * bpp; blk = x / blksize; bw = MIN(blksize, ssd->dirty.right - x); if (memcmp(guest + yoff + xoff, mirror + yoff + xoff, bw * bpp) == 0) { if (dirty_top[blk] != -1) { QXLRect update = { .top = dirty_top[blk], .bottom = y, .left = x, .right = x + bw, }; qemu_spice_create_one_update(ssd, &update); dirty_top[blk] = -1; } } else { if (dirty_top[blk] == -1) { dirty_top[blk] = y; } } } }
static void process_image_data(struct fp_img_dev *dev, char **output, int *output_height) { //pixman stuff taken from libfprint/pixman.c, adapted for my purposes. pixman_image_t *orig, *resized; pixman_transform_t transform; struct vfs0050_dev *vfs_dev = dev->priv; struct vfs0050_line *line, *calibration_line; char *buf = malloc(vfs_dev->scanbuf_idx); int lines = vfs_dev->scanbuf_idx / VFS0050_FRAME_SIZE; int i, x, sum, last_sum, diff; int new_height; //just grab one around middle, there should be 100 calibration_line = (struct vfs0050_line *) ((char *) vfs_dev->calbuf + (50 * VFS0050_FRAME_SIZE)); new_height = 0; for (i = 0; i < lines; i++) { line = (struct vfs0050_line *) ((char *) vfs_dev->scanbuf + (i * VFS0050_FRAME_SIZE)); if (!is_noise(line)) memcpy(buf + (new_height++ * VFS0050_IMG_WIDTH), line->row, VFS0050_IMG_WIDTH); else fp_dbg("removed noise at line: %d\n", i); } orig = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, (uint32_t *) buf, VFS0050_IMG_WIDTH); new_height *= VFS0050_SCALE_FACTOR; //scale for resized image resized = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, NULL, VFS0050_IMG_WIDTH); pixman_transform_init_identity(&transform); pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(1), pixman_double_to_fixed(0.2)); pixman_image_set_transform(orig, &transform); pixman_image_set_filter(orig, PIXMAN_FILTER_BEST, NULL, 0); pixman_image_composite32(PIXMAN_OP_SRC, orig, NULL, resized, 0, 0, 0, 0, 0, 0, VFS0050_IMG_WIDTH, new_height ); memcpy(buf, pixman_image_get_data(resized), VFS0050_IMG_WIDTH * new_height); pixman_image_unref(orig); pixman_image_unref(resized); *output_height = new_height; *output = buf; }
/* 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; uint32_t *data = pixman_image_get_data (img); if (fmt != PIXMAN_null) crc32 = compute_crc32_for_image (initcrc, img); if (img->bits.rowstride < 0) data += img->bits.rowstride * (img->bits.height - 1); pixman_image_unref (img); free (data); return crc32; }
static inline void copy_to_gldrawable_from_pixmap(const RedDrawable_p* dest, const SpiceRect& area, const SpicePoint& offset, const PixelsSource_p* source, int src_x, int src_y) { uint8_t *addr; GLXContext context = NULL; GLXPbuffer pbuffer; RenderType rendertype; Window win; rendertype = dest->source.x_drawable.rendertype; if (rendertype == RENDER_TYPE_FBO) { glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); glBindTexture(GL_TEXTURE_2D, 0); } else { context = dest->source.x_drawable.context; win = dest->source.x_drawable.drawable; glXMakeCurrent(XPlatform::get_display(), win, context); glDisable(GL_TEXTURE_2D); } glPixelStorei(GL_UNPACK_ROW_LENGTH, pixman_image_get_stride(source->pixmap.pixman_image) / 4); glPixelZoom(1, -1); addr = (uint8_t *)pixman_image_get_data(source->pixmap.pixman_image); addr += (src_x * 4 + src_y * pixman_image_get_stride(source->pixmap.pixman_image)); glWindowPos2i(area.left + offset.x, dest->source.x_drawable.height - (area.top + offset.y)); //+ (area.bottom - area.top))); glDrawPixels(area.right - area.left, area.bottom - area.top, GL_BGRA, GL_UNSIGNED_BYTE, addr); if (rendertype == RENDER_TYPE_FBO) { GLuint fbo; fbo = dest->source.x_drawable.fbo; glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); } else { pbuffer = dest->source.x_drawable.pbuff; glXMakeCurrent(XPlatform::get_display(), pbuffer, context); } }
static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest, const SpiceRect& area, const SpicePoint& offset, const PixelsSource_p* source, int src_x, int src_y) { int y, height; GLXContext context = NULL; GLXPbuffer pbuffer; Window win; RenderType rendertype; y = source->gl.height - src_y; height = area.bottom - area.top; rendertype = source->gl.rendertype; if (rendertype == RENDER_TYPE_FBO) { glBindFramebuffer(GL_FRAMEBUFFER_EXT, source->gl.fbo); glBindTexture(GL_TEXTURE_2D, 0); } else { context = source->gl.context; pbuffer = source->gl.pbuff; glXMakeCurrent(XPlatform::get_display(), pbuffer, context); glDisable(GL_TEXTURE_2D); } glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glPixelStorei(GL_PACK_ROW_LENGTH, pixman_image_get_stride(dest->source.pixmap.pixman_image) / 4); while (height > 0) { glReadPixels(src_x, y - height, area.right - area.left, 1, GL_BGRA, GL_UNSIGNED_BYTE, (uint8_t *)pixman_image_get_data(dest->source.pixmap.pixman_image) + (area.left + offset.x) * 4 + (area.top + offset.y + height - 1) * pixman_image_get_stride(dest->source.pixmap.pixman_image)); height--; } if (rendertype != RENDER_TYPE_FBO) { win = source->gl.win; glXMakeCurrent(XPlatform::get_display(), win, context); } }
pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font, unsigned int ch) { pixman_image_t *glyph; uint8_t *data; bool bit; int x, y; glyph = pixman_image_create_bits(PIXMAN_a8, 8, height, NULL, 0); data = (uint8_t *)pixman_image_get_data(glyph); font += height * ch; for (y = 0; y < height; y++, font++) { for (x = 0; x < 8; x++, data++) { bit = (*font) & (1 << (7-x)); *data = bit ? 0xff : 0x00; } } return glyph; }
static void create_border(struct wayland_compositor *c) { pixman_image_t *image; int32_t edges[4]; image = load_image(DATADIR "/weston/border.png"); if (!image) { weston_log("could'nt load border image\n"); return; } edges[0] = c->border.left; edges[1] = c->border.right; edges[2] = c->border.top; edges[3] = c->border.bottom; gl_renderer_set_border(&c->base, pixman_image_get_width(image), pixman_image_get_height(image), pixman_image_get_data(image), edges); pixman_image_unref(image); }
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor) { int new_width = img->width * w_factor; int new_height = img->height * h_factor; pixman_image_t *orig, *resized; pixman_transform_t transform; struct fp_img *newimg; orig = pixman_image_create_bits(PIXMAN_a8, img->width, img->height, (uint32_t *)img->data, img->width); resized = pixman_image_create_bits(PIXMAN_a8, new_width, new_height, NULL, new_width); pixman_transform_init_identity(&transform); pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(w_factor), pixman_int_to_fixed(h_factor)); pixman_image_set_transform(orig, &transform); pixman_image_set_filter(orig, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_composite32(PIXMAN_OP_SRC, orig, /* src */ NULL, /* mask */ resized, /* dst */ 0, 0, /* src x y */ 0, 0, /* mask x y */ 0, 0, /* dst x y */ new_width, new_height /* width height */ ); newimg = fpi_img_new(new_width * new_height); newimg->width = new_width; newimg->height = new_height; newimg->flags = img->flags; memcpy(newimg->data, pixman_image_get_data(resized), new_width * new_height); pixman_image_unref(orig); pixman_image_unref(resized); return newimg; }
void _cairo_image_surface_init (cairo_image_surface_t *surface, pixman_image_t *pixman_image, pixman_format_code_t pixman_format) { surface->parent = NULL; surface->pixman_image = pixman_image; surface->pixman_format = pixman_format; surface->format = _cairo_format_from_pixman_format (pixman_format); surface->data = (uint8_t *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; surface->transparency = CAIRO_IMAGE_UNKNOWN; surface->color = CAIRO_IMAGE_UNKNOWN_COLOR; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); surface->base.is_clear = surface->width == 0 || surface->height == 0; surface->compositor = _cairo_image_spans_compositor_get (); }
void* PixmanBitmap::pixels() { return (void*) pixman_image_get_data(bitmap); }
/* * Composite operation with pseudorandom images */ uint32_t test_composite (int testnum, int verbose) { int i; pixman_image_t *src_img = NULL; pixman_image_t *dst_img = NULL; pixman_image_t *mask_img = NULL; int src_width, src_height; int dst_width, dst_height; int src_stride, dst_stride; int src_x, src_y; int dst_x, dst_y; int mask_x, mask_y; int w, h; pixman_op_t op; pixman_format_code_t src_fmt, dst_fmt, mask_fmt; uint32_t *dstbuf, *srcbuf, *maskbuf; uint32_t crc32; int max_width, max_height, max_extra_stride; FLOAT_REGS_CORRUPTION_DETECTOR_START (); max_width = max_height = 24 + testnum / 10000; max_extra_stride = 4 + testnum / 1000000; if (max_width > 256) max_width = 256; if (max_height > 16) max_height = 16; if (max_extra_stride > 8) max_extra_stride = 8; lcg_srand (testnum); op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))]; if (lcg_rand_n (8)) { /* normal image */ src_img = create_random_image (img_fmt_list, max_width, max_height, max_extra_stride, &src_fmt); } else { /* solid case */ src_img = create_random_image (img_fmt_list, 1, 1, max_extra_stride, &src_fmt); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); } dst_img = create_random_image (img_fmt_list, max_width, max_height, max_extra_stride, &dst_fmt); src_width = pixman_image_get_width (src_img); src_height = pixman_image_get_height (src_img); src_stride = pixman_image_get_stride (src_img); dst_width = pixman_image_get_width (dst_img); dst_height = pixman_image_get_height (dst_img); dst_stride = pixman_image_get_stride (dst_img); dstbuf = pixman_image_get_data (dst_img); srcbuf = pixman_image_get_data (src_img); src_x = lcg_rand_n (src_width); src_y = lcg_rand_n (src_height); dst_x = lcg_rand_n (dst_width); dst_y = lcg_rand_n (dst_height); mask_img = NULL; mask_fmt = PIXMAN_null; mask_x = 0; mask_y = 0; maskbuf = NULL; if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) && (lcg_rand_n (4) == 0)) { /* PIXBUF */ mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; mask_img = pixman_image_create_bits (mask_fmt, src_width, src_height, srcbuf, src_stride); mask_x = src_x; mask_y = src_y; maskbuf = srcbuf; } else if (lcg_rand_n (2)) { if (lcg_rand_n (2)) { mask_img = create_random_image (mask_fmt_list, max_width, max_height, max_extra_stride, &mask_fmt); } else { /* solid case */ mask_img = create_random_image (mask_fmt_list, 1, 1, max_extra_stride, &mask_fmt); pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); } if (lcg_rand_n (2)) pixman_image_set_component_alpha (mask_img, 1); mask_x = lcg_rand_n (pixman_image_get_width (mask_img)); mask_y = lcg_rand_n (pixman_image_get_height (mask_img)); } w = lcg_rand_n (dst_width - dst_x + 1); h = lcg_rand_n (dst_height - dst_y + 1); if (verbose) { printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n", op, src_fmt, dst_fmt, mask_fmt); printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", src_width, src_height, dst_width, dst_height); printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", src_x, src_y, dst_x, dst_y); printf ("src_stride=%d, dst_stride=%d\n", src_stride, dst_stride); printf ("w=%d, h=%d\n", w, h); } pixman_image_composite (op, src_img, mask_img, dst_img, src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); if (verbose) { int j; printf ("---\n"); for (i = 0; i < dst_height; i++) { for (j = 0; j < dst_stride; j++) { if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8) printf ("| "); printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j)); } printf ("\n"); } printf ("---\n"); } free_random_image (0, src_img, PIXMAN_null); crc32 = free_random_image (0, dst_img, dst_fmt); if (mask_img) { if (srcbuf == maskbuf) pixman_image_unref(mask_img); else free_random_image (0, mask_img, PIXMAN_null); } FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); return crc32; }
/** * glamor_trapezoids will generate trapezoid mask accumulating in * system memory. */ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; BoxRec bounds; PicturePtr picture; INT16 x_dst, y_dst; INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; pixman_image_t *image = NULL; /* If a mask format wasn't provided, we get to choose, but behavior should * be as if there was no temporary mask the traps were accumulated into. */ if (!mask_format) { if (dst->polyEdge == PolyEdgeSharp) mask_format = PictureMatchFormat(screen, 1, PICT_a1); else mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, 1, traps); return; } miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; stride = PixmapBytePad(width, mask_format->depth); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height); if (!picture) return; image = pixman_image_create_bits(picture->format, width, height, NULL, stride); if (!image) { FreePicture(picture, 0); return; } for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); pixmap = glamor_get_drawable_pixmap(picture->pDrawable); screen->ModifyPixmapHeader(pixmap, width, height, mask_format->depth, BitsPerPixel(mask_format->depth), PixmapBytePad(width, mask_format->depth), pixman_image_get_data(image)); x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; CompositePicture(op, src, picture, dst, x_rel, y_rel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (image) pixman_image_unref(image); FreePicture(picture, 0); }
static void uxa_check_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { pixman_image_t *image; PixmapPtr scratch; PicturePtr mask, mask_src = NULL, mask_dst = NULL, white = NULL; int width = 0, height = 0; int x, y, n; int xDst = list->xOff, yDst = list->yOff; BoxRec extents = { 0, 0, 0, 0 }; CARD8 mask_op = 0; if (maskFormat) { pixman_format_code_t format; CARD32 component_alpha; xRenderColor color; int error; uxa_glyph_extents(nlist, list, glyphs, &extents); if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) return; width = extents.x2 - extents.x1; height = extents.y2 - extents.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; scratch = GetScratchPixmapHeader(dst->pDrawable->pScreen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!scratch) { pixman_image_unref(image); return; } component_alpha = NeedsComponent(maskFormat->format); mask = CreatePicture(0, &scratch->drawable, maskFormat, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) { FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } ValidatePicture(mask); x = -extents.x1; y = -extents.y1; color.red = color.green = color.blue = color.alpha = 0xffff; white = CreateSolidPicture(0, &color, &error); mask_op = op; op = PictOpAdd; mask_src = src; src = white; mask_dst = dst; dst = mask; } else { mask = dst; x = 0; y = 0; } while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { GlyphPtr glyph = *glyphs++; PicturePtr g = GetGlyphPicture(glyph, dst->pDrawable->pScreen); if (g) { CompositePicture(op, src, g, dst, xSrc + (x - glyph->info.x) - xDst, ySrc + (y - glyph->info.y) - yDst, 0, 0, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); } x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (white) FreePicture(white, 0); if (maskFormat) { x = extents.x1; y = extents.y1; CompositePicture(mask_op, mask_src, mask, mask_dst, xSrc + x - xDst, ySrc + y - yDst, 0, 0, x, y, width, height); FreePicture(mask, 0); FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } }
int main (int argc, char **argv) { #define d2f pixman_double_to_fixed GtkWidget *window, *swindow; GtkWidget *table; uint32_t *dest = malloc (WIDTH * HEIGHT * 4); uint32_t *src = malloc (WIDTH * HEIGHT * 4); pixman_image_t *src_img; pixman_image_t *dest_img; pixman_point_fixed_t p1 = { -10 << 0, 0 }; pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 }; uint16_t full = 0xcfff; uint16_t low = 0x5000; uint16_t alpha = 0xffff; pixman_gradient_stop_t stops[6] = { { d2f (0.0), { full, low, low, alpha } }, { d2f (0.25), { full, full, low, alpha } }, { d2f (0.4), { low, full, low, alpha } }, { d2f (0.6), { low, full, full, alpha } }, { d2f (0.8), { low, low, full, alpha } }, { d2f (1.0), { full, low, full, alpha } }, }; int i; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL); table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE); src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops)); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD); dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); pixman_image_set_accessors (dest_img, reader, writer); for (i = 0; i < G_N_ELEMENTS (operators); ++i) { GtkWidget *image; GdkPixbuf *pixbuf; GtkWidget *vbox; GtkWidget *label; int j, k; vbox = gtk_vbox_new (FALSE, 0); label = gtk_label_new (operators[i].name); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6); gtk_widget_show (label); for (j = 0; j < HEIGHT; ++j) { for (k = 0; k < WIDTH; ++k) dest[j * WIDTH + k] = 0x7f6f6f00; } pixman_image_composite (operators[i].op, src_img, NULL, dest_img, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE, WIDTH, HEIGHT, WIDTH * 4); image = gtk_image_new_from_pixbuf (pixbuf); gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0); gtk_widget_show (image); gtk_table_attach_defaults (GTK_TABLE (table), vbox, i % 6, (i % 6) + 1, i / 6, (i / 6) + 1); gtk_widget_show (vbox); g_object_unref (pixbuf); } pixman_image_unref (src_img); free (src); pixman_image_unref (dest_img); free (dest); swindow = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table); gtk_widget_show (table); gtk_container_add (GTK_CONTAINER (window), swindow); gtk_widget_show (swindow); gtk_widget_show (window); gtk_main (); return 0; }
int freerds_send_bitmap_update(rdsConnection* connection, int bpp, RDS_MSG_PAINT_RECT* msg) { BYTE* data; BYTE* tile; BYTE* buffer; int i, j, k; wStream* s; wStream* ts; int e, lines; int scanline; int rows, cols; int MaxRegionWidth; int MaxRegionHeight; INT32 nWidth, nHeight; pixman_image_t* image; pixman_image_t* fbImage; BITMAP_DATA* bitmapData; BITMAP_UPDATE bitmapUpdate; rdpUpdate* update = connection->client->update; //printf("%s\n", __FUNCTION__); MaxRegionWidth = 64 * 4; MaxRegionHeight = 64 * 1; if ((msg->nLeftRect % 4) != 0) { msg->nWidth += (msg->nLeftRect % 4); msg->nLeftRect -= (msg->nLeftRect % 4); } if ((msg->nTopRect % 4) != 0) { msg->nHeight += (msg->nTopRect % 4); msg->nTopRect -= (msg->nTopRect % 4); } if ((msg->nWidth * msg->nHeight) > (MaxRegionWidth * MaxRegionHeight)) { RDS_MSG_PAINT_RECT subMsg; rows = (msg->nWidth + (MaxRegionWidth - (msg->nWidth % MaxRegionWidth))) / MaxRegionWidth; cols = (msg->nHeight + (MaxRegionHeight - (msg->nHeight % MaxRegionHeight))) / MaxRegionHeight; //printf("Partitioning x: %d y: %d width: %d height: %d in %d partitions (%d rows, %d cols)\n", // msg->nLeftRect, msg->nTopRect, msg->nWidth, msg->nHeight, rows * cols, rows, cols); for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { CopyMemory(&subMsg, msg, sizeof(RDS_MSG_PAINT_RECT)); subMsg.nLeftRect = msg->nLeftRect + (i * MaxRegionWidth); subMsg.nTopRect = msg->nTopRect + (j * MaxRegionHeight); subMsg.nWidth = (i < (rows - 1)) ? MaxRegionWidth : msg->nWidth - (i * MaxRegionWidth); subMsg.nHeight = (j < (cols - 1)) ? MaxRegionHeight : msg->nHeight - (j * MaxRegionHeight); //printf("\t[%d, %d]: x: %d y: %d width: %d height: %d\n", // i, j, subMsg.nLeftRect, subMsg.nTopRect, subMsg.nWidth, subMsg.nHeight); if ((subMsg.nWidth * subMsg.nHeight) > 0) freerds_send_bitmap_update(connection, bpp, &subMsg); } } return 0; } tile = (BYTE*) malloc(64 * 64 * 4); fbImage = (pixman_image_t*) msg->framebuffer->image; rows = (msg->nWidth + (64 - (msg->nWidth % 64))) / 64; cols = (msg->nHeight + (64 - (msg->nHeight % 64))) / 64; k = 0; bitmapUpdate.count = bitmapUpdate.number = rows * cols; bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number); bitmapUpdate.rectangles = bitmapData; if ((msg->nWidth % 4) != 0) { msg->nLeftRect -= (msg->nWidth % 4); msg->nWidth += (msg->nWidth % 4); } if ((msg->nHeight % 4) != 0) { msg->nTopRect -= (msg->nHeight % 4); msg->nHeight += (msg->nHeight % 4); } for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { nWidth = (i < (rows - 1)) ? 64 : msg->nWidth - (i * 64); nHeight = (j < (cols - 1)) ? 64 : msg->nHeight - (j * 64); bitmapData[k].bitsPerPixel = 16; bitmapData[k].width = nWidth; bitmapData[k].height = nHeight; bitmapData[k].destLeft = msg->nLeftRect + (i * 64); bitmapData[k].destTop = msg->nTopRect + (j * 64); bitmapData[k].destRight = bitmapData[k].destLeft + nWidth - 1; bitmapData[k].destBottom = bitmapData[k].destTop + nHeight - 1; bitmapData[k].compressed = TRUE; if (((nWidth * nHeight) > 0) && (nWidth >= 4) && (nHeight >= 4)) { e = nWidth % 4; if (e != 0) e = 4 - e; //printf("k: %d destLeft: %d destTop: %d destRight: %d destBottom: %d nWidth: %d nHeight: %d\n", // k, bitmapData[k].destLeft, bitmapData[k].destTop, // bitmapData[k].destRight, bitmapData[k].destBottom, nWidth, nHeight); s = connection->encoder->bs; ts = connection->encoder->bts; Stream_SetPosition(s, 0); Stream_SetPosition(ts, 0); data = msg->framebuffer->fbSharedMemory; data = &data[(bitmapData[k].destTop * msg->framebuffer->fbScanline) + (bitmapData[k].destLeft * msg->framebuffer->fbBytesPerPixel)]; scanline = msg->framebuffer->fbScanline; if (bpp > 16) { int dstSize; UINT32 format; format = FREERDP_PIXEL_FORMAT(msg->framebuffer->fbBitsPerPixel, FREERDP_PIXEL_FORMAT_TYPE_ARGB, FREERDP_PIXEL_FLIP_NONE); buffer = connection->encoder->grid[k]; buffer = freerdp_bitmap_compress_planar(connection->encoder->planar_context, data, format, nWidth, nHeight, scanline, buffer, &dstSize); bitmapData[k].bitmapDataStream = buffer; bitmapData[k].bitmapLength = dstSize; bitmapData[k].bitsPerPixel = 32; bitmapData[k].cbScanWidth = nWidth * 4; bitmapData[k].cbUncompressedSize = nWidth * nHeight * 4; } else { image = pixman_image_create_bits(PIXMAN_r5g6b5, nWidth, nHeight, (uint32_t*) tile, nWidth * 2); pixman_image_composite(PIXMAN_OP_OVER, fbImage, NULL, image, bitmapData[k].destLeft, bitmapData[k].destTop, 0, 0, 0, 0, nWidth, nHeight); lines = freerdp_bitmap_compress((char*) pixman_image_get_data(image), nWidth, nHeight, s, 16, 16384, nHeight - 1, ts, e); Stream_SealLength(s); bitmapData[k].bitmapDataStream = Stream_Buffer(s); bitmapData[k].bitmapLength = Stream_Length(s); buffer = connection->encoder->grid[k]; CopyMemory(buffer, bitmapData[k].bitmapDataStream, bitmapData[k].bitmapLength); bitmapData[k].bitmapDataStream = buffer; bitmapData[k].bitsPerPixel = 16; bitmapData[k].cbScanWidth = nWidth * 2; bitmapData[k].cbUncompressedSize = nWidth * nHeight * 2; pixman_image_unref(image); } bitmapData[k].cbCompFirstRowSize = 0; bitmapData[k].cbCompMainBodySize = bitmapData[k].bitmapLength; k++; } } } bitmapUpdate.count = bitmapUpdate.number = k; IFCALL(update->BitmapUpdate, (rdpContext*) connection, &bitmapUpdate); free(bitmapData); free(tile); return 0; }
static void composite_clipped(pixman_image_t *src, pixman_image_t *mask, pixman_image_t *dest, const pixman_transform_t *transform, pixman_filter_t filter, pixman_region32_t *src_clip) { int n_box; pixman_box32_t *boxes; int32_t dest_width; int32_t dest_height; int src_stride; int bitspp; pixman_format_code_t src_format; void *src_data; int i; /* Hardcoded to use PIXMAN_OP_OVER, because sampling outside of * a Pixman image produces (0,0,0,0) instead of discarding the * fragment. */ dest_width = pixman_image_get_width(dest); dest_height = pixman_image_get_height(dest); src_format = pixman_image_get_format(src); src_stride = pixman_image_get_stride(src); bitspp = PIXMAN_FORMAT_BPP(src_format); src_data = pixman_image_get_data(src); assert(src_format); /* This would be massive overdraw, except when n_box is 1. */ boxes = pixman_region32_rectangles(src_clip, &n_box); for (i = 0; i < n_box; i++) { uint8_t *ptr = src_data; pixman_image_t *boximg; pixman_transform_t adj = *transform; ptr += boxes[i].y1 * src_stride; ptr += boxes[i].x1 * bitspp / 8; boximg = pixman_image_create_bits_no_clear(src_format, boxes[i].x2 - boxes[i].x1, boxes[i].y2 - boxes[i].y1, (uint32_t *)ptr, src_stride); pixman_transform_translate(&adj, NULL, pixman_int_to_fixed(-boxes[i].x1), pixman_int_to_fixed(-boxes[i].y1)); pixman_image_set_transform(boximg, &adj); pixman_image_set_filter(boximg, filter, NULL, 0); pixman_image_composite32(PIXMAN_OP_OVER, boximg, mask, dest, 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ dest_width, dest_height); pixman_image_unref(boximg); } if (n_box > 1) { static bool warned = false; if (!warned) weston_log("Pixman-renderer warning: %dx overdraw\n", n_box); warned = true; } }
/* * Composite operation with pseudorandom images */ uint32_t test_composite (int testnum, int verbose) { pixman_image_t *src_img = NULL; pixman_image_t *dst_img = NULL; pixman_image_t *mask_img = NULL; int src_width, src_height; int dst_width, dst_height; int src_stride, dst_stride; int src_x, src_y; int dst_x, dst_y; int mask_x, mask_y; int w, h; pixman_op_t op; pixman_format_code_t src_fmt, dst_fmt, mask_fmt; uint32_t *srcbuf, *maskbuf; uint32_t crc32; int max_width, max_height, max_extra_stride; FLOAT_REGS_CORRUPTION_DETECTOR_START (); max_width = max_height = 24 + testnum / 10000; max_extra_stride = 4 + testnum / 1000000; if (max_width > 256) max_width = 256; if (max_height > 16) max_height = 16; if (max_extra_stride > 8) max_extra_stride = 8; prng_srand (testnum); op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; if (prng_rand_n (8)) { /* normal image */ src_img = create_random_image (img_fmt_list, max_width, max_height, max_extra_stride, &src_fmt); } else { /* solid case */ src_img = create_random_image (img_fmt_list, 1, 1, max_extra_stride, &src_fmt); pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); } dst_img = create_random_image (img_fmt_list, max_width, max_height, max_extra_stride, &dst_fmt); src_width = pixman_image_get_width (src_img); src_height = pixman_image_get_height (src_img); src_stride = pixman_image_get_stride (src_img); dst_width = pixman_image_get_width (dst_img); dst_height = pixman_image_get_height (dst_img); dst_stride = pixman_image_get_stride (dst_img); srcbuf = pixman_image_get_data (src_img); src_x = prng_rand_n (src_width); src_y = prng_rand_n (src_height); dst_x = prng_rand_n (dst_width); dst_y = prng_rand_n (dst_height); mask_img = NULL; mask_fmt = PIXMAN_null; mask_x = 0; mask_y = 0; maskbuf = NULL; if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) && (prng_rand_n (4) == 0)) { /* PIXBUF */ mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; mask_img = pixman_image_create_bits (mask_fmt, src_width, src_height, srcbuf, src_stride); mask_x = src_x; mask_y = src_y; maskbuf = srcbuf; } else if (prng_rand_n (2)) { if (prng_rand_n (2)) { mask_img = create_random_image (mask_fmt_list, max_width, max_height, max_extra_stride, &mask_fmt); } else { /* solid case */ mask_img = create_random_image (mask_fmt_list, 1, 1, max_extra_stride, &mask_fmt); pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); } if (prng_rand_n (2)) pixman_image_set_component_alpha (mask_img, 1); mask_x = prng_rand_n (pixman_image_get_width (mask_img)); mask_y = prng_rand_n (pixman_image_get_height (mask_img)); } w = prng_rand_n (dst_width - dst_x + 1); h = prng_rand_n (dst_height - dst_y + 1); if (verbose) { printf ("op=%s\n", operator_name (op)); printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", format_name (src_fmt), format_name (dst_fmt), format_name (mask_fmt)); printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", src_width, src_height, dst_width, dst_height); printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", src_x, src_y, dst_x, dst_y); printf ("src_stride=%d, dst_stride=%d\n", src_stride, dst_stride); printf ("w=%d, h=%d\n", w, h); } pixman_image_composite (op, src_img, mask_img, dst_img, src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); if (verbose) print_image (dst_img); free_random_image (0, src_img, PIXMAN_null); crc32 = free_random_image (0, dst_img, dst_fmt); if (mask_img) { if (srcbuf == maskbuf) pixman_image_unref(mask_img); else free_random_image (0, mask_img, PIXMAN_null); } FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); return crc32; }