ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/util/enlarge/filla.C
Revision: 1.2
Committed: Sun Mar 4 01:45:42 2007 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_0, STABLE
Changes since 1.1: +1 -8 lines
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 Rshift 24
32 # define Gshift 16
33 # define Bshift 8
34 # define Ashift 0
35 #else
36 # define Rshift 0
37 # define Gshift 8
38 # define Bshift 16
39 # define Ashift 24
40 #endif
41
42 #define Cmask 0xffUL
43 #define Amask (Cmask << Ashift)
44
45 typedef uint32_t pixel;
46
47 inline void gather (pixel *img, char *flag, int x, int y, int w, int h, int &c, int &r, int &g, int &b)
48 {
49 if (x < 0 || x >= w)
50 return;
51
52 if (y < 0 || y >= h)
53 return;
54
55 int p = img [y * w + x];
56
57 int weight = (p >> Ashift) & Cmask;
58 if (!weight)
59 weight = !!flag [y * w + x];
60
61 if (!weight)
62 return;
63
64 c += weight;
65
66 r += ((p >> Rshift) & Cmask) * weight;
67 g += ((p >> Gshift) & Cmask) * weight;
68 b += ((p >> Bshift) & Cmask) * weight;
69 }
70
71 void filla (pixel *img, int w, int h)
72 {
73 char *flag = (char *)calloc (w * h, 1);
74 char *flag2 = (char *)calloc (w * h, 1);
75 pixel *dst = new pixel [w * h];
76
77 for (int iter = 3; --iter; )
78 {
79 for (int x = 0; x < w; x++)
80 for (int y = 0; y < h; y++)
81 {
82 int o = y * w + x;
83
84 if ((img [o] & Amask) || flag [o])
85 dst [o] = img [o];
86 else
87 {
88 int weight = 0, r = 0, g = 0, b = 0;
89
90 gather (img, flag, x - 1, y - 1, w, h, weight, r, g, b);
91 gather (img, flag, x , y - 1, w, h, weight, r, g, b);
92 gather (img, flag, x + 1, y - 1, w, h, weight, r, g, b);
93 gather (img, flag, x - 1, y , w, h, weight, r, g, b);
94 gather (img, flag, x + 1, y , w, h, weight, r, g, b);
95 gather (img, flag, x - 1, y + 1, w, h, weight, r, g, b);
96 gather (img, flag, x , y + 1, w, h, weight, r, g, b);
97 gather (img, flag, x + 1, y + 1, w, h, weight, r, g, b);
98
99 if (weight)
100 {
101 flag2 [o] = 1;
102 dst [o] = ((r + weight / 2) / weight) << Rshift
103 | ((g + weight / 2) / weight) << Gshift
104 | ((b + weight / 2) / weight) << Bshift;
105 }
106 else
107 dst [o] = img [o]; // not yet here
108 }
109 }
110
111 memcpy (img, dst, w * h * sizeof (pixel));
112 memcpy (flag, flag2, w * h);
113 }
114
115 for (int o = w * h; o--; )
116 if (!(img [o] & Amask || flag [o]))
117 img [o] = 0;
118
119 free (dst);
120 free (flag);
121 free (flag2);
122 }
123
124 int main (int argc, char* argv[])
125 {
126 if (argc <= 2)
127 {
128 printf("\nUsage: filla w h <input.rgba >output.rgba\n");
129 printf("input file must be 32 bit rgba w*h.\n");
130 return 1;
131 }
132
133 int w = atoi (argv [1]);
134 int h = atoi (argv [2]);
135
136 int size = w * h * sizeof (pixel);
137
138 pixel *img = (pixel *)new unsigned char [size];
139
140 if (fread (img, size, 1, stdin) != 1)
141 {
142 perror ("unable to read input file\n");
143 exit (1);
144 }
145
146 filla (img, w, h);
147
148 if (fwrite (img, size, 1, stdout) != 1)
149 {
150 perror ("unable to read output file\n");
151 exit (1);
152 }
153
154 return 0;
155 }