move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common / evas_scale_smooth_scaler_up.c
1 {
2    int         srx = src_region_x, sry = src_region_y;
3    int         srw = src_region_w, srh = src_region_h;
4    int         drx = dst_region_x, dry = dst_region_y;
5    int         drw = dst_region_w, drh = dst_region_h;
6
7    int         dsxx, dsyy, sxx, syy, sx, sy;
8    int         cx, cy;
9    int         direct_scale = 0, buf_step = 0;
10
11    DATA32      *psrc, *pdst, *pdst_end;
12    DATA32      *buf, *pbuf, *pbuf_end;
13    RGBA_Gfx_Func  func;
14
15    /* a scanline buffer */
16    pdst = dst_ptr;  // it's been set at (dst_clip_x, dst_clip_y)
17    pdst_end = pdst + (dst_clip_h * dst_w);
18    if (!dc->mul.use)
19      {
20         if ((dc->render_op == _EVAS_RENDER_BLEND) && !src->cache_entry.flags.alpha)
21           { direct_scale = 1;  buf_step = dst->cache_entry.w; }
22         else if (dc->render_op == _EVAS_RENDER_COPY)
23           {
24             direct_scale = 1;  buf_step = dst->cache_entry.w;
25             if (src->cache_entry.flags.alpha)
26                 dst->cache_entry.flags.alpha = 1;
27           }
28      }
29    if (!direct_scale)
30      {
31         buf = alloca(dst_clip_w * sizeof(DATA32));
32         if (dc->mul.use)
33            func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
34         else
35            func  = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
36      }
37    else
38         buf = pdst;
39
40    if ((srw > 1) && (drw > 1))
41         dsxx = ((srw - 1) << 16) / (drw - 1);
42    else
43         dsxx = (srw << 16) / drw;
44    if ((srh > 1) && (drh > 1))
45         dsyy = ((srh - 1) << 16) / (drh - 1);
46    else
47         dsyy = (srh << 16) / drh;
48
49    cx = dst_clip_x - drx;
50    cy = dst_clip_y - dry;
51
52    sxx = (dsxx * cx);
53    syy = (dsyy * cy);
54
55    sx = sxx >> 16;
56    sy = syy >> 16;
57
58    if (drh == srh)
59      {
60         int  sxx0 = sxx;
61 #ifdef EVAS_SLI
62         int ysli = dst_clip_y;
63 #endif
64         psrc = src->image.data + (src_w * (sry + cy)) + srx;
65         while (pdst < pdst_end)
66           {
67 #ifdef EVAS_SLI
68              if (((ysli) % dc->sli.h) == dc->sli.y)
69 #endif
70                {
71                   pbuf = buf;  pbuf_end = buf + dst_clip_w;
72                   sxx = sxx0;
73 #ifdef SCALE_USING_MMX
74                   pxor_r2r(mm0, mm0);
75                   MOV_A2R(ALPHA_255, mm5)
76 #endif
77                     while (pbuf < pbuf_end)
78                       {
79                          DATA32   p0, p1;
80                          int      ax;
81
82                          sx = (sxx >> 16);
83                          ax = 1 + ((sxx - (sx << 16)) >> 8);
84                          p0 = p1 = *(psrc + sx);
85                          if ((sx + 1) < srw)
86                            p1 = *(psrc + sx + 1);
87 #ifdef SCALE_USING_MMX
88                          MOV_P2R(p0, mm1, mm0)
89                            if (p0 | p1)
90                              {
91                                 MOV_A2R(ax, mm3)
92                                   MOV_P2R(p1, mm2, mm0)
93                                     INTERP_256_R2R(mm3, mm2, mm1, mm5)
94                              }
95                          MOV_R2P(mm1, *pbuf, mm0)
96                            pbuf++;
97 #else
98                          if (p0 | p1)
99                            p0 = INTERP_256(ax, p1, p0);
100                          *pbuf++ = p0;
101 #endif
102                          sxx += dsxx;
103                       }
104                   /* * blend here [clip_w *] buf -> dptr * */
105                   if (!direct_scale)
106                     func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
107                }
108 #ifdef EVAS_SLI
109              ysli++;
110 #endif
111              pdst += dst_w;
112              psrc += src_w;
113              buf += buf_step;
114           }
115
116         goto done_scale_up;
117      }
118    else if (drw == srw)
119      {
120         DATA32  *ps = src->image.data + (src_w * sry) + srx + cx;
121 #ifdef EVAS_SLI
122         int ysli = dst_clip_y;
123 #endif
124
125         while (pdst < pdst_end)
126           {
127 #ifdef EVAS_SLI
128              if (((ysli) % dc->sli.h) == dc->sli.y)
129 #endif
130                {
131                   int        ay;
132
133                   sy = syy >> 16;
134                   psrc = ps + (sy * src_w);
135                   ay = 1 + ((syy - (sy << 16)) >> 8);
136 #ifdef SCALE_USING_MMX
137                   pxor_r2r(mm0, mm0);
138                   MOV_A2R(ALPHA_255, mm5)
139                     MOV_A2R(ay, mm4)
140 #endif
141                       pbuf = buf;  pbuf_end = buf + dst_clip_w;
142                   while (pbuf < pbuf_end)
143                     {
144                        DATA32  p0 = *psrc, p2 = p0;
145
146                        if ((sy + 1) < srh)
147                          p2 = *(psrc + src_w);
148 #ifdef SCALE_USING_MMX
149                        MOV_P2R(p0, mm1, mm0)
150                          if (p0 | p2)
151                            {
152                               MOV_P2R(p2, mm2, mm0)
153                                 INTERP_256_R2R(mm4, mm2, mm1, mm5)
154                            }
155                        MOV_R2P(mm1, *pbuf, mm0)
156                          pbuf++;
157 #else
158                        if (p0 | p2)
159                          p0 = INTERP_256(ay, p2, p0);
160                        *pbuf++ = p0;
161 #endif
162                        psrc++;
163                     }
164                   /* * blend here [clip_w *] buf -> dptr * */
165                   if (!direct_scale)
166                     func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
167                }
168 #ifdef EVAS_SLI
169              ysli++;
170 #endif
171             pdst += dst_w;
172             syy += dsyy;
173             buf += buf_step;
174           }
175         goto done_scale_up;
176      }
177
178      {
179         DATA32  *ps = src->image.data + (src_w * sry) + srx;
180         int     sxx0 = sxx;
181 #ifdef EVAS_SLI
182         int ysli = dst_clip_y;
183 #endif
184
185         while (pdst < pdst_end)
186           {
187 #ifdef EVAS_SLI
188              if (((ysli) % dc->sli.h) == dc->sli.y)
189 #endif
190                {
191                   int   ay;
192
193                   sy = syy >> 16;
194                   psrc = ps + (sy * src_w);
195                   ay = 1 + ((syy - (sy << 16)) >> 8);
196 #ifdef SCALE_USING_MMX
197                   MOV_A2R(ay, mm4)
198                     pxor_r2r(mm0, mm0);
199                   MOV_A2R(ALPHA_255, mm5)
200 #endif
201                     pbuf = buf;  pbuf_end = buf + dst_clip_w;
202                   sxx = sxx0;
203                   while (pbuf < pbuf_end)
204                     {
205                        int     ax;
206                        DATA32  *p, *q;
207                        DATA32  p0, p1, p2, p3;
208
209                        sx = sxx >> 16;
210                        ax = 1 + ((sxx - (sx << 16)) >> 8);
211                        p = psrc + sx;  q = p + src_w;
212                        p0 = p1 = p2 = p3 = *p;
213                        if ((sx + 1) < srw)
214                          p1 = *(p + 1);
215                        if ((sy + 1) < srh)
216                          {
217                             p2 = *q;  p3 = p2;
218                             if ((sx + 1) < srw)
219                               p3 = *(q + 1);
220                          }
221 #ifdef SCALE_USING_MMX
222                        MOV_A2R(ax, mm6)
223                          MOV_P2R(p0, mm1, mm0)
224                            if (p0 | p1)
225                              {
226                                 MOV_P2R(p1, mm2, mm0)
227                                   INTERP_256_R2R(mm6, mm2, mm1, mm5)
228                              }
229                        MOV_P2R(p2, mm2, mm0)
230                          if (p2 | p3)
231                            {
232                               MOV_P2R(p3, mm3, mm0)
233                                 INTERP_256_R2R(mm6, mm3, mm2, mm5)
234                            }
235                        INTERP_256_R2R(mm4, mm2, mm1, mm5)
236                          MOV_R2P(mm1, *pbuf, mm0)
237                            pbuf++;
238 #else
239                        if (p0 | p1)
240                          p0 = INTERP_256(ax, p1, p0);
241                        if (p2 | p3)
242                          p2 = INTERP_256(ax, p3, p2);
243                        if (p0 | p2)
244                          p0 = INTERP_256(ay, p2, p0);
245                        *pbuf++ = p0;
246 #endif
247                        sxx += dsxx;
248                     }
249                   /* * blend here [clip_w *] buf -> dptr * */
250                   if (!direct_scale)
251                     func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
252                }
253 #ifdef EVAS_SLI
254              ysli++;
255 #endif
256              pdst += dst_w;
257              syy += dsyy;
258              buf += buf_step;
259           }
260      }
261    done_scale_up:
262    return;
263 }