📄 pixops.c
字号:
for (i = 0; i < n_x; i++) { if (i < x) { if (i + 1 > x) x_weights[i] = MIN(i+1, x + 1/x_scale) - x; else x_weights[i] = 0; } else { if (x + 1/x_scale > i) x_weights[i] = MIN(i+1, x + 1/x_scale) - i; else x_weights[i] = 0; } } } if (y_scale > 1.0) /* Bilinear */ { for (i = 0; i < n_y; i++) { y_weights[i] = ((i == 0) ? (1 - y) : y) / y_scale; } } else /* Tile */ { /* y * ---------|--.-|----|--.-|------- SRC * ------------|---------|--------- DEST */ for (i = 0; i < n_y; i++) { if (i < y) { if (i + 1 > y) y_weights[i] = MIN(i+1, y + 1/y_scale) - y; else y_weights[i] = 0; } else { if (y + 1/y_scale > i) y_weights[i] = MIN(i+1, y + 1/y_scale) - i; else y_weights[i] = 0; } } } for (i = 0; i < n_y; i++) { for (j = 0; j < n_x; j++) { int weight = 65536 * x_weights[j] * x_scale * y_weights[i] * y_scale * overall_alpha + 0.5; *(pixel_weights + n_x * i + j) = weight; total += weight; } } correct_total (pixel_weights, n_x, n_y, total, overall_alpha); } } free (x_weights); free (y_weights);}static doublebilinear_quadrant (double bx0, double bx1, double by0, double by1){ double ax0, ax1, ay0, ay1; double x0, x1, y0, y1; ax0 = 0.; ax1 = 1.; ay0 = 0.; ay1 = 1.; if (ax0 < bx0) { if (ax1 > bx0) { x0 = bx0; x1 = MIN (ax1, bx1); } else { return 0; } } else { if (bx1 > ax0) { x0 = ax0; x1 = MIN (ax1, bx1); } else { return 0; } } if (ay0 < by0) { if (ay1 > by0) { y0 = by0; y1 = MIN (ay1, by1); } else { return 0; } } else { if (by1 > ay0) { y0 = ay0; y1 = MIN (ay1, by1); } else { return 0; } } return 0.25 * (x1*x1 - x0*x0) * (y1*y1 - y0*y0);}static voidbilinear_make_weights (PixopsFilter *filter, double x_scale, double y_scale, double overall_alpha){ int i_offset, j_offset; int n_x = ceil(1/x_scale + 2.0); int n_y = ceil(1/y_scale + 2.0); filter->x_offset = -1.0; filter->y_offset = -1.0; filter->n_x = n_x; filter->n_y = n_y; filter->weights = mnew (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y); for (i_offset=0; i_offset<SUBSAMPLE; i_offset++) { for (j_offset=0; j_offset<SUBSAMPLE; j_offset++) { int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y; double x = (double)j_offset / SUBSAMPLE; double y = (double)i_offset / SUBSAMPLE; int i,j; int total = 0; for (i = 0; i < n_y; i++) { for (j = 0; j < n_x; j++) { double w; int weight; w = bilinear_quadrant (0.5 + j - (x + 1 / x_scale), 0.5 + j - x, 0.5 + i - (y + 1 / y_scale), 0.5 + i - y); w += bilinear_quadrant (1.5 + x - j, 1.5 + (x + 1 / x_scale) - j, 0.5 + i - (y + 1 / y_scale), 0.5 + i - y); w += bilinear_quadrant (0.5 + j - (x + 1 / x_scale), 0.5 + j - x, 1.5 + y - i, 1.5 + (y + 1 / y_scale) - i); w += bilinear_quadrant (1.5 + x - j, 1.5 + (x + 1 / x_scale) - j, 1.5 + y - i, 1.5 + (y + 1 / y_scale) - i); weight = 65536 * w * x_scale * y_scale * overall_alpha + 0.5; *(pixel_weights + n_x * i + j) = weight; total += weight; } } correct_total (pixel_weights, n_x, n_y, total, overall_alpha); } }}PixopsStatuspixops_scale_composite_color (uint8 *dest_buf, int render_x0, int render_y0, int render_x1, int render_y1, int dest_rowstride, int dest_channels, boolean dest_has_alpha, const uint8 *src_buf, int src_width, int src_height, int src_rowstride, int src_channels, boolean src_has_alpha, double scale_x, double scale_y, PixopsInterpType interp_type, int overall_alpha, int check_x, int check_y, int check_size, uint32 color1, uint32 color2){ PixopsFilter filter; PixopsLineFunc line_func;#ifdef USE_MMX boolean found_mmx = pixops_have_mmx();#endif if (pixops_support_scale_composite_formats (dest_channels, dest_has_alpha, src_channels, src_has_alpha) != PIXOPS_STATUS_SUCCESS) { return PIXOPS_STATUS_UNSUPPORTED_FORMAT; } if (scale_x == 0 || scale_y == 0) return PIXOPS_STATUS_FAILURE; if (!src_has_alpha && overall_alpha == 255) { return pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, 24, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, 24, NULL, src_has_alpha, scale_x, scale_y, interp_type); } switch (interp_type) { case PIXOPS_INTERP_NEAREST: pixops_scale_composite_color_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha, scale_x, scale_y, overall_alpha, check_x, check_y, check_size, color1, color2); return PIXOPS_STATUS_SUCCESS; case PIXOPS_INTERP_TILES: tile_make_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; case PIXOPS_INTERP_BILINEAR: bilinear_make_fast_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; case PIXOPS_INTERP_HYPER: bilinear_make_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; }#ifdef USE_MMX if (filter.n_x == 2 && filter.n_y == 2 && dest_channels == 4 && src_channels == 4 && src_has_alpha && !dest_has_alpha && found_mmx) { line_func = composite_line_color_22_4a4_mmx_stub; } else {#endif line_func = composite_line_color; } pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, 24, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, 24, NULL, src_has_alpha, scale_x, scale_y, check_x, check_y, check_size, color1, color2, &filter, line_func, composite_pixel_color); free (filter.weights); return PIXOPS_STATUS_SUCCESS;}/** * pixops_scale_composite: * @dest_buf: pointer to location to store result * @render_x0: x0 of region of scaled source to store into @dest_buf * @render_y0: y0 of region of scaled source to store into @dest_buf * @render_x1: x1 of region of scaled source to store into @dest_buf * @render_y1: y1 of region of scaled source to store into @dest_buf * @dest_rowstride: rowstride of @dest_buf * @dest_channels: number of channels in @dest_buf * @dest_has_alpha: whether @dest_buf has alpha * @src_buf: pointer to source pixels * @src_width: width of source (used for clipping) * @src_height: height of source (used for clipping) * @src_rowstride: rowstride of source * @src_channels: number of channels in @src_buf * @src_has_alpha: whether @src_buf has alpha * @scale_x: amount to scale source by in X direction * @scale_y: amount to scale source by in Y direction * @interp_type: type of enumeration * @overall_alpha: overall alpha factor to multiply source by * * Scale source buffer by scale_x / scale_y, then composite a given rectangle * of the result into the destination buffer. **/PixopsStatuspixops_scale_composite (uint8 *dest_buf, int render_x0, int render_y0, int render_x1, int render_y1, int dest_rowstride, int dest_channels, boolean dest_has_alpha, const uint8 *src_buf, int src_width, int src_height, int src_rowstride, int src_channels, boolean src_has_alpha, double scale_x, double scale_y, PixopsInterpType interp_type, int overall_alpha){ PixopsFilter filter; PixopsLineFunc line_func;#ifdef USE_MMX boolean found_mmx = pixops_have_mmx();#endif if (pixops_support_scale_composite_formats (dest_channels, dest_has_alpha, src_channels, src_has_alpha) != PIXOPS_STATUS_SUCCESS) { return PIXOPS_STATUS_UNSUPPORTED_FORMAT; } if (scale_x == 0 || scale_y == 0) { return PIXOPS_STATUS_FAILURE; } if (!src_has_alpha && overall_alpha == 255) { return pixops_scale (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, 24, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, 24, NULL, src_has_alpha, scale_x, scale_y, interp_type); } switch (interp_type) { case PIXOPS_INTERP_NEAREST: pixops_scale_composite_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, src_has_alpha, scale_x, scale_y, overall_alpha); return PIXOPS_STATUS_SUCCESS; case PIXOPS_INTERP_TILES: tile_make_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; case PIXOPS_INTERP_BILINEAR: bilinear_make_fast_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; case PIXOPS_INTERP_HYPER: bilinear_make_weights (&filter, scale_x, scale_y, overall_alpha / 255.); break; } if (filter.n_x == 2 && filter.n_y == 2 && dest_channels == 4 && src_channels == 4 && src_has_alpha && !dest_has_alpha) {#ifdef USE_MMX if (found_mmx) { line_func = composite_line_22_4a4_mmx_stub; } else {#endif line_func = composite_line_22_4a4; } } else { line_func = composite_line; } pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_channels, 24, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_channels, 24, NULL, src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, &filter, line_func, composite_pixel); free (filter.weights); return PIXOPS_STATUS_SUCCESS;}PixopsStatuspixops_scale (uint8 *dest_buf, int render_x0, int render_y0, int render_x1, int render_y1, int dest_rowstride, int dest_bytes_per_pixel, int dest_depth, boolean dest_has_alpha, const uint8 *src_buf, int src_width, int src_height, int src_rowstride, int src_bytes_per_pixel, int src_depth, uint32 *src_colormap, boolean src_has_alpha, double scale_x, double scale_y, PixopsInterpType interp_type){ PixopsFilter filter; PixopsLineFunc line_func;#ifdef USE_MMX boolean found_mmx = pixops_have_mmx();#endif if (pixops_support_scale_formats (dest_bytes_per_pixel, dest_depth, dest_has_alpha, src_bytes_per_pixel, src_depth, src_colormap, src_has_alpha) != PIXOPS_STATUS_SUCCESS) { return PIXOPS_STATUS_UNSUPPORTED_FORMAT; } if (scale_x == 0 || scale_y == 0) { return PIXOPS_STATUS_FAILURE; } switch (interp_type) { case PIXOPS_INTERP_NEAREST: pixops_scale_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_bytes_per_pixel, dest_depth, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_bytes_per_pixel, src_depth, src_colormap, src_has_alpha, scale_x, scale_y); return PIXOPS_STATUS_SUCCESS; case PIXOPS_INTERP_TILES: tile_make_weights (&filter, scale_x, scale_y, 1.0); break; case PIXOPS_INTERP_BILINEAR: bilinear_make_fast_weights (&filter, scale_x, scale_y, 1.0); break; case PIXOPS_INTERP_HYPER: bilinear_make_weights (&filter, scale_x, scale_y, 1.0); break; } if (filter.n_x == 2 && filter.n_y == 2 && dest_bytes_per_pixel == 3 && src_bytes_per_pixel == 3) {#ifdef USE_MMX if (found_mmx) { line_func = scale_line_22_33_mmx_stub; } else {#endif line_func = scale_line_22_33; } } else { line_func = scale_line; } pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, dest_rowstride, dest_bytes_per_pixel, dest_depth, dest_has_alpha, src_buf, src_width, src_height, src_rowstride, src_bytes_per_pixel, src_depth, src_colormap, src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, &filter, line_func, scale_pixel); free (filter.weights); return PIXOPS_STATUS_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -