move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common_16 / evas_soft16_image_scaled_sampled.c
1 #include "evas_common_soft16.h"
2 #include "evas_soft16_scanline_blend.c"
3
4 static void
5 _soft16_image_draw_scaled_solid_solid(Soft16_Image *src,
6                                       Soft16_Image *dst,
7                                       RGBA_Draw_Context *dc,
8                                       int dst_offset, int w, int h,
9                                       int *offset_x, int *offset_y)
10 {
11    DATA16 *dst_itr;
12    int y, w_align;
13
14    w_align = w & ~7;
15
16    dst_itr = dst->pixels + dst_offset;
17    for (y = 0; y < h; y++, dst_itr += dst->stride)
18      {
19         DATA16 *d, *s;
20         int x;
21
22         s = src->pixels + offset_y[y];
23         pld(s, 0);
24         pld(offset_x, 0);
25
26         d = dst_itr;
27         x = 0;
28         while (x < w_align)
29           {
30              pld(s, 32);
31              pld(offset_x + x, 32);
32
33              UNROLL8({
34                 _soft16_pt_blend_solid_solid(d, s[offset_x[x]]);
35                 x++;
36                 d++;
37              });
38           }
39
40         for (; x < w; x++, d++)
41           _soft16_pt_blend_solid_solid(d, s[offset_x[x]]);
42      }
43 }
44 static void
45 _soft16_image_draw_scaled_transp_solid(Soft16_Image *src,
46                                        Soft16_Image *dst,
47                                        RGBA_Draw_Context *dc,
48                                        int dst_offset, int w, int h,
49                                        int *offset_x, int *offset_y)
50 {
51    DATA16 *dst_itr;
52    int y, w_align;
53
54    w_align = w & ~7;
55
56    dst_itr = dst->pixels + dst_offset;
57    for (y = 0; y < h; y++, dst_itr += dst->stride)
58      {
59         DATA16 *d, *s;
60         DATA8 *a;
61         int x;
62
63         s = src->pixels + offset_y[y];
64         a = src->alpha + offset_y[y];
65         pld(s, 0);
66         pld(a, 0);
67         pld(offset_x, 0);
68
69         d = dst_itr;
70         x = 0;
71         while (x < w_align)
72           {
73              pld(s, 32);
74              pld(a, 8);
75              pld(offset_x + x, 32);
76
77              UNROLL8({
78                 int off_x = offset_x[x];
79                 _soft16_pt_blend_transp_solid(d, s[off_x], a[off_x]);
80                 x++;
81                 d++;
82              });
83           }
84
85         for (; x < w; x++, d++)
86           _soft16_pt_blend_transp_solid(d, s[offset_x[x]], a[offset_x[x]]);
87      }
88 }
89
90 static inline void
91 _soft16_image_draw_scaled_no_mul(Soft16_Image *src, Soft16_Image *dst,
92                                  RGBA_Draw_Context *dc,
93                                  int dst_offset, int w, int h,
94                                  int *offset_x, int *offset_y)
95 {
96    if ((src->cache_entry.flags.alpha && src->alpha) && 
97        (!dst->cache_entry.flags.alpha))
98       _soft16_image_draw_scaled_transp_solid
99         (src, dst, dc, dst_offset, w, h, offset_x, offset_y);
100    else if (!dst->cache_entry.flags.alpha)
101       _soft16_image_draw_scaled_solid_solid
102         (src, dst, dc, dst_offset, w, h, offset_x, offset_y);
103    else
104       fprintf(stderr,
105               "Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
106               "dst->cache_entry.flags.alpha=%d, WITHOUT COLOR MUL\n",
107               src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha);
108 }
109
110 static void
111 _soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src,
112                                                 Soft16_Image *dst,
113                                                 RGBA_Draw_Context *dc,
114                                                 int dst_offset, int w, int h,
115                                                 int *offset_x, int *offset_y,
116                                                 DATA8 alpha)
117 {
118    DATA16 *dst_itr;
119    int y, w_align;
120
121    w_align = w & ~7;
122
123    dst_itr = dst->pixels + dst_offset;
124    for (y = 0; y < h; y++, dst_itr += dst->stride)
125      {
126         DATA16 *d, *s;
127         int x;
128
129         s = src->pixels + offset_y[y];
130         pld(s, 0);
131         pld(offset_x, 0);
132
133         d = dst_itr;
134         x = 0;
135         while (x < w_align)
136           {
137              pld(s, 32);
138              pld(offset_x + x, 32);
139
140              UNROLL8({
141                 _soft16_pt_blend_solid_solid_mul_alpha
142                   (d, s[offset_x[x]], alpha);
143                 x++;
144                 d++;
145              });
146           }
147
148         for (; x < w; x++, d++)
149           _soft16_pt_blend_solid_solid_mul_alpha
150             (d, s[offset_x[x]], alpha);
151      }
152 }
153
154 static void
155 _soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src,
156                                                  Soft16_Image *dst,
157                                                  RGBA_Draw_Context *dc,
158                                                  int dst_offset, int w, int h,
159                                                  int *offset_x, int *offset_y,
160                                                  DATA8 alpha)
161 {
162    DATA16 *dst_itr;
163    int y, w_align;
164
165    w_align = w & ~7;
166
167    dst_itr = dst->pixels + dst_offset;
168    for (y = 0; y < h; y++, dst_itr += dst->stride)
169      {
170         DATA16 *d, *s;
171         DATA8 *a;
172         int x;
173
174         s = src->pixels + offset_y[y];
175         a = src->alpha + offset_y[y];
176         pld(s, 0);
177         pld(a, 0);
178         pld(offset_x, 0);
179
180         d = dst_itr;
181         x = 0;
182         while (x < w_align)
183           {
184              pld(s, 32);
185              pld(a, 8);
186              pld(offset_x + x, 32);
187
188              UNROLL8({
189                 int off_x = offset_x[x];
190                 _soft16_pt_blend_transp_solid_mul_alpha
191                   (d, s[off_x], a[off_x], alpha);
192                 x++;
193                 d++;
194              });
195           }
196
197         for (; x < w; x++, d++)
198           _soft16_pt_blend_transp_solid_mul_alpha
199             (d, s[offset_x[x]], a[offset_x[x]], alpha);
200      }
201 }
202
203 static inline void
204 _soft16_image_draw_scaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst,
205                                     RGBA_Draw_Context *dc,
206                                     int dst_offset, int w, int h,
207                                     int *offset_x, int *offset_y, DATA8 a)
208 {
209    if ((src->cache_entry.flags.alpha && src->alpha) && 
210        (!dst->cache_entry.flags.alpha))
211       _soft16_image_draw_scaled_transp_solid_mul_alpha
212          (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
213    else if (!dst->cache_entry.flags.alpha)
214       _soft16_image_draw_scaled_solid_solid_mul_alpha
215          (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
216    else
217       fprintf(stderr,
218               "Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
219               "dst->cache_entry.flags.alpha=%d, WITH ALPHA MUL %d\n",
220               src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, A_VAL(&dc->mul.col));
221 }
222
223 static void
224 _soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src,
225                                                 Soft16_Image *dst,
226                                                 RGBA_Draw_Context *dc,
227                                                 int dst_offset, int w, int h,
228                                                 int *offset_x, int *offset_y,
229                                                 DATA8 r, DATA8 g, DATA8 b,
230                                                 DATA8 alpha)
231 {
232    DATA16 *dst_itr;
233    int y, w_align;
234
235    w_align = w & ~7;
236
237    dst_itr = dst->pixels + dst_offset;
238
239    if (alpha == 31)
240      for (y = 0; y < h; y++, dst_itr += dst->stride)
241        {
242           DATA16 *d, *s;
243           int x;
244
245           s = src->pixels + offset_y[y];
246           pld(s, 0);
247           pld(offset_x, 0);
248
249           d = dst_itr;
250           x = 0;
251           while (x < w_align)
252             {
253                pld(s, 32);
254                pld(offset_x + x, 32);
255
256                UNROLL8({
257                   _soft16_pt_blend_solid_solid_mul_color_solid
258                     (d, s[offset_x[x]], r, g, b);
259                   x++;
260                   d++;
261                });
262             }
263
264           for (; x < w; x++, d++)
265             _soft16_pt_blend_solid_solid_mul_color_solid
266               (d, s[offset_x[x]], r, g, b);
267        }
268    else
269      for (y = 0; y < h; y++, dst_itr += dst->stride)
270        {
271           DATA16 *d, *s;
272           int x;
273
274           s = src->pixels + offset_y[y];
275           pld(s, 0);
276           pld(offset_x, 0);
277
278           d = dst_itr;
279           x = 0;
280           while (x < w_align)
281             {
282                pld(s, 32);
283                pld(offset_x + x, 32);
284
285                UNROLL8({
286                   _soft16_pt_blend_solid_solid_mul_color_transp
287                     (d, s[offset_x[x]], alpha, r, g, b);
288                   x++;
289                   d++;
290                });
291             }
292
293           for (; x < w; x++, d++)
294             _soft16_pt_blend_solid_solid_mul_color_transp
295               (d, s[offset_x[x]], alpha, r, g, b);
296        }
297 }
298
299 static void
300 _soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src,
301                                                  Soft16_Image *dst,
302                                                  RGBA_Draw_Context *dc,
303                                                  int dst_offset, int w, int h,
304                                                  int *offset_x, int *offset_y,
305                                                  DATA8 r, DATA8 g, DATA8 b,
306                                                  DATA8 alpha)
307 {
308    DATA16 *dst_itr;
309    int y, w_align;
310
311    w_align = w & ~7;
312
313    dst_itr = dst->pixels + dst_offset;
314
315    if (alpha == 31)
316      for (y = 0; y < h; y++, dst_itr += dst->stride)
317        {
318           DATA16 *d, *s;
319           DATA8 *a;
320           int x;
321
322           s = src->pixels + offset_y[y];
323           a = src->alpha + offset_y[y];
324           pld(s, 0);
325           pld(a, 0);
326           pld(offset_x, 0);
327
328           d = dst_itr;
329           x = 0;
330           while (x < w_align)
331             {
332                pld(s, 32);
333                pld(a, 8);
334                pld(offset_x + x, 32);
335
336                UNROLL8({
337                   int off_x = offset_x[x];
338                   _soft16_pt_blend_transp_solid_mul_color_solid
339                     (d, s[off_x], a[off_x], r, g, b);
340                   x++;
341                   d++;
342                });
343             }
344
345           for (; x < w; x++, d++)
346             _soft16_pt_blend_transp_solid_mul_color_solid
347               (d, s[offset_x[x]], a[offset_x[x]], r, g, b);
348        }
349    else
350      for (y = 0; y < h; y++, dst_itr += dst->stride)
351        {
352           DATA16 *d, *s;
353           DATA8 *a;
354           int x;
355
356           s = src->pixels + offset_y[y];
357           a = src->alpha + offset_y[y];
358           pld(s, 0);
359           pld(a, 0);
360           pld(offset_x, 0);
361
362           d = dst_itr;
363           x = 0;
364           while (x < w_align)
365             {
366                pld(s, 32);
367                pld(a, 8);
368                pld(offset_x + x, 32);
369
370                UNROLL8({
371                   int off_x = offset_x[x];
372                   _soft16_pt_blend_transp_solid_mul_color_transp
373                     (d, s[off_x], a[off_x], alpha, r, g, b);
374                   x++;
375                   d++;
376                });
377             }
378
379           for (; x < w; x++, d++)
380             _soft16_pt_blend_transp_solid_mul_color_transp
381               (d, s[offset_x[x]], a[offset_x[x]], alpha, r, g, b);
382        }
383 }
384
385 static inline void
386 _soft16_image_draw_scaled_mul_color(Soft16_Image *src, Soft16_Image *dst,
387                                     RGBA_Draw_Context *dc,
388                                     int dst_offset, int w, int h,
389                                     int *offset_x, int *offset_y,
390                                     DATA8 r, DATA8 g, DATA8 b, DATA8 a)
391 {
392    if ((src->cache_entry.flags.alpha && src->alpha) && 
393        (!dst->cache_entry.flags.alpha))
394       _soft16_image_draw_scaled_transp_solid_mul_color
395          (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
396    else if (!dst->cache_entry.flags.alpha)
397       _soft16_image_draw_scaled_solid_solid_mul_color
398          (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
399    else
400       fprintf(stderr,
401               "Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
402               "dst->cache_entry.flags.alpha=%d, WITH COLOR MUL 0x%08x\n",
403               src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, dc->mul.col);
404 }
405
406 static inline void
407 _soft16_image_draw_scaled_mul(Soft16_Image *src, Soft16_Image *dst,
408                               RGBA_Draw_Context *dc,
409                               int dst_offset, int w, int h,
410                               int *offset_x, int *offset_y, DATA8 r, DATA8 g,
411                               DATA8 b, DATA8 a)
412 {
413    if ((a == r) && (a == (g >> 1)) && (a == b))
414       _soft16_image_draw_scaled_mul_alpha
415         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
416    else
417       _soft16_image_draw_scaled_mul_color
418         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
419 }
420
421 void
422 soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst,
423                                  RGBA_Draw_Context *dc,
424                                  const Evas_Rectangle sr,
425                                  const Evas_Rectangle dr,
426                                  const Evas_Rectangle cr)
427 {
428    int x, y, dst_offset, *offset_x, *offset_y;
429    DATA16 mul_rgb565;
430    DATA8 r, g, b, a;
431
432    if (!dc->mul.use)
433      {
434         r = b = a = 31;
435         g = 63;
436         mul_rgb565 = 0xffff;
437      }
438    else
439      {
440         a = A_VAL(&dc->mul.col) >> 3;
441         if (a == 0)
442           return;
443
444         r = R_VAL(&dc->mul.col) >> 3;
445         g = G_VAL(&dc->mul.col) >> 2;
446         b = B_VAL(&dc->mul.col) >> 3;
447
448         if (r > a) r = a;
449         if (g > (a << 1)) g = (a << 1);
450         if (b > a) b = a;
451
452         mul_rgb565 = (r << 11) || (g << 5) | b;
453      }
454
455    /* pre-calculated scale tables */
456    offset_x = alloca(cr.w * sizeof(*offset_x));
457    for (x = 0; x < cr.w; x++)
458      offset_x[x] = (((x + cr.x - dr.x) * sr.w) / dr.w) + sr.x;
459
460    offset_y = alloca(cr.h * sizeof(*offset_y));
461    for (y = 0; y < cr.h; y++)
462      offset_y[y] = (((((y + cr.y - dr.y) * sr.h) / dr.h) + sr.y)
463                     * src->stride);
464
465    dst_offset = cr.x + (cr.y * dst->stride);
466
467
468    if (mul_rgb565 == 0xffff)
469      _soft16_image_draw_scaled_no_mul
470        (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y);
471    else
472      _soft16_image_draw_scaled_mul
473        (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y, r, g, b, a);
474 }