Diffstat (limited to 'noncore/graphics/opie-eye/slave/gif_slave.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/graphics/opie-eye/slave/gif_slave.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/noncore/graphics/opie-eye/slave/gif_slave.cpp b/noncore/graphics/opie-eye/slave/gif_slave.cpp new file mode 100644 index 0000000..feb69b6 --- a/dev/null +++ b/noncore/graphics/opie-eye/slave/gif_slave.cpp | |||
@@ -0,0 +1,305 @@ | |||
1 | #include "gif_slave.h" | ||
2 | |||
3 | #include "thumbnailtool.h" | ||
4 | |||
5 | #include <qimage.h> | ||
6 | #include <qobject.h> | ||
7 | #include <qfile.h> | ||
8 | #include <qpixmap.h> | ||
9 | |||
10 | |||
11 | PHUNK_VIEW_INTERFACE( "Gif", GifSlave ); | ||
12 | |||
13 | |||
14 | namespace { | ||
15 | /* | ||
16 | ** $Id$ | ||
17 | ** | ||
18 | ** Minimal GIF parser, for use in extracting and setting metadata. | ||
19 | ** Modified for standalone & KDE calling by Bryce Nesbitt | ||
20 | ** | ||
21 | ** TODO: | ||
22 | ** Support gif comments that span more than one comment block. | ||
23 | ** Verify that Unicode utf-8 is fully unmolested by this code. | ||
24 | ** Implement gif structure verifier. | ||
25 | ** | ||
26 | ** Based on: GIFtrans v1.12.2 | ||
27 | ** Copyright (C) 24.2.94 by Andreas Ley <ley@rz.uni-karlsruhe.de> | ||
28 | ** | ||
29 | ******************************************************************************* | ||
30 | ** | ||
31 | ** Original distribution site is | ||
32 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.c | ||
33 | ** A man-page by knordlun@fltxa.helsinki.fi (Kai Nordlund) is at | ||
34 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.1 | ||
35 | ** An online version by taylor@intuitive.com (Dave Taylor) is at | ||
36 | ** http://www.intuitive.com/coolweb/Addons/giftrans-doc.html | ||
37 | ** To compile for MS-DOS or OS/2, you need getopt: | ||
38 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/getopt.c | ||
39 | ** MS-DOS executable can be found at | ||
40 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.exe | ||
41 | ** OS/2 executable can be found at | ||
42 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.os2.exe | ||
43 | ** A template rgb.txt for use with the MS-DOS version can be found at | ||
44 | ** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/rgb.txt | ||
45 | ** Additional info can be found on | ||
46 | ** http://melmac.corp.harris.com/transparent_images.html | ||
47 | ** | ||
48 | ** The GIF file format is documented in | ||
49 | ** ftp://ftp.uu.net/doc/literary/obi/Standards/Graphics/Formats/gif89a.doc.Z | ||
50 | ** A good quick reference is at: | ||
51 | ** http://www.goice.co.jp/member/mo/formats/gif.html | ||
52 | ** | ||
53 | ******************************************************************************* | ||
54 | ** | ||
55 | ** This program is free software; you can redistribute it and/or modify | ||
56 | ** it under the terms of the GNU General Public License as published by | ||
57 | ** the Free Software Foundation; either version 2 of the License, or | ||
58 | ** (at your option) any later version. | ||
59 | ** | ||
60 | ** This program is distributed in the hope that it will be useful, | ||
61 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
62 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
63 | ** GNU General Public License for more details. | ||
64 | ** | ||
65 | ** You should have received a copy of the GNU General Public License | ||
66 | ** along with this program; if not, write to the Free Software | ||
67 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
68 | ** | ||
69 | */ | ||
70 | #define SUCCESS (0) | ||
71 | #define FAILURE (1) | ||
72 | |||
73 | #define READ_BINARY "r" | ||
74 | #define WRITE_BINARY "w" | ||
75 | |||
76 | |||
77 | static long int pos; | ||
78 | static char skipcomment,verbose; | ||
79 | char *global_comment; | ||
80 | |||
81 | #define readword(buffer) ((buffer)[0]+256*(buffer)[1]) | ||
82 | #define readflag(buffer) ((buffer)?true:false) | ||
83 | #define hex(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+10:'A'<=(c)&&(c)<='Z'?(c)-'A'+10:(c)-'0') | ||
84 | |||
85 | static bool debug = false; | ||
86 | static bool output= false; | ||
87 | |||
88 | void dump(long int, unsigned char *, size_t) { | ||
89 | } | ||
90 | |||
91 | void skipdata(FILE *src) | ||
92 | { | ||
93 | unsigned char size,buffer[256]; | ||
94 | |||
95 | do { | ||
96 | pos=ftell(src); | ||
97 | (void)fread((void *)&size,1,1,src); | ||
98 | if (debug) | ||
99 | dump(pos,&size,1); | ||
100 | if (debug) { | ||
101 | pos=ftell(src); | ||
102 | (void)fread((void *)buffer,(size_t)size,1,src); | ||
103 | dump(pos,buffer,(size_t)size); | ||
104 | } | ||
105 | else | ||
106 | (void)fseek(src,(long int)size,SEEK_CUR); | ||
107 | } while (!feof(src)&&size>0); | ||
108 | } | ||
109 | |||
110 | |||
111 | void transdata(FILE *src, FILE *dest) | ||
112 | { | ||
113 | unsigned char size,buffer[256]; | ||
114 | |||
115 | do { | ||
116 | pos=ftell(src); | ||
117 | (void)fread((void *)&size,1,1,src); | ||
118 | pos=ftell(src); | ||
119 | (void)fread((void *)buffer,(size_t)size,1,src); | ||
120 | if (debug) | ||
121 | dump(pos,buffer,(size_t)size); | ||
122 | if (output) | ||
123 | (void)fwrite((void *)buffer,(size_t)size,1,dest); | ||
124 | } while (!feof(src)&&size>0); | ||
125 | } | ||
126 | |||
127 | void transblock(FILE *src, FILE* dest) | ||
128 | { | ||
129 | unsigned char size,buffer[256]; | ||
130 | |||
131 | pos=ftell(src); | ||
132 | (void)fread((void *)&size,1,1,src); | ||
133 | if (debug) | ||
134 | dump(pos,&size,1); | ||
135 | if (output) | ||
136 | (void)fwrite((void *)&size,1,1,dest); | ||
137 | pos=ftell(src); | ||
138 | (void)fread((void *)buffer,(size_t)size,1,src); | ||
139 | if (debug) | ||
140 | dump(pos,buffer,(size_t)size); | ||
141 | if (output) | ||
142 | (void)fwrite((void *)buffer,(size_t)size,1,dest); | ||
143 | } | ||
144 | |||
145 | void dumpcomment(FILE *src, QCString& str) | ||
146 | { | ||
147 | unsigned char size; | ||
148 | |||
149 | pos=ftell(src); | ||
150 | (void)fread((void *)&size,1,1,src); | ||
151 | if (debug) | ||
152 | dump(pos,&size,1); | ||
153 | str.resize( size+1 ); | ||
154 | (void)fread((void *)str.data(),size,1,src); | ||
155 | (void)fseek(src,(long int)pos,SEEK_SET); | ||
156 | } | ||
157 | |||
158 | |||
159 | |||
160 | |||
161 | int giftrans(FILE *src, FILE* dest, QString& str, bool full) | ||
162 | { | ||
163 | unsigned char buffer[3*256],lsd[7],gct[3*256]; | ||
164 | unsigned int size,gct_size; | ||
165 | |||
166 | /* Header */ | ||
167 | pos=ftell(src); | ||
168 | (void)fread((void *)buffer,6,1,src); | ||
169 | if (strncmp((char *)buffer,"GIF",3)) { | ||
170 | str = QObject::tr("Not a GIF file"); | ||
171 | (void)fprintf(stderr,"Not GIF file!\n"); | ||
172 | return(1); | ||
173 | } | ||
174 | |||
175 | /* Logical Screen Descriptor */ | ||
176 | pos=ftell(src); | ||
177 | (void)fread((void *)lsd,7,1,src); | ||
178 | //(void)fprintf(stderr,"Logical Screen Descriptor:\n"); | ||
179 | str += QObject::tr("Dimensions: %1x%2\n").arg( readword(lsd) ).arg( readword(lsd+2 ) ); | ||
180 | //(void)fprintf(stderr,"Global Color Table Flag: %s\n",readflag(lsd[4]&0x80)); | ||
181 | str += QObject::tr("Depth: %1 bits\n").arg( (lsd[4]&0x70>>4 )+1); | ||
182 | //(void)fprintf(stderr,"Depth : %d bits\n",(lsd[4]&0x70>>4)+1); | ||
183 | if (lsd[4]&0x80 && full) { | ||
184 | str += QObject::tr("Sort Flag: %1\n" ).arg(readflag(lsd[4]&0x8) ); | ||
185 | str += QObject::tr("Size of Global Color Table: %1 colors\n" ).arg( 2<<(lsd[4]&0x7)); | ||
186 | str += QObject::tr("Background Color Index: %1\n" ).arg(lsd[5]); | ||
187 | } | ||
188 | if (lsd[6] && full) | ||
189 | str += QObject::tr("Pixel Aspect Ratio: %1 (Aspect Ratio %2)\n" ).arg( lsd[6] ). | ||
190 | arg( ((double)lsd[6]+15)/64 ); | ||
191 | |||
192 | /* Global Color Table */ | ||
193 | if (lsd[4]&0x80) { | ||
194 | gct_size=2<<(lsd[4]&0x7); | ||
195 | pos=ftell(src); | ||
196 | (void)fread((void *)gct,gct_size,3,src); | ||
197 | } | ||
198 | |||
199 | do { | ||
200 | pos=ftell(src); | ||
201 | (void)fread((void *)buffer,1,1,src); | ||
202 | switch (buffer[0]) { | ||
203 | case 0x2c: /* Image Descriptor */ | ||
204 | (void)fread((void *)(buffer+1),9,1,src); | ||
205 | /* Local Color Table */ | ||
206 | if (buffer[8]&0x80) { | ||
207 | size=2<<(buffer[8]&0x7); | ||
208 | pos=ftell(src); | ||
209 | (void)fread((void *)buffer,size,3,src); | ||
210 | } | ||
211 | /* Table Based Image Data */ | ||
212 | pos=ftell(src); | ||
213 | (void)fread((void *)buffer,1,1,src); | ||
214 | transdata(src,dest); | ||
215 | break; | ||
216 | case 0x21: /* Extension */ | ||
217 | (void)fread((void *)(buffer+1),1,1,src); | ||
218 | switch (buffer[1]) { | ||
219 | case 0xfe: /* Comment Extension */ | ||
220 | if (true) | ||
221 | { | ||
222 | QCString st; | ||
223 | dumpcomment(src, st); | ||
224 | str += QObject::tr("Comment: %1\n" ).arg( st ); | ||
225 | } | ||
226 | if (skipcomment) | ||
227 | skipdata(src); | ||
228 | else { | ||
229 | transdata(src,dest); | ||
230 | } | ||
231 | break; | ||
232 | case 0x01: /* Plain Text Extension */ | ||
233 | case 0xf9: /* Graphic Control Extension */ | ||
234 | case 0xff: /* Application Extension */ | ||
235 | default: | ||
236 | transblock(src,dest); | ||
237 | transdata(src,dest); | ||
238 | break; | ||
239 | } | ||
240 | break; | ||
241 | case 0x3b: /* Trailer (write comment just before here) */ | ||
242 | break; | ||
243 | default: | ||
244 | (void)fprintf(stderr,"0x%08lx: Error, unknown block 0x%02x!\n",ftell(src)-1,buffer[0]); | ||
245 | return(1); | ||
246 | } | ||
247 | } while (buffer[0]!=0x3b&&!feof(src)); | ||
248 | return(buffer[0]==0x3b?SUCCESS:FAILURE); | ||
249 | } | ||
250 | |||
251 | |||
252 | /****************************************************************************/ | ||
253 | extern void get_gif_info( const char * original_filename, QString& str, | ||
254 | bool full =false) | ||
255 | { | ||
256 | FILE * infile; | ||
257 | |||
258 | if ((infile = fopen(original_filename, READ_BINARY)) == NULL) { | ||
259 | fprintf(stderr, "can't open gif image '%s'\n", original_filename); | ||
260 | return ; | ||
261 | } | ||
262 | |||
263 | output = FALSE; | ||
264 | verbose = TRUE; | ||
265 | debug = FALSE; | ||
266 | skipcomment = FALSE; | ||
267 | giftrans( infile, NULL, str, full ); | ||
268 | fclose( infile ); | ||
269 | } | ||
270 | |||
271 | } | ||
272 | |||
273 | |||
274 | GifSlave::GifSlave() | ||
275 | : SlaveInterface(QStringList("gif")) | ||
276 | {} | ||
277 | |||
278 | GifSlave::~GifSlave() { | ||
279 | |||
280 | } | ||
281 | |||
282 | QString GifSlave::iconViewName(const QString& str) { | ||
283 | QString st; | ||
284 | get_gif_info(QFile::encodeName( str ).data(), st ); | ||
285 | return st; | ||
286 | } | ||
287 | |||
288 | QString GifSlave::fullImageInfo( const QString& str) { | ||
289 | QString st; | ||
290 | get_gif_info(QFile::encodeName( str ).data(), st, true ); | ||
291 | return st; | ||
292 | } | ||
293 | |||
294 | QPixmap GifSlave::pixmap(const QString& path, int width, int height ) { | ||
295 | static QImage img; | ||
296 | img.load( path ); | ||
297 | if ( img.isNull() ) { | ||
298 | QPixmap pix; | ||
299 | return pix; | ||
300 | } | ||
301 | |||
302 | return ThumbNailTool::scaleImage( img, width,height ); | ||
303 | } | ||
304 | |||
305 | |||