00001 #include "gif_slave.h"
00002
00003 #include "thumbnailtool.h"
00004
00005 #include <qimage.h>
00006 #include <qobject.h>
00007 #include <qfile.h>
00008 #include <qpixmap.h>
00009
00010
00011 PHUNK_VIEW_INTERFACE( "Gif", GifSlave );
00012
00013
00014 namespace {
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define SUCCESS (0)
00071 #define FAILURE (1)
00072
00073 #define READ_BINARY "r"
00074 #define WRITE_BINARY "w"
00075
00076
00077 static long int pos;
00078 static char skipcomment,verbose;
00079 char *global_comment;
00080
00081 #define readword(buffer) ((buffer)[0]+256*(buffer)[1])
00082 #define readflag(buffer) ((buffer)?true:false)
00083 #define hex(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+10:'A'<=(c)&&(c)<='Z'?(c)-'A'+10:(c)-'0')
00084
00085 static bool debug = false;
00086 static bool output= false;
00087
00088 void dump(long int, unsigned char *, size_t) {
00089 }
00090
00091 void skipdata(FILE *src)
00092 {
00093 unsigned char size,buffer[256];
00094
00095 do {
00096 pos=ftell(src);
00097 (void)fread((void *)&size,1,1,src);
00098 if (debug)
00099 dump(pos,&size,1);
00100 if (debug) {
00101 pos=ftell(src);
00102 (void)fread((void *)buffer,(size_t)size,1,src);
00103 dump(pos,buffer,(size_t)size);
00104 }
00105 else
00106 (void)fseek(src,(long int)size,SEEK_CUR);
00107 } while (!feof(src)&&size>0);
00108 }
00109
00110
00111 void transdata(FILE *src, FILE *dest)
00112 {
00113 unsigned char size,buffer[256];
00114
00115 do {
00116 pos=ftell(src);
00117 (void)fread((void *)&size,1,1,src);
00118 pos=ftell(src);
00119 (void)fread((void *)buffer,(size_t)size,1,src);
00120 if (debug)
00121 dump(pos,buffer,(size_t)size);
00122 if (output)
00123 (void)fwrite((void *)buffer,(size_t)size,1,dest);
00124 } while (!feof(src)&&size>0);
00125 }
00126
00127 void transblock(FILE *src, FILE* dest)
00128 {
00129 unsigned char size,buffer[256];
00130
00131 pos=ftell(src);
00132 (void)fread((void *)&size,1,1,src);
00133 if (debug)
00134 dump(pos,&size,1);
00135 if (output)
00136 (void)fwrite((void *)&size,1,1,dest);
00137 pos=ftell(src);
00138 (void)fread((void *)buffer,(size_t)size,1,src);
00139 if (debug)
00140 dump(pos,buffer,(size_t)size);
00141 if (output)
00142 (void)fwrite((void *)buffer,(size_t)size,1,dest);
00143 }
00144
00145 void dumpcomment(FILE *src, QCString& str)
00146 {
00147 unsigned char size;
00148
00149 pos=ftell(src);
00150 (void)fread((void *)&size,1,1,src);
00151 if (debug)
00152 dump(pos,&size,1);
00153 str.resize( size+1 );
00154 (void)fread((void *)str.data(),size,1,src);
00155 (void)fseek(src,(long int)pos,SEEK_SET);
00156 }
00157
00158
00159
00160
00161 int giftrans(FILE *src, FILE* dest, QString& str, bool full)
00162 {
00163 unsigned char buffer[3*256],lsd[7],gct[3*256];
00164 unsigned int size,gct_size;
00165
00166
00167 pos=ftell(src);
00168 (void)fread((void *)buffer,6,1,src);
00169 if (strncmp((char *)buffer,"GIF",3)) {
00170 str = QObject::tr("Not a GIF file");
00171 (void)fprintf(stderr,"Not GIF file!\n");
00172 return(1);
00173 }
00174
00175
00176 pos=ftell(src);
00177 (void)fread((void *)lsd,7,1,src);
00178
00179 str += QObject::tr("Dimensions: %1x%2\n").arg( readword(lsd) ).arg( readword(lsd+2 ) );
00180
00181 str += QObject::tr("Depth: %1 bits\n").arg( (lsd[4]&0x70>>4 )+1);
00182
00183 if (lsd[4]&0x80 && full) {
00184 str += QObject::tr("Sort Flag: %1\n" ).arg(readflag(lsd[4]&0x8) );
00185 str += QObject::tr("Size of Global Color Table: %1 colors\n" ).arg( 2<<(lsd[4]&0x7));
00186 str += QObject::tr("Background Color Index: %1\n" ).arg(lsd[5]);
00187 }
00188 if (lsd[6] && full)
00189 str += QObject::tr("Pixel Aspect Ratio: %1 (Aspect Ratio %2)\n" ).arg( lsd[6] ).
00190 arg( ((double)lsd[6]+15)/64 );
00191
00192
00193 if (lsd[4]&0x80) {
00194 gct_size=2<<(lsd[4]&0x7);
00195 pos=ftell(src);
00196 (void)fread((void *)gct,gct_size,3,src);
00197 }
00198
00199 do {
00200 pos=ftell(src);
00201 (void)fread((void *)buffer,1,1,src);
00202 switch (buffer[0]) {
00203 case 0x2c:
00204 (void)fread((void *)(buffer+1),9,1,src);
00205
00206 if (buffer[8]&0x80) {
00207 size=2<<(buffer[8]&0x7);
00208 pos=ftell(src);
00209 (void)fread((void *)buffer,size,3,src);
00210 }
00211
00212 pos=ftell(src);
00213 (void)fread((void *)buffer,1,1,src);
00214 transdata(src,dest);
00215 break;
00216 case 0x21:
00217 (void)fread((void *)(buffer+1),1,1,src);
00218 switch (buffer[1]) {
00219 case 0xfe:
00220 if (true)
00221 {
00222 QCString st;
00223 dumpcomment(src, st);
00224 str += QObject::tr("Comment: %1\n" ).arg( st );
00225 }
00226 if (skipcomment)
00227 skipdata(src);
00228 else {
00229 transdata(src,dest);
00230 }
00231 break;
00232 case 0x01:
00233 case 0xf9:
00234 case 0xff:
00235 default:
00236 transblock(src,dest);
00237 transdata(src,dest);
00238 break;
00239 }
00240 break;
00241 case 0x3b:
00242 break;
00243 default:
00244 (void)fprintf(stderr,"0x%08lx: Error, unknown block 0x%02x!\n",ftell(src)-1,buffer[0]);
00245 return(1);
00246 }
00247 } while (buffer[0]!=0x3b&&!feof(src));
00248 return(buffer[0]==0x3b?SUCCESS:FAILURE);
00249 }
00250
00251
00252
00253 extern void get_gif_info( const char * original_filename, QString& str,
00254 bool full =false)
00255 {
00256 FILE * infile;
00257
00258 if ((infile = fopen(original_filename, READ_BINARY)) == NULL) {
00259 fprintf(stderr, "can't open gif image '%s'\n", original_filename);
00260 return ;
00261 }
00262
00263 output = FALSE;
00264 verbose = TRUE;
00265 debug = FALSE;
00266 skipcomment = FALSE;
00267 giftrans( infile, NULL, str, full );
00268 fclose( infile );
00269 }
00270
00271 }
00272
00273
00274 GifSlave::GifSlave()
00275 : SlaveInterface(QStringList("gif"))
00276 {}
00277
00278 GifSlave::~GifSlave() {
00279
00280 }
00281
00282 QString GifSlave::iconViewName(const QString& str) {
00283 QString st;
00284 get_gif_info(QFile::encodeName( str ).data(), st );
00285 return st;
00286 }
00287
00288 QString GifSlave::fullImageInfo( const QString& str) {
00289 QString st = "<qt>";
00290 get_gif_info(QFile::encodeName( str ).data(), st, true );
00291 st.append( "</qt>" );
00292 return st;
00293 }
00294
00295 QPixmap GifSlave::pixmap(const QString& path, int width, int height ) {
00296 static QImage img;
00297 img.load( path );
00298 if ( img.isNull() ) {
00299 QPixmap pix;
00300 return pix;
00301 }
00302
00303 return ThumbNailTool::scaleImage( img, width,height );
00304 }
00305
00306