From b0442de485dcb6328366d9b05a62af345e5fa39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Neuwirth?= Date: Fri, 1 May 2009 14:58:58 +0200 Subject: Adding cpixelformat_indexd8.h and .cpp. Adding virtual methode getColorMode to CPixelFormat. Adding color table to CBitmap. Adding implementation of CPixmap --- ue2/imgsynth2/cbitmap.cpp | 8 + ue2/imgsynth2/cbitmap.h | 5 + ue2/imgsynth2/cpixelformat.h | 11 ++ ue2/imgsynth2/cpixelformat_bgr24.h | 15 +- ue2/imgsynth2/cpixelformat_bgr555.h | 14 ++ ue2/imgsynth2/cpixelformat_indexed8.cpp | 90 ++++++++++ ue2/imgsynth2/cpixelformat_indexed8.h | 102 +++++++++++ ue2/imgsynth2/cpixmap.cpp | 226 ++++++++++++++++++------- ue2/imgsynth2/cpixmap.h | 62 ++++--- ue2/imgsynth2/cscriptparser.cpp | 2 +- ue2/imgsynth2/test/yellow_man1_indexed8_in.xpm | 9 +- 11 files changed, 444 insertions(+), 100 deletions(-) create mode 100644 ue2/imgsynth2/cpixelformat_indexed8.cpp create mode 100644 ue2/imgsynth2/cpixelformat_indexed8.h (limited to 'ue2/imgsynth2') diff --git a/ue2/imgsynth2/cbitmap.cpp b/ue2/imgsynth2/cbitmap.cpp index b9cfc62..acee870 100644 --- a/ue2/imgsynth2/cbitmap.cpp +++ b/ue2/imgsynth2/cbitmap.cpp @@ -25,6 +25,14 @@ CBitmap::~CBitmap() for (it = m_handlers.begin(); it != m_handlers.end(); it++) delete *it; m_pixelformat = NULL; + + /* delete color table */ + map >::iterator it1; + map::iterator it2; + for ( it1= xpmColors.begin() ; it1 != xpmColors.end(); it1++ ) + for ( it2=(*it1).second.begin() ; it2 != (*it1).second.end(); it2++ ) + delete [] (*it2).second; + } /*----------------------------------------------------------------------------*/ diff --git a/ue2/imgsynth2/cbitmap.h b/ue2/imgsynth2/cbitmap.h index f8f8850..f521bcc 100644 --- a/ue2/imgsynth2/cbitmap.h +++ b/ue2/imgsynth2/cbitmap.h @@ -9,6 +9,8 @@ #define CBITMAP_H #include +#include +#include #include "cfile.h" class CPixelFormat; @@ -132,6 +134,9 @@ class CBitmap : public CFile std::set m_handlers; /** pointer to CPixelFormat implementation */ CPixelFormat *m_pixelformat; + /* color table */ + std::map > xpmColors; + }; #endif diff --git a/ue2/imgsynth2/cpixelformat.h b/ue2/imgsynth2/cpixelformat.h index 911a141..2300f2f 100644 --- a/ue2/imgsynth2/cpixelformat.h +++ b/ue2/imgsynth2/cpixelformat.h @@ -10,6 +10,7 @@ #define CPIXELFORMAT_H #include +#include #include class CBitmap; @@ -108,6 +109,16 @@ class CPixelFormat */ virtual uint32_t getBitCount() = 0; + /** + * @method getColorMode + * @brief returns the color mode supported by this class + * @param - + * @return color mode supported by this class + * @globalvars none + * @exception none + * @conditions none + */ + virtual std::string getColorMode() = 0; /* * TODO */ diff --git a/ue2/imgsynth2/cpixelformat_bgr24.h b/ue2/imgsynth2/cpixelformat_bgr24.h index 73f22c1..da1592b 100644 --- a/ue2/imgsynth2/cpixelformat_bgr24.h +++ b/ue2/imgsynth2/cpixelformat_bgr24.h @@ -74,7 +74,20 @@ class CPixelFormat_BGR24 : public CPixelFormat { return 24; } - + + /** + * @method getColorMode + * @brief returns the color mode supported by this class + * @param - + * @return color mode supported by this class + * @globalvars none + * @exception none + * @conditions none + */ + std::string getColorMode() + { + return "c"; + } /* * TODO */ diff --git a/ue2/imgsynth2/cpixelformat_bgr555.h b/ue2/imgsynth2/cpixelformat_bgr555.h index b04e4be..890b744 100644 --- a/ue2/imgsynth2/cpixelformat_bgr555.h +++ b/ue2/imgsynth2/cpixelformat_bgr555.h @@ -85,6 +85,20 @@ class CPixelFormat_BGR555 : public CPixelFormat return 16; } + /** + * @method getColorMode + * @brief returns the color mode supported by this class + * @param - + * @return color mode supported by this class + * @globalvars none + * @exception none + * @conditions none + */ + std::string getColorMode() + { + return "c"; + } + /* * TODO */ diff --git a/ue2/imgsynth2/cpixelformat_indexed8.cpp b/ue2/imgsynth2/cpixelformat_indexed8.cpp new file mode 100644 index 0000000..c62a1ba --- /dev/null +++ b/ue2/imgsynth2/cpixelformat_indexed8.cpp @@ -0,0 +1,90 @@ +/** + * @module CPixelFormat_Indexed8 + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief Implementation of CPixelFormat handling 24bit color Windows Bitmaps. + * @date 18.04.2009 + */ + +#include +#include "cpixelformat_indexed8.h" + +using namespace std; + +void CPixelFormat_Indexed8::getPixel(uint32_t *pixel, uint32_t x, uint32_t y) +{ + /* + * pixel[0] ... red + * pixel[1] ... green + * pixel[2] ... blue + */ + // if (m_bitmap->getPixelData() == NULL) + // throw PixelFormatError("No pixelbuffer allocated."); + + /* calc rowsize - boundary is 32 */ + /* uint32_t rowsize = 4 * static_cast( + ((getBitCount() * abs(m_bitmap->getInfoHeader().biWidth)) + 31) / 32 + );*/ + + /* if height is positive the y-coordinates are mirrored */ + /* if (m_bitmap->getInfoHeader().biHeight > 0) + y = m_bitmap->getInfoHeader().biHeight - y - 1; + uint32_t offset = y * rowsize + x * (4 * getBitCount() / 32); + + /* boundary check */ + /* if (offset + getBitCount()/8 > m_bitmap->getInfoHeader().biSizeImage) + throw PixelFormatError("Pixel position is out of range."); + + /* get pixel */ +/* try + { + pixel[0] = boost::numeric_cast(*(m_bitmap->getPixelData() + offset + 2)); + pixel[1] = boost::numeric_cast(*(m_bitmap->getPixelData() + offset + 1)); + pixel[2] = boost::numeric_cast(*(m_bitmap->getPixelData() + offset)); + } + catch(boost::numeric::bad_numeric_cast& ex) + { + throw PixelFormatError("Unable to convert pixelcolor to correct size: " + string(ex.what())); + }*/ +} + +void CPixelFormat_Indexed8::setPixel(const uint32_t *pixel, uint32_t x, uint32_t y) +{ + /* + * pixel[0] ... red + * pixel[1] ... green + * pixel[2] ... blue + */ +/* if (m_bitmap->getPixelData() == NULL) + throw PixelFormatError("No pixelbuffer allocated."); + + /* calc rowsize - boundary is 32 */ + /* uint32_t rowsize = 4 * static_cast( + ((getBitCount() * abs(m_bitmap->getInfoHeader().biWidth)) + 31) / 32 + ); + + /* if height is positive the y-coordinates are mirrored */ + /* if (m_bitmap->getInfoHeader().biHeight > 0) + y = m_bitmap->getInfoHeader().biHeight - y - 1; + uint32_t offset = y * rowsize + x * (4 * getBitCount() / 32); + + /* boundary check */ + /* if (offset + getBitCount()/8 > m_bitmap->getInfoHeader().biSizeImage) + throw PixelFormatError("Pixel position is out of range."); + + /* convert color values to correct types */ + /*uint8_t data[3]; + try + { + data[0] = boost::numeric_cast(pixel[2]); + data[1] = boost::numeric_cast(pixel[1]); + data[2] = boost::numeric_cast(pixel[0]); + } + catch(boost::numeric::bad_numeric_cast& ex) + { + throw PixelFormatError("Unable to convert pixelcolor to correct size: " + string(ex.what())); + } + + copy(data, data + 3, m_bitmap->getPixelData() + offset); +*/} + +/* vim: set et sw=2 ts=2: */ diff --git a/ue2/imgsynth2/cpixelformat_indexed8.h b/ue2/imgsynth2/cpixelformat_indexed8.h new file mode 100644 index 0000000..ff95840 --- /dev/null +++ b/ue2/imgsynth2/cpixelformat_indexed8.h @@ -0,0 +1,102 @@ +/** + * @module cpixelformat_bgr24 + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief Implementation of CPixelFormat handling 24bit color Windows Bitmaps. + * @date 18.04.2009 + */ + +#ifndef CPixelFormat_Indexed8_H +#define CPixelFormat_Indexed8_H + +#include +#include "cpixelformat.h" +#include "cpixmap.h" +/** + * @class CPixelFormat_Indexed8 + * @brief Implementation of CPixelFormat handling 24bit color Windows Bitmaps. + * + * On error CPixelFormat::PixelFormatError is thrown. + */ +class CPixelFormat_Indexed8 : public CPixelFormat +{ + public: + /** + * @method CPixelFormat_Indexed8 + * @brief Default ctor + * @param bitmap pointer to CBitmap instance + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CPixelFormat_Indexed8(CPixmap *pixmap) + : CPixelFormat(pixmap) + {} + + /** + * @method ~CPixelFormat_Indexed8 + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CPixelFormat_Indexed8() + {} + + /** + * @method setPixel + * @brief Modifies pixel at coordinates x, y + * @param pixel pointer to new pixel data + * @param x x-coordinate + * @param y y-coordinate + * @return - + * @globalvars none + * @exception PixelFormatError + * @conditions none + */ + void setPixel(const uint32_t *pixel, uint32_t x, uint32_t y); + + /* TODO */ + void getPixel(uint32_t *pixel, uint32_t x, uint32_t y); + + /** + * @method getBitCount + * @brief returns the bitcount needed for indexing the color tabel. + * @param - + * @return bitcount of indexes supported by this class + * @globalvars none + * @exception none + * @conditions none + */ + uint32_t getBitCount() + { + return 8; + } + + /** + * @method getColorMode + * @brief returns the color mode supported by this class + * @param - + * @return color mode supported by this class + * @globalvars none + * @exception none + * @conditions none + */ + std::string getColorMode() + { + return "c"; + } + /* + * TODO + */ + void getMaxColor(unsigned int *red, unsigned int *green, unsigned int *blue) + { + *red = *green = *blue = 255; /* 2^8 - 1 */ + } +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue2/imgsynth2/cpixmap.cpp b/ue2/imgsynth2/cpixmap.cpp index de9ec94..91419b6 100644 --- a/ue2/imgsynth2/cpixmap.cpp +++ b/ue2/imgsynth2/cpixmap.cpp @@ -1,5 +1,5 @@ /** - * @module CPixMap + * @module CPixmap * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) * @brief Implementation of CFile handling Windows Bitmaps. * @date 27.04.2009 @@ -11,14 +11,19 @@ #ifdef DEBUG # include #endif +#include +#include # include # include + + + #include "cpixmap.h" #include "cpixelformat_indexed8.h" using namespace std; -CPixMap::CPixMap() +CPixmap::CPixmap() { m_types.insert("XPM"); @@ -31,10 +36,12 @@ CPixMap::CPixMap() /*----------------------------------------------------------------------------*/ -void CPixMap::read(std::ifstream& in) +void CPixmap::read(std::ifstream& in) { string str; + m_fileheader._XPMEXT = false; + m_fileheader._HOTSPOT = false; /* parse the values section */ getline( in, str, '"'); @@ -46,62 +53,73 @@ void CPixMap::read(std::ifstream& in) istr >> m_fileheader.nColor ; istr >> m_fileheader.nChar ; - /* if there are optional values */ - if (in.good()) - { - istr >> m_fileheader.xHotspot; - istr >> m_fileheader.yHotspot; - } - else + /*optional values */ + if (istr.good()) { - m_fileheader.xHotspot = NULL; - m_fileheader.yHotspot = NULL; + string tmp; + istr >> tmp; + if(tmp.compare("XPMEXT") == 0) + m_fileheader._XPMEXT = true; + else + { + m_fileheader._HOTSPOT = true; + m_fileheader.xHotspot = + static_cast(strtoul(tmp.c_str(), NULL, 16)); + istr >> m_fileheader.yHotspot; + } + if (istr.good()) + { + istr >> tmp; + if (tmp.compare("XPMEXT") == 0) + m_fileheader._XPMEXT = true; + } } + - /* parse the colors section */ + /* parse color table*/ getline( in, str, '"'); + string character, mode, colors; for (unsigned int i = 0; i < m_fileheader.nColor; i++ ) { getline( in, str, '"' ); stringstream istr2 (str ); - char character; - string mode, colors; - + istr2 >> character; istr2 >> mode; istr2 >> colors; - //m_fileheader.xpmColors[character][mode] = colors; - m_fileheader.xpmColors[character] = colors; + + if ( colors.size() != 7) + throw FileError("Pixmap color tabel is invalid."); + if ( colors.at(0) != '#') + throw FileError("Pixmap color tabel value is not hexadecimal."); + + xpmColors[character][mode] = new (nothrow) unsigned int[3]; + if (xpmColors[character][mode] == 0) + throw FileError("Bad color table allocation."); + + xpmColors[character][mode][0] = + static_cast(strtoul(colors.substr(1,2).c_str(), NULL, 16)); + xpmColors[character][mode][1] = + static_cast(strtoul(colors.substr(3,2).c_str(), NULL, 16)); + xpmColors[character][mode][2] = + static_cast(strtoul(colors.substr(5,2).c_str(), NULL, 16)); + + + + + getline( in, str, '"' ); } - -/* colors.replace(0,1,"0x"); - colors.insert(4, " 0x"); - colors.insert(9," 0x"); - - stringstream istr3 (colors, stringstream::out|stringstream::in ); - istr3 >>hex>> r; - istr3 >>hex>> g; - istr3 >>hex>> b; - //?????????????ß - cout<(r); - m_fileheader.xpmColors[c1]['g'] = static_cast(g); - m_fileheader.xpmColors[c1]['b'] = static_cast(b);*/ - - - - /* read pixel data using separate class */ + /* read pixel data using separate class */ if (getPixelDataSize() > 0) { if (m_pixeldata != NULL) delete[] m_pixeldata; m_pixeldata = new uint8_t[getPixelDataSize()]; - /* parse the pixel data */ for (unsigned int y = 0; y < getHeight(); y++ ) { for (unsigned int x = 0; x < getWidth(); x++ ) @@ -114,58 +132,140 @@ void CPixMap::read(std::ifstream& in) } } + /* parse extension */ + if ( m_fileheader._XPMEXT ) + getline( in, m_fileheader.extension, '}' ); /* debug*/ - CPixMap::dump (cout); + CPixmap::dump (cout); - + /* get pixelformat instance */ + m_pixelformat = NULL; + set::iterator it; + for (it = m_handlers.begin(); it != m_handlers.end(); it++) + { + /* check color mode */ + if (mode.compare((*it)->getColorMode()) == 0) + { + m_pixelformat = *it; + break; + } + } + if (m_pixelformat == NULL) + throw FileError("Pixmap color mode \""+mode+"\" is not supported."); } /*----------------------------------------------------------------------------*/ -void CPixMap::write(std::ofstream& out) +void CPixmap::write(std::ofstream& out, std::string& filename) { + + /* header comment */ out<<"/* XPM */"< >::iterator it1; + map::iterator it2; + + for ( it1= xpmColors.begin() ; it1 != xpmColors.end(); it1++ ) + { + out << "\""<<(*it1).first; + for ( it2=(*it1).second.begin() ; it2 != (*it1).second.end(); it2++ ) + { + + out<<"\t" <<(*it2).first<<"\t#"; + + for (int i = 0 ; i < 3; i++ ) + { + out.width(2); + out << hex < "<< (*it2).second< -#include #include "cbitmap.h" /** - * @class CBitmap - * @brief Implementation of CFile handling Windows Bitmaps. + * @class CPixmap + * @brief Implementation of CFile handling Pixmap file format. * - * In order to support operations on bitmaps with different color bitcounts - * different implementations of CPixelFormat are used. These classes are - * allowed to modify the bitmap headers and pixelbuffer directly. + * In order to support operations on pixmaps in color mode an + * implementations of CPixelFormat is used. These classe are + * allowed to modify the pixmap header, pixelbuffer and color table directly. * * On error CFile::FileError is thrown. */ -class CPixMap : public CBitmap +class CPixmap : public CBitmap { public: /** - * @method CPixMap + * @method CPixmap * @brief Default ctor * @param - * @return - @@ -35,10 +34,10 @@ class CPixMap : public CBitmap * @exception none * @conditions none */ - CPixMap(); + CPixmap(); /** - * @method ~CPixMap + * @method ~CPixmap * @brief Default dtor * @param - * @return - @@ -46,12 +45,12 @@ class CPixMap : public CBitmap * @exception none * @conditions none */ - ~CPixMap() + ~CPixmap() {} /** * @method read - * @brief Reads Windows Bitmap from filestream. + * @brief Reads Pixmap from filestream. * On error an exception is thrown. * @param in filestream to read data from * @return - @@ -64,7 +63,7 @@ class CPixMap : public CBitmap /** * @method write - * @brief Writes Windows Bitmap to filestream. + * @brief Writes Pixmap to filestream. * @param out filestream to read data from * @return - * @globalvars none @@ -73,11 +72,11 @@ class CPixMap : public CBitmap * @conditions none */ - void write(std::ofstream& out); + void write(std::ofstream& out, std::string& filename); #ifdef DEBUG /** * @method dump - * @brief Dumps the Windows Bitmap file headers to ostream + * @brief Dumps the Pixmap file header and pixel data to ostream * @param out output stream * @return - * @globalvars @@ -90,7 +89,7 @@ class CPixMap : public CBitmap /** - * @brief Windows Bitmap Info Header structure + * @brief Pixmap Header structure */ #pragma pack(push,1) typedef struct @@ -101,25 +100,23 @@ class CPixMap : public CBitmap uint32_t xpmHeight; /** the number of colors (signed integer) */ uint32_t nColor; - /** the number of characters per pixel (signed integer) */ uint32_t nChar; - /** X-Position Hotspots */ uint32_t xHotspot; - /** Y-Position Hotspots */ uint32_t yHotspot; - - /* color tables*/ - // std::map > xpmColors; - // std::map xpmColors; - - - } PIXMAP_FILEHEADER; + /* is hotspot set */ + bool _HOTSPOT; + /* XPMEXT extension tag found*/ + bool _XPMEXT; + /* unchanged extension */ + std::string extension; + + } PIXMAP_FILEHEADER; #pragma pack(pop) - /* TODO */ + const uint32_t getPixelDataSize() { return m_fileheader.xpmWidth * @@ -127,21 +124,20 @@ class CPixMap : public CBitmap m_fileheader.nChar; } - /* TODO */ + const uint32_t getHeight() { /* width and height can be negativ */ return m_fileheader.xpmHeight; } - /* TODO */ const uint32_t getWidth() { /* width and height can be negativ */ return m_fileheader.xpmWidth; } - /* TODO */ + const bool isMirrored() { /* pixmap is never mirrored */ diff --git a/ue2/imgsynth2/cscriptparser.cpp b/ue2/imgsynth2/cscriptparser.cpp index e6bc9ae..6b886a3 100644 --- a/ue2/imgsynth2/cscriptparser.cpp +++ b/ue2/imgsynth2/cscriptparser.cpp @@ -20,7 +20,7 @@ CScriptparser::CScriptparser(const std::string& scriptfile) { /* add our handlers */ m_handlers.insert(new CWindowsBitmap); - m_handlers.insert(new CPixMap); + m_handlers.insert(new CPixmap); } /*----------------------------------------------------------------------------*/ diff --git a/ue2/imgsynth2/test/yellow_man1_indexed8_in.xpm b/ue2/imgsynth2/test/yellow_man1_indexed8_in.xpm index cbfe217..6e5fa2c 100644 --- a/ue2/imgsynth2/test/yellow_man1_indexed8_in.xpm +++ b/ue2/imgsynth2/test/yellow_man1_indexed8_in.xpm @@ -1,6 +1,6 @@ /* XPM */ static char * yellow_man1_default_xpm[] = { -"9 17 2 1", +"9 17 2 1 0 0 XPMEXT", ". c #000000", "# c #FFF200", ".........", @@ -19,4 +19,9 @@ static char * yellow_man1_default_xpm[] = { "...#.#...", "...#.#...", ".........", -"........."}; +"........." +"XPMEXT ext1 data1", +"XPMEXT ext2", +"data2_1", +"data2_2", +"XPMENDEXT"}; -- cgit v1.2.3