2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "evas_common.h"
6 #include "evas_scale_smooth.h"
7 #include "evas_blend_private.h"
10 static DATA32 **scale_calc_y_points(DATA32 *src, int sw, int sh, int dh);
11 static int *scale_calc_x_points(int sw, int dw);
12 static int *scale_calc_a_points(int s, int d);
15 scale_calc_y_points(DATA32 *src, int sw, int sh, int dh)
20 p = malloc((dh + 1) * sizeof(DATA32 *));
23 inc = (sh << 16) / dh;
24 for (i = 0; i < dh; i++)
26 p[i] = src + ((val >> 16) * sw);
34 scale_calc_x_points(int sw, int dw)
39 p = malloc((dw + 1) * sizeof(int));
42 inc = (sw << 16) / dw;
43 for (i = 0; i < dw; i++)
53 scale_calc_a_points(int s, int d)
58 p = malloc(d * sizeof(int));
64 for (i = 0; i < d; i++)
66 p[i] = (val >> 8) - ((val >> 8) & 0xffffff00);
67 if ((val >> 16) >= (s - 1)) p[i] = 0;
77 Cp = ((d << 14) / s) + 1;
78 for (i = 0; i < d; i++)
80 ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
81 p[i] = ap | (Cp << 16);
89 #ifdef BUILD_SCALE_SMOOTH
92 evas_common_scale_rgba_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
94 int x, y, dst_w, dst_h;
95 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
100 if (dst_w < 1) dst_w = 1;
101 if (dst_h < 1) dst_h = 1;
104 src_ptr2 = src + src_w;
106 for (y = 0; y < dst_h; y++)
108 src_ptr = src + (y * src_w * 2);
109 src_ptr2 = src_ptr + src_w;
110 for (x = 0; x < dst_w; x++)
112 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2;
113 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2;
114 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2;
115 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1) + A_VAL(src_ptr2) + A_VAL(src_ptr2 + 1)) >> 2;
126 #ifdef BUILD_SCALE_SMOOTH
129 evas_common_scale_rgba_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
131 int x, y, dst_w, dst_h;
132 DATA32 *src_ptr, *dst_ptr;
137 if (dst_w < 1) dst_w = 1;
138 if (dst_h < 1) dst_h = 1;
142 for (y = 0; y < dst_h; y++)
144 src_ptr = src + (y * src_w * 2);
145 for (x = 0; x < dst_w; x++)
147 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1;
148 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1;
149 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1;
150 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1)) >> 1;
160 #ifdef BUILD_SCALE_SMOOTH
163 evas_common_scale_rgba_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
165 int x, y, dst_w, dst_h;
166 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
171 if (dst_w < 1) dst_w = 1;
172 if (dst_h < 1) dst_h = 1;
175 src_ptr2 = src + src_w;
177 for (y = 0; y < dst_h; y++)
179 src_ptr = src + (y * src_w * 2);
180 src_ptr2 = src_ptr + src_w;
181 for (x = 0; x < dst_w; x++)
183 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1;
184 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1;
185 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1;
186 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr2)) >> 1;
197 #ifdef BUILD_SCALE_SMOOTH
200 evas_common_scale_rgb_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
202 int x, y, dst_w, dst_h;
203 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
208 if (dst_w < 1) dst_w = 1;
209 if (dst_h < 1) dst_h = 1;
212 src_ptr2 = src + src_w;
214 for (y = 0; y < dst_h; y++)
216 for (x = 0; x < dst_w; x++)
218 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2;
219 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2;
220 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2;
221 A_VAL(dst_ptr) = 0xff;
234 #ifdef BUILD_SCALE_SMOOTH
237 evas_common_scale_rgb_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
239 int x, y, dst_w, dst_h;
240 DATA32 *src_ptr, *dst_ptr;
245 if (dst_w < 1) dst_w = 1;
246 if (dst_h < 1) dst_h = 1;
250 for (y = 0; y < dst_h; y++)
252 for (x = 0; x < dst_w; x++)
254 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1;
255 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1;
256 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1;
257 A_VAL(dst_ptr) = 0xff;
268 #ifdef BUILD_SCALE_SMOOTH
271 evas_common_scale_rgb_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
273 int x, y, dst_w, dst_h;
274 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
279 if (dst_w < 1) dst_w = 1;
280 if (dst_h < 1) dst_h = 1;
283 src_ptr2 = src + src_w;
285 for (y = 0; y < dst_h; y++)
287 for (x = 0; x < dst_w; x++)
289 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1;
290 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1;
291 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1;
292 A_VAL(dst_ptr) = 0xff;
305 #ifdef BUILD_SCALE_SMOOTH
308 evas_common_scale_rgba_mipmap_down_2x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
310 int x, y, dst_w, dst_h;
311 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
316 if (dst_w < 1) dst_w = 1;
317 if (dst_h < 1) dst_h = 1;
320 src_ptr2 = src + src_w;
322 for (y = 0; y < dst_h; y++)
324 src_ptr = src + (y * src_w * 2);
325 src_ptr2 = src_ptr + src_w;
326 for (x = 0; x < dst_w; x++)
328 punpcklbw_m2r(src_ptr[0], mm0);
329 punpcklbw_m2r(src_ptr[1], mm1);
330 punpcklbw_m2r(src_ptr2[0], mm2);
331 punpcklbw_m2r(src_ptr2[1], mm3);
340 packuswb_r2r(mm0, mm0);
341 movd_r2m(mm0, dst_ptr[0]);
352 #ifdef BUILD_SCALE_SMOOTH
355 evas_common_scale_rgba_mipmap_down_2x1_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
357 int x, y, dst_w, dst_h;
358 DATA32 *src_ptr, *dst_ptr;
363 if (dst_w < 1) dst_w = 1;
364 if (dst_h < 1) dst_h = 1;
368 for (y = 0; y < dst_h; y++)
370 src_ptr = src + (y * src_w * 2);
371 for (x = 0; x < dst_w; x++)
373 punpcklbw_m2r(src_ptr[0], mm0);
374 punpcklbw_m2r(src_ptr[1], mm1);
379 packuswb_r2r(mm0, mm0);
380 movd_r2m(mm0, dst_ptr[0]);
390 #ifdef BUILD_SCALE_SMOOTH
393 evas_common_scale_rgba_mipmap_down_1x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
395 int x, y, dst_w, dst_h;
396 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
401 if (dst_w < 1) dst_w = 1;
402 if (dst_h < 1) dst_h = 1;
405 src_ptr2 = src + src_w;
407 for (y = 0; y < dst_h; y++)
409 src_ptr = src + (y * src_w * 2);
410 src_ptr2 = src_ptr + src_w;
411 for (x = 0; x < dst_w; x++)
413 punpcklbw_m2r(src_ptr[0], mm0);
414 punpcklbw_m2r(src_ptr2[0], mm1);
419 packuswb_r2r(mm0, mm0);
420 movd_r2m(mm0, dst_ptr[0]);
431 #ifdef BUILD_SCALE_SMOOTH
434 # define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_mmx
435 # undef SCALE_USING_MMX
436 # define SCALE_USING_MMX
437 # include "evas_scale_smooth_scaler.c"
441 # define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_c
442 # undef SCALE_USING_MMX
443 # include "evas_scale_smooth_scaler.c"
446 evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
447 RGBA_Draw_Context *dc,
448 int src_region_x, int src_region_y,
449 int src_region_w, int src_region_h,
450 int dst_region_x, int dst_region_y,
451 int dst_region_w, int dst_region_h)
458 int c, cx, cy, cw, ch;
460 /* handle cutouts here! */
462 if ((dst_region_w <= 0) || (dst_region_h <= 0)) return;
463 if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
466 evas_common_cpu_can_do(&mmx, &sse, &sse2);
468 /* no cutouts - cut right to the chase */
469 if (!dc->cutout.rects)
473 evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
474 src_region_x, src_region_y,
475 src_region_w, src_region_h,
476 dst_region_x, dst_region_y,
477 dst_region_w, dst_region_h);
481 evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
482 src_region_x, src_region_y,
483 src_region_w, src_region_h,
484 dst_region_x, dst_region_y,
485 dst_region_w, dst_region_h);
489 /* save out clip info */
490 c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
491 evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
492 evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
493 /* our clip is 0 size.. abort */
494 if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
496 dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
499 rects = evas_common_draw_context_apply_cutouts(dc);
500 for (i = 0; i < rects->active; ++i)
502 r = rects->rects + i;
503 evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
506 evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
507 src_region_x, src_region_y,
508 src_region_w, src_region_h,
509 dst_region_x, dst_region_y,
510 dst_region_w, dst_region_h);
514 evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
515 src_region_x, src_region_y,
516 src_region_w, src_region_h,
517 dst_region_x, dst_region_y,
518 dst_region_w, dst_region_h);
521 evas_common_draw_context_apply_clear_cutouts(rects);
522 /* restore clip info */
523 dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;