3 #include <SDL/SDL_image.h>
6 typedef struct tColorRGBA
{
14 #define ZOOM_VALUE_LIMIT 0.0001
16 SDL_Surface
*zoomSurface(SDL_Surface
* src
, double zoomx
, double zoomy
)
20 int dstwidth
, dstheight
;
32 * Determine if source surface is 32bit or 8bit
34 is32bit
= (src
->format
->BitsPerPixel
== 32);
35 if ((is32bit
) || (src
->format
->BitsPerPixel
== 8)) {
37 * Use source surface 'as is'
43 * New source surface is 32bit with a defined RGBA ordering
46 SDL_CreateRGBSurface(SDL_SWSURFACE
, src
->w
, src
->h
, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
47 SDL_BlitSurface(src
, NULL
, rz_src
, NULL
);
53 if (flipx
) zoomx
= -zoomx
;
55 if (flipy
) zoomy
= -zoomy
;
57 /* Get size if target */
59 * Sanity check zoom factors
61 if (zoomx
< ZOOM_VALUE_LIMIT
) {
62 zoomx
= ZOOM_VALUE_LIMIT
;
64 if (zoomy
< ZOOM_VALUE_LIMIT
) {
65 zoomy
= ZOOM_VALUE_LIMIT
;
69 * Calculate target size
71 dstwidth
= (int) ((double) rz_src
->w
* zoomx
);
72 dstheight
= (int) ((double) rz_src
->h
* zoomy
);
83 * Alloc space to completely contain the zoomed surface
88 * Target surface is 32bit with source RGBA/ABGR ordering
91 SDL_CreateRGBSurface(SDL_SWSURFACE
, dstwidth
, dstheight
, 32,
92 rz_src
->format
->Rmask
, rz_src
->format
->Gmask
,
93 rz_src
->format
->Bmask
, rz_src
->format
->Amask
);
96 * Target surface is 8bit
98 rz_dst
= SDL_CreateRGBSurface(SDL_SWSURFACE
, dstwidth
, dstheight
, 8, 0, 0, 0, 0);
102 * Lock source surface
104 SDL_LockSurface(rz_src
);
106 * Check which kind of surface we have
110 * Call the 32bit transformation routine to do the zooming (using alpha)
112 // zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy);
114 int x
, y
, sx
, sy
, *sax
, *say
, *csax
, *csay
, csx
, csy
, ex
, ey
, t1
, t2
, sstep
;
115 tColorRGBA
*c00
, *c01
, *c10
, *c11
;
116 tColorRGBA
*sp
, *csp
, *dp
;
120 * For interpolation: assume source dimension is one pixel
123 * smaller to avoid overflow on right and bottom edge.
125 sx
= (int) (65536.0 * (float) (src
->w
- 1) / (float) rz_dst
->w
);
126 sy
= (int) (65536.0 * (float) (src
->h
- 1) / (float) rz_dst
->h
);
130 * Allocate memory for row increments
132 if ((sax
= (int *) malloc((rz_dst
->w
+ 1) * sizeof(Uint32
))) == NULL
) {
135 if ((say
= (int *) malloc((rz_dst
->h
+ 1) * sizeof(Uint32
))) == NULL
) {
141 * Precalculate row increments
143 sp
= csp
= (tColorRGBA
*) rz_src
->pixels
;
144 dp
= (tColorRGBA
*) rz_dst
->pixels
;
146 if (flipx
) csp
+= (rz_src
->w
-1);
147 if (flipy
) csp
= (tColorRGBA
*)( (Uint8
*)csp
+ rz_src
->pitch
*(src
->h
-1) );
151 for (x
= 0; x
<= rz_dst
->w
; x
++) {
159 for (y
= 0; y
<= rz_dst
->h
; y
++) {
166 dgap
= rz_dst
->pitch
- rz_dst
->w
* 4;
176 for (y
= 0; y
< rz_dst
->h
; y
++) {
178 * Setup color source pointers
183 c10
= (tColorRGBA
*) ((Uint8
*) csp
+ rz_src
->pitch
);
187 for (x
= 0; x
< rz_dst
->w
; x
++) {
192 ex
= (*csax
& 0xffff);
193 ey
= (*csay
& 0xffff);
194 t1
= ((((c01
->r
- c00
->r
) * ex
) >> 16) + c00
->r
) & 0xff;
195 t2
= ((((c11
->r
- c10
->r
) * ex
) >> 16) + c10
->r
) & 0xff;
196 dp
->r
= (((t2
- t1
) * ey
) >> 16) + t1
;
197 t1
= ((((c01
->g
- c00
->g
) * ex
) >> 16) + c00
->g
) & 0xff;
198 t2
= ((((c11
->g
- c10
->g
) * ex
) >> 16) + c10
->g
) & 0xff;
199 dp
->g
= (((t2
- t1
) * ey
) >> 16) + t1
;
200 t1
= ((((c01
->b
- c00
->b
) * ex
) >> 16) + c00
->b
) & 0xff;
201 t2
= ((((c11
->b
- c10
->b
) * ex
) >> 16) + c10
->b
) & 0xff;
202 dp
->b
= (((t2
- t1
) * ey
) >> 16) + t1
;
203 t1
= ((((c01
->a
- c00
->a
) * ex
) >> 16) + c00
->a
) & 0xff;
204 t2
= ((((c11
->a
- c10
->a
) * ex
) >> 16) + c10
->a
) & 0xff;
205 dp
->a
= (((t2
- t1
) * ey
) >> 16) + t1
;
208 * Advance source pointers
211 sstep
= (*csax
>> 16);
217 * Advance destination pointer
222 * Advance source pointer
225 csp
= (tColorRGBA
*) ((Uint8
*) csp
+ (*csay
>> 16) * rz_src
->pitch
);
227 * Advance destination pointers
229 dp
= (tColorRGBA
*) ((Uint8
*) dp
+ dgap
);
243 * Turn on source-alpha support
245 SDL_SetAlpha(rz_dst
, SDL_SRCALPHA
, 255);
248 * Copy palette and colorkey info
250 for (i
= 0; i
< rz_src
->format
->palette
->ncolors
; i
++) {
251 rz_dst
->format
->palette
->colors
[i
] = rz_src
->format
->palette
->colors
[i
];
253 rz_dst
->format
->palette
->ncolors
= rz_src
->format
->palette
->ncolors
;
255 * Call the 8bit transformation routine to do the zooming
257 Uint32 x
, y
, sx
, sy
, *sax
, *say
, *csax
, *csay
, csx
, csy
;
258 Uint8
*sp
, *dp
, *csp
;
264 sx
= (Uint32
) (65536.0 * (float) rz_src
->w
/ (float) rz_dst
->w
);
265 sy
= (Uint32
) (65536.0 * (float) rz_src
->h
/ (float) rz_dst
->h
);
268 * Allocate memory for row increments
270 if ((sax
= (Uint32
*) malloc(rz_dst
->w
* sizeof(Uint32
))) == NULL
) {
273 if ((say
= (Uint32
*) malloc(rz_dst
->h
* sizeof(Uint32
))) == NULL
) {
281 * Precalculate row increments
285 for (x
= 0; x
< rz_dst
->w
; x
++) {
293 for (y
= 0; y
< rz_dst
->h
; y
++) {
302 for (x
= 0; x
< rz_dst
->w
; x
++) {
308 for (y
= 0; y
< rz_dst
->h
; y
++) {
316 sp
= csp
= (Uint8
*) rz_src
->pixels
;
317 dp
= (Uint8
*) rz_dst
->pixels
;
318 dgap
= rz_dst
->pitch
- rz_dst
->w
;
324 for (y
= 0; y
< rz_dst
->h
; y
++) {
327 for (x
= 0; x
< rz_dst
->w
; x
++) {
333 * Advance source pointers
338 * Advance destination pointer
343 * Advance source pointer (for row)
345 csp
+= ((*csay
) * src
->pitch
);
348 * Advance destination pointers
360 SDL_SetColorKey(rz_dst
, SDL_SRCCOLORKEY
| SDL_RLEACCEL
, rz_src
->format
->colorkey
);
363 * Unlock source surface
365 SDL_UnlockSurface(rz_src
);
368 * Cleanup temp surface
371 SDL_FreeSurface(rz_src
);
375 * Return destination surface