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 int 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 if ((sax
= (int *) malloc((dst
->w
+ 1) * sizeof(Uint32
))) == NULL
) {
77 if ((say
= (int *) malloc((dst
->h
+ 1) * sizeof(Uint32
))) == NULL
) {
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
);
88 for (x
= 0; x
<= dst
->w
; x
++) {
96 for (y
= 0; y
<= dst
->h
; y
++) {
103 d_gap
= dst
->pitch
- dst_rect
->w
* dst
->format
->BytesPerPixel
;
107 for (y
= 0; y
< dst_rect
->y
; y
++) {
109 sstep
= (*csay
>> 16) * src
->pitch
;
110 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
113 /* Calculate sstep_jump */
116 for (x
= 0; x
< dst_rect
->x
; x
++) {
118 sstep
= (*csax
>> 16);
122 for (y
= 0; y
< dst_rect
->h
; y
++) {
123 /* Setup colour source pointers */
124 c00
= csp
+ sstep_jump
;
126 c10
= (SDL_TYPE
*) ((Uint8
*) csp
+ src
->pitch
) + sstep_jump
;
128 csax
= sax
+ dst_rect
->x
;
130 for (x
= 0; x
< dst_rect
->w
; x
++) {
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
);
156 /* Advance source pointers */
158 sstep
= (*csax
>> 16);
163 /* Advance destination pointer */
166 /* Advance source pointer */
168 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ (*csay
>> 16) * src
->pitch
);
169 /* Advance destination pointers */
170 dp
= (SDL_TYPE
*) ((Uint8
*) dp
+ d_gap
);
177 for (y
= 0; y
< dst_rect
->y
; y
++) {
179 sstep
= (*csay
>> 16) * src
->pitch
;
180 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
183 /* Calculate sstep_jump */
186 for (x
= 0; x
< dst_rect
->x
; x
++) {
188 sstep
= (*csax
>> 16);
192 for (y
= 0 ; y
< dst_rect
->h
; y
++) {
193 sp
= csp
+ sstep_jump
;
194 csax
= sax
+ dst_rect
->x
;
196 for (x
= 0; x
< dst_rect
->w
; x
++) {
201 /* Advance source pointers */
203 sstep
= (*csax
>> 16);
206 /* Advance destination pointer */
209 /* Advance source pointers */
211 sstep
= (*csay
>> 16) * src
->pitch
;
212 csp
= (SDL_TYPE
*) ((Uint8
*) csp
+ sstep
);
214 /* Advance destination pointer */
215 dp
= (SDL_TYPE
*) ((Uint8
*) dp
+ d_gap
);