00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qimage.h>
00023 #include <qtextstream.h>
00024 #include <qregexp.h>
00025 #include <qfile.h>
00026 #include <qfileinfo.h>
00027 #include <qdatetime.h>
00028
00029 #include <iostream>
00030
00031 static int primes[] = {
00032 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
00033 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
00034 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
00035 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
00036 179, 181, 191, 193, 197, 199, 211, 223, 227, 229
00037 };
00038
00039 struct EmbedImage {
00040 QString string;
00041 int width;
00042 int height;
00043 bool alpha;
00044 QString name;
00045 };
00046
00047 class KeramikEmbedder {
00048 public:
00049 KeramikEmbedder();
00050 ~KeramikEmbedder();
00051
00052 void embed( const char * );
00053 void writeIndex();
00054
00055 private:
00056 QFile *file;
00057 QPtrList<EmbedImage> *index;
00058 QTextStream stream;
00059 };
00060
00061 KeramikEmbedder::KeramikEmbedder()
00062 {
00063 QDateTime date( QDateTime::currentDateTime() );
00064 QString datestring( date.toString() );
00065
00066 file = new QFile( "tiles.h" );
00067 file->open( IO_WriteOnly | IO_Truncate );
00068
00069 stream.setDevice( file );
00070
00071 stream << "/*\n";
00072 stream << " * Generated by embedtool 1.0 on " << datestring << endl;
00073 stream << " */\n\n";
00074
00075 stream << "#ifndef __TILES_H\n";
00076 stream << "#define __TILES_H\n\n";
00077 stream << "#include <qimage.h>\n";
00078 stream << "#include <qdict.h>\n\n";
00079 stream << "namespace Keramik {\n\n";
00080
00081 index = new QPtrList<EmbedImage>;
00082 index->setAutoDelete( true );
00083 }
00084
00085 KeramikEmbedder::~KeramikEmbedder()
00086 {
00087 stream << "} // namespace Keramik\n\n";
00088 stream << "#endif // __TILES_H\n\n";
00089 stream << "// vim: set noet ts=4 sw=4:\n";
00090
00091 file->close();
00092 delete file;
00093 delete index;
00094 }
00095
00096 void KeramikEmbedder::embed( const char *name )
00097 {
00098 QFileInfo fileinfo( name );
00099 QString basename( fileinfo.baseName() );
00100 QString codename( basename );
00101 QImage image( name );
00102
00103 codename = codename.replace( QRegExp("[^a-zA-Z0-9]"), "_" );
00104
00105 stream << "\tstatic const QRgb " << codename << "_data[] = {" << endl << "\t\t";
00106 stream.setf( QTextStream::hex | QTextStream::right );
00107 stream.fill( '0' );
00108
00109 int pixels = image.width() * image.height();
00110 Q_UINT32 *data = reinterpret_cast<Q_UINT32*>( image.bits() );
00111 bool hasAlpha = false;
00112
00113
00114 for ( int i = 0, j = 0; i < pixels; i++ ) {
00115 if ( qAlpha( *data ) && qAlpha( *data ) != 0xff )
00116 hasAlpha = true;
00117
00118 stream << "0x" << qSetW(8) << *(data++);
00119
00120 if ( i != pixels-1 ) {
00121 stream << ',';
00122
00123 if ( j++ > 4 ) {
00124 j = 0;
00125 stream << endl << "\t\t";
00126 } else
00127 stream << ' ';
00128 }
00129 }
00130
00131 stream.reset();
00132
00133 stream << endl << "\t}; // " << codename << "_data" << endl << endl;
00134
00135 EmbedImage *imginfo = new EmbedImage;
00136 imginfo->width = image.width();
00137 imginfo->height = image.height();
00138 imginfo->alpha = hasAlpha;
00139 imginfo->name = codename;
00140 imginfo->string = basename;
00141 index->append( imginfo );
00142 }
00143
00144 void KeramikEmbedder::writeIndex()
00145 {
00146 stream << "\tstruct EmbedImage {\n";
00147 stream << "\t\tconst char *name;\n";
00148 stream << "\t\tint width;\n";
00149 stream << "\t\tint height;\n";
00150 stream << "\t\tbool alpha;\n";
00151 stream << "\t\tconst QRgb *data;\n";
00152 stream << "\t};\n\n";
00153
00154 uint i = 0;
00155 stream << "\tstatic const EmbedImage image_db[] = {\n";
00156 for ( EmbedImage *image = index->first(); image; image = index->next() )
00157 {
00158 stream << "\t\t{ \"" << image->string << "\", "
00159 << image->width << ", " << image->height <<
00160 ", " << (image->alpha ? "true" : "false")
00161 << ", " << image->name << "_data }";
00162 if ( i++ < index->count() - 1 )
00163 stream << ',';
00164 stream << endl;
00165 }
00166 stream << "\t};\n\n";
00167
00168 uint prime = 0;
00169
00170 for ( i = 0; i < 50; i++ )
00171 if ( (prime = primes[i]) >= index->count() )
00172 break;
00173
00174 stream << "\tclass KeramikImageDb {\n";
00175 stream << "\tprivate:\n";
00176 stream << "\t\tstatic KeramikImageDb *m_inst;\n";
00177 stream << "\t\tQDict<QImage> *db;\n\n";
00178 stream << "\t\tKeramikImageDb() {\n";
00179 stream << "\t\t\tdb = new QDict<QImage>( " << prime << " );\n";
00180 stream << "\t\t\tdb->setAutoDelete( true );\n\n";
00181 stream << "\t\t\tfor ( int i = 0; i < " << index->count() << "; i++ ) {\n";
00182 stream << "\t\t\t\tQImage *img = new QImage( (uchar*)image_db[i].data,\n";
00183 stream << "\t\t\t\t\t\timage_db[i].width, image_db[i].height,\n";
00184 stream << "\t\t\t\t\t\t32, NULL, 0, QImage::LittleEndian );\n\n";
00185 stream << "\t\t\t\tif ( image_db[i].alpha )\n";
00186 stream << "\t\t\t\t\timg->setAlphaBuffer( true );\n\n";
00187 stream << "\t\t\t\tdb->insert( image_db[i].name, img );\n";
00188 stream << "\t\t\t}\n";
00189 stream << "\t\t}\n\n";
00190 stream << "\t\t~KeramikImageDb() {\n";
00191 stream << "\t\t\tdelete db;\n";
00192 stream << "\t\t}\n\n";
00193 stream << "\tpublic:\n";
00194 stream << "\t\tstatic KeramikImageDb* instance() {\n";
00195 stream << "\t\t\tif ( ! m_inst ) m_inst = new KeramikImageDb;\n";
00196 stream << "\t\t\treturn m_inst;\n";
00197 stream << "\t\t}\n\n";
00198 stream << "\t\tstatic void release() {\n";
00199 stream << "\t\t\tif ( m_inst ) delete m_inst;\n";
00200 stream << "\t\t\tm_inst = NULL;\n";
00201 stream << "\t\t}\n\n";
00202 stream << "\t\tQImage *image( const QString &name ) const {\n";
00203 stream << "\t\t\treturn db->find( name );\n";
00204 stream << "\t\t}\n\n";
00205 stream << "\t}; // class KeramikImageDb\n\n";
00206 stream << "\tKeramikImageDb *KeramikImageDb::m_inst = NULL;\n\n";
00207 }
00208
00209 int main( int argv, char **argc )
00210 {
00211 if ( argv < 2 ) {
00212 std::cout << "Insufficient arguments" << std::endl;
00213 return 1;
00214 }
00215
00216 KeramikEmbedder embedder;
00217
00218 for ( int i = 1; i < argv; i++ )
00219 {
00220 std::cout << argc[i] << std::endl;
00221 embedder.embed( argc[i] );
00222 }
00223
00224 embedder.writeIndex();
00225
00226 return 0;
00227 }
00228
00229
00230