ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/util/enlarge/filla.C
Revision: 1.1
Committed: Sun Mar 4 00:53:45 2007 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# Content
1 // fill transparent areas of an image with nearby values
2 // increases compressibility and enhances image quality
3 // in the presence of naive interpolation algorithms.
4
5 //----------------------------------------------------------
6 //Copyright (C) 2006 Marc Lehmann <pcg@goof.com>
7
8 //This program is free software; you can redistribute it and/or
9 //modify it under the terms of the GNU Lesser General Public
10 //License as published by the Free Software Foundation; either
11 //version 2.1 of the License, or (at your option) any later version.
12 //
13 //This program is distributed in the hope that it will be useful,
14 //but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 //Lesser General Public License for more details.
17 //
18 //You should have received a copy of the GNU Lesser General Public
19 //License along with this program; if not, write to the Free Software
20 //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <stdint.h>
26 #include <endian.h>
27
28 using namespace std;
29
30 #if __BYTE_ORDER == __BIG_ENDIAN
31 # define Rmask 0xff000000UL
32 # define Gmask 0x00ff0000UL
33 # define Bmask 0x0000ff00UL
34 # define Amask 0x000000ffUL
35 # define Rshift 24
36 # define Gshift 16
37 # define Bshift 8
38 # define Ashift 0
39 #else
40 # define Rmask 0x000000ffUL
41 # define Gmask 0x0000ff00UL
42 # define Bmask 0x00ff0000UL
43 # define Amask 0xff000000UL
44 # define Rshift 0
45 # define Gshift 8
46 # define Bshift 16
47 # define Ashift 24
48 #endif
49
50 #define Cmask 0xffUL
51
52 typedef uint32_t pixel;
53
54 inline void gather (pixel *img, char *flag, int x, int y, int w, int h, int &c, int &r, int &g, int &b)
55 {
56 if (x < 0 || x >= w)
57 return;
58
59 if (y < 0 || y >= h)
60 return;
61
62 int p = img [y * w + x];
63
64 int weight = (p >> Ashift) & Cmask;
65 if (!weight)
66 weight = !!flag [y * w + x];
67
68 if (!weight)
69 return;
70
71 c += weight;
72
73 r += ((p >> Rshift) & Cmask) * weight;
74 g += ((p >> Gshift) & Cmask) * weight;
75 b += ((p >> Bshift) & Cmask) * weight;
76 }
77
78 void filla (pixel *img, int w, int h)
79 {
80 char *flag = (char *)calloc (w * h, 1);
81 char *flag2 = (char *)calloc (w * h, 1);
82 pixel *dst = new pixel [w * h];
83
84 for (int iter = 3; --iter; )
85 {
86 for (int x = 0; x < w; x++)
87 for (int y = 0; y < h; y++)
88 {
89 int o = y * w + x;
90
91 if ((img [o] & Amask) || flag [o])
92 dst [o] = img [o];
93 else
94 {
95 int weight = 0, r = 0, g = 0, b = 0;
96
97 gather (img, flag, x - 1, y - 1, w, h, weight, r, g, b);
98 gather (img, flag, x , y - 1, w, h, weight, r, g, b);
99 gather (img, flag, x + 1, y - 1, w, h, weight, r, g, b);
100 gather (img, flag, x - 1, y , w, h, weight, r, g, b);
101 gather (img, flag, x + 1, y , w, h, weight, r, g, b);
102 gather (img, flag, x - 1, y + 1, w, h, weight, r, g, b);
103 gather (img, flag, x , y + 1, w, h, weight, r, g, b);
104 gather (img, flag, x + 1, y + 1, w, h, weight, r, g, b);
105
106 if (weight)
107 {
108 flag2 [o] = 1;
109 dst [o] = ((r + weight / 2) / weight) << Rshift
110 | ((g + weight / 2) / weight) << Gshift
111 | ((b + weight / 2) / weight) << Bshift;
112 }
113 else
114 dst [o] = img [o]; // not yet here
115 }
116 }
117
118 memcpy (img, dst, w * h * sizeof (pixel));
119 memcpy (flag, flag2, w * h);
120 }
121
122 for (int o = w * h; o--; )
123 if (!(img [o] & Amask || flag [o]))
124 img [o] = 0;
125
126 free (dst);
127 free (flag);
128 free (flag2);
129 }
130
131 int main (int argc, char* argv[])
132 {
133 if (argc <= 2)
134 {
135 printf("\nUsage: filla w h <input.rgba >output.rgba\n");
136 printf("input file must be 32 bit rgba w*h.\n");
137 return 1;
138 }
139
140 int w = atoi (argv [1]);
141 int h = atoi (argv [2]);
142
143 int size = w * h * sizeof (pixel);
144
145 pixel *img = (pixel *)new unsigned char [size];
146
147 if (fread (img, size, 1, stdin) != 1)
148 {
149 perror ("unable to read input file\n");
150 exit (1);
151 }
152
153 filla (img, w, h);
154
155 if (fwrite (img, size, 1, stdout) != 1)
156 {
157 perror ("unable to read output file\n");
158 exit (1);
159 }
160
161 return 0;
162 }