root / sdl_zoom.c @ 12381085
History | View | Annotate | Download (2.8 kB)
1 |
/*
|
---|---|
2 |
* SDL_zoom - 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 |
#include "sdl_zoom.h" |
15 |
#include "osdep.h" |
16 |
#include <stdint.h> |
17 |
#include <stdio.h> |
18 |
|
19 |
static int sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth, |
20 |
SDL_Rect *dst_rect); |
21 |
static int sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth, |
22 |
SDL_Rect *dst_rect); |
23 |
|
24 |
#define BPP 32 |
25 |
#include "sdl_zoom_template.h" |
26 |
#undef BPP
|
27 |
#define BPP 16 |
28 |
#include "sdl_zoom_template.h" |
29 |
#undef BPP
|
30 |
|
31 |
int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth, |
32 |
SDL_Rect *in_rect) |
33 |
{ |
34 |
SDL_Rect zoom, src_rect; |
35 |
int extra;
|
36 |
|
37 |
/* Grow the size of the modified rectangle to avoid edge artefacts */
|
38 |
src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0; |
39 |
src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0; |
40 |
|
41 |
src_rect.w = in_rect->w + 1;
|
42 |
if (src_rect.x + src_rect.w > src_sfc->w)
|
43 |
src_rect.w = src_sfc->w - src_rect.x; |
44 |
|
45 |
src_rect.h = in_rect->h + 1;
|
46 |
if (src_rect.y + src_rect.h > src_sfc->h)
|
47 |
src_rect.h = src_sfc->h - src_rect.y; |
48 |
|
49 |
/* (x,y) : round down */
|
50 |
zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w)); |
51 |
zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h)); |
52 |
|
53 |
/* (w,h) : round up */
|
54 |
zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) / |
55 |
(double)(src_sfc->w));
|
56 |
|
57 |
zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) / |
58 |
(double)(src_sfc->h));
|
59 |
|
60 |
/* Account for any (x,y) rounding by adding one-source-pixel's worth
|
61 |
* of destination pixels and then edge checking.
|
62 |
*/
|
63 |
|
64 |
extra = ((dst_sfc->w-1) / src_sfc->w) + 1; |
65 |
|
66 |
if ((zoom.x + zoom.w) < (dst_sfc->w - extra))
|
67 |
zoom.w += extra; |
68 |
else
|
69 |
zoom.w = dst_sfc->w - zoom.x; |
70 |
|
71 |
extra = ((dst_sfc->h-1) / src_sfc->h) + 1; |
72 |
|
73 |
if ((zoom.y + zoom.h) < (dst_sfc->h - extra))
|
74 |
zoom.h += extra; |
75 |
else
|
76 |
zoom.h = dst_sfc->h - zoom.y; |
77 |
|
78 |
/* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the
|
79 |
* destination surface that needs to be updated.
|
80 |
*/
|
81 |
if (src_sfc->format->BitsPerPixel == 32) |
82 |
sdl_zoom_rgb32(src_sfc, dst_sfc, smooth, &zoom); |
83 |
else if (src_sfc->format->BitsPerPixel == 16) |
84 |
sdl_zoom_rgb16(src_sfc, dst_sfc, smooth, &zoom); |
85 |
else {
|
86 |
fprintf(stderr, "pixel format not supported\n");
|
87 |
return -1; |
88 |
} |
89 |
|
90 |
/* Return the rectangle of the update to the caller */
|
91 |
*in_rect = zoom; |
92 |
|
93 |
return 0; |
94 |
} |
95 |
|