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.cpp151
1 files changed, 114 insertions, 37 deletions
diff --git a/ue2/imgsynth2/cbitmap.cpp b/ue2/imgsynth2/cbitmap.cpp
index b9cfc62..a064130 100644
--- a/ue2/imgsynth2/cbitmap.cpp
+++ b/ue2/imgsynth2/cbitmap.cpp
@@ -5,6 +5,7 @@
5 * @date 17.04.2009 5 * @date 17.04.2009
6 */ 6 */
7 7
8#include <algorithm>
8#include <boost/lexical_cast.hpp> 9#include <boost/lexical_cast.hpp>
9#include <boost/numeric/conversion/cast.hpp> 10#include <boost/numeric/conversion/cast.hpp>
10#include "cbitmap.h" 11#include "cbitmap.h"
@@ -25,6 +26,11 @@ CBitmap::~CBitmap()
25 for (it = m_handlers.begin(); it != m_handlers.end(); it++) 26 for (it = m_handlers.begin(); it != m_handlers.end(); it++)
26 delete *it; 27 delete *it;
27 m_pixelformat = NULL; 28 m_pixelformat = NULL;
29
30 /* delete colortable content */
31 map<string, CPixelFormat::RGBPIXEL *>::iterator it2;
32 for (it2 = m_colortable.begin(); it2 != m_colortable.end(); it2++)
33 delete (*it2).second;
28} 34}
29 35
30/*----------------------------------------------------------------------------*/ 36/*----------------------------------------------------------------------------*/
@@ -36,6 +42,8 @@ void CBitmap::callFunc(const std::string& func, const std::list<std::string>& pa
36 42
37 if (func == "fillrect") 43 if (func == "fillrect")
38 fillrect(params); 44 fillrect(params);
45 else if (func == "brightness")
46 brightness(params);
39 else if (func == "mirror_x") 47 else if (func == "mirror_x")
40 mirror_x(params); 48 mirror_x(params);
41 else if (func == "mirror_y") 49 else if (func == "mirror_y")
@@ -80,17 +88,22 @@ void CBitmap::fillrect(std::list<std::string> params)
80 throw FileError("At least one x/y-parameter is out of range."); 88 throw FileError("At least one x/y-parameter is out of range.");
81 89
82 /* check parameter values are in range */ 90 /* check parameter values are in range */
83 unsigned int max[3]; 91 CPixelFormat::RGBPIXEL pixel;
84 m_pixelformat->getMaxColor(&max[0], &max[1], &max[2]); 92 m_pixelformat->getMaxColor(pixel);
85 if (pparams[4] < 0 || pparams[4] > max[0] 93 if (pparams[4] < 0 || pparams[4] > pixel.red
86 || pparams[5] < 0 || pparams[5] > max[1] 94 || pparams[5] < 0 || pparams[5] > pixel.green
87 || pparams[6] < 0 || pparams[6] > max[2]) 95 || pparams[6] < 0 || pparams[6] > pixel.blue)
88 throw FileError("At least one pixel color parameter is out of range."); 96 throw FileError("At least one pixel color parameter is out of range.");
89 97
90 if (pparams[2] < 0 || pparams[2] + pparams[0] > getWidth() 98 if (pparams[2] < 0 || pparams[2] + pparams[0] > getWidth()
91 || pparams[3] < 0 || pparams[3] + pparams[1] > getHeight()) 99 || pparams[3] < 0 || pparams[3] + pparams[1] > getHeight())
92 throw FileError("At least one w/h-parameter is out of range."); 100 throw FileError("At least one w/h-parameter is out of range.");
93 101
102 /* new pixel data */
103 pixel.red = pparams[4];
104 pixel.green = pparams[5];
105 pixel.blue = pparams[6];
106
94 /* call setPixel for every pixel in the rectangel */ 107 /* call setPixel for every pixel in the rectangel */
95 for(uint32_t i = pparams[0]; i < pparams[2] + pparams[0]; i++) 108 for(uint32_t i = pparams[0]; i < pparams[2] + pparams[0]; i++)
96 { 109 {
@@ -98,7 +111,7 @@ void CBitmap::fillrect(std::list<std::string> params)
98 { 111 {
99 try 112 try
100 { 113 {
101 m_pixelformat->setPixel(&pparams[4], i, j); 114 m_pixelformat->setPixel(pixel, i, j);
102 } 115 }
103 catch(CPixelFormat::PixelFormatError& ex) 116 catch(CPixelFormat::PixelFormatError& ex)
104 { 117 {
@@ -114,7 +127,6 @@ void CBitmap::fillrect(std::list<std::string> params)
114 127
115/*----------------------------------------------------------------------------*/ 128/*----------------------------------------------------------------------------*/
116 129
117/* TODO */
118void CBitmap::invert(std::list<std::string> params) 130void CBitmap::invert(std::list<std::string> params)
119{ 131{
120 /* check prerequirements */ 132 /* check prerequirements */
@@ -125,49 +137,114 @@ void CBitmap::invert(std::list<std::string> params)
125 if (m_pixeldata == NULL || m_pixelformat == NULL) 137 if (m_pixeldata == NULL || m_pixelformat == NULL)
126 return; 138 return;
127 139
128 /* TODO pixelwidth */ 140 CPixelFormat::RGBPIXEL pixel;
129 unsigned int pixelwidth = m_pixelformat->getBitCount()/8; 141 CPixelFormat::RGBPIXEL max;
130 142 m_pixelformat->getMaxColor(max);
131 /* calc rowsize - boundary is 32 */ 143 if (hasColorTable())
132 uint32_t rowsize = 4 * static_cast<uint32_t>(
133 ((m_pixelformat->getBitCount() * getWidth()) + 31) / 32
134 );
135
136 for(uint32_t i = 0; i < getHeight(); i++)
137 { 144 {
138 for(uint32_t j = 0; j <= getWidth(); j++) 145 /* invert every entry in the colortable */
146 map<string, CPixelFormat::RGBPIXEL *>::iterator it;
147 for (it = m_colortable.begin(); it != m_colortable.end(); it++)
139 { 148 {
140 /*TODO cout << j << endl;*/ 149 (*it).second->red = max.red - (*it).second->red;
141 break; 150 (*it).second->green = max.green - (*it).second->green;
151 (*it).second->blue = max.blue - (*it).second->blue;
142 } 152 }
143 } 153 }
144 154 else
145#if 0 155 {
146 uint32_t offset = i * rowsize; 156 /* invert per pixel */
147 157 for(uint32_t y = 0; y < getHeight(); y++)
148 for(uint32_t j = 0; j <= getWidth()/2; j++)
149 { 158 {
150 uint32_t poffset = offset + j * pixelwidth; 159 for(uint32_t x = 0; x < getWidth(); x++)
151 uint32_t pbackset = offset + getWidth() * pixelwidth - j * pixelwidth; 160 {
152 161 try
153 /* boundary check */ 162 {
154 if (pbackset > m_infoheader.biSizeImage) 163 m_pixelformat->getPixel(pixel, x, y);
155 throw FileError("Mirrored pixel position is out of range."); 164 pixel.red = max.red - pixel.red;
156 165 pixel.green = max.green - pixel.green;
157 /* mirroring, backup right data first */ 166 pixel.blue = max.blue - pixel.blue;
158 copy(m_pixeldata + pbackset - pixelwidth, m_pixeldata + pbackset, buf); 167 m_pixelformat->setPixel(pixel, x, y);
159 copy(m_pixeldata + poffset, m_pixeldata + poffset + pixelwidth, m_pixeldata + pbackset - pixelwidth); 168 }
160 copy(buf, buf + pixelwidth, m_pixeldata + poffset); 169 catch(CPixelFormat::PixelFormatError& ex)
170 {
171 stringstream errstr;
172 errstr << "Can't invert pixel (pos=[" << x << "," << y << "]): "
173 << ex.what();
174 throw FileError(errstr.str());
175 }
176 }
161 } 177 }
162 } 178 }
163#endif
164} 179}
165 180
166/*----------------------------------------------------------------------------*/ 181/*----------------------------------------------------------------------------*/
167 182
168/* TODO */
169void CBitmap::brightness(std::list<std::string> params) 183void CBitmap::brightness(std::list<std::string> params)
170{ 184{
185 /* check prerequirements */
186 if (params.size() != 1)
187 throw FileError("Invalid number of function parameters (must be 1).");
188
189 /* do nothing if no pixel exists */
190 if (m_pixeldata == NULL || m_pixelformat == NULL)
191 return;
192
193 /* convert parameters */
194 float factor;
195 try
196 {
197 factor = boost::lexical_cast<float>(params.front());
198 params.pop_front();
199 }
200 catch(boost::bad_lexical_cast& ex)
201 {
202 throw FileError("Invalid parameter (" + params.front() + ").");
203 }
204
205 /* negative factor doesn't make sense */
206 if (factor < 0)
207 throw FileError("Brightness parameter must be positive.");
208
209 CPixelFormat::RGBPIXEL pixel;
210 CPixelFormat::RGBPIXEL max;
211 m_pixelformat->getMaxColor(max);
212 if (hasColorTable())
213 {
214 /* invert every entry in the colortable */
215 map<string, CPixelFormat::RGBPIXEL *>::iterator it;
216 for (it = m_colortable.begin(); it != m_colortable.end(); it++)
217 {
218 (*it).second->red = min(max.red, static_cast<uint32_t>((*it).second->red * factor));
219 (*it).second->green = min(max.green, static_cast<uint32_t>((*it).second->green * factor));
220 (*it).second->blue = min(max.blue, static_cast<uint32_t>((*it).second->blue * factor));
221 }
222 }
223 else
224 {
225 /* invert per pixel */
226 for(uint32_t y = 0; y < getHeight(); y++)
227 {
228 for(uint32_t x = 0; x < getWidth(); x++)
229 {
230 try
231 {
232 m_pixelformat->getPixel(pixel, x, y);
233 pixel.red = min(max.red, static_cast<uint32_t>(pixel.red * factor));
234 pixel.green = min(max.green, static_cast<uint32_t>(pixel.green * factor));
235 pixel.blue = min(max.blue, static_cast<uint32_t>(pixel.blue * factor));
236 m_pixelformat->setPixel(pixel, x, y);
237 }
238 catch(CPixelFormat::PixelFormatError& ex)
239 {
240 stringstream errstr;
241 errstr << "Can't invert pixel (pos=[" << x << "," << y << "]): "
242 << ex.what();
243 throw FileError(errstr.str());
244 }
245 }
246 }
247 }
171} 248}
172 249
173/*----------------------------------------------------------------------------*/ 250/*----------------------------------------------------------------------------*/