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

# User Rev Content
1 root 1.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     }