src/tools/uic3/embed.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "ui3reader.h"
       
    43 #include <QFile>
       
    44 #include <QImage>
       
    45 #include <QStringList>
       
    46 #include <QDateTime>
       
    47 #include <QFileInfo>
       
    48 #include <QVector>
       
    49 #include <stdio.h>
       
    50 #include <ctype.h>
       
    51 
       
    52 QT_BEGIN_NAMESPACE
       
    53 
       
    54 // on embedded, we do not compress image data. Rationale: by mapping
       
    55 // the ready-only data directly into memory we are both faster and
       
    56 // more memory efficient
       
    57 #if defined(Q_WS_QWS) && !defined(QT_NO_IMAGE_COLLECTION_COMPRESSION)
       
    58 #  define QT_NO_IMAGE_COLLECTION_COMPRESSION
       
    59 #elif defined (QT_NO_COMPRESS)
       
    60 #  define QT_NO_IMAGE_COLLECTION_COMPRESSION
       
    61 #endif
       
    62 
       
    63 struct EmbedImage
       
    64 {
       
    65     ~EmbedImage() { delete[] colorTable; }
       
    66 
       
    67     int width, height, depth;
       
    68     int numColors;
       
    69     QRgb* colorTable;
       
    70     QString name;
       
    71     QString cname;
       
    72     bool alpha;
       
    73 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
    74     ulong compressed;
       
    75 #endif
       
    76 };
       
    77 
       
    78 static QString convertToCIdentifier( const char *s )
       
    79 {
       
    80     QByteArray r = s;
       
    81     int len = r.length();
       
    82     if ( len > 0 && !isalpha( (char)r[0] ) )
       
    83         r[0] = '_';
       
    84     for ( int i=1; i<len; i++ ) {
       
    85         if ( !isalnum( (char)r[i] ) )
       
    86             r[i] = '_';
       
    87     }
       
    88 
       
    89     return QString::fromAscii(r);
       
    90 }
       
    91 
       
    92 
       
    93 static ulong embedData( QTextStream& out, const uchar* input, int nbytes )
       
    94 {
       
    95 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
    96     QByteArray bazip( qCompress( input, nbytes ) );
       
    97     ulong len = bazip.size();
       
    98 #else
       
    99     ulong len = nbytes;
       
   100 #endif
       
   101     static const char hexdigits[] = "0123456789abcdef";
       
   102     QString s;
       
   103     for ( int i=0; i<(int)len; i++ ) {
       
   104         if ( (i%14) == 0 ) {
       
   105             s += QLatin1String("\n    ");
       
   106             out << s.latin1();
       
   107             s.truncate( 0 );
       
   108         }
       
   109         uint v = (uchar)
       
   110 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   111                  bazip
       
   112 #else
       
   113                  input
       
   114 #endif
       
   115                  [i];
       
   116         s += QLatin1String("0x");
       
   117         s += QLatin1Char(hexdigits[(v >> 4) & 15]);
       
   118         s += QLatin1Char(hexdigits[v & 15]);
       
   119         if ( i < (int)len-1 )
       
   120             s += QLatin1Char(',');
       
   121     }
       
   122     if ( s.length() )
       
   123         out << s.latin1();
       
   124     return len;
       
   125 }
       
   126 
       
   127 static void embedData( QTextStream& out, const QRgb* input, int n )
       
   128 {
       
   129     out << hex;
       
   130     const QRgb *v = input;
       
   131     for ( int i=0; i<n; i++ ) {
       
   132         if ( (i%14) == 0  )
       
   133             out << "\n    ";
       
   134         out << "0x";
       
   135         out << hex << *v++;
       
   136         if ( i < n-1 )
       
   137             out << ',';
       
   138     }
       
   139     out << dec; // back to decimal mode
       
   140 }
       
   141 
       
   142 void Ui3Reader::embed(const char *project, const QStringList &images)
       
   143 {
       
   144 
       
   145     QString cProject = convertToCIdentifier( project );
       
   146 
       
   147     QStringList::ConstIterator it;
       
   148     out << "/****************************************************************************\n";
       
   149     out << "** Image collection for project '" << project << "'.\n";
       
   150     out << "**\n";
       
   151     out << "** Generated from reading image files: \n";
       
   152     for ( it = images.begin(); it != images.end(); ++it )
       
   153         out << "**      " << *it << "\n";
       
   154     out << "**\n";
       
   155     out << "** Created: " << QDateTime::currentDateTime().toString() << "\n";
       
   156     out << "**      by: The User Interface Compiler for Qt version " << QT_VERSION_STR << "\n";
       
   157     out << "**\n";
       
   158     out << "** WARNING! All changes made in this file will be lost!\n";
       
   159     out << "****************************************************************************/\n";
       
   160     out << "\n";
       
   161 
       
   162     out << "#include <qimage.h>\n";
       
   163     out << "#include <qmime.h>\n";
       
   164     out << "#include <q3mimefactory.h>\n";
       
   165     out << "#include <q3dragobject.h>\n";
       
   166     out << "\n";
       
   167 
       
   168     QList<EmbedImage*> list_image;
       
   169     int image_count = 0;
       
   170     for ( it = images.begin(); it != images.end(); ++it ) {
       
   171         QImage img;
       
   172         if ( !img.load( *it ) ) {
       
   173             fprintf( stderr, "uic: cannot load image file %s\n", (*it).latin1() );
       
   174             continue;
       
   175         }
       
   176         EmbedImage *e = new EmbedImage;
       
   177         e->width = img.width();
       
   178         e->height = img.height();
       
   179         e->depth = img.depth();
       
   180         e->numColors = img.numColors();
       
   181         e->colorTable = new QRgb[e->numColors];
       
   182         e->alpha = img.hasAlphaBuffer();
       
   183         QVector<QRgb> ct = img.colorTable();
       
   184         memcpy(e->colorTable, ct.constData(), e->numColors*sizeof(QRgb));
       
   185         QFileInfo fi( *it );
       
   186         e->name = fi.fileName();
       
   187         e->cname = QString::fromLatin1("image_%1").arg( image_count++);
       
   188         list_image.append( e );
       
   189         out << "// " << *it << "\n";
       
   190         QString s;
       
   191         if ( e->depth == 1 )
       
   192             img = img.convertBitOrder(QImage::BigEndian);
       
   193         out << s.sprintf( "static const unsigned char %s_data[] = {",
       
   194                           e->cname.latin1() );
       
   195 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   196         e->compressed =
       
   197 #endif
       
   198             embedData( out, img.bits(), img.numBytes() );
       
   199         out << "\n};\n\n";
       
   200         if ( e->numColors ) {
       
   201             out << s.sprintf( "static const QRgb %s_ctable[] = {",
       
   202                               e->cname.latin1() );
       
   203             embedData( out, e->colorTable, e->numColors );
       
   204             out << "\n};\n\n";
       
   205         }
       
   206     }
       
   207 
       
   208     if ( !list_image.isEmpty() ) {
       
   209         out << "static const struct EmbedImage {\n"
       
   210             "    int width, height, depth;\n"
       
   211             "    const unsigned char *data;\n"
       
   212 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   213             "    ulong compressed;\n"
       
   214 #endif
       
   215             "    int numColors;\n"
       
   216             "    const QRgb *colorTable;\n"
       
   217             "    bool alpha;\n"
       
   218             "    const char *name;\n"
       
   219             "} embed_image_vec[] = {\n";
       
   220         EmbedImage *e = 0;
       
   221         int i;
       
   222         for (i = 0; i < list_image.count(); ++i) {
       
   223             e = list_image.at(i);
       
   224             out << "    { "
       
   225                 << e->width << ", "
       
   226                 << e->height << ", "
       
   227                 << e->depth << ", "
       
   228                 << "(const unsigned char*)" << e->cname << "_data, "
       
   229 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   230                 << e->compressed << ", "
       
   231 #endif
       
   232                 << e->numColors << ", ";
       
   233             if ( e->numColors )
       
   234                 out << e->cname << "_ctable, ";
       
   235             else
       
   236                 out << "0, ";
       
   237             if ( e->alpha )
       
   238                 out << "true, ";
       
   239             else
       
   240                 out << "false, ";
       
   241             out << '\"' << e->name << "\" },\n";
       
   242             delete e;
       
   243         }
       
   244 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   245         out << "    { 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n";
       
   246 #else
       
   247         out << "    { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n";
       
   248 #endif
       
   249 
       
   250         out << "\n"
       
   251             "static QImage uic_findImage( const QString& name )\n"
       
   252             "{\n"
       
   253             "    for ( int i=0; embed_image_vec[i].data; i++ ) {\n"
       
   254             "        if ( QString::fromUtf8(embed_image_vec[i].name) == name ) {\n"
       
   255 #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION
       
   256             "            QByteArray baunzip;\n"
       
   257             "            baunzip = qUncompress( embed_image_vec[i].data, \n"
       
   258             "                embed_image_vec[i].compressed );\n"
       
   259             "            QImage img((uchar*)baunzip.data(),\n"
       
   260             "                        embed_image_vec[i].width,\n"
       
   261             "                        embed_image_vec[i].height,\n"
       
   262             "                        embed_image_vec[i].depth,\n"
       
   263             "                        (QRgb*)embed_image_vec[i].colorTable,\n"
       
   264             "                        embed_image_vec[i].numColors,\n"
       
   265             "                        QImage::BigEndian\n"
       
   266             "                );\n"
       
   267             "            img = img.copy();\n"
       
   268 #else
       
   269             "            QImage img((uchar*)embed_image_vec[i].data,\n"
       
   270             "                        embed_image_vec[i].width,\n"
       
   271             "                        embed_image_vec[i].height,\n"
       
   272             "                        embed_image_vec[i].depth,\n"
       
   273             "                        (QRgb*)embed_image_vec[i].colorTable,\n"
       
   274             "                        embed_image_vec[i].numColors,\n"
       
   275             "                        QImage::BigEndian\n"
       
   276             "                );\n"
       
   277 #endif
       
   278             "            if ( embed_image_vec[i].alpha )\n"
       
   279             "                img.setAlphaBuffer(true);\n"
       
   280             "            return img;\n"
       
   281             "        }\n"
       
   282             "    }\n"
       
   283             "    return QImage();\n"
       
   284             "}\n\n";
       
   285 
       
   286         out << "class MimeSourceFactory_" << cProject << " : public Q3MimeSourceFactory\n";
       
   287         out << "{\n";
       
   288         out << "public:\n";
       
   289         out << "    MimeSourceFactory_" << cProject << "() {}\n";
       
   290         out << "    ~MimeSourceFactory_" << cProject << "() {}\n";
       
   291         out << "    const QMimeSource* data( const QString& abs_name ) const {\n";
       
   292         out << "\tconst QMimeSource* d = Q3MimeSourceFactory::data( abs_name );\n";
       
   293         out << "\tif ( d || abs_name.isNull() ) return d;\n";
       
   294         out << "\tQImage img = uic_findImage( abs_name );\n";
       
   295         out << "\tif ( !img.isNull() )\n";
       
   296         out << "\t    ((Q3MimeSourceFactory*)this)->setImage( abs_name, img );\n";
       
   297         out << "\treturn Q3MimeSourceFactory::data( abs_name );\n";
       
   298         out << "    };\n";
       
   299         out << "};\n\n";
       
   300 
       
   301         out << "static Q3MimeSourceFactory* factory = 0;\n";
       
   302         out << "\n";
       
   303 
       
   304         out << "void qInitImages_" << cProject << "()\n";
       
   305         out << "{\n";
       
   306         out << "    if ( !factory ) {\n";
       
   307         out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n";
       
   308         out << "\tQ3MimeSourceFactory::defaultFactory()->addFactory( factory );\n";
       
   309         out << "    }\n";
       
   310         out << "}\n\n";
       
   311 
       
   312         out << "void qCleanupImages_" << cProject << "()\n";
       
   313         out << "{\n";
       
   314         out << "    if ( factory ) {\n";
       
   315         out << "\tQ3MimeSourceFactory::defaultFactory()->removeFactory( factory );\n";
       
   316         out << "\tdelete factory;\n";
       
   317         out << "\tfactory = 0;\n";
       
   318         out << "    }\n";
       
   319         out << "}\n\n";
       
   320 
       
   321         out << "class StaticInitImages_" << cProject << "\n";
       
   322         out << "{\n";
       
   323         out << "public:\n";
       
   324         out << "    StaticInitImages_" << cProject << "() { qInitImages_" << cProject << "(); }\n";
       
   325         out << "#if defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE)\n";
       
   326         out << "    ~StaticInitImages_" << cProject << "() { }\n";
       
   327         out << "#else\n";
       
   328         out << "    ~StaticInitImages_" << cProject << "() { qCleanupImages_" << cProject << "(); }\n";
       
   329         out << "#endif\n";
       
   330         out << "};\n\n";
       
   331 
       
   332         out << "static StaticInitImages_" << cProject << " staticImages;\n";
       
   333     }
       
   334 }
       
   335 
       
   336 QT_END_NAMESPACE