diff options
| author | manuel <manuel@nc8430.lan> | 2009-05-02 16:44:53 +0200 |
|---|---|---|
| committer | manuel <manuel@nc8430.lan> | 2009-05-02 16:44:53 +0200 |
| commit | bcadfa267f976fe9f29afa50a635cbe3ea174e38 (patch) | |
| tree | b069a34c9d100dcc9229311b47cbfa0697ee7fc9 /ue2/imgsynth2/cpixmap.cpp | |
| parent | bca08c6de2b156cbec90944c809e5e7faecd231d (diff) | |
| download | ooprog-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.cpp | 125 |
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 | ||
| 52 | std::string CPixmap::getArrayLine(std::ifstream& in, bool ignore_comments) | 52 | std::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 | |||
| 265 | const 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 | ||
| 244 | void CPixmap::write(std::ofstream& out) | 280 | void 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 |
| 293 | void CPixmap::dump(std::ostream& out) | 344 | void 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 << " " |
