src/tools/uic3/embed.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the tools applications of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "ui3reader.h"
00025 #include <QFile>
00026 #include <QImage>
00027 #include <QStringList>
00028 #include <QDateTime>
00029 #include <QFileInfo>
00030 #include <QVector>
00031 #include <stdio.h>
00032 #include <ctype.h>
00033 
00034 // on embedded, we do not compress image data. Rationale: by mapping
00035 // the ready-only data directly into memory we are both faster and
00036 // more memory efficient
00037 #if defined(Q_WS_QWS) && !defined(QT_NO_IMAGE_COLLECTION_COMPRESSION)
00038 #  define QT_NO_IMAGE_COLLECTION_COMPRESSION
00039 #elif defined (QT_NO_COMPRESS)
00040 #  define QT_NO_IMAGE_COLLECTION_COMPRESSION
00041 #endif
00042 
00043 struct EmbedImage
00044 {
00045     ~EmbedImage() { delete[] colorTable; }
00046 
00047     int width, height, depth;
00048     int numColors;
00049     QRgb* colorTable;
00050     QString name;
00051     QString cname;
00052     bool alpha;
00053 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00054     ulong compressed;
00055 #endif
00056 };
00057 
00058 static QString convertToCIdentifier( const char *s )
00059 {
00060     QByteArray r = s;
00061     int len = r.length();
00062     if ( len > 0 && !isalpha( (char)r[0] ) )
00063         r[0] = '_';
00064     for ( int i=1; i<len; i++ ) {
00065         if ( !isalnum( (char)r[i] ) )
00066             r[i] = '_';
00067     }
00068 
00069     return QString::fromAscii(r);
00070 }
00071 
00072 
00073 static ulong embedData( QTextStream& out, const uchar* input, int nbytes )
00074 {
00075 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00076     QByteArray bazip( qCompress( input, nbytes ) );
00077     ulong len = bazip.size();
00078 #else
00079     ulong len = nbytes;
00080 #endif
00081     static const char hexdigits[] = "0123456789abcdef";
00082     QString s;
00083     for ( int i=0; i<(int)len; i++ ) {
00084         if ( (i%14) == 0 ) {
00085             s += QLatin1String("\n    ");
00086             out << s.latin1();
00087             s.truncate( 0 );
00088         }
00089         uint v = (uchar)
00090 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00091                  bazip
00092 #else
00093                  input
00094 #endif
00095                  [i];
00096         s += QLatin1String("0x");
00097         s += QLatin1Char(hexdigits[(v >> 4) & 15]);
00098         s += QLatin1Char(hexdigits[v & 15]);
00099         if ( i < (int)len-1 )
00100             s += QLatin1Char(',');
00101     }
00102     if ( s.length() )
00103         out << s.latin1();
00104     return len;
00105 }
00106 
00107 static void embedData( QTextStream& out, const QRgb* input, int n )
00108 {
00109     out << hex;
00110     const QRgb *v = input;
00111     for ( int i=0; i<n; i++ ) {
00112         if ( (i%14) == 0  )
00113             out << "\n    ";
00114         out << "0x";
00115         out << hex << *v++;
00116         if ( i < n-1 )
00117             out << ',';
00118     }
00119     out << dec; // back to decimal mode
00120 }
00121 
00122 void Ui3Reader::embed(const char *project, const QStringList &images)
00123 {
00124 
00125     QString cProject = convertToCIdentifier( project );
00126 
00127     QStringList::ConstIterator it;
00128     out << "/****************************************************************************\n";
00129     out << "** Image collection for project '" << project << "'.\n";
00130     out << "**\n";
00131     out << "** Generated from reading image files: \n";
00132     for ( it = images.begin(); it != images.end(); ++it )
00133         out << "**      " << *it << "\n";
00134     out << "**\n";
00135     out << "** Created: " << QDateTime::currentDateTime().toString() << "\n";
00136     out << "**      by: The User Interface Compiler for Qt version " << QT_VERSION_STR << "\n";
00137     out << "**\n";
00138     out << "** WARNING! All changes made in this file will be lost!\n";
00139     out << "****************************************************************************/\n";
00140     out << "\n";
00141 
00142     out << "#include <qimage.h>\n";
00143     out << "#include <qmime.h>\n";
00144     out << "#include <q3mimefactory.h>\n";
00145     out << "#include <q3dragobject.h>\n";
00146     out << "\n";
00147 
00148     QList<EmbedImage*> list_image;
00149     int image_count = 0;
00150     for ( it = images.begin(); it != images.end(); ++it ) {
00151         QImage img;
00152         if ( !img.load( *it ) ) {
00153             fprintf( stderr, "uic: cannot load image file %s\n", (*it).latin1() );
00154             continue;
00155         }
00156         EmbedImage *e = new EmbedImage;
00157         e->width = img.width();
00158         e->height = img.height();
00159         e->depth = img.depth();
00160         e->numColors = img.numColors();
00161         e->colorTable = new QRgb[e->numColors];
00162         e->alpha = img.hasAlphaBuffer();
00163         QVector<QRgb> ct = img.colorTable();
00164         memcpy(e->colorTable, ct.constData(), e->numColors*sizeof(QRgb));
00165         QFileInfo fi( *it );
00166         e->name = fi.fileName();
00167         e->cname = QString::fromLatin1("image_%1").arg( image_count++);
00168         list_image.append( e );
00169         out << "// " << *it << "\n";
00170         QString s;
00171         if ( e->depth == 1 )
00172             img = img.convertBitOrder(QImage::BigEndian);
00173         out << s.sprintf( "static const unsigned char %s_data[] = {",
00174                           e->cname.latin1() );
00175 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00176         e->compressed =
00177 #endif
00178             embedData( out, img.bits(), img.numBytes() );
00179         out << "\n};\n\n";
00180         if ( e->numColors ) {
00181             out << s.sprintf( "static const QRgb %s_ctable[] = {",
00182                               e->cname.latin1() );
00183             embedData( out, e->colorTable, e->numColors );
00184             out << "\n};\n\n";
00185         }
00186     }
00187 
00188     if ( !list_image.isEmpty() ) {
00189         out << "static const struct EmbedImage {\n"
00190             "    int width, height, depth;\n"
00191             "    const unsigned char *data;\n"
00192 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00193             "    ulong compressed;\n"
00194 #endif
00195             "    int numColors;\n"
00196             "    const QRgb *colorTable;\n"
00197             "    bool alpha;\n"
00198             "    const char *name;\n"
00199             "} embed_image_vec[] = {\n";
00200         EmbedImage *e = 0;
00201         int i;
00202         for (i = 0; i < list_image.count(); ++i) {
00203             e = list_image.at(i);
00204             out << "    { "
00205                 << e->width << ", "
00206                 << e->height << ", "
00207                 << e->depth << ", "
00208                 << "(const unsigned char*)" << e->cname << "_data, "
00209 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00210                 << e->compressed << ", "
00211 #endif
00212                 << e->numColors << ", ";
00213             if ( e->numColors )
00214                 out << e->cname << "_ctable, ";
00215             else
00216                 out << "0, ";
00217             if ( e->alpha )
00218                 out << "true, ";
00219             else
00220                 out << "false, ";
00221             out << "\"" << e->name << "\" },\n";
00222             delete e;
00223         }
00224 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00225         out << "    { 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n";
00226 #else
00227         out << "    { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n";
00228 #endif
00229 
00230         out << "\n"
00231             "static QImage uic_findImage( const QString& name )\n"
00232             "{\n"
00233             "    for ( int i=0; embed_image_vec[i].data; i++ ) {\n"
00234             "        if ( QString::fromUtf8(embed_image_vec[i].name) == name ) {\n"
00235 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
00236             "            QByteArray baunzip;\n"
00237             "            baunzip = qUncompress( embed_image_vec[i].data, \n"
00238             "                embed_image_vec[i].compressed );\n"
00239             "            QImage img((uchar*)baunzip.data(),\n"
00240             "                        embed_image_vec[i].width,\n"
00241             "                        embed_image_vec[i].height,\n"
00242             "                        embed_image_vec[i].depth,\n"
00243             "                        (QRgb*)embed_image_vec[i].colorTable,\n"
00244             "                        embed_image_vec[i].numColors,\n"
00245             "                        QImage::BigEndian\n"
00246             "                );\n"
00247             "            img = img.copy();\n"
00248 #else
00249             "            QImage img((uchar*)embed_image_vec[i].data,\n"
00250             "                        embed_image_vec[i].width,\n"
00251             "                        embed_image_vec[i].height,\n"
00252             "                        embed_image_vec[i].depth,\n"
00253             "                        (QRgb*)embed_image_vec[i].colorTable,\n"
00254             "                        embed_image_vec[i].numColors,\n"
00255             "                        QImage::BigEndian\n"
00256             "                );\n"
00257 #endif
00258             "            if ( embed_image_vec[i].alpha )\n"
00259             "                img.setAlphaBuffer(true);\n"
00260             "            return img;\n"
00261             "        }\n"
00262             "    }\n"
00263             "    return QImage();\n"
00264             "}\n\n";
00265 
00266         out << "class MimeSourceFactory_" << cProject << " : public Q3MimeSourceFactory\n";
00267         out << "{\n";
00268         out << "public:\n";
00269         out << "    MimeSourceFactory_" << cProject << "() {}\n";
00270         out << "    ~MimeSourceFactory_" << cProject << "() {}\n";
00271         out << "    const QMimeSource* data( const QString& abs_name ) const {\n";
00272         out << "\tconst QMimeSource* d = Q3MimeSourceFactory::data( abs_name );\n";
00273         out << "\tif ( d || abs_name.isNull() ) return d;\n";
00274         out << "\tQImage img = uic_findImage( abs_name );\n";
00275         out << "\tif ( !img.isNull() )\n";
00276         out << "\t    ((Q3MimeSourceFactory*)this)->setImage( abs_name, img );\n";
00277         out << "\treturn Q3MimeSourceFactory::data( abs_name );\n";
00278         out << "    };\n";
00279         out << "};\n\n";
00280 
00281         out << "static Q3MimeSourceFactory* factory = 0;\n";
00282         out << "\n";
00283 
00284         out << "void qInitImages_" << cProject << "()\n";
00285         out << "{\n";
00286         out << "    if ( !factory ) {\n";
00287         out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n";
00288         out << "\tQ3MimeSourceFactory::defaultFactory()->addFactory( factory );\n";
00289         out << "    }\n";
00290         out << "}\n\n";
00291 
00292         out << "void qCleanupImages_" << cProject << "()\n";
00293         out << "{\n";
00294         out << "    if ( factory ) {\n";
00295         out << "\tQ3MimeSourceFactory::defaultFactory()->removeFactory( factory );\n";
00296         out << "\tdelete factory;\n";
00297         out << "\tfactory = 0;\n";
00298         out << "    }\n";
00299         out << "}\n\n";
00300 
00301         out << "class StaticInitImages_" << cProject << "\n";
00302         out << "{\n";
00303         out << "public:\n";
00304         out << "    StaticInitImages_" << cProject << "() { qInitImages_" << cProject << "(); }\n";
00305         out << "#if defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE)\n";
00306         out << "    ~StaticInitImages_" << cProject << "() { }\n";
00307         out << "#else\n";
00308         out << "    ~StaticInitImages_" << cProject << "() { qCleanupImages_" << cProject << "(); }\n";
00309         out << "#endif\n";
00310         out << "};\n\n";
00311 
00312         out << "static StaticInitImages_" << cProject << " staticImages;\n";
00313     }
00314 }

Generated on Thu Mar 15 12:00:33 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1