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

Contents of /aorta/image_ext.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Sun May 21 22:36:37 2006 UTC (7 years, 1 month 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 /*
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 Rescale((int) (GetWidth() * scale), (int) (GetHeight() * scale));
73 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 // 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