Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gif_slave.cpp

Go to the documentation of this file.
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 ** $Id: gif_slave.cpp,v 1.2 2004/04/02 19:28:09 zecke Exp $
00017 **
00018 ** Minimal GIF parser, for use in extracting and setting metadata.
00019 ** Modified for standalone & KDE calling by Bryce Nesbitt
00020 **
00021 **  TODO:
00022 **      Support gif comments that span more than one comment block.
00023 **      Verify that Unicode utf-8 is fully unmolested by this code.
00024 **      Implement gif structure verifier.
00025 **
00026 ** Based on: GIFtrans v1.12.2
00027 ** Copyright (C) 24.2.94 by Andreas Ley <ley@rz.uni-karlsruhe.de>
00028 **
00029 *******************************************************************************
00030 **
00031 ** Original distribution site is
00032 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.c
00033 ** A man-page by knordlun@fltxa.helsinki.fi (Kai Nordlund) is at
00034 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.1
00035 ** An online version by taylor@intuitive.com (Dave Taylor) is at
00036 **         http://www.intuitive.com/coolweb/Addons/giftrans-doc.html
00037 ** To compile for MS-DOS or OS/2, you need getopt:
00038 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/getopt.c
00039 ** MS-DOS executable can be found at
00040 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.exe
00041 ** OS/2 executable can be found at
00042 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.os2.exe
00043 ** A template rgb.txt for use with the MS-DOS version can be found at
00044 **      ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/rgb.txt
00045 ** Additional info can be found on
00046 **      http://melmac.corp.harris.com/transparent_images.html
00047 **
00048 ** The GIF file format is documented in
00049 **      ftp://ftp.uu.net/doc/literary/obi/Standards/Graphics/Formats/gif89a.doc.Z
00050 ** A good quick reference is at:
00051 **      http://www.goice.co.jp/member/mo/formats/gif.html
00052 **
00053 *******************************************************************************
00054 **
00055 ** This program is free software; you can redistribute it and/or modify
00056 ** it under the terms of the GNU General Public License as published by
00057 ** the Free Software Foundation; either version 2 of the License, or
00058 ** (at your option) any later version.
00059 **
00060 ** This program is distributed in the hope that it will be useful,
00061 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00062 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00063 ** GNU General Public License for more details.
00064 **
00065 ** You should have received a copy of the GNU General Public License
00066 ** along with this program; if not, write to the Free Software
00067 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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         /* Header */
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         /* Logical Screen Descriptor */
00176         pos=ftell(src);
00177         (void)fread((void *)lsd,7,1,src);
00178                 //(void)fprintf(stderr,"Logical Screen Descriptor:\n");
00179             str += QObject::tr("Dimensions: %1x%2\n").arg( readword(lsd) ).arg( readword(lsd+2 ) );
00180                 //(void)fprintf(stderr,"Global Color Table Flag: %s\n",readflag(lsd[4]&0x80));
00181             str += QObject::tr("Depth: %1 bits\n").arg( (lsd[4]&0x70>>4 )+1);
00182                 //(void)fprintf(stderr,"Depth  : %d bits\n",(lsd[4]&0x70>>4)+1);
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         /* Global Color Table */
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:      /* Image Descriptor */
00204                         (void)fread((void *)(buffer+1),9,1,src);
00205                         /* Local Color Table */
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                         /* Table Based Image Data */
00212                         pos=ftell(src);
00213                         (void)fread((void *)buffer,1,1,src);
00214                         transdata(src,dest);
00215                         break;
00216                 case 0x21:      /* Extension */
00217                         (void)fread((void *)(buffer+1),1,1,src);
00218                         switch (buffer[1]) {
00219                         case 0xfe:      /* Comment Extension */
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:      /* Plain Text Extension */
00233                         case 0xf9:      /* Graphic Control Extension */
00234                         case 0xff:      /* Application Extension */
00235                         default:
00236                                 transblock(src,dest);
00237                                 transdata(src,dest);
00238                                 break;
00239                         }
00240                         break;
00241                 case 0x3b:      /* Trailer (write comment just before here) */
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 

Generated on Sat Nov 5 16:17:30 2005 for OPIE by  doxygen 1.4.2