2 * SDL_zoom_template - surface scaling
4 * Copyright (c) 2009 Citrix Systems, Inc.
6 * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
7 * Modifications by Stefano Stabellini.
9 * This work is licensed under the terms of the GNU GPL version 2.
10 * See the COPYING file in the top-level directory.
15 #define SDL_TYPE Uint16
17 #define SDL_TYPE Uint32
19 #error unsupport depth
23 * Simple helper functions to make the code looks nicer
25 * Assume spf = source SDL_PixelFormat
26 * dpf = dest SDL_PixelFormat
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)
34 #define setRed(r, pcolor) do { \
35 *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
36 (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
39 #define setGreen(g, pcolor) do { \
40 *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
41 (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
44 #define setBlue(b, pcolor) do { \
45 *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
46 (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
49 #define setAlpha(a, pcolor) do { \
50 *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
51 (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
54 static void glue(sdl_zoom_rgb
, BPP
)(SDL_Surface
*src
, SDL_Surface
*dst
, int smooth
,
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
;
60 SDL_PixelFormat
*spf
= src
->format
;
61 SDL_PixelFormat
*dpf
= dst
->format
;
64 /* For interpolation: assume source dimension is one pixel.
65 * Smaller here to avoid overflow on right and bottom edge.
67 sx
= (int) (65536.0 * (float) (src
->w
- 1) / (float) dst
->w
);
68 sy
= (int) (65536.0 * (float) (src
->h
- 1) / (float) dst
->h
);
70 sx
= (int) (65536.0 * (float) src
->w
/ (float) dst
->w
);
71 sy
= (int) (65536.0 * (float) src
->h
/ (float) dst
->h
);
74 sax
= g_new(int, dst
->w
+ 1);
75 say
= g_new(int, dst
->h
+ 1);
77 sp
= csp
= (SDL_TYPE
*) src
->pixels
;
78 dp
= (SDL_TYPE
*) (dst
->pixels
+ dst_rect
->y
* dst
->pitch
+
79 dst_rect
->x
* dst
->format
->BytesPerPixel
);
83 for (x
= 0; x
<= dst
->w
; x
++) {
91 for (y
= 0; y
<= dst
->h
; y
++) {
98 d_gap
= dst
->pitch
- dst_rect
->w
* dst
->format
->BytesPerPixel
;
102 for (y
= 0; y
< dst_rect
->y
; y
++) {
104 sstep
= (*csay
>> 16) * src
->pitch
;
105 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
108 /* Calculate sstep_jump */
111 for (x
= 0; x
< dst_rect
->x
; x
++) {
113 sstep
= (*csax
>> 16);
117 for (y
= 0; y
< dst_rect
->h
; y
++) {
118 /* Setup colour source pointers */
119 c00
= csp
+ sstep_jump
;
121 c10
= (SDL_TYPE
*) ((Uint8
*) csp
+ src
->pitch
) + sstep_jump
;
123 csax
= sax
+ dst_rect
->x
;
125 for (x
= 0; x
< dst_rect
->w
; x
++) {
127 /* Interpolate colours */
128 ex
= (*csax
& 0xffff);
129 ey
= (*csay
& 0xffff);
130 t1
= ((((getRed(*c01
) - getRed(*c00
)) * ex
) >> 16) +
131 getRed(*c00
)) & (dpf
->Rmask
>> dpf
->Rshift
);
132 t2
= ((((getRed(*c11
) - getRed(*c10
)) * ex
) >> 16) +
133 getRed(*c10
)) & (dpf
->Rmask
>> dpf
->Rshift
);
134 setRed((((t2
- t1
) * ey
) >> 16) + t1
, dp
);
135 t1
= ((((getGreen(*c01
) - getGreen(*c00
)) * ex
) >> 16) +
136 getGreen(*c00
)) & (dpf
->Gmask
>> dpf
->Gshift
);
137 t2
= ((((getGreen(*c11
) - getGreen(*c10
)) * ex
) >> 16) +
138 getGreen(*c10
)) & (dpf
->Gmask
>> dpf
->Gshift
);
139 setGreen((((t2
- t1
) * ey
) >> 16) + t1
, dp
);
140 t1
= ((((getBlue(*c01
) - getBlue(*c00
)) * ex
) >> 16) +
141 getBlue(*c00
)) & (dpf
->Bmask
>> dpf
->Bshift
);
142 t2
= ((((getBlue(*c11
) - getBlue(*c10
)) * ex
) >> 16) +
143 getBlue(*c10
)) & (dpf
->Bmask
>> dpf
->Bshift
);
144 setBlue((((t2
- t1
) * ey
) >> 16) + t1
, dp
);
145 t1
= ((((getAlpha(*c01
) - getAlpha(*c00
)) * ex
) >> 16) +
146 getAlpha(*c00
)) & (dpf
->Amask
>> dpf
->Ashift
);
147 t2
= ((((getAlpha(*c11
) - getAlpha(*c10
)) * ex
) >> 16) +
148 getAlpha(*c10
)) & (dpf
->Amask
>> dpf
->Ashift
);
149 setAlpha((((t2
- t1
) * ey
) >> 16) + t1
, dp
);
151 /* Advance source pointers */
153 sstep
= (*csax
>> 16);
158 /* Advance destination pointer */
161 /* Advance source pointer */
163 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ (*csay
>> 16) * src
->pitch
);
164 /* Advance destination pointers */
165 dp
= (SDL_TYPE
*) ((Uint8
*) dp
+ d_gap
);
172 for (y
= 0; y
< dst_rect
->y
; y
++) {
174 sstep
= (*csay
>> 16) * src
->pitch
;
175 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
178 /* Calculate sstep_jump */
181 for (x
= 0; x
< dst_rect
->x
; x
++) {
183 sstep
= (*csax
>> 16);
187 for (y
= 0 ; y
< dst_rect
->h
; y
++) {
188 sp
= csp
+ sstep_jump
;
189 csax
= sax
+ dst_rect
->x
;
191 for (x
= 0; x
< dst_rect
->w
; x
++) {
196 /* Advance source pointers */
198 sstep
= (*csax
>> 16);
201 /* Advance destination pointer */
204 /* Advance source pointers */
206 sstep
= (*csay
>> 16) * src
->pitch
;
207 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
209 /* Advance destination pointer */
210 dp
= (SDL_TYPE
*) ((Uint8
*) dp
+ d_gap
);