linux-user: fix ppc target_stat64 st_blocks layout
[qemu] / sdl_zoom_template.h
1 /*
2  * SDL_zoom_template - surface scaling
3  * 
4  * Copyright (c) 2009 Citrix Systems, Inc.
5  *
6  * Derived from: SDL_rotozoom,  LGPL (c) A. Schiffler from the SDL_gfx library.
7  * Modifications by Stefano Stabellini.
8  *
9  * This work is licensed under the terms of the GNU GPL version 2.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13
14 #if BPP == 16
15 #define SDL_TYPE Uint16
16 #elif BPP == 32
17 #define SDL_TYPE Uint32
18 #else
19 #error unsupport depth
20 #endif
21
22 /*  
23  *  Simple helper functions to make the code looks nicer
24  *
25  *  Assume spf = source SDL_PixelFormat
26  *         dpf = dest SDL_PixelFormat
27  *
28  */
29 #define getRed(color)   (((color) & spf->Rmask) >> spf->Rshift)
30 #define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
31 #define getBlue(color)  (((color) & spf->Bmask) >> spf->Bshift)
32 #define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)
33
34 #define setRed(r, pcolor) do { \
35     *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
36               (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
37 } while (0);
38
39 #define setGreen(g, pcolor) do { \
40     *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
41               (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
42 } while (0);
43
44 #define setBlue(b, pcolor) do { \
45     *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
46               (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
47 } while (0);
48
49 #define setAlpha(a, pcolor) do { \
50     *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
51               (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
52 } while (0);
53
54 static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
55                                    SDL_Rect *dst_rect)
56 {
57     int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
58     SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp;
59     int d_gap;
60     SDL_PixelFormat *spf = src->format;
61     SDL_PixelFormat *dpf = dst->format;
62
63     if (smooth) { 
64         /* For interpolation: assume source dimension is one pixel.
65          * Smaller here to avoid overflow on right and bottom edge.
66          */
67         sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
68         sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
69     } else {
70         sx = (int) (65536.0 * (float) src->w / (float) dst->w);
71         sy = (int) (65536.0 * (float) src->h / (float) dst->h);
72     }
73
74     if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
75         return (-1);
76     }
77     if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
78         free(sax);
79         return (-1);
80     }
81
82     sp = csp = (SDL_TYPE *) src->pixels;
83     dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
84                        dst_rect->x * dst->format->BytesPerPixel);
85
86     csx = 0;
87     csax = sax;
88     for (x = 0; x <= dst->w; x++) {
89         *csax = csx;
90         csax++;
91         csx &= 0xffff;
92         csx += sx;
93     }
94     csy = 0;
95     csay = say;
96     for (y = 0; y <= dst->h; y++) {
97         *csay = csy;
98         csay++;
99         csy &= 0xffff;
100         csy += sy;
101     }
102
103     d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;
104
105     if (smooth) {
106         csay = say;
107         for (y = 0; y < dst_rect->y; y++) {
108             csay++;
109             sstep = (*csay >> 16) * src->pitch;
110             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
111         }
112
113         /* Calculate sstep_jump */
114         csax = sax; 
115         sstep_jump = 0;
116         for (x = 0; x < dst_rect->x; x++) {
117             csax++; 
118             sstep = (*csax >> 16);
119             sstep_jump += sstep;
120         }
121
122         for (y = 0; y < dst_rect->h ; y++) {
123             /* Setup colour source pointers */
124             c00 = csp + sstep_jump;
125             c01 = c00 + 1;
126             c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
127             c11 = c10 + 1;
128             csax = sax + dst_rect->x; 
129
130             for (x = 0; x < dst_rect->w; x++) {
131
132                 /* Interpolate colours */
133                 ex = (*csax & 0xffff);
134                 ey = (*csay & 0xffff);
135                 t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
136                      getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
137                 t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
138                      getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
139                 setRed((((t2 - t1) * ey) >> 16) + t1, dp);
140                 t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
141                      getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
142                 t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
143                      getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
144                 setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
145                 t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
146                      getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
147                 t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
148                      getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
149                 setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
150                 t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
151                      getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
152                 t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
153                      getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
154                 setAlpha((((t2 - t1) * ey) >> 16) + t1, dp); 
155
156                 /* Advance source pointers */
157                 csax++; 
158                 sstep = (*csax >> 16);
159                 c00 += sstep;
160                 c01 += sstep;
161                 c10 += sstep;
162                 c11 += sstep;
163                 /* Advance destination pointer */
164                 dp++;
165             }
166             /* Advance source pointer */
167             csay++;
168             csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
169             /* Advance destination pointers */
170             dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
171         }
172
173
174     } else {
175         csay = say;
176
177         for (y = 0; y < dst_rect->y; y++) {
178             csay++;
179             sstep = (*csay >> 16) * src->pitch;
180             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
181         }
182
183         /* Calculate sstep_jump */
184         csax = sax; 
185         sstep_jump = 0;
186         for (x = 0; x < dst_rect->x; x++) {
187             csax++; 
188             sstep = (*csax >> 16);
189             sstep_jump += sstep;
190         }
191
192         for (y = 0 ; y < dst_rect->h ; y++) {
193             sp = csp + sstep_jump;
194             csax = sax + dst_rect->x;
195
196             for (x = 0; x < dst_rect->w; x++) {
197
198                 /* Draw */
199                 *dp = *sp;
200
201                 /* Advance source pointers */
202                 csax++;
203                 sstep = (*csax >> 16);
204                 sp += sstep;
205
206                 /* Advance destination pointer */
207                 dp++;
208             }
209             /* Advance source pointers */
210             csay++;
211             sstep = (*csay >> 16) * src->pitch;
212             csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
213
214             /* Advance destination pointer */
215             dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
216         }
217     }
218
219     free(sax);
220     free(say);
221     return (0);
222 }
223
224 #undef SDL_TYPE
225