move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common / evas_scale_span.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "evas_common.h"
6 #include "evas_convert_color.h"
7 #include "evas_scale_span.h"
8
9 static void
10 evas_common_scale_rgba_span_(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
11 {
12    int  mul = 0, step = 1;
13    DATA32 *pdst = dst;
14
15    if (!src || !dst) return;
16    if ((src_len < 1) || (dst_len < 1)) return;
17    if ((src_len > 65535) || (dst_len > 65535)) return;
18    if (mul_col != 0xffffffff)
19         mul = 1;
20    if (dir < 0)
21      {
22         pdst += dst_len - 1;
23         step = -1;
24      }
25
26    if ((src_len == 1) || (dst_len == 1))
27      {
28         DATA32 c = *src;
29
30         if (mul) c = MUL4_SYM(mul_col, c);
31         while (dst_len--)
32            *dst++ = c;
33         return;
34      }
35
36    if (src_len == dst_len)
37      {
38         if (mul)
39           {
40 #ifdef BUILD_MMX
41             pxor_r2r(mm0, mm0);
42             MOV_A2R(ALPHA_255, mm5)
43             MOV_P2R(mul_col, mm7, mm0)
44 #endif
45             while (dst_len--)
46               {
47 #ifdef BUILD_MMX
48                 MOV_P2R(*src, mm1, mm0)
49                 MUL4_SYM_R2R(mm7, mm1, mm5)
50                 MOV_R2P(mm1, *pdst, mm0)
51 #else
52                 *pdst = MUL4_SYM(mul_col, *src);
53 #endif
54                 src++;  pdst += step;
55               }
56             return;
57           }
58         while (dst_len--)
59           {
60             *pdst = *src;
61             src++;  pdst += step;
62           }
63         return;
64      }
65
66      {
67         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
68         DATA32  sxx = 0;
69         int     sx = sxx >> 16;
70
71 #ifdef BUILD_MMX
72         pxor_r2r(mm0, mm0);
73         MOV_A2R(ALPHA_255, mm5)
74         if (mul)
75           {
76             MOV_P2R(mul_col, mm7, mm0)
77           }
78 #endif
79         while (dst_len--)
80           {
81             DATA32   p2, p1 = 0;
82             int      a;
83
84             sx = (sxx >> 16);
85             if (sx < src_len)
86                 p1 = *(src + sx);
87             p2 = p1;
88             if ((sx + 1) < src_len)
89                 p2 = *(src + sx + 1);
90             a = 1 + ((sxx - (sx << 16)) >> 8);
91 #ifdef BUILD_MMX
92             MOV_A2R(a, mm3)
93             MOV_P2R(p1, mm1, mm0)
94             MOV_P2R(p2, mm2, mm0)
95             INTERP_256_R2R(mm3, mm2, mm1, mm5)
96             if (mul)
97               {
98                 MUL4_SYM_R2R(mm7, mm1, mm5)
99               }
100             MOV_R2P(mm1, *pdst, mm0)
101 #else
102             p1 = INTERP_256(a, p2, p1);
103             if (mul)
104                 p1 = MUL4_SYM(mul_col, p1);
105             *pdst = p1;
106 #endif
107             pdst += step;  sxx += dsxx;
108           }
109         return;
110      }
111 }
112
113 static void
114 evas_common_scale_rgba_a8_span_(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
115 {
116    int  mul = 0, step = 1;
117    DATA32 *pdst = dst;
118
119    if (!src || !mask || !dst) return;
120    if ((src_len < 1) || (dst_len < 1)) return;
121    if ((src_len > 65535) || (dst_len > 65535)) return;
122    if (mul_col != 0xffffffff)
123         mul = 1;
124    if (dir < 0)
125      {
126         pdst += dst_len - 1;
127         step = -1;
128      }
129
130    if ((src_len == 1) || (dst_len == 1))
131      {
132         DATA32 c = MUL_SYM(*mask, *src);
133
134         if (mul) c = MUL4_SYM(mul_col, c);
135         while (dst_len--)
136            *dst++ = c;
137         return;
138      }
139
140    if (src_len == dst_len)
141      {
142 #ifdef BUILD_MMX
143         pxor_r2r(mm0, mm0);
144         MOV_A2R(ALPHA_255, mm5)
145 #endif
146         if (mul)
147           {
148 #ifdef BUILD_MMX
149             MOV_P2R(mul_col, mm7, mm0)
150 #endif
151             while (dst_len--)
152               {
153 #ifdef BUILD_MMX
154                 MOV_P2R(*src, mm1, mm0)
155                 MOV_A2R(*mask, mm3)
156                 MUL4_SYM_R2R(mm3, mm1, mm5)
157                 MUL4_SYM_R2R(mm7, mm1, mm5)
158                 MOV_R2P(mm1, *pdst, mm0)
159 #else
160                 DATA32  c = MUL_SYM(*mask, *src);
161                 *pdst = MUL4_SYM(mul_col, c);
162 #endif
163                 src++;  mask++;  pdst += step;
164               }
165             return;
166           }
167         while (dst_len--)
168           {
169 #ifdef BUILD_MMX
170             MOV_P2R(*src, mm1, mm0)
171             MOV_A2R(*mask, mm3)
172             MUL4_SYM_R2R(mm3, mm1, mm5)
173             MOV_R2P(mm1, *pdst, mm0)
174 #else
175             *pdst = MUL_SYM(*mask, *src);
176 #endif
177             src++;  mask++;  pdst += step;
178           }
179         return;
180      }
181
182      {
183         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
184         DATA32  sxx = 0;
185         int     sx = sxx >> 16;
186
187 #ifdef BUILD_MMX
188         pxor_r2r(mm0, mm0);
189         MOV_A2R(ALPHA_255, mm5)
190         if (mul)
191           {
192             MOV_P2R(mul_col, mm7, mm0)
193           }
194 #endif
195         while (dst_len--)
196           {
197             DATA32   p2, p1 = 0;
198             int      a, a2, a1 = 0;
199
200             sx = (sxx >> 16);
201             if (sx < src_len)
202               {
203                 p1 = *(src + sx);
204                 a1 = *(mask + sx);
205               }
206             p2 = p1;  a2 = a1;
207             if ((sx + 1) < src_len)
208               {
209                 p2 = *(src + sx + 1);
210                 a2 = *(mask + sx + 1);
211               }
212             a = 1 + ((sxx - (sx << 16)) >> 8);
213 #ifdef BUILD_MMX
214             MOV_A2R(a, mm3)
215             MOV_P2R(p1, mm1, mm0)
216             MOV_P2R(p2, mm2, mm0)
217             INTERP_256_R2R(mm3, mm2, mm1, mm5)
218             a1 += 1 + ((a * (a2 - a1)) >> 8);
219             MOV_A2R(a1, mm3)
220             MUL4_256_R2R(mm3, mm1)
221             if (mul)
222               {
223                 MUL4_SYM_R2R(mm7, mm1, mm5)
224               }
225             MOV_R2P(mm1, *pdst, mm0)
226 #else
227             p1 = INTERP_256(a, p2, p1);
228             a1 += 1 + ((a * (a2 - a1)) >> 8);
229             p1 = MUL_256(a1, p1);
230             if (mul)
231                 p1 = MUL4_SYM(mul_col, p1);
232             *pdst = p1;
233 #endif
234             pdst += step;  sxx += dsxx;
235           }
236         return;
237      }
238 }
239
240 static void
241 evas_common_scale_a8_span_(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
242 {
243    int    step = 1;
244    DATA32 *pdst = dst;
245
246    if (!mask || !dst) return;
247    if ((src_len < 1) || (dst_len < 1)) return;
248    if ((src_len > 65535) || (dst_len > 65535)) return;
249    if (dir < 0)
250      {
251         pdst += dst_len - 1;
252         step = -1;
253      }
254
255    if ((src_len == 1) || (dst_len == 1))
256      {
257         DATA32 c = MUL_SYM(*mask, mul_col);
258
259         while (dst_len--)
260            *dst++ = c;
261         return;
262      }
263
264 #ifdef BUILD_MMX
265    pxor_r2r(mm0, mm0);
266    MOV_A2R(ALPHA_255, mm5)
267    MOV_P2R(mul_col, mm7, mm0)
268 #endif
269    if (src_len == dst_len)
270      {
271         while (dst_len--)
272           {
273 #ifdef BUILD_MMX
274             MOV_A2R(*mask, mm3)
275             MUL4_SYM_R2R(mm7, mm3, mm5)
276             MOV_R2P(mm3, *pdst, mm0)
277 #else
278             *pdst = MUL_SYM(*mask, mul_col);
279 #endif
280             mask++;  pdst += step;
281           }
282         return;
283      }
284
285      {
286         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
287         DATA32  sxx = 0;
288         int     sx = sxx >> 16;
289
290         while (dst_len--)
291           {
292             int   a, a2, a1 = 0;
293
294             sx = (sxx >> 16);
295             if (sx < src_len)
296                 a1 = *(mask + sx);
297             a2 = a1;
298             if ((sx + 1) < src_len)
299                 a2 = *(mask + sx + 1);
300             a = 1 + ((sxx - (sx << 16)) >> 8);
301             a1 += 1 + ((a * (a2 - a1)) >> 8);
302 #ifdef BUILD_MMX
303             MOV_A2R(a1, mm3)
304             MUL4_256_R2R(mm7, mm3)
305             MOV_R2P(mm3, *pdst, mm0)
306 #else
307             *pdst = MUL_256(a1, mul_col);
308 #endif
309             pdst += step;  sxx += dsxx;
310           }
311         return;
312      }
313 }
314
315 static void
316 evas_common_scale_clip_a8_span_(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
317 {
318    int   mul = 0, step = 1;
319    DATA32 *pdst = dst;
320
321    if (!mask || !dst) return;
322    if ((src_len < 1) || (dst_len < 1)) return;
323    if ((src_len > 65535) || (dst_len > 65535)) return;
324    if (mul_col != 0xffffffff)
325         mul = 1;
326    if (dir < 0)
327      {
328         pdst += dst_len - 1;
329         step = -1;
330      }
331
332 #ifdef BUILD_MMX
333    pxor_r2r(mm0, mm0);
334    MOV_A2R(ALPHA_255, mm5)
335    if (mul)
336      {
337         MOV_P2R(mul_col, mm7, mm0)
338      }
339 #endif
340    if ((src_len == 1) || (dst_len == 1))
341      {
342 #ifdef BUILD_MMX
343         MOV_A2R(*mask, mm3)
344 #else
345         DATA32 c = *mask;
346 #endif
347         if (mul)
348           {
349 #ifdef BUILD_MMX
350             MUL4_SYM_R2R(mm7, mm3, mm5)
351 #else
352             c = MUL_SYM(c, mul_col);
353 #endif
354             while (dst_len--)
355               {
356 #ifdef BUILD_MMX
357                 MOV_P2R(*dst, mm1, mm0)
358                 MUL4_SYM_R2R(mm3, mm1, mm5)
359                 MOV_R2P(mm1, *dst, mm0)
360 #else
361                 *dst = MUL4_SYM(c, *dst);
362 #endif
363                 dst++;
364               }
365             return;
366           }
367         while (dst_len--)
368           {
369 #ifdef BUILD_MMX
370             MOV_P2R(*dst, mm1, mm0)
371             MUL4_SYM_R2R(mm3, mm1, mm5)
372             MOV_R2P(mm1, *dst, mm0)
373 #else
374             *dst = MUL_SYM(c, *dst);
375 #endif
376             dst++;
377           }
378         return;
379      }
380
381    if (src_len == dst_len)
382      {
383         if (mul)
384           {
385             while (dst_len--)
386               {
387 #ifdef BUILD_MMX
388                 MOV_A2R(*mask, mm3)
389                 MUL4_SYM_R2R(mm7, mm3, mm5)
390                 MOV_P2R(*pdst, mm1, mm0)
391                 MUL4_SYM_R2R(mm3, mm1, mm5)
392                 MOV_R2P(mm1, *pdst, mm0)
393 #else
394                 DATA32 c = MUL_SYM(*mask, mul_col);
395
396                 *pdst = MUL4_SYM(c, *pdst);
397 #endif
398                 mask++;  pdst += step;
399               }
400             return;
401           }
402         while (dst_len--)
403           {
404 #ifdef BUILD_MMX
405             MOV_A2R(*mask, mm3)
406             MOV_P2R(*pdst, mm1, mm0)
407             MUL4_SYM_R2R(mm3, mm1, mm5)
408             MOV_R2P(mm1, *pdst, mm0)
409 #else
410             *pdst = MUL_SYM(*mask, *pdst);
411 #endif
412             mask++;  pdst += step;
413           }
414         return;
415      }
416
417      {
418         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
419         DATA32  sxx = 0;
420         int     sx = sxx >> 16;
421
422         while (dst_len--)
423           {
424             int   a, a2, a1 = 0;
425
426             sx = (sxx >> 16);
427             if (sx < src_len)
428                 a1 = *(mask + sx);
429             a2 = a1;
430             if ((sx + 1) < src_len)
431                 a2 = *(mask + sx + 1);
432             a = 1 + ((sxx - (sx << 16)) >> 8);
433             a1 += 1 + ((a * (a2 - a1)) >> 8);
434 #ifdef BUILD_MMX
435             MOV_A2R(a1, mm3)
436             MOV_P2R(*pdst, mm1, mm0)
437             MUL4_256_R2R(mm3, mm1)
438             if (mul)
439               {
440                 MUL4_SYM_R2R(mm7, mm1, mm5)
441               }
442             MOV_R2P(mm1, *pdst, mm0)
443 #else
444             *pdst = MUL_256(a1, *pdst);
445             if (mul)
446                 *pdst = MUL4_SYM(mul_col, *pdst);
447 #endif
448             pdst += step;  sxx += dsxx;
449           }
450         return;
451      }
452 }
453
454 EAPI void
455 evas_common_scale_rgba_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
456 {
457    evas_common_scale_rgba_span_(src, mask, src_len, mul_col, dst, dst_len, dir);
458    evas_common_cpu_end_opt();
459 }
460
461 EAPI void
462 evas_common_scale_rgba_a8_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
463 {
464    evas_common_scale_rgba_a8_span_(src, mask, src_len, mul_col, dst, dst_len, dir);
465    evas_common_cpu_end_opt();
466 }
467
468 EAPI void
469 evas_common_scale_a8_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
470 {
471    evas_common_scale_a8_span_(src, mask, src_len, mul_col, dst, dst_len, dir);
472    evas_common_cpu_end_opt();
473 }
474
475 EAPI void
476 evas_common_scale_clip_a8_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
477 {
478    evas_common_scale_clip_a8_span_(src, mask, src_len, mul_col, dst, dst_len, dir);
479    evas_common_cpu_end_opt();
480 }
481
482 EAPI void
483 evas_common_scale_hsva_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
484 {
485    int  mul = 0, step = 1;
486    DATA32 *pdst = dst;
487
488    if (!src || !dst) return;
489    if ((src_len < 1) || (dst_len < 1)) return;
490    if ((src_len > 65535) || (dst_len > 65535)) return;
491    if (mul_col != 0xffffffff)
492         mul = 1;
493    if (dir < 0)
494      {
495         pdst += dst_len - 1;
496         step = -1;
497      }
498
499    if ((src_len == 1) || (dst_len == 1))
500      {
501         DATA32 c = *src;
502
503         if (mul) c = MUL4_SYM(mul_col, c);
504         while (dst_len--)
505            *dst++ = c;
506         return;
507      }
508
509    if (src_len == dst_len)
510      {
511         if (mul)
512           {
513             while (dst_len--)
514               {
515                 *pdst = MUL4_SYM(mul_col, *src);
516                 src++;  pdst += step;
517               }
518             return;
519           }
520         while (dst_len--)
521           {
522             *pdst = *src;
523             src++;  pdst += step;
524           }
525         return;
526      }
527
528      {
529         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
530         DATA32  sxx = 0;
531         int     sx = sxx >> 16;
532
533         while (dst_len--)
534           {
535             DATA32   p2, p1 = 0;
536             int      a, h1, s1, v1, h2, s2, v2;
537
538             sx = (sxx >> 16);
539             if (sx < src_len)
540                 p1 = *(src + sx);
541             evas_common_convert_color_rgb_to_hsv_int((p1 >> 16) & 0xff, (p1 >> 8) & 0xff, p1 & 0xff,
542                                                      &h1, &s1, &v1);
543             p2 = p1;
544             if ((sx + 1) < src_len)
545                 p2 = *(src + sx + 1);
546             evas_common_convert_color_rgb_to_hsv_int((p2 >> 16) & 0xff, (p2 >> 8) & 0xff, p2 & 0xff,
547                                                      &h2, &s2, &v2);
548             a = 1 + ((sxx - (sx << 16)) >> 8);
549             h1 += (a * (h2 - h1)) >> 8;
550             s1 += (a * (s2 - s1)) >> 8;
551             v1 += (a * (v2 - v1)) >> 8;
552             a = (((((p2 >> 8) & 0xff0000) - ((p1 >> 8) & 0xff0000)) * a) +
553                  (p1 & 0xff000000)) & 0xff000000;
554             evas_common_convert_color_hsv_to_rgb_int(h1, s1, v1, &h2, &s2, &v2);
555             p1 = a + RGB_JOIN(h2,s2,v2);
556             if (mul)
557                 p1 = MUL4_SYM(mul_col, p1);
558             *pdst = p1;
559             pdst += step;  sxx += dsxx;
560           }
561         return;
562      }
563 }
564
565 EAPI void
566 evas_common_scale_hsva_a8_span(DATA32 *src, DATA8 *mask, int src_len, DATA32 mul_col, DATA32 *dst, int dst_len, int dir)
567 {
568    int  mul = 0, step = 1;
569    DATA32 *pdst = dst;
570
571    if (!src || !mask || !dst) return;
572    if ((src_len < 1) || (dst_len < 1)) return;
573    if ((src_len > 65535) || (dst_len > 65535)) return;
574    if (mul_col != 0xffffffff)
575         mul = 1;
576    if (dir < 0)
577      {
578         pdst += dst_len - 1;
579         step = -1;
580      }
581
582    if ((src_len == 1) || (dst_len == 1))
583      {
584         DATA32 c = MUL_SYM(*mask, *src);
585
586         if (mul) c = MUL4_SYM(mul_col, c);
587         while (dst_len--)
588            *dst++ = c;
589         return;
590      }
591
592    if (src_len == dst_len)
593      {
594         if (mul)
595           {
596             while (dst_len--)
597               {
598                 DATA32  c = MUL_SYM(*mask, *src);
599                 *pdst = MUL4_SYM(mul_col, c);
600                 src++;  mask++;  pdst += step;
601               }
602             return;
603           }
604         while (dst_len--)
605           {
606             *pdst = MUL_SYM(*mask, *src);
607             src++;  mask++;  pdst += step;
608           }
609         return;
610      }
611
612      {
613         DATA32  dsxx = (((src_len - 1) << 16) / (dst_len - 1));
614         DATA32  sxx = 0;
615         int     sx = sxx >> 16;
616
617         while (dst_len--)
618           {
619             DATA32   p2, p1 = 0;
620             int      a, a2, a1 = 0;
621             int      h1, s1, v1, h2, s2, v2;
622
623             sx = (sxx >> 16);
624             if (sx < src_len)
625               {
626                 p1 = *(src + sx);
627                 a1 = *(mask + sx);
628               }
629             p2 = p1;  a2 = a1;
630             if ((sx + 1) < src_len)
631               {
632                 p2 = *(src + sx + 1);
633                 a2 = *(mask + sx + 1);
634               }
635             evas_common_convert_color_rgb_to_hsv_int((p1 >> 16) & 0xff, (p1 >> 8) & 0xff, p1 & 0xff,
636                                                       &h1, &s1, &v1);
637             evas_common_convert_color_rgb_to_hsv_int((p2 >> 16) & 0xff, (p2 >> 8) & 0xff, p2 & 0xff,
638                                                       &h2, &s2, &v2);
639             a = 1 + ((sxx - (sx << 16)) >> 8);
640             a1 += (a * (a2 - a1)) >> 8;
641             h1 += (a * (h2 - h1)) >> 8;
642             s1 += (a * (s2 - s1)) >> 8;
643             v1 += (a * (v2 - v1)) >> 8;
644             a = (((((p2 >> 8) & 0xff0000) - ((p1 >> 8) & 0xff0000)) * a) +
645                  (p1 & 0xff000000)) & 0xff000000;
646
647             evas_common_convert_color_hsv_to_rgb_int(h1, s1, v1, &h2, &s2, &v2);
648             p1 = a + RGB_JOIN(h2,s2,v2);
649             p1 = MUL_SYM(a1, p1);
650             if (mul)
651                 p1 = MUL4_SYM(mul_col, p1);
652             *pdst = p1;
653             pdst += step;  sxx += dsxx;
654           }
655         return;
656      }
657 }