root / sdl_zoom.c @ abb6ae2c
History | View | Annotate | Download (2.8 kB)
1 | c18a2c36 | Stefano Stabellini | /*
|
---|---|---|---|
2 | c18a2c36 | Stefano Stabellini | * SDL_zoom - surface scaling
|
3 | c18a2c36 | Stefano Stabellini | *
|
4 | c18a2c36 | Stefano Stabellini | * Copyright (c) 2009 Citrix Systems, Inc.
|
5 | c18a2c36 | Stefano Stabellini | *
|
6 | c18a2c36 | Stefano Stabellini | * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
|
7 | c18a2c36 | Stefano Stabellini | * Modifications by Stefano Stabellini.
|
8 | c18a2c36 | Stefano Stabellini | *
|
9 | c18a2c36 | Stefano Stabellini | * This work is licensed under the terms of the GNU GPL version 2.
|
10 | c18a2c36 | Stefano Stabellini | * See the COPYING file in the top-level directory.
|
11 | c18a2c36 | Stefano Stabellini | *
|
12 | c18a2c36 | Stefano Stabellini | */
|
13 | c18a2c36 | Stefano Stabellini | |
14 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom.h" |
15 | c18a2c36 | Stefano Stabellini | #include "osdep.h" |
16 | c18a2c36 | Stefano Stabellini | #include <stdint.h> |
17 | 22d091b3 | Blue Swirl | #include <stdio.h> |
18 | c18a2c36 | Stefano Stabellini | |
19 | c18a2c36 | Stefano Stabellini | static int sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth, |
20 | c18a2c36 | Stefano Stabellini | SDL_Rect *dst_rect); |
21 | c18a2c36 | Stefano Stabellini | static int sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth, |
22 | c18a2c36 | Stefano Stabellini | SDL_Rect *dst_rect); |
23 | c18a2c36 | Stefano Stabellini | |
24 | c18a2c36 | Stefano Stabellini | #define BPP 32 |
25 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom_template.h" |
26 | c18a2c36 | Stefano Stabellini | #undef BPP
|
27 | c18a2c36 | Stefano Stabellini | #define BPP 16 |
28 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom_template.h" |
29 | c18a2c36 | Stefano Stabellini | #undef BPP
|
30 | c18a2c36 | Stefano Stabellini | |
31 | c18a2c36 | Stefano Stabellini | int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth, |
32 | c18a2c36 | Stefano Stabellini | SDL_Rect *in_rect) |
33 | c18a2c36 | Stefano Stabellini | { |
34 | c18a2c36 | Stefano Stabellini | SDL_Rect zoom, src_rect; |
35 | c18a2c36 | Stefano Stabellini | int extra;
|
36 | c18a2c36 | Stefano Stabellini | |
37 | c18a2c36 | Stefano Stabellini | /* Grow the size of the modified rectangle to avoid edge artefacts */
|
38 | c18a2c36 | Stefano Stabellini | src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0; |
39 | c18a2c36 | Stefano Stabellini | src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0; |
40 | c18a2c36 | Stefano Stabellini | |
41 | c18a2c36 | Stefano Stabellini | src_rect.w = in_rect->w + 1;
|
42 | c18a2c36 | Stefano Stabellini | if (src_rect.x + src_rect.w > src_sfc->w)
|
43 | c18a2c36 | Stefano Stabellini | src_rect.w = src_sfc->w - src_rect.x; |
44 | c18a2c36 | Stefano Stabellini | |
45 | c18a2c36 | Stefano Stabellini | src_rect.h = in_rect->h + 1;
|
46 | c18a2c36 | Stefano Stabellini | if (src_rect.y + src_rect.h > src_sfc->h)
|
47 | c18a2c36 | Stefano Stabellini | src_rect.h = src_sfc->h - src_rect.y; |
48 | c18a2c36 | Stefano Stabellini | |
49 | c18a2c36 | Stefano Stabellini | /* (x,y) : round down */
|
50 | c18a2c36 | Stefano Stabellini | zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w)); |
51 | c18a2c36 | Stefano Stabellini | zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h)); |
52 | c18a2c36 | Stefano Stabellini | |
53 | c18a2c36 | Stefano Stabellini | /* (w,h) : round up */
|
54 | c18a2c36 | Stefano Stabellini | zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) / |
55 | c18a2c36 | Stefano Stabellini | (double)(src_sfc->w));
|
56 | c18a2c36 | Stefano Stabellini | |
57 | c18a2c36 | Stefano Stabellini | zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) / |
58 | c18a2c36 | Stefano Stabellini | (double)(src_sfc->h));
|
59 | c18a2c36 | Stefano Stabellini | |
60 | c18a2c36 | Stefano Stabellini | /* Account for any (x,y) rounding by adding one-source-pixel's worth
|
61 | c18a2c36 | Stefano Stabellini | * of destination pixels and then edge checking.
|
62 | c18a2c36 | Stefano Stabellini | */
|
63 | c18a2c36 | Stefano Stabellini | |
64 | c18a2c36 | Stefano Stabellini | extra = ((dst_sfc->w-1) / src_sfc->w) + 1; |
65 | c18a2c36 | Stefano Stabellini | |
66 | c18a2c36 | Stefano Stabellini | if ((zoom.x + zoom.w) < (dst_sfc->w - extra))
|
67 | c18a2c36 | Stefano Stabellini | zoom.w += extra; |
68 | c18a2c36 | Stefano Stabellini | else
|
69 | c18a2c36 | Stefano Stabellini | zoom.w = dst_sfc->w - zoom.x; |
70 | c18a2c36 | Stefano Stabellini | |
71 | c18a2c36 | Stefano Stabellini | extra = ((dst_sfc->h-1) / src_sfc->h) + 1; |
72 | c18a2c36 | Stefano Stabellini | |
73 | c18a2c36 | Stefano Stabellini | if ((zoom.y + zoom.h) < (dst_sfc->h - extra))
|
74 | c18a2c36 | Stefano Stabellini | zoom.h += extra; |
75 | c18a2c36 | Stefano Stabellini | else
|
76 | c18a2c36 | Stefano Stabellini | zoom.h = dst_sfc->h - zoom.y; |
77 | c18a2c36 | Stefano Stabellini | |
78 | c18a2c36 | Stefano Stabellini | /* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the
|
79 | c18a2c36 | Stefano Stabellini | * destination surface that needs to be updated.
|
80 | c18a2c36 | Stefano Stabellini | */
|
81 | c18a2c36 | Stefano Stabellini | if (src_sfc->format->BitsPerPixel == 32) |
82 | c18a2c36 | Stefano Stabellini | sdl_zoom_rgb32(src_sfc, dst_sfc, smooth, &zoom); |
83 | c18a2c36 | Stefano Stabellini | else if (src_sfc->format->BitsPerPixel == 16) |
84 | c18a2c36 | Stefano Stabellini | sdl_zoom_rgb16(src_sfc, dst_sfc, smooth, &zoom); |
85 | c18a2c36 | Stefano Stabellini | else {
|
86 | c18a2c36 | Stefano Stabellini | fprintf(stderr, "pixel format not supported\n");
|
87 | c18a2c36 | Stefano Stabellini | return -1; |
88 | c18a2c36 | Stefano Stabellini | } |
89 | c18a2c36 | Stefano Stabellini | |
90 | c18a2c36 | Stefano Stabellini | /* Return the rectangle of the update to the caller */
|
91 | c18a2c36 | Stefano Stabellini | *in_rect = zoom; |
92 | c18a2c36 | Stefano Stabellini | |
93 | c18a2c36 | Stefano Stabellini | return 0; |
94 | c18a2c36 | Stefano Stabellini | } |