summaryrefslogtreecommitdiffstats
path: root/ue2/imgsynth2/cbitmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ue2/imgsynth2/cbitmap.cpp')
-rw-r--r--ue2/imgsynth2/cbitmap.cpp382
1 files changed, 0 insertions, 382 deletions
diff --git a/ue2/imgsynth2/cbitmap.cpp b/ue2/imgsynth2/cbitmap.cpp
deleted file mode 100644
index fc1a7c0..0000000
--- a/ue2/imgsynth2/cbitmap.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
1/**
2 * @module cbitmap
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Implementation of CFile handling Windows Bitmaps.
5 * @date 17.04.2009
6 */
7
8#include <boost/lexical_cast.hpp>
9#include <boost/numeric/conversion/cast.hpp>
10#ifdef DEBUG
11# include <iostream>
12#endif
13#include "cbitmap.h"
14#include "cpixelformat_bgr24.h"
15#include "cpixelformat_bgr555.h"
16
17using namespace std;
18
19CBitmap::CBitmap()
20 : m_pixeldata(NULL), m_pixelformat(NULL)
21{
22 m_types.insert("BMP");
23
24 /* add our handlers */
25 m_handlers.insert(new CPixelFormat_BGR24(this));
26 m_handlers.insert(new CPixelFormat_BGR555(this));
27}
28
29/*----------------------------------------------------------------------------*/
30
31CBitmap::~CBitmap()
32{
33 /* delete pixeldata */
34 if (m_pixeldata != NULL)
35 delete[] m_pixeldata;
36 m_pixeldata = NULL;
37
38 /* delete pixelformat handlers */
39 set<CPixelFormat *>::iterator it;
40 for (it = m_handlers.begin(); it != m_handlers.end(); it++)
41 delete *it;
42 m_pixelformat = NULL;
43}
44
45/*----------------------------------------------------------------------------*/
46
47void CBitmap::read(std::ifstream& in)
48{
49 /* read and check file header */
50 in.read(reinterpret_cast<char *>(&m_fileheader), sizeof(m_fileheader));
51
52 if (m_fileheader.bfType[0] != 'B' || m_fileheader.bfType[1] != 'M')
53 throw FileError("Imagefile has invalid Bitmap header.");
54 /* bfSize is unreliable (http://de.wikipedia.org/wiki/Windows_Bitmap) */
55 if (m_fileheader.bfSize < 0)
56 throw FileError("Bitmap filesize is less than zero?");
57
58 /* read and check info header */
59 in.read(reinterpret_cast<char *>(&m_infoheader), sizeof(m_infoheader));
60
61 if (m_infoheader.biSize != 40)
62 throw FileError("Bitmap info header size is invalid.");
63 if (m_infoheader.biPlanes != 1)
64 throw FileError("Bitmap color planes is not set to 1.");
65 if (m_infoheader.biCompression != 0)
66 throw FileError("Bitmap compression is set but not supported.");
67 if (m_infoheader.biSizeImage < 0)
68 throw FileError("Bitmap image size is less than zero?");
69 if (m_infoheader.biClrUsed != 0 || m_infoheader.biClrImportant != 0)
70 throw FileError("Bitmap colortable is used but not supported.");
71
72 /* read pixel data using separate class */
73 if (m_infoheader.biSizeImage > 0)
74 {
75 if (m_pixeldata != NULL)
76 delete[] m_pixeldata;
77 m_pixeldata = new uint8_t[m_infoheader.biSizeImage];
78 in.read(reinterpret_cast<char *>(m_pixeldata), m_infoheader.biSizeImage);
79 }
80
81 /* get pixelformat instance */
82 m_pixelformat = NULL;
83 set<CPixelFormat *>::iterator it;
84 for (it = m_handlers.begin(); it != m_handlers.end(); it++)
85 {
86 if (m_infoheader.biBitCount == (*it)->getBitCount())
87 {
88 m_pixelformat = *it;
89 break;
90 }
91 }
92 if (m_pixelformat == NULL)
93 throw FileError("Bitmap bitcount is not supported.");
94}
95
96/*----------------------------------------------------------------------------*/
97
98void CBitmap::write(std::ofstream& out)
99{
100 /* set header values */
101 m_fileheader.bfSize = m_infoheader.biSizeImage + sizeof(m_infoheader) + sizeof(m_fileheader);
102
103 /* write file header */
104 out.write(reinterpret_cast<char *>(&m_fileheader), sizeof(m_fileheader));
105
106 /* write info header */
107 out.write(reinterpret_cast<char *>(&m_infoheader), sizeof(m_infoheader));
108
109 /* write pixel data */
110 if (m_pixeldata != NULL)
111 out.write(reinterpret_cast<char *>(m_pixeldata), m_infoheader.biSizeImage);
112}
113
114/*----------------------------------------------------------------------------*/
115
116void CBitmap::callFunc(const std::string& func, const std::list<std::string>& params)
117{
118 if (func.empty())
119 throw FileError("Function name is empty.");
120
121 if (func == "fillrect")
122 fillrect(params);
123 else if (func == "mirror_x")
124 mirror_x(params);
125 else if (func == "mirror_y")
126 mirror_y(params);
127 else if (func == "invert")
128 invert(params);
129 else
130 throw FileError("Unknown function '" + func + "'.");
131}
132
133/*----------------------------------------------------------------------------*/
134
135void CBitmap::fillrect(std::list<std::string> params)
136{
137 /* check prerequirements */
138 if (params.size() != 7)
139 throw FileError("Invalid number of function parameters (must be 7).");
140
141 /* do nothing if no pixel exists */
142 if (m_pixeldata == NULL || m_pixelformat == NULL)
143 return;
144
145 /* convert parameters */
146 uint32_t pparams[7];
147 int i = 0;
148 try
149 {
150 for(i = 0; i < 7; i++)
151 {
152 pparams[i] = boost::lexical_cast<uint32_t>(params.front());
153 params.pop_front();
154 }
155 }
156 catch(boost::bad_lexical_cast& ex)
157 {
158 throw FileError("Invalid parameter (" + params.front() + ").");
159 }
160
161 /* width and height can be negativ */
162 uint32_t width = static_cast<uint32_t>(abs(m_infoheader.biWidth));
163 uint32_t height = static_cast<uint32_t>(abs(m_infoheader.biHeight));
164
165 /* check parameter values are in range */
166 if (pparams[0] < 0 || pparams[0] > width
167 || pparams[1] < 0 || pparams[1] > height)
168 throw FileError("At least one x/y-parameter is out of range.");
169
170 /* check parameter values are in range */
171 unsigned int max[3];
172 m_pixelformat->getMaxColor(&max[0], &max[1], &max[2]);
173 if (pparams[4] < 0 || pparams[4] > max[0]
174 || pparams[5] < 0 || pparams[5] > max[1]
175 || pparams[6] < 0 || pparams[6] > max[2])
176 throw FileError("At least one pixel color parameter is out of range.");
177
178 if (pparams[2] < 0 || pparams[2] + pparams[0] > width
179 || pparams[3] < 0 || pparams[3] + pparams[1] > height)
180 throw FileError("At least one w/h-parameter is out of range.");
181
182 /* call setPixel for every pixel in the rectangel */
183 for(uint32_t i = pparams[0]; i < pparams[2] + pparams[0]; i++)
184 {
185 for(uint32_t j = pparams[1]; j < pparams[3] + pparams[1]; j++)
186 {
187 try
188 {
189 m_pixelformat->setPixel(&pparams[4], i, j);
190 }
191 catch(CPixelFormat::PixelFormatError& ex)
192 {
193 stringstream errstr;
194 errstr << "Can't set pixel (pos=[" << i << "," << j << "] col=["
195 << pparams[4] << "," << pparams[5] << "," << pparams[6] << "]): "
196 << ex.what();
197 throw FileError(errstr.str());
198 }
199 }
200 }
201}
202
203/*----------------------------------------------------------------------------*/
204
205#include <iostream>
206void CBitmap::invert(std::list<std::string> params)
207{
208 /* check prerequirements */
209 if (params.size() != 0)
210 throw FileError("Invalid number of function parameters (must be 0).");
211
212 /* do nothing if no pixel exists */
213 if (m_pixeldata == NULL || m_pixelformat == NULL)
214 return;
215
216 /* width and height can be negativ */
217 uint32_t width = static_cast<uint32_t>(abs(m_infoheader.biWidth));
218 uint32_t height = static_cast<uint32_t>(abs(m_infoheader.biHeight));
219 unsigned int pixelwidth = m_pixelformat->getBitCount()/8;
220
221 /* calc rowsize - boundary is 32 */
222 uint32_t rowsize = 4 * static_cast<uint32_t>(
223 ((m_pixelformat->getBitCount() * abs(m_infoheader.biWidth)) + 31) / 32
224 );
225
226 for(uint32_t i = 0; i < height; i++)
227 {
228 for(uint32_t j = 0; j <= width; j++)
229 {
230 cout << j << endl;
231 }
232 }
233
234#if 0
235/* uint32_t offset = i * rowsize;
236
237 for(uint32_t j = 0; j <= width/2; j++)
238 {
239 uint32_t poffset = offset + j * pixelwidth;
240 uint32_t pbackset = offset + width * pixelwidth - j * pixelwidth;
241
242 /* boundary check */
243 if (pbackset > m_infoheader.biSizeImage)
244 throw FileError("Mirrored pixel position is out of range.");
245
246 /* mirroring, backup right data first */
247 copy(m_pixeldata + pbackset - pixelwidth, m_pixeldata + pbackset, buf);
248 copy(m_pixeldata + poffset, m_pixeldata + poffset + pixelwidth, m_pixeldata + pbackset - pixelwidth);
249 copy(buf, buf + pixelwidth, m_pixeldata + poffset);
250 }
251 }
252#endif
253}
254
255/*----------------------------------------------------------------------------*/
256
257void CBitmap::brightness(std::list<std::string> params)
258{
259}
260
261/*----------------------------------------------------------------------------*/
262
263void CBitmap::mirror_y(std::list<std::string> params)
264{
265 /* check prerequirements */
266 if (params.size() != 0)
267 throw FileError("Invalid number of function parameters (must be 0).");
268
269 /* do nothing if no pixel exists */
270 if (m_pixeldata == NULL || m_pixelformat == NULL)
271 return;
272
273 /* height can be negativ */
274 uint32_t height = static_cast<uint32_t>(abs(m_infoheader.biHeight));
275
276 /* calc rowsize - boundary is 32 */
277 uint32_t rowsize = 4 * static_cast<uint32_t>(
278 ((m_pixelformat->getBitCount() * abs(m_infoheader.biWidth)) + 31) / 32
279 );
280
281 uint8_t *buf = new uint8_t[rowsize];
282 for(uint32_t i = 0; i < height/2; i++)
283 {
284 uint32_t j = height - i - 1;
285 uint32_t offset = i * rowsize;
286 uint32_t backset = j * rowsize;
287
288 /* boundary check */
289 if (offset + rowsize > m_infoheader.biSizeImage
290 || backset + rowsize > m_infoheader.biSizeImage)
291 throw FileError("Mirrored pixel position is out of range.");
292
293 /* mirroring, backup lower data first */
294 copy(m_pixeldata + backset, m_pixeldata + backset + rowsize, buf);
295 copy(m_pixeldata + offset, m_pixeldata + offset + rowsize, m_pixeldata + backset);
296 copy(buf, buf + rowsize, m_pixeldata + offset);
297 }
298 delete[] buf;
299}
300
301/*----------------------------------------------------------------------------*/
302
303void CBitmap::mirror_x(std::list<std::string> params)
304{
305 /* check prerequirements */
306 if (params.size() != 0)
307 throw FileError("Invalid number of function parameters (must be 0).");
308
309 /* do nothing if no pixel exists */
310 if (m_pixeldata == NULL || m_pixelformat == NULL)
311 return;
312
313 /* width and height can be negativ */
314 uint32_t width = static_cast<uint32_t>(abs(m_infoheader.biWidth));
315 uint32_t height = static_cast<uint32_t>(abs(m_infoheader.biHeight));
316
317 /* calc rowsize - boundary is 32 */
318 uint32_t rowsize = 4 * static_cast<uint32_t>(
319 ((m_pixelformat->getBitCount() * abs(m_infoheader.biWidth)) + 31) / 32
320 );
321
322 /* calc pixelwidth */
323 unsigned int pixelwidth = m_pixelformat->getBitCount()/8;
324
325 uint8_t *buf = new uint8_t[pixelwidth];
326 for(uint32_t i = 0; i < height; i++)
327 {
328 uint32_t offset = i * rowsize;
329
330 for(uint32_t j = 0; j <= width/2; j++)
331 {
332 uint32_t poffset = offset + j * pixelwidth;
333 uint32_t pbackset = offset + width * pixelwidth - j * pixelwidth;
334
335 /* boundary check */
336 if (pbackset > m_infoheader.biSizeImage)
337 throw FileError("Mirrored pixel position is out of range.");
338
339 /* mirroring, backup right data first */
340 copy(m_pixeldata + pbackset - pixelwidth, m_pixeldata + pbackset, buf);
341 copy(m_pixeldata + poffset, m_pixeldata + poffset + pixelwidth, m_pixeldata + pbackset - pixelwidth);
342 copy(buf, buf + pixelwidth, m_pixeldata + poffset);
343 }
344 }
345 delete[] buf;
346}
347
348/*----------------------------------------------------------------------------*/
349
350#ifdef DEBUG
351void CBitmap::dump(std::ostream& out)
352{
353 out
354 << "Bitmap File Header:" << endl
355 << " bfType=" << m_fileheader.bfType[0] << m_fileheader.bfType[1]
356 << ", bfSize=" << m_fileheader.bfSize
357 << ", bfReserved=" << m_fileheader.bfReserved
358 << ", bfOffBits=" << m_fileheader.bfOffBits
359 << endl;
360
361 out
362 << "Bitmap Info Header:" << endl
363 << " biSize=" << m_infoheader.biSize
364 << ", biWidth=" << m_infoheader.biWidth
365 << ", biHeight=" << m_infoheader.biHeight
366 << ", biPlanes=" << m_infoheader.biPlanes
367 << endl
368
369 << " biBitCount=" << m_infoheader.biBitCount
370 << ", biCompression=" << m_infoheader.biCompression
371 << ", biSizeImage=" << m_infoheader.biSizeImage
372 << endl
373
374 << " biXPelsPerMeter=" << m_infoheader.biXPelsPerMeter
375 << ", biYPelsPerMeter=" << m_infoheader.biYPelsPerMeter
376 << ", biClrUsed=" << m_infoheader.biClrUsed
377 << ", biClrImportant=" << m_infoheader.biClrImportant
378 << endl;
379}
380#endif
381
382/* vim: set et sw=2 ts=2: */