Reduce mapc dependences (need to split image.[ch])
[neverball] / share / base_image.c
1 /*   
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <SDL.h>
16
17 /*---------------------------------------------------------------------------*/
18
19 void image_swab(SDL_Surface *src)
20 {
21     int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
22     
23     SDL_LockSurface(src);
24     {
25         unsigned char *s = (unsigned char *) src->pixels;
26         unsigned char  t;
27
28         /* Iterate over each pixel of the image. */
29
30         for (i = 0; i < src->h; i++)
31             for (j = 0; j < src->w; j++)
32             {
33                 int k = (i * src->w + j) * b;
34
35                 /* Swap the red and blue channels of each. */
36
37                 t        = s[k + 2];
38                 s[k + 2] = s[k + 0];
39                 s[k + 0] =        t;
40             }
41     }
42     SDL_UnlockSurface(src);
43 }
44
45 void image_white(SDL_Surface *src)
46 {
47     int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
48     
49     SDL_LockSurface(src);
50     {
51         unsigned char *s = (unsigned char *) src->pixels;
52
53         /* Iterate over each pixel of the image. */
54
55         for (i = 0; i < src->h; i++)
56             for (j = 0; j < src->w; j++)
57             {
58                 int k = (i * src->w + j) * b;
59
60                 /* Whiten the RGB channels without touching any Alpha. */
61
62                 s[k + 0] = 0xFF;
63                 s[k + 1] = 0xFF;
64                 s[k + 2] = 0xFF;
65             }
66     }
67     SDL_UnlockSurface(src);
68 }
69
70 SDL_Surface *image_scale(SDL_Surface *src, int n)
71 {
72     int si, di;
73     int sj, dj;
74     int k, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
75
76     SDL_Surface *dst = SDL_CreateRGBSurface(SDL_SWSURFACE,
77                                             src->w / n,
78                                             src->h / n,
79                                             src->format->BitsPerPixel,
80                                             src->format->Rmask,
81                                             src->format->Gmask,
82                                             src->format->Bmask,
83                                             src->format->Amask);
84     if (dst)
85     {
86         SDL_LockSurface(src);
87         SDL_LockSurface(dst);
88         {
89             unsigned char *s = (unsigned char *) src->pixels;
90             unsigned char *d = (unsigned char *) dst->pixels;
91
92             /* Iterate each component of each distination pixel. */
93
94             for (di = 0; di < src->h / n; di++)
95                 for (dj = 0; dj < src->w / n; dj++)
96                     for (k = 0; k < b; k++)
97                     {
98                         int c = 0;
99
100                         /* Average the NxN source pixel block for each. */
101
102                         for (si = di * n; si < (di + 1) * n; si++)
103                             for (sj = dj * n; sj < (dj + 1) * n; sj++)
104                                 c += s[(si * src->w + sj) * b + k];
105
106                         d[(di * dst->w + dj) * b + k] =
107                             (unsigned char) (c / (n * n));
108                     }
109         }
110         SDL_UnlockSurface(dst);
111         SDL_UnlockSurface(src);
112     }
113
114     return dst;
115 }
116
117 /*---------------------------------------------------------------------------*/