|
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 |