/[alephone]/aorta/image_ext.cpp
ViewVC logotype

Contents of /aorta/image_ext.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations)
Sun May 21 22:36:37 2006 UTC (7 years ago) by ghs
Branch: MAIN
Changes since 1.2: +107 -0 lines
add an experimental de-haloing algorithm, checkboxes for de-halo and mipmaps,
choose DDS or PNG based on file extension, an about box

1 ghs 1.1 /*
2    
3     image_ext.cpp: extra functionality for wxImage
4     Copyright (C) 2006 Gregory Smith
5    
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19    
20     */
21    
22     #include "image_ext.h"
23    
24     void wxImageExt::White()
25     {
26     int NumBytes = GetWidth() * GetHeight() * 3;
27     for (int i = 0; i < NumBytes; i++)
28     {
29     GetData()[i] = 0xff;
30     }
31     }
32    
33     void wxImageExt::RemoveAlpha()
34     {
35     wxImageExt image;
36     image.Create(GetWidth(), GetHeight());
37     memcpy(image.GetData(), GetData(), GetWidth() * GetHeight() * 3);
38    
39     *this = image;
40     }
41    
42     void wxImageExt::MaskToAlpha()
43     {
44     wxImageExt image;
45     image.Create(GetWidth(), GetHeight());
46     image.InitAlpha();
47     image.SetMask(false);
48    
49     memcpy(image.GetData(), GetData(), GetWidth() * GetHeight() * 3);
50    
51     for (int x = 0; x < GetWidth(); x++)
52     {
53     for (int y = 0; y < GetHeight(); y++)
54     {
55     if (IsTransparent(x, y))
56     {
57     image.GetAlpha()[x + y * GetWidth()] = 0x00;
58     }
59     else
60     {
61     image.GetAlpha()[x + y * GetWidth()] = 0xff;
62     }
63     }
64     }
65    
66     *this = image;
67     }
68    
69     void wxImageExt::PropRescale(int width, int height)
70     {
71     float scale = (float) MAX(width, height) / MAX(GetWidth(), GetHeight());
72 ghs 1.2 Rescale((int) (GetWidth() * scale), (int) (GetHeight() * scale));
73 ghs 1.1 Resize(wxSize(width, height), wxPoint((width - GetWidth()) / 2, (height - GetHeight()) / 2));
74     }
75    
76     void wxImageExt::FromAlpha(const wxImageExt& source)
77     {
78     Create(source.GetWidth(), source.GetHeight());
79     int NumPixels = GetWidth() * GetHeight();
80     for (int i = 0; i < NumPixels; i++)
81     {
82     GetData()[i * 3 + 0] = GetData()[i * 3 + 1] = GetData()[i * 3 + 2] = source.GetAlpha()[i];
83     }
84     }
85    
86     void wxImageExt::ToAlpha(wxImageExt& dest) const
87     {
88     if (!dest.HasAlpha())
89     {
90     dest.InitAlpha();
91     }
92    
93     int NumPixels = GetWidth() * GetHeight();
94     for (int i = 0; i < NumPixels; i++)
95     {
96     unsigned int Average = (GetData()[i * 3 + 0] + GetData()[i * 3 + 1] + GetData()[i * 3 + 2]) / 3;
97     dest.GetAlpha()[i] = Average & 0xff;
98     }
99     }
100    
101     void wxImageExt::MakeOpacTypeTwo()
102     {
103     wxImageExt image;
104     image.Create(GetWidth(), GetHeight());
105     int NumPixels = GetWidth() * GetHeight();
106     for (int i = 0; i < NumPixels; i++)
107     {
108     unsigned int Average = (GetData()[i * 3 + 0] + GetData()[i * 3 + 1] + GetData()[i * 3 + 2]) / 3;
109     image.GetData()[i * 3 + 0] = image.GetData()[i * 3 + 1] = image.GetData()[i * 3 + 2] = Average & 0xff;
110     }
111    
112     *this = image;
113     }
114    
115     void wxImageExt::MakeOpacTypeThree()
116     {
117     wxImageExt image;
118     image.Create(GetWidth(), GetHeight());
119     int NumPixels = GetWidth() * GetHeight();
120     for (int i = 0; i < NumPixels; i++)
121     {
122     unsigned char Max = MAX(GetData()[i * 3 + 0], MAX(GetData()[i * 3 + 1], GetData()[i * 3 + 2]));
123     image.GetData()[i * 3 + 0] = image.GetData()[i * 3 + 1] = image.GetData()[i * 3 + 2] = Max;
124     }
125    
126     *this = image;
127     }
128    
129 ghs 1.3 // thanks to the Virtual Terrain Project for this algorithm, and the code looks
130     // pretty similar too...
131     void wxImageExt::PrepareForMipmaps()
132     {
133     if (!HasAlpha()) return;
134     wxBusyCursor();
135     short bgBlue, bgGreen, bgRed;
136     bgBlue = bgGreen = bgRed = 0xff;
137     // restore the color of edge texels by guessing correct non-background color
138     wxImageExt result;
139    
140     int numBackgroundPixels = 0;
141    
142     result.Create(GetWidth(), GetHeight());
143     result.InitAlpha();
144     for (int x = 0; x < GetWidth(); x++) {
145     for (int y = 0; y < GetHeight(); y++) {
146     if (GetAlpha(x, y) == 0) {
147     result.SetAlpha(x, y, 0);
148     result.SetRGB(x, y, bgRed, bgGreen, bgBlue);
149     numBackgroundPixels++;
150     } else if (GetAlpha(x, y) == 0xff) {
151     result.SetAlpha(x, y, 0xff);
152     result.SetRGB(x, y, GetRed(x, y), GetGreen(x, y), GetBlue(x, y));
153     } else {
154     float blend_factor = GetAlpha(x, y) / 255.0f;
155     result.SetAlpha(x, y, GetAlpha(x, y));
156     short rDiff = GetRed(x, y) - bgRed;
157     short gDiff = GetGreen(x, y) - bgGreen;
158     short bDiff = GetBlue(x, y) - bgBlue;
159    
160     result.SetRGB(x, y, PIN(bgRed + (int) (rDiff * (1.0f / blend_factor)), 0, 255), PIN(bgGreen + (int) (gDiff * (1.0f / blend_factor)), 0, 255), PIN(bgBlue + (int) (bDiff * (1.0f / blend_factor)), 0, 255));
161     }
162     }
163     }
164    
165     wxProgressDialog pd(_T("Processing"), _T("Processing background pixels"), numBackgroundPixels, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME);
166    
167     wxImageExt tempImage;
168     tempImage.Create(GetWidth(), GetHeight());
169     tempImage.InitAlpha();
170     int filled_in = 1;
171     while (filled_in) {
172     filled_in = 0;
173     int numBackgroundPixelsRemaining = 0;
174     tempImage.Create(GetWidth(), GetHeight(), true);
175    
176     short rSum, gSum, bSum, aSum;
177     int surround;
178     for (int i = 0; i < GetWidth(); i++) {
179     for (int j = 0; j < GetHeight(); j++) {
180     if (result.GetAlpha(i, j) != 0)
181     continue;
182    
183     numBackgroundPixelsRemaining++;
184     rSum = gSum = bSum = aSum = 0;
185     surround = 0;
186     for (int x = -1; x <= 1; x++)
187     for (int y = -1; y <= 1; y++) {
188     if (x == 0 && y == 0) continue;
189     if (i + x < 0) continue;
190     if (i + x > GetWidth() - 1) continue;
191     if (j + y < 0) continue;
192     if (j + y > GetHeight() - 1) continue;
193     if (result.GetAlpha(i + x, j + y) != 0) {
194     rSum += result.GetRed(i + x, j + y);
195     gSum += result.GetGreen(i + x, j + y);
196     bSum += result.GetBlue(i + x, j + y);
197     aSum += result.GetAlpha(i + x, j + y);
198     surround++;
199     }
200     }
201    
202     if (surround > 2)
203     {
204     tempImage.SetRGB(i, j, rSum / surround, gSum / surround, bSum / surround);
205     tempImage.SetAlpha(i, j, aSum / surround);
206     }
207     }
208     }
209    
210     for (int i = 0; i < GetWidth(); i++)
211     {
212     for (int j = 0; j < GetHeight(); j++)
213     {
214     if (result.GetAlpha(i, j) == 0) {
215     if (tempImage.GetRed(i, j) != 0 || tempImage.GetGreen(i, j) != 0 || tempImage.GetBlue(i, j) != 0) {
216     result.SetRGB(i, j, tempImage.GetRed(i, j), tempImage.GetGreen(i, j), tempImage.GetBlue(i, j));
217     result.SetAlpha(i, j, 1);
218     filled_in++;
219     }
220     }
221     }
222     }
223     pd.Update(numBackgroundPixels - numBackgroundPixelsRemaining);
224     }
225    
226     pd.Update(numBackgroundPixels);
227    
228     for (int i = 0; i < GetWidth(); i++) {
229     for (int j = 0; j < GetHeight(); j++) {
230     if (result.GetAlpha(i, j) == 1) result.SetAlpha(i, j, 0);
231     }
232     }
233    
234     *this = result;
235     }

Christian Bauer">Christian Bauer
ViewVC Help
Powered by ViewVC 1.1.15