summaryrefslogtreecommitdiffstats
path: root/ue2/imgsynth2/cpixmap.cpp
diff options
context:
space:
mode:
authormanuel <manuel@nc8430.lan>2009-05-02 16:44:53 +0200
committermanuel <manuel@nc8430.lan>2009-05-02 16:44:53 +0200
commitbcadfa267f976fe9f29afa50a635cbe3ea174e38 (patch)
treeb069a34c9d100dcc9229311b47cbfa0697ee7fc9 /ue2/imgsynth2/cpixmap.cpp
parentbca08c6de2b156cbec90944c809e5e7faecd231d (diff)
downloadooprog-bcadfa267f976fe9f29afa50a635cbe3ea174e38.tar.gz
ooprog-bcadfa267f976fe9f29afa50a635cbe3ea174e38.tar.bz2
ooprog-bcadfa267f976fe9f29afa50a635cbe3ea174e38.zip
- colortable now uses uint32_t as identifier
- rewrote xpm colortable parsing to convert their identifiers to our own and vica vi - implemented indexed8::setpixel/getpixel - moved rowsize to member variable in cbitmap - added second test for xpm/indexed8
Diffstat (limited to 'ue2/imgsynth2/cpixmap.cpp')
-rw-r--r--ue2/imgsynth2/cpixmap.cpp125
1 files changed, 83 insertions, 42 deletions
diff --git a/ue2/imgsynth2/cpixmap.cpp b/ue2/imgsynth2/cpixmap.cpp
index 9e03d86..94f0310 100644
--- a/ue2/imgsynth2/cpixmap.cpp
+++ b/ue2/imgsynth2/cpixmap.cpp
@@ -49,9 +49,9 @@ std::string CPixmap::getLine(std::ifstream& in, bool ignore_comments)
49 49
50/*----------------------------------------------------------------------------*/ 50/*----------------------------------------------------------------------------*/
51 51
52std::string CPixmap::getArrayLine(std::ifstream& in, bool ignore_comments) 52std::string CPixmap::getCArrayLine(std::ifstream& in)
53{ 53{
54 string line = getLine(in, ignore_comments); 54 string line = getLine(in, true);
55 if (line.empty()) 55 if (line.empty())
56 return line; 56 return line;
57 57
@@ -87,6 +87,18 @@ void CPixmap::read(std::ifstream& in)
87 m_fileheader._XPMEXT = false; 87 m_fileheader._XPMEXT = false;
88 m_fileheader._HOTSPOT = false; 88 m_fileheader._HOTSPOT = false;
89 89
90 /* get pixelformat instance first */
91 m_pixelformat = NULL;
92 set<CPixelFormat *>::iterator it;
93 for (it = m_handlers.begin(); it != m_handlers.end(); it++)
94 {
95 /* we only have one! */
96 m_pixelformat = *it;
97 break;
98 }
99 if (m_pixelformat == NULL)
100 throw FileError("Pixmap color mode is not supported.");
101
90 /* first line has to be PIXMAP_IDENTIFIER */ 102 /* first line has to be PIXMAP_IDENTIFIER */
91 line = getLine(in, false); 103 line = getLine(in, false);
92 if (line != PIXMAP_IDENTIFIER) 104 if (line != PIXMAP_IDENTIFIER)
@@ -115,7 +127,7 @@ void CPixmap::read(std::ifstream& in)
115 throw FileError("Pixmap array has no opening bracket."); 127 throw FileError("Pixmap array has no opening bracket.");
116 128
117 /* parse <Values>-section */ 129 /* parse <Values>-section */
118 line = getArrayLine(in); 130 line = getCArrayLine(in);
119 if (line.empty()) 131 if (line.empty())
120 throw FileError("Pixmap has no Values-section."); 132 throw FileError("Pixmap has no Values-section.");
121 algorithm::split(list, line, is_any_of(" \t")); 133 algorithm::split(list, line, is_any_of(" \t"));
@@ -152,10 +164,14 @@ void CPixmap::read(std::ifstream& in)
152 164
153 /* parse <Colors>-table */ 165 /* parse <Colors>-table */
154 string character; 166 string character;
155 map<string, CPixelFormat::RGBPIXEL *> colors; 167 /* map[id][colortype] = color */
168 map<string, map<string, CPixelFormat::RGBPIXEL *> > colors;
169 /* map[id] = indices */
170 map<string, uint32_t> colornr;
171 uint32_t index = 0;
156 for(uint32_t i = 0; i < m_fileheader.nColor; i++) 172 for(uint32_t i = 0; i < m_fileheader.nColor; i++)
157 { 173 {
158 line = getArrayLine(in); 174 line = getCArrayLine(in);
159 if (line.empty()) 175 if (line.empty())
160 throw FileError("Pixmap has missing colortable-entry."); 176 throw FileError("Pixmap has missing colortable-entry.");
161 algorithm::split(list, line, is_any_of(" \t")); 177 algorithm::split(list, line, is_any_of(" \t"));
@@ -166,19 +182,21 @@ void CPixmap::read(std::ifstream& in)
166 character = list[0]; 182 character = list[0];
167 if (character.length() != m_fileheader.nChar) 183 if (character.length() != m_fileheader.nChar)
168 throw FileError("Pixmap colorcharacter is invalid."); 184 throw FileError("Pixmap colorcharacter is invalid.");
185 if (colors.find(character) != colors.end())
186 throw FileError("Duplicate colorcharacter found.");
169 187
170 /* read colors */ 188 /* read colors */
171 string color("");
172 if ((list.size() - 1) % 2 != 0) 189 if ((list.size() - 1) % 2 != 0)
173 throw FileError("Pixmap color entrys are invalid."); 190 throw FileError("Pixmap color entrys are invalid.");
174 for(uint32_t j = 1; j < list.size(); j = j + 2) 191 for(uint32_t j = 1; j < list.size(); j = j + 2)
175 { 192 {
193 /* we only support hex-color notations */
176 if (list[j + 1].length() != 7) 194 if (list[j + 1].length() != 7)
177 throw FileError("Pixmap color value is invalid."); 195 throw FileError("Pixmap color value is invalid.");
178 if (list[j + 1].at(0) != '#') 196 if (list[j + 1].at(0) != '#')
179 throw FileError("Pixmap color table value is not hexadecimal."); 197 throw FileError("Pixmap color table value is not hexadecimal.");
180 198
181 /* we only support c-colors! */ 199 /* we only support c-colors! - remove only if you free the pixels */
182 if (list[j] != "c") 200 if (list[j] != "c")
183 continue; 201 continue;
184 202
@@ -186,15 +204,17 @@ void CPixmap::read(std::ifstream& in)
186 pixel->red = strtoul(list[j + 1].substr(1, 2).c_str(), NULL, 16); 204 pixel->red = strtoul(list[j + 1].substr(1, 2).c_str(), NULL, 16);
187 pixel->green = strtoul(list[j + 1].substr(3, 2).c_str(), NULL, 16); 205 pixel->green = strtoul(list[j + 1].substr(3, 2).c_str(), NULL, 16);
188 pixel->blue = strtoul(list[j + 1].substr(5, 2).c_str(), NULL, 16); 206 pixel->blue = strtoul(list[j + 1].substr(5, 2).c_str(), NULL, 16);
189 colors[ list[j] ] = pixel; 207 colors[ character ][ list[j] ] = pixel;
190 } 208 }
191 209
192 /* we only support c-colors! */ 210 /* we only support c-colors! */
193 if (colors.find("c") == colors.end()) 211 if (colors[ character ].find("c") == colors[ character ].end())
194 throw FileError("Pixmap color entry has missing c-value."); 212 throw FileError("Pixmap color entry has missing c-value.");
195 213
196 /* add pixel to colortable */ 214 /* add pixel to colortable */
197 m_colortable[character] = colors["c"]; 215 colornr[ character ] = index;
216 m_colortable[ index ] = colors[ character ]["c"];
217 index++;
198 } 218 }
199 219
200 /* read pixel data */ 220 /* read pixel data */
@@ -206,12 +226,27 @@ void CPixmap::read(std::ifstream& in)
206 226
207 for (uint32_t y = 0; y < getHeight(); y++) 227 for (uint32_t y = 0; y < getHeight(); y++)
208 { 228 {
209 line = getArrayLine(in); 229 line = getCArrayLine(in);
210 if (line.empty()) 230 if (line.empty())
211 throw FileError("Pixmap has no pixel data."); 231 throw FileError("Pixmap has no pixel data.");
212 if (line.length() != getWidth()) 232 if (line.length() != getWidth())
213 throw FileError("Pixmap pixeldata width is larger than header width."); 233 throw FileError("Pixmap pixeldata width is larger than header width.");
214 copy(line.c_str(), line.c_str() + line.length(), m_pixeldata + y * getWidth()); 234
235 /* convert color identifier to our own identifiers */
236 for(uint32_t x = 0; x < getWidth(); x++)
237 {
238 character = line.substr(x * m_fileheader.nChar, m_fileheader.nChar);
239 if (colornr.find(character) == colornr.end())
240 throw FileError("Pixel has no reference in colortable.");
241
242 uint32_t offset = y * getWidth() + x;
243
244 /* boundary check */
245 if (offset * sizeof(uint32_t) + sizeof(uint32_t) > getPixelDataSize())
246 throw FileError("Pixel position is out of range.");
247
248 *((uint32_t *)m_pixeldata + offset) = colornr[ character ];
249 }
215 } 250 }
216 } 251 }
217 252
@@ -221,28 +256,32 @@ void CPixmap::read(std::ifstream& in)
221 if (!in.good()) 256 if (!in.good())
222 throw FileError("Pixmap array isn't closed properly."); 257 throw FileError("Pixmap array isn't closed properly.");
223 258
224 /* get pixelformat instance */ 259 /* set rowsize */
225 m_pixelformat = NULL; 260 m_rowsize = sizeof(uint32_t) * getWidth();
226 set<CPixelFormat *>::iterator it; 261}
227 for (it = m_handlers.begin(); it != m_handlers.end(); it++) 262
263/*----------------------------------------------------------------------------*/
264
265const std::string CPixmap::getXPMColorID(unsigned int index, unsigned int length)
266{
267 static const char code[] = PIXMAP_COLORCHARS;
268 string str("");
269 for(unsigned int i = length - 1; i > 0; i--)
228 { 270 {
229 /* we only have one! */ 271 str += code[index % strlen(code)];
230 m_pixelformat = *it; 272 index /= strlen(code);
231 break;
232 } 273 }
233 if (m_pixelformat == NULL) 274 str += code[index];
234 throw FileError("Pixmap color mode is not supported."); 275 return str;
235
236#ifdef DEBUG
237 /* debug*/
238 CPixmap::dump(cout);
239#endif
240} 276}
241 277
242/*----------------------------------------------------------------------------*/ 278/*----------------------------------------------------------------------------*/
243 279
244void CPixmap::write(std::ofstream& out) 280void CPixmap::write(std::ofstream& out)
245{ 281{
282 m_fileheader.nColor = m_colortable.size();
283 m_fileheader.nChar = m_fileheader.nColor / strlen(PIXMAP_COLORCHARS) + 1;
284
246 /* header comment */ 285 /* header comment */
247 out << PIXMAP_IDENTIFIER << endl; 286 out << PIXMAP_IDENTIFIER << endl;
248 287
@@ -259,10 +298,10 @@ void CPixmap::write(std::ofstream& out)
259 out << "\"," << endl; 298 out << "\"," << endl;
260 299
261 /* color table */ 300 /* color table */
262 map<string, CPixelFormat::RGBPIXEL *>::iterator it; 301 map<uint32_t, CPixelFormat::RGBPIXEL *>::iterator it;
263 for (it = m_colortable.begin(); it != m_colortable.end(); it++) 302 for (it = m_colortable.begin(); it != m_colortable.end(); it++)
264 { 303 {
265 out << "\"" << (*it).first; 304 out << "\"" << getXPMColorID((*it).first, m_fileheader.nChar);
266 /* we only support c-colors! */ 305 /* we only support c-colors! */
267 out << "\tc #"; 306 out << "\tc #";
268 out << setfill('0') << setw(2) << hex << uppercase << (*it).second->red 307 out << setfill('0') << setw(2) << hex << uppercase << (*it).second->red
@@ -275,8 +314,20 @@ void CPixmap::write(std::ofstream& out)
275 for (uint32_t y = 0; y < getHeight(); y++) 314 for (uint32_t y = 0; y < getHeight(); y++)
276 { 315 {
277 out << "\""; 316 out << "\"";
278 uint32_t offset = y * getWidth(); 317 for(uint32_t x = 0; x < getWidth(); x++)
279 copy(m_pixeldata + offset, m_pixeldata + offset + getWidth(), ostream_iterator<uint8_t>(out)); 318 {
319 uint32_t offset = y * getWidth() + x;
320
321 /* boundary check */
322 if (offset * sizeof(uint32_t) + sizeof(uint32_t) > getPixelDataSize())
323 throw FileError("Pixel position is out of range.");
324
325 uint32_t color = *((uint32_t *)m_pixeldata + offset);
326
327 if ((it = m_colortable.find(color)) == m_colortable.end())
328 throw FileError("Pixel has no reference in colortable.");
329 out << getXPMColorID((*it).first, m_fileheader.nChar);
330 }
280 out << "\"," << endl; 331 out << "\"," << endl;
281 } 332 }
282 333
@@ -292,16 +343,6 @@ void CPixmap::write(std::ofstream& out)
292#ifdef DEBUG 343#ifdef DEBUG
293void CPixmap::dump(std::ostream& out) 344void CPixmap::dump(std::ostream& out)
294{ 345{
295 /* pixeldata */
296 cout << "[XPM Pixel Data]" << endl;
297 for (uint32_t y = 0; y < getHeight(); y++)
298 {
299 uint32_t offset = y * getWidth();
300 copy(m_pixeldata + offset, m_pixeldata + offset + getWidth(), ostream_iterator<uint8_t>(cout));
301 out << endl;
302 }
303 out << endl;
304
305 /* values*/ 346 /* values*/
306 cout << "[XPM Header Values]" << endl 347 cout << "[XPM Header Values]" << endl
307 << "width=" << m_fileheader.width << endl 348 << "width=" << m_fileheader.width << endl
@@ -316,11 +357,11 @@ void CPixmap::dump(std::ostream& out)
316 << endl; 357 << endl;
317 358
318 /* colors*/ 359 /* colors*/
319 map<string, CPixelFormat::RGBPIXEL *>::iterator it; 360 map<uint32_t, CPixelFormat::RGBPIXEL *>::iterator it;
320 cout << "[Color Table]" << endl; 361 cout << "[Color Table]" << endl;
321 for (it = m_colortable.begin(); it != m_colortable.end(); it++) 362 for (it = m_colortable.begin(); it != m_colortable.end(); it++)
322 { 363 {
323 out << (*it).first << " " 364 out << (*it).first << ": "
324 << setfill('0') << setw(3) << (*it).second->red << " " 365 << setfill('0') << setw(3) << (*it).second->red << " "
325 << setfill('0') << setw(3) << (*it).second->green << " " 366 << setfill('0') << setw(3) << (*it).second->green << " "
326 << setfill('0') << setw(3) << (*it).second->blue << " " 367 << setfill('0') << setw(3) << (*it).second->blue << " "