Mercurial > sdl-ios-xcode
annotate test/testbitmap.c @ 1012:f14e3059e138
Date: Mon, 13 Dec 2004 21:28:18 -0500
From: Jonathan Atkins
Subject: [SDL] SDL_SaveBMP width bugfix
this fixes the pitch versus width difference that can happen
(especially for 8bit and 24bit (with the exact RGBAmasks) surfaces)
when you use SDL_SaveBMP. The problem was the pitch was used
instead of the width, which in some cases is much wider than the
screen area you really want to save...making for ugly crud on the
saved image borders.
This code has been tested with & without pitch overhangs...and
with the right masks for 24 bit surfaces.
I tested 8,15,16,24,32-0RGB,32-RGBA(with no SDL_SRCALPHA flag).
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 14 Dec 2004 06:20:49 +0000 |
parents | 609543e2b3a1 |
children | be9c9c8f6d53 |
rev | line source |
---|---|
0 | 1 |
2 /* Simple program: Test bitmap blits */ | |
3 | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 | |
8 #include "SDL.h" | |
9 #include "picture.xbm" | |
10 | |
11 SDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits) | |
12 { | |
13 SDL_Surface *bitmap; | |
14 Uint8 *line; | |
15 | |
16 /* Allocate the bitmap */ | |
17 bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0); | |
18 if ( bitmap == NULL ) { | |
19 fprintf(stderr, "Couldn't allocate bitmap: %s\n", | |
20 SDL_GetError()); | |
21 return(NULL); | |
22 } | |
23 | |
24 /* Copy the pixels */ | |
25 line = (Uint8 *)bitmap->pixels; | |
26 w = (w+7)/8; | |
27 while ( h-- ) { | |
28 memcpy(line, bits, w); | |
29 /* X11 Bitmap images have the bits reversed */ | |
30 { int i, j; Uint8 *buf, byte; | |
31 for ( buf=line, i=0; i<w; ++i, ++buf ) { | |
32 byte = *buf; | |
33 *buf = 0; | |
34 for ( j=7; j>=0; --j ) { | |
35 *buf |= (byte&0x01)<<j; | |
36 byte >>= 1; | |
37 } | |
38 } | |
39 } | |
40 line += bitmap->pitch; | |
41 bits += w; | |
42 } | |
43 return(bitmap); | |
44 } | |
45 | |
46 int main(int argc, char *argv[]) | |
47 { | |
48 SDL_Surface *screen; | |
49 SDL_Surface *bitmap; | |
50 Uint8 video_bpp; | |
51 Uint32 videoflags; | |
52 Uint8 *buffer; | |
691
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
53 int i, k, done; |
0 | 54 SDL_Event event; |
691
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
55 Uint16 *buffer16; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
56 Uint16 color; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
57 Uint8 gradient; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
58 SDL_Color palette[256]; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
59 |
0 | 60 |
61 /* Initialize SDL */ | |
62 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { | |
63 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | |
64 exit(1); | |
65 } | |
66 atexit(SDL_Quit); | |
67 | |
68 video_bpp = 0; | |
69 videoflags = SDL_SWSURFACE; | |
70 while ( argc > 1 ) { | |
71 --argc; | |
72 if ( strcmp(argv[argc-1], "-bpp") == 0 ) { | |
73 video_bpp = atoi(argv[argc]); | |
74 --argc; | |
75 } else | |
76 if ( strcmp(argv[argc], "-warp") == 0 ) { | |
77 videoflags |= SDL_HWPALETTE; | |
78 } else | |
79 if ( strcmp(argv[argc], "-hw") == 0 ) { | |
80 videoflags |= SDL_HWSURFACE; | |
81 } else | |
82 if ( strcmp(argv[argc], "-fullscreen") == 0 ) { | |
83 videoflags |= SDL_FULLSCREEN; | |
84 } else { | |
85 fprintf(stderr, | |
86 "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", | |
87 argv[0]); | |
88 exit(1); | |
89 } | |
90 } | |
91 | |
92 /* Set 640x480 video mode */ | |
93 if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) { | |
94 fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", | |
95 video_bpp, SDL_GetError()); | |
96 exit(2); | |
97 } | |
98 | |
691
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
99 if (video_bpp==8) { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
100 /* Set a gray colormap, reverse order from white to black */ |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
101 for ( i=0; i<256; ++i ) { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
102 palette[i].r = 255-i; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
103 palette[i].g = 255-i; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
104 palette[i].b = 255-i; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
105 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
106 SDL_SetColors(screen, palette, 0, 256); |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
107 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
108 |
0 | 109 /* Set the surface pixels and refresh! */ |
110 if ( SDL_LockSurface(screen) < 0 ) { | |
111 fprintf(stderr, "Couldn't lock the display surface: %s\n", | |
112 SDL_GetError()); | |
113 exit(2); | |
114 } | |
115 buffer=(Uint8 *)screen->pixels; | |
691
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
116 if (screen->format->BytesPerPixel!=2) { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
117 for ( i=0; i<screen->h; ++i ) { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
118 memset(buffer,(i*255)/screen->h, screen->pitch); |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
119 buffer += screen->pitch; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
120 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
121 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
122 else |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
123 { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
124 for ( i=0; i<screen->h; ++i ) { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
125 gradient=((i*255)/screen->h); |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
126 color = SDL_MapRGB(screen->format, gradient, gradient, gradient); |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
127 buffer16=(Uint16*)buffer; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
128 for (k=0; k<screen->w; k++) |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
129 { |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
130 *(buffer16+k)=color; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
131 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
132 buffer += screen->pitch; |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
133 } |
609543e2b3a1
Date: Fri, 15 Aug 2003 09:13:59 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
134 } |
0 | 135 SDL_UnlockSurface(screen); |
136 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
137 | |
138 /* Load the bitmap */ | |
139 bitmap = LoadXBM(screen, picture_width, picture_height, | |
140 (Uint8 *)picture_bits); | |
141 if ( bitmap == NULL ) { | |
142 exit(1); | |
143 } | |
144 | |
145 /* Wait for a keystroke */ | |
146 done = 0; | |
147 while ( !done ) { | |
148 /* Check for events */ | |
149 while ( SDL_PollEvent(&event) ) { | |
150 switch (event.type) { | |
151 case SDL_MOUSEBUTTONDOWN: { | |
152 SDL_Rect dst; | |
153 | |
154 dst.x = event.button.x - bitmap->w/2; | |
155 dst.y = event.button.y - bitmap->h/2; | |
156 dst.w = bitmap->w; | |
157 dst.h = bitmap->h; | |
158 SDL_BlitSurface(bitmap, NULL, | |
159 screen, &dst); | |
160 SDL_UpdateRects(screen,1,&dst); | |
161 } | |
162 break; | |
163 case SDL_KEYDOWN: | |
164 /* Any key press quits the app... */ | |
165 done = 1; | |
166 break; | |
167 case SDL_QUIT: | |
168 done = 1; | |
169 break; | |
170 default: | |
171 break; | |
172 } | |
173 } | |
174 } | |
175 SDL_FreeSurface(bitmap); | |
176 return(0); | |
177 } |