diff options
Diffstat (limited to 'src/plugins/thumbnailextractorqt.cc')
-rw-r--r-- | src/plugins/thumbnailextractorqt.cc | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/src/plugins/thumbnailextractorqt.cc b/src/plugins/thumbnailextractorqt.cc deleted file mode 100644 index 9ab3079..0000000 --- a/src/plugins/thumbnailextractorqt.cc +++ /dev/null | |||
@@ -1,273 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (C) 2006 Vidyut Samanta and Christian Grothoff | ||
4 | |||
5 | libextractor is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | libextractor is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with libextractor; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file thumbnailextractorqt.cc | ||
23 | * @author Nils Durner | ||
24 | * @brief this extractor produces a binary (!) encoded | ||
25 | * thumbnail of images (using Qt). | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "extractor.h" | ||
30 | #include <Qt/qpixmap.h> | ||
31 | #include <Qt/qbytearray.h> | ||
32 | #include <Qt/qbuffer.h> | ||
33 | #include <Qt/qapplication.h> | ||
34 | #include <pthread.h> | ||
35 | |||
36 | #ifdef HAVE_QT_SVG | ||
37 | #include <Qt/qsvgrenderer.h> | ||
38 | #include <Qt/qpainter.h> | ||
39 | #endif | ||
40 | |||
41 | #define THUMBSIZE 128 | ||
42 | |||
43 | extern "C" | ||
44 | { | ||
45 | |||
46 | static EXTRACTOR_KeywordList * addKeyword(EXTRACTOR_KeywordType type, | ||
47 | char * keyword, | ||
48 | EXTRACTOR_KeywordList * next) { | ||
49 | EXTRACTOR_KeywordList * result; | ||
50 | |||
51 | if (keyword == NULL) | ||
52 | return next; | ||
53 | result = (EXTRACTOR_KeywordList *) malloc(sizeof(EXTRACTOR_KeywordList)); | ||
54 | result->next = next; | ||
55 | result->keyword = keyword; | ||
56 | result->keywordType = type; | ||
57 | return result; | ||
58 | } | ||
59 | |||
60 | |||
61 | /* which mime-types maybe subjected to | ||
62 | the thumbnail extractor (ImageMagick | ||
63 | crashes and/or prints errors for bad | ||
64 | formats, so we need to be rather | ||
65 | conservative here) */ | ||
66 | static const char * whitelist[] = { | ||
67 | "image/x-bmp", | ||
68 | "image/gif", | ||
69 | "image/jpeg", | ||
70 | "image/png", | ||
71 | "image/x-png", | ||
72 | "image/x-portable-bitmap", | ||
73 | "image/x-portable-graymap", | ||
74 | "image/x-portable-pixmap", | ||
75 | "image/x-xbitmap", | ||
76 | "image/x-xpixmap" | ||
77 | "image/x-xpm", | ||
78 | #ifdef HAVE_QT_SVG | ||
79 | "image/svg+xml", | ||
80 | #endif | ||
81 | NULL | ||
82 | }; | ||
83 | |||
84 | static struct EXTRACTOR_Keywords * | ||
85 | extract(const unsigned char * data, | ||
86 | size_t size, | ||
87 | struct EXTRACTOR_Keywords * prev, | ||
88 | const char * options) { | ||
89 | QImage *img; | ||
90 | QByteArray bytes; | ||
91 | QBuffer buffer; | ||
92 | unsigned long width; | ||
93 | unsigned long height; | ||
94 | char * binary; | ||
95 | const char * mime; | ||
96 | int j; | ||
97 | char * format; | ||
98 | QImage::Format colors; | ||
99 | |||
100 | /* if the mime-type of the file is not whitelisted | ||
101 | do not run the thumbnail extactor! */ | ||
102 | mime = EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE, | ||
103 | prev); | ||
104 | if (mime == NULL) | ||
105 | return prev; | ||
106 | j = 0; | ||
107 | while (whitelist[j] != NULL) { | ||
108 | if (0 == strcmp(whitelist[j], mime)) | ||
109 | break; | ||
110 | j++; | ||
111 | } | ||
112 | |||
113 | if (whitelist[j] == NULL) | ||
114 | return prev; | ||
115 | |||
116 | /* Determine image format to use */ | ||
117 | if (options == NULL) | ||
118 | colors = QImage::Format_Indexed8; | ||
119 | else | ||
120 | switch(atoi(options)) | ||
121 | { | ||
122 | case 1: | ||
123 | colors = QImage::Format_Mono; | ||
124 | break; | ||
125 | case 8: | ||
126 | colors = QImage::Format_Indexed8; | ||
127 | break; | ||
128 | case 16: | ||
129 | case 24: | ||
130 | colors = QImage::Format_RGB32; | ||
131 | break; | ||
132 | default: | ||
133 | colors = QImage::Format_ARGB32; | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | #ifdef HAVE_QT_SVG | ||
138 | if (strcmp(mime, "image/svg+xml") == 0) | ||
139 | { | ||
140 | /* Render SVG image */ | ||
141 | QSvgRenderer svg; | ||
142 | QSize size; | ||
143 | |||
144 | if (! svg.load(QByteArray((const char *) data))) | ||
145 | return prev; | ||
146 | |||
147 | size = svg.defaultSize(); | ||
148 | img = new QImage(size, QImage::Format_ARGB32); | ||
149 | |||
150 | QPainter painter(img); | ||
151 | painter.setViewport(0, 0, size.width(), size.height()); | ||
152 | painter.eraseRect(0, 0, size.width(), size.height()); | ||
153 | |||
154 | svg.render(&painter); | ||
155 | } | ||
156 | else | ||
157 | #endif | ||
158 | { | ||
159 | /* Load image */ | ||
160 | img = new QImage(); | ||
161 | img->loadFromData(data, size); | ||
162 | } | ||
163 | |||
164 | height = img->height(); | ||
165 | width = img->width(); | ||
166 | format = (char *) malloc(64); | ||
167 | snprintf(format, | ||
168 | 64, | ||
169 | "%ux%u", | ||
170 | (unsigned int) width, | ||
171 | (unsigned int) height); | ||
172 | prev = addKeyword(EXTRACTOR_SIZE, | ||
173 | format, | ||
174 | prev); | ||
175 | if (height == 0) | ||
176 | height = 1; | ||
177 | if (width == 0) | ||
178 | width = 1; | ||
179 | |||
180 | /* Change color depth */ | ||
181 | QImage thumb = img->convertToFormat(colors); | ||
182 | delete img; | ||
183 | |||
184 | /* Resize image | ||
185 | * | ||
186 | * Qt's scaled() produces poor quality if the image is resized to less than | ||
187 | * half the size. Therefore, we resize the image in multiple steps. | ||
188 | * http://lists.trolltech.com/qt-interest/2006-04/msg00376.html */ | ||
189 | while(true) | ||
190 | { | ||
191 | width /= 2; | ||
192 | if (width < THUMBSIZE) | ||
193 | width = THUMBSIZE; | ||
194 | |||
195 | height /= 2; | ||
196 | if (height < THUMBSIZE) | ||
197 | height = THUMBSIZE; | ||
198 | |||
199 | thumb = thumb.scaled(width, height, Qt::KeepAspectRatio, | ||
200 | Qt::SmoothTransformation); | ||
201 | |||
202 | if (width == THUMBSIZE && height == THUMBSIZE) | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | buffer.setBuffer(&bytes); | ||
207 | buffer.open(QIODevice::WriteOnly); | ||
208 | thumb.save(&buffer, "PNG"); | ||
209 | |||
210 | binary | ||
211 | = EXTRACTOR_binaryEncode((const unsigned char*) bytes.data(), | ||
212 | bytes.length()); | ||
213 | |||
214 | if (binary == NULL) | ||
215 | return prev; | ||
216 | |||
217 | return addKeyword(EXTRACTOR_THUMBNAIL_DATA, | ||
218 | binary, | ||
219 | prev); | ||
220 | } | ||
221 | |||
222 | /* create new thread for C++ code (see Mantis #905) */ | ||
223 | |||
224 | struct X { | ||
225 | const unsigned char * data; | ||
226 | size_t size; | ||
227 | struct EXTRACTOR_Keywords * prev; | ||
228 | const char * options; | ||
229 | }; | ||
230 | |||
231 | static void * run(void * arg) { | ||
232 | struct X * x = (struct X*) arg; | ||
233 | return extract(x->data, x->size, x->prev, | ||
234 | x->options); | ||
235 | } | ||
236 | |||
237 | struct EXTRACTOR_Keywords * | ||
238 | libextractor_thumbnailqt_extract(const char * filename, | ||
239 | const unsigned char * data, | ||
240 | size_t size, | ||
241 | struct EXTRACTOR_Keywords * prev, | ||
242 | const char * options) { | ||
243 | pthread_t pt; | ||
244 | struct X cls; | ||
245 | |||
246 | void * ret; | ||
247 | cls.data = data; | ||
248 | cls.size = size; | ||
249 | cls.prev = prev; | ||
250 | cls.options = options; | ||
251 | if (0 == pthread_create(&pt, NULL, &run, &cls)) | ||
252 | if (0 == pthread_join(pt, &ret)) | ||
253 | return (struct EXTRACTOR_Keywords*) ret; | ||
254 | return prev; | ||
255 | } | ||
256 | |||
257 | |||
258 | struct EXTRACTOR_Keywords * | ||
259 | libextractor_thumbnail_extract(const char * filename, | ||
260 | const unsigned char * data, | ||
261 | size_t size, | ||
262 | struct EXTRACTOR_Keywords * prev, | ||
263 | const char * options) { | ||
264 | return libextractor_thumbnailqt_extract(filename, | ||
265 | data, | ||
266 | size, | ||
267 | prev, | ||
268 | options); | ||
269 | } | ||
270 | |||
271 | } // extern "C" | ||
272 | |||
273 | /* end of thumbnailextractorqt.cc */ | ||