]> git.proxmox.com Git - qemu.git/blame - sdl_zoom_template.h
finish VPATH -> vpath translation
[qemu.git] / sdl_zoom_template.h
CommitLineData
c18a2c36
SS
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
54static 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