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

# 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 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 root 1.2 #define Amask (Cmask << Ashift)
44 root 1.1
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     }