void vegaColorMatrix(VGImage dst, VGImage src, const VGfloat * matrix) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; struct filter_info info; if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!matrix || !is_aligned(matrix)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } d = handle_to_image(dst); s = handle_to_image(src); if (vg_image_overlaps(d, s)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } info.dst = d; info.src = s; info.setup_shader = &setup_color_matrix; info.user_data = NULL; info.const_buffer = matrix; info.const_buffer_len = 20 * sizeof(VGfloat); info.tiling_mode = VG_TILE_PAD; info.extra_texture_view = NULL; execute_filter(ctx, &info); }
void vegaLookup(VGImage dst, VGImage src, const VGubyte * redLUT, const VGubyte * greenLUT, const VGubyte * blueLUT, const VGubyte * alphaLUT, VGboolean outputLinear, VGboolean outputPremultiplied) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; VGuint color_data[256]; VGint i; struct pipe_sampler_view *lut_texture_view; VGfloat buffer[4]; struct filter_info info; if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!redLUT || !greenLUT || !blueLUT || !alphaLUT) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } d = handle_to_image(dst); s = handle_to_image(src); if (vg_image_overlaps(d, s)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } for (i = 0; i < 256; ++i) { color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 | redLUT[i] << 8 | alphaLUT[i]; } lut_texture_view = create_texture_1d_view(ctx, color_data, 255); buffer[0] = 0.f; buffer[1] = 0.f; buffer[2] = 1.f; buffer[3] = 1.f; info.dst = d; info.src = s; info.setup_shader = &setup_lookup; info.user_data = NULL; info.const_buffer = buffer; info.const_buffer_len = 4 * sizeof(VGfloat); info.tiling_mode = VG_TILE_PAD; info.extra_texture_view = lut_texture_view; execute_filter(ctx, &info); pipe_sampler_view_reference(&lut_texture_view, NULL); }
VGImage vegaChildImage(VGImage parent, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *p; if (parent == VG_INVALID_HANDLE || !vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, parent) || !vg_object_is_valid(parent, VG_OBJECT_IMAGE)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return VG_INVALID_HANDLE; } if (width <= 0 || height <= 0 || x < 0 || y < 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } p = handle_to_image(parent); if (x > p->width || y > p->height) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } if (x + width > p->width || y + height > p->height) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return VG_INVALID_HANDLE; } return image_to_handle(image_child_image(p, x, y, width, height)); }
void vegaGetImageSubData(VGImage image, void * data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); return; } if (width <= 0 || height <= 0 || !data || !is_aligned(data)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } img = handle_to_image(image); image_get_sub_data(img, data, dataStride, dataFormat, x, y, width, height); }
void vegaMask(VGHandle mask, VGMaskOperation operation, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); if (width <=0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (operation < VG_CLEAR_MASK || operation > VG_SUBTRACT_MASK) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); if (operation == VG_CLEAR_MASK) { mask_fill(x, y, width, height, 0.f); } else if (operation == VG_FILL_MASK) { mask_fill(x, y, width, height, 1.f); } else if (vg_object_is_valid(mask, VG_OBJECT_IMAGE)) { struct vg_image *image = handle_to_image(mask); mask_using_image(image, operation, x, y, width, height); } else if (vg_object_is_valid(mask, VG_OBJECT_MASK)) { struct vg_mask_layer *layer = handle_to_masklayer(mask); mask_using_layer(layer, operation, x, y, width, height); } else { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); } }
void vegaPaintPattern(VGPaint paint, VGImage pattern) { struct vg_context *ctx = vg_current_context(); if (paint == VG_INVALID_HANDLE || !vg_context_is_object_valid(ctx, VG_OBJECT_PAINT, paint)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (pattern == VG_INVALID_HANDLE) { paint_set_type(handle_to_paint(paint), VG_PAINT_TYPE_COLOR); return; } if (!vg_context_is_object_valid(ctx, VG_OBJECT_IMAGE, pattern)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!vg_object_is_valid(paint, VG_OBJECT_PAINT) || !vg_object_is_valid(pattern, VG_OBJECT_IMAGE)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } paint_set_pattern(handle_to_paint(paint), handle_to_image(pattern)); }
void vegaCopyImage(VGImage dst, VGint dx, VGint dy, VGImage src, VGint sx, VGint sy, VGint width, VGint height, VGboolean dither) { struct vg_context *ctx = vg_current_context(); if (src == VG_INVALID_HANDLE || dst == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); image_copy(handle_to_image(dst), dx, dy, handle_to_image(src), sx, sy, width, height, dither); }
void vegaDestroyImage(VGImage image) { struct vg_context *ctx = vg_current_context(); struct vg_image *img = handle_to_image(image); if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!vg_object_is_valid(image, VG_OBJECT_IMAGE)) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } image_destroy(img); }
void vegaDrawImage(VGImage image) { struct vg_context *ctx = vg_current_context(); if (!ctx) return; if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } vg_validate_state(ctx); image_draw(handle_to_image(image), &ctx->state.vg.image_user_to_surface_matrix); }
VGImage vegaGetParent(VGImage image) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return VG_INVALID_HANDLE; } img = handle_to_image(image); if (img->parent) return image_to_handle(img->parent); else return image; }
void vegaSetPixels(VGint dx, VGint dy, VGImage src, VGint sx, VGint sy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); vg_validate_state(ctx); if (src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } image_set_pixels(dx, dy, handle_to_image(src), sx, sy, width, height); }
void vegaGetPixels(VGImage dst, VGint dx, VGint dy, VGint sx, VGint sy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; if (dst == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } img = handle_to_image(dst); image_get_pixels(img, dx, dy, sx, sy, width, height); }
void vegaClearImage(VGImage image, VGint x, VGint y, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); struct vg_image *img; if (image == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } img = handle_to_image(image); if (x + width < 0 || y + height < 0) return; image_clear(img, x, y, width, height); }
void vegaLookupSingle(VGImage dst, VGImage src, const VGuint * lookupTable, VGImageChannel sourceChannel, VGboolean outputLinear, VGboolean outputPremultiplied) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; struct pipe_sampler_view *lut_texture_view; VGfloat buffer[4]; struct filter_info info; VGuint color_data[256]; VGint i; if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (!lookupTable || !is_aligned(lookupTable)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (sourceChannel != VG_RED && sourceChannel != VG_GREEN && sourceChannel != VG_BLUE && sourceChannel != VG_ALPHA) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } d = handle_to_image(dst); s = handle_to_image(src); if (vg_image_overlaps(d, s)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); for (i = 0; i < 256; ++i) { VGuint rgba = lookupTable[i]; VGubyte blue, green, red, alpha; red = (rgba & 0xff000000)>>24; green = (rgba & 0x00ff0000)>>16; blue = (rgba & 0x0000ff00)>> 8; alpha = (rgba & 0x000000ff)>> 0; color_data[i] = blue << 24 | green << 16 | red << 8 | alpha; } lut_texture_view = create_texture_1d_view(ctx, color_data, 256); buffer[0] = 0.f; buffer[1] = 0.f; buffer[2] = 1.f; buffer[3] = 1.f; info.dst = d; info.src = s; info.setup_shader = &setup_lookup_single; info.user_data = (void*)sourceChannel; info.const_buffer = buffer; info.const_buffer_len = 4 * sizeof(VGfloat); info.tiling_mode = VG_TILE_PAD; info.extra_texture_view = lut_texture_view; execute_filter(ctx, &info); pipe_sampler_view_reference(&lut_texture_view, NULL); }
void vegaGaussianBlur(VGImage dst, VGImage src, VGfloat stdDeviationX, VGfloat stdDeviationY, VGTilingMode tilingMode) { struct vg_context *ctx = vg_current_context(); struct vg_image *d, *s; VGfloat *buffer, *kernel; VGint kernel_width, kernel_height, kernel_size; VGint buffer_len; VGint idx, i, j; struct filter_info info; if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (stdDeviationX <= 0 || stdDeviationY <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (tilingMode < VG_TILE_FILL || tilingMode > VG_TILE_REFLECT) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } d = handle_to_image(dst); s = handle_to_image(src); if (vg_image_overlaps(d, s)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } kernel_width = compute_kernel_size(stdDeviationX); kernel_height = compute_kernel_size(stdDeviationY); kernel_size = kernel_width * kernel_height; kernel = malloc(sizeof(VGfloat)*kernel_size); compute_gaussian_kernel(kernel, kernel_width, kernel_height, stdDeviationX, stdDeviationY); buffer_len = 8 + 2 * 4 * kernel_size; buffer = malloc(buffer_len * sizeof(VGfloat)); buffer[0] = 0.f; buffer[1] = 1.f; buffer[2] = 2.f; /*unused*/ buffer[3] = 4.f; /*unused*/ buffer[4] = kernel_width * kernel_height; buffer[5] = 1.f;/*scale*/ buffer[6] = 0.f;/*bias*/ buffer[7] = 0.f; idx = 8; for (j = 0; j < kernel_height; ++j) { for (i = 0; i < kernel_width; ++i) { VGint index = j * kernel_width + i; VGfloat x, y; x = texture_offset(s->width, kernel_width, i, kernel_width/2); y = texture_offset(s->height, kernel_height, j, kernel_height/2); buffer[idx + index*4 + 0] = x; buffer[idx + index*4 + 1] = y; buffer[idx + index*4 + 2] = 0.f; buffer[idx + index*4 + 3] = 0.f; } } idx += kernel_size * 4; for (j = 0; j < kernel_height; ++j) { for (i = 0; i < kernel_width; ++i) { /* transpose the kernel */ VGint index = j * kernel_width + i; VGint kindex = (kernel_width - i - 1) * kernel_height + (kernel_height - j - 1); buffer[idx + index*4 + 0] = kernel[kindex]; buffer[idx + index*4 + 1] = kernel[kindex]; buffer[idx + index*4 + 2] = kernel[kindex]; buffer[idx + index*4 + 3] = kernel[kindex]; } } info.dst = d; info.src = s; info.setup_shader = &setup_convolution; info.user_data = (void*)(long)(buffer_len/4); info.const_buffer = buffer; info.const_buffer_len = buffer_len * sizeof(VGfloat); info.tiling_mode = tilingMode; info.extra_texture_view = NULL; execute_filter(ctx, &info); free(buffer); free(kernel); }
void vegaConvolve(VGImage dst, VGImage src, VGint kernelWidth, VGint kernelHeight, VGint shiftX, VGint shiftY, const VGshort * kernel, VGfloat scale, VGfloat bias, VGTilingMode tilingMode) { struct vg_context *ctx = vg_current_context(); VGfloat *buffer; VGint buffer_len; VGint i, j; VGint idx = 0; struct vg_image *d, *s; VGint kernel_size = kernelWidth * kernelHeight; struct filter_info info; const VGint max_kernel_size = vegaGeti(VG_MAX_KERNEL_SIZE); if (dst == VG_INVALID_HANDLE || src == VG_INVALID_HANDLE) { vg_set_error(ctx, VG_BAD_HANDLE_ERROR); return; } if (kernelWidth <= 0 || kernelHeight <= 0 || kernelWidth > max_kernel_size || kernelHeight > max_kernel_size) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (!kernel || !is_aligned_to(kernel, 2)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } if (tilingMode < VG_TILE_FILL || tilingMode > VG_TILE_REFLECT) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } d = handle_to_image(dst); s = handle_to_image(src); if (vg_image_overlaps(d, s)) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } vg_validate_state(ctx); buffer_len = 8 + 2 * 4 * kernel_size; buffer = malloc(buffer_len * sizeof(VGfloat)); buffer[0] = 0.f; buffer[1] = 1.f; buffer[2] = 2.f; /*unused*/ buffer[3] = 4.f; /*unused*/ buffer[4] = kernelWidth * kernelHeight; buffer[5] = scale; buffer[6] = bias; buffer[7] = 0.f; idx = 8; for (j = 0; j < kernelHeight; ++j) { for (i = 0; i < kernelWidth; ++i) { VGint index = j * kernelWidth + i; VGfloat x, y; x = texture_offset(s->width, kernelWidth, i, shiftX); y = texture_offset(s->height, kernelHeight, j, shiftY); buffer[idx + index*4 + 0] = x; buffer[idx + index*4 + 1] = y; buffer[idx + index*4 + 2] = 0.f; buffer[idx + index*4 + 3] = 0.f; } } idx += kernel_size * 4; for (j = 0; j < kernelHeight; ++j) { for (i = 0; i < kernelWidth; ++i) { /* transpose the kernel */ VGint index = j * kernelWidth + i; VGint kindex = (kernelWidth - i - 1) * kernelHeight + (kernelHeight - j - 1); buffer[idx + index*4 + 0] = kernel[kindex]; buffer[idx + index*4 + 1] = kernel[kindex]; buffer[idx + index*4 + 2] = kernel[kindex]; buffer[idx + index*4 + 3] = kernel[kindex]; } } info.dst = d; info.src = s; info.setup_shader = &setup_convolution; info.user_data = (void*)(long)(buffer_len/4); info.const_buffer = buffer; info.const_buffer_len = buffer_len * sizeof(VGfloat); info.tiling_mode = tilingMode; info.extra_texture_view = NULL; execute_filter(ctx, &info); free(buffer); }