summaryrefslogtreecommitdiffstats
path: root/tdefile-plugins/gif
diff options
context:
space:
mode:
Diffstat (limited to 'tdefile-plugins/gif')
-rw-r--r--tdefile-plugins/gif/CMakeLists.txt34
-rw-r--r--tdefile-plugins/gif/Makefile.am24
-rw-r--r--tdefile-plugins/gif/README10
-rw-r--r--tdefile-plugins/gif/gif-info.125
-rw-r--r--tdefile-plugins/gif/gif-info.c561
-rw-r--r--tdefile-plugins/gif/tdefile_gif.cpp122
-rw-r--r--tdefile-plugins/gif/tdefile_gif.desktop65
-rw-r--r--tdefile-plugins/gif/tdefile_gif.h38
8 files changed, 879 insertions, 0 deletions
diff --git a/tdefile-plugins/gif/CMakeLists.txt b/tdefile-plugins/gif/CMakeLists.txt
new file mode 100644
index 00000000..8e71efbf
--- /dev/null
+++ b/tdefile-plugins/gif/CMakeLists.txt
@@ -0,0 +1,34 @@
+#################################################
+#
+# (C) 2010-2011 Calvin Morrison
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+#### other data #################################
+
+install( FILES tdefile_gif.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+#### tdefile_gif (module) #########################
+tde_add_kpart( tdefile_gif AUTOMOC
+ SOURCES tdefile_gif.cpp
+ LINK tdeio-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/tdefile-plugins/gif/Makefile.am b/tdefile-plugins/gif/Makefile.am
new file mode 100644
index 00000000..d6f8d82c
--- /dev/null
+++ b/tdefile-plugins/gif/Makefile.am
@@ -0,0 +1,24 @@
+## Makefile.am for gif file meta info plugin
+
+KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = tdefile_gif.h
+
+kde_module_LTLIBRARIES = tdefile_gif.la
+
+tdefile_gif_la_SOURCES = tdefile_gif.cpp
+tdefile_gif_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+tdefile_gif_la_LIBADD = $(LIB_KIO)
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages:
+ $(XGETTEXT) *.cpp -o $(podir)/tdefile_gif.pot
+
+services_DATA = tdefile_gif.desktop
+servicesdir = $(kde_servicesdir)
diff --git a/tdefile-plugins/gif/README b/tdefile-plugins/gif/README
new file mode 100644
index 00000000..811cbb28
--- /dev/null
+++ b/tdefile-plugins/gif/README
@@ -0,0 +1,10 @@
+The original README for this file read:
+<quote>
+Note: Development of this module has been suspended.
+Please feel free to contact me, and pick it up. All I ask
+is that you preserve both command line and tdefile abilities. Thanks.
+</quote>
+
+I contacted Bryce, but received no response. The command line code
+is unchanged - I just fixed the tdefile code to work, read only.
diff --git a/tdefile-plugins/gif/gif-info.1 b/tdefile-plugins/gif/gif-info.1
new file mode 100644
index 00000000..6c36b1c4
--- /dev/null
+++ b/tdefile-plugins/gif/gif-info.1
@@ -0,0 +1,25 @@
+.TH gif-info 1 "April 2002"
+
+.SH NAME
+gif-info \- reads gif image info or sets comment.
+
+.SH SYNOPSIS
+.B gif-info
+.RB <filename>
+['Comment']
+
+.SH DESCRIPTION
+.LP
+.B gif-info
+displays information about the given gif (Graphic Interchange Format) image. If a comment is specified, the comment is set instead.
+.PP
+Write a empty comment ('') to delete the comment block.
+.PP
+The GIF standard allows any number of 256 byte comment blocks in an image file, but most implementations (including this one) restrict you to just one block. The GIF standard restricts comment blocks to "7 Bit ASCII", but this is widely ignored. You are welcome to store text in your own native language, and are especially encouraged to use comments in utf-8 unicode format.
+
+.SH "SEE ALSO"
+.BR wrjpgcom (1)
+.BR rdjpgcom (1)
+
+.SH AUTHOR
+Bryce Nesbitt
diff --git a/tdefile-plugins/gif/gif-info.c b/tdefile-plugins/gif/gif-info.c
new file mode 100644
index 00000000..2f64a2f2
--- /dev/null
+++ b/tdefile-plugins/gif/gif-info.c
@@ -0,0 +1,561 @@
+/*
+** $Id$
+**
+** Minimal GIF parser, for use in extracting and setting metadata.
+** Modified for standalone & KDE calling by Bryce Nesbitt
+**
+** TODO:
+** Support gif comments that span more than one comment block.
+** Verify that Unicode utf-8 is fully unmolested by this code.
+** Implement gif structure verifier.
+**
+** Based on: GIFtrans v1.12.2
+** Copyright (C) 24.2.94 by Andreas Ley <[email protected]>
+**
+*******************************************************************************
+**
+** Original distribution site is
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.c
+** A man-page by [email protected] (Kai Nordlund) is at
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.1
+** An online version by [email protected] (Dave Taylor) is at
+** http://www.intuitive.com/coolweb/Addons/giftrans-doc.html
+** To compile for MS-DOS or OS/2, you need getopt:
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/getopt.c
+** MS-DOS executable can be found at
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.exe
+** OS/2 executable can be found at
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/giftrans.os2.exe
+** A template rgb.txt for use with the MS-DOS version can be found at
+** ftp://ftp.rz.uni-karlsruhe.de/pub/net/www/tools/giftrans/rgb.txt
+** Additional info can be found on
+** http://melmac.corp.harris.com/transparent_images.html
+**
+** The GIF file format is documented in
+** ftp://ftp.uu.net/doc/literary/obi/Standards/Graphics/Formats/gif89a.doc.Z
+** A good quick reference is at:
+** http://www.goice.co.jp/member/mo/formats/gif.html
+**
+*******************************************************************************
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define STANDALONE_COMPILE
+
+extern int set_gif_comment( const char * original_filename, char * comment );
+extern void * get_gif_info( const char * original_filename );
+extern int validate_gif_structure( const char * original_filename );
+int giftrans( FILE * src, FILE * dest);
+
+#define WARNING_GARBAGE 1 /* Original file had some unspecified content */
+#define ERROR_NOT_A_JPEG 5 /* Original file not a proper jpeg (must be 1st) */
+#define ERROR_TEMP_FILE 6 /* Problem writing temporay file */
+#define ERROR_SCREWUP 7 /* Original file is now damaged. Ooops. */
+#define ERROR_PREMATURE_EOF 8 /* Unexpected end of file */
+#define ERROR_BAD_MARKER 9 /* Marker with illegal length */
+#define ERROR_MARKER_ORDER 10 /* File seems to be mixed up */
+
+/*****************************************************************************/
+#ifndef FALSE
+#define FALSE (0) /* This is the naked Truth */
+#define TRUE (1) /* and this is the Light */
+#endif
+
+#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
+#define READ_BINARY "r"
+#define WRITE_BINARY "w"
+#else
+#ifdef VMS /* VMS is very nonstandard */
+#define READ_BINARY "rb", "ctx=stm"
+#define WRITE_BINARY "wb", "ctx=stm"
+#else /* standard ANSI-compliant case */
+#define READ_BINARY "rb"
+#define WRITE_BINARY "wb"
+#endif
+#endif
+
+#define SUCCESS (0)
+#define FAILURE (1)
+
+static char skipcomment,list,verbose,output,debug;
+char *global_comment;
+static long int pos;
+
+static char true[] = "True";
+static char false[] = "False";
+static char id[] = "$Id$";
+
+/*****************************************************************************/
+
+#define readword(buffer) ((buffer)[0]+256*(buffer)[1])
+#define readflag(buffer) ((buffer)?true:false)
+#define hex(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+10:'A'<=(c)&&(c)<='Z'?(c)-'A'+10:(c)-'0')
+
+void dump(adr,data,len)
+long int adr;
+unsigned char *data;
+size_t len;
+{
+ int i;
+
+ while (len>0) {
+ (void)fprintf(stderr,"%08lx:%*s",adr,(int)((adr%16)*3+(adr%16>8?1:0)),"");
+ for (i=adr%16;i<16&&len>0;i++,adr++,data++,len--)
+ (void)fprintf(stderr,"%s%02x",i==8?" ":" ",*data);
+ (void)fprintf(stderr,"\n");
+ }
+}
+
+void writedata(dest,data,len)
+FILE *dest;
+unsigned char *data;
+size_t len;
+{
+ unsigned char size;
+
+ while (len) {
+ size=len<256?len:255;
+ (void)fwrite((void *)&size,1,1,dest);
+ (void)fwrite((void *)data,(size_t)size,1,dest);
+ data+=size;
+ len-=size;
+ }
+ size=0;
+ (void)fwrite((void *)&size,1,1,dest);
+}
+
+void skipdata(src)
+FILE *src;
+{
+ unsigned char size,buffer[256];
+
+ do {
+ pos=ftell(src);
+ (void)fread((void *)&size,1,1,src);
+ if (debug)
+ dump(pos,&size,1);
+ if (debug) {
+ pos=ftell(src);
+ (void)fread((void *)buffer,(size_t)size,1,src);
+ dump(pos,buffer,(size_t)size);
+ }
+ else
+ (void)fseek(src,(long int)size,SEEK_CUR);
+ } while (!feof(src)&&size>0);
+}
+
+void transblock(src,dest)
+FILE *src;
+FILE *dest;
+{
+ unsigned char size,buffer[256];
+
+ pos=ftell(src);
+ (void)fread((void *)&size,1,1,src);
+ if (debug)
+ dump(pos,&size,1);
+ if (output)
+ (void)fwrite((void *)&size,1,1,dest);
+ pos=ftell(src);
+ (void)fread((void *)buffer,(size_t)size,1,src);
+ if (debug)
+ dump(pos,buffer,(size_t)size);
+ if (output)
+ (void)fwrite((void *)buffer,(size_t)size,1,dest);
+}
+
+void dumpcomment(src)
+FILE *src;
+{
+ unsigned char size,buffer[256];
+ size_t i;
+
+ pos=ftell(src);
+ (void)fread((void *)&size,1,1,src);
+ if (debug)
+ dump(pos,&size,1);
+ (void)fread((void *)buffer,(size_t)size,1,src);
+ if (debug)
+ dump(pos+1,buffer,(size_t)size);
+ for (i=0; i<(size_t)size; i++)
+ {
+ if ( buffer[i] >= 0x20 || buffer[i] == '\t' ||
+ buffer[i] =='\r' || buffer[i] == '\n')
+ (void)putc(buffer[i],stderr);
+ else
+ (void)fprintf(stderr,"\\%03o",buffer[i]);
+ }
+ (void)fseek(src,(long int)pos,SEEK_SET);
+}
+
+void transdata(src,dest)
+FILE *src;
+FILE *dest;
+{
+ unsigned char size,buffer[256];
+
+ do {
+ pos=ftell(src);
+ (void)fread((void *)&size,1,1,src);
+ if (debug)
+ dump(pos,&size,1);
+ if (output)
+ (void)fwrite((void *)&size,1,1,dest);
+ pos=ftell(src);
+ (void)fread((void *)buffer,(size_t)size,1,src);
+ if (debug)
+ dump(pos,buffer,(size_t)size);
+ if (output)
+ (void)fwrite((void *)buffer,(size_t)size,1,dest);
+ } while (!feof(src)&&size>0);
+}
+
+
+/*****************************************************************************/
+
+int giftrans(src,dest)
+FILE *src;
+FILE *dest;
+{
+ unsigned char buffer[3*256],lsd[7],gct[3*256];
+ unsigned int cnt,cols,size,gct_size;
+
+ /* Header */
+ pos=ftell(src);
+ (void)fread((void *)buffer,6,1,src);
+ if (strncmp((char *)buffer,"GIF",3)) {
+ (void)fprintf(stderr,"Not GIF file!\n");
+ return(1);
+ }
+ if (verbose && debug) {
+ buffer[6]='\0';
+ (void)fprintf(stderr,"Header: \"%s\"\n",buffer);
+ }
+ if (debug)
+ dump(pos,buffer,6);
+ if (output) {
+ (void)fwrite((void *)buffer,6,1,dest);
+ }
+
+ /* Logical Screen Descriptor */
+ pos=ftell(src);
+ (void)fread((void *)lsd,7,1,src);
+ if (verbose) {
+ //(void)fprintf(stderr,"Logical Screen Descriptor:\n");
+ (void)fprintf(stderr,"Size : %dx%d pixels\n",readword(lsd), readword(lsd+2));
+ //(void)fprintf(stderr,"Global Color Table Flag: %s\n",readflag(lsd[4]&0x80));
+ (void)fprintf(stderr,"Depth : %d bits\n",(lsd[4]&0x70>>4)+1);
+ //if (lsd[4]&0x80) {
+ // (void)fprintf(stderr,"\tSort Flag: %s\n",readflag(lsd[4]&0x8));
+ // (void)fprintf(stderr,"\tSize of Global Color Table: %d colors\n",2<<(lsd[4]&0x7));
+ // (void)fprintf(stderr,"\tBackground Color Index: %d\n",lsd[5]);
+ //}
+ if (lsd[6])
+ (void)fprintf(stderr,"Pixel Aspect Ratio: %d (Aspect Ratio %f)\n",lsd[6],((double)lsd[6]+15)/64);
+ }
+ if (debug)
+ dump(pos,lsd,7);
+ if (output)
+ (void)fwrite((void *)lsd,7,1,dest);
+
+ /* Global Color Table */
+ if (lsd[4]&0x80) {
+ gct_size=2<<(lsd[4]&0x7);
+ pos=ftell(src);
+ (void)fread((void *)gct,gct_size,3,src);
+ if (output)
+ (void)fwrite((void *)gct,gct_size,3,dest);
+ }
+
+ do {
+ pos=ftell(src);
+ (void)fread((void *)buffer,1,1,src);
+ switch (buffer[0]) {
+ case 0x2c: /* Image Descriptor */
+ if (verbose && debug)
+ (void)fprintf(stderr,"Image Descriptor:\n");
+ (void)fread((void *)(buffer+1),9,1,src);
+ if (debug)
+ dump(pos,buffer,10);
+ if (output)
+ (void)fwrite((void *)buffer,10,1,dest);
+ /* Local Color Table */
+ if (buffer[8]&0x80) {
+ size=2<<(buffer[8]&0x7);
+ pos=ftell(src);
+ (void)fread((void *)buffer,size,3,src);
+ if (verbose && debug) {
+ (void)fprintf(stderr,"Local Color Table:\n");
+ for(cnt=0;cnt<size;cnt++)
+ (void)fprintf(stderr,"\tColor %d: Red %d, Green %d, Blue %d\n",cnt,buffer[3*cnt],buffer[3*cnt+1],buffer[3*cnt+2]);
+ }
+ if (debug)
+ dump(pos,buffer,size*3);
+ if (output)
+ (void)fwrite((void *)buffer,size,3,dest);
+ }
+ /* Table Based Image Data */
+ pos=ftell(src);
+ (void)fread((void *)buffer,1,1,src);
+ if (verbose && debug) {
+ (void)fprintf(stderr,"Table Based Image Data:\n");
+ (void)fprintf(stderr,"\tLZW Minimum Code Size: 0x%02x\n",buffer[0]);
+ }
+ if (debug)
+ dump(pos,buffer,1);
+ if (output)
+ (void)fwrite((void *)buffer,1,1,dest);
+ transdata(src,dest);
+ break;
+ case 0x21: /* Extension */
+ (void)fread((void *)(buffer+1),1,1,src);
+ switch (buffer[1]) {
+ case 0xfe: /* Comment Extension */
+ if (verbose)
+ {
+ (void)fprintf(stderr,"Comment: ");
+ dumpcomment(src);
+ (void)fprintf(stderr,"\n");
+ }
+ if (debug)
+ dump(pos,buffer,2);
+ if (skipcomment)
+ skipdata(src);
+ else {
+ if (output)
+ (void)fwrite((void *)buffer,2,1,dest);
+ transdata(src,dest);
+ }
+ break;
+ case 0x01: /* Plain Text Extension */
+ case 0xf9: /* Graphic Control Extension */
+ case 0xff: /* Application Extension */
+ default:
+ if (verbose && debug)
+ (void)fprintf(stderr,"Extension type: 0x%02x\n",buffer[1]);
+ if (debug)
+ dump(pos,buffer,2);
+ if (output)
+ (void)fwrite((void *)buffer,2,1,dest);
+ transblock(src,dest);
+ transdata(src,dest);
+ break;
+ }
+ break;
+ case 0x3b: /* Trailer (write comment just before here) */
+ if (verbose && debug)
+ (void)fprintf(stderr,"Trailer %o\n", pos);
+ if (debug)
+ dump(pos,buffer,1);
+ if (global_comment && *global_comment && output) {
+ (void)fputs("\041\376",dest);
+ writedata(dest,(unsigned char *)global_comment,strlen(global_comment));
+ }
+ if (output)
+ (void)fwrite((void *)buffer,1,1,dest);
+ break;
+ default:
+ (void)fprintf(stderr,"0x%08lx: Error, unknown block 0x%02x!\n",ftell(src)-1,buffer[0]);
+ if (debug)
+ dump(pos,buffer,1);
+ return(1);
+ }
+ } while (buffer[0]!=0x3b&&!feof(src));
+ return(buffer[0]==0x3b?SUCCESS:FAILURE);
+}
+
+
+/****************************************************************************/
+extern int validate_gif_structure( const char * original_filename )
+{
+FILE * infile;
+int rc;
+
+ if ((infile = fopen(original_filename, READ_BINARY)) == NULL) {
+ fprintf(stderr, "can't open gif image '%s'\n", original_filename);
+ return( 1 );
+ }
+ output = FALSE;
+ verbose = FALSE;
+ debug = FALSE;
+ skipcomment = FALSE;
+ rc = giftrans( infile, NULL );
+ fclose( infile );
+ return( rc );
+}
+
+
+/****************************************************************************/
+extern void * get_gif_info( const char * original_filename )
+{
+FILE * infile;
+
+ if ((infile = fopen(original_filename, READ_BINARY)) == NULL) {
+ fprintf(stderr, "can't open gif image '%s'\n", original_filename);
+ return( NULL );
+ }
+
+ output = FALSE;
+ verbose = TRUE;
+ debug = FALSE;
+ skipcomment = FALSE;
+ giftrans( infile, NULL );
+ return( NULL );
+}
+
+
+/*****************************************************************************
+ Modify the file in place, but be paranoid and safe about it.
+ It's worth a few extra CPU cycles to make sure we never
+ destory an original image:
+
+ 1) Validate the input file.
+ 2) Open a temporary file in same directory (filenameXX).
+ 3) Copy the data, writing a new comment block.
+ 4) Sync everything to disc.
+ 5) Validate the temporary file.
+ 6) Move the temporary file over the original.
+*/
+extern int set_gif_comment( const char * original_filename, char * comment )
+{
+int i;
+int rc;
+char * temp_filename;
+int temp_filename_length;
+struct stat statbuf;
+FILE * infile;
+FILE * outfile;
+
+
+ /*
+ * Make sure we're dealing with a proper input file. Safety first!
+ */
+ if( validate_gif_structure( original_filename ) ) {
+ fprintf(stderr, "error validating gif image '%s'\n", original_filename);
+ return(ERROR_NOT_A_JPEG);
+ }
+
+ /* Get a unique temporary file in the same directory. Hopefully
+ * if things go wrong, this file will still be left for recovery purposes.
+ *
+ * NB: I hate these stupid unsafe string functions in C...
+ */
+ outfile = NULL;
+ temp_filename_length = strlen( original_filename) + 4;
+ temp_filename = (char *)calloc( temp_filename_length, 1 );
+ for( i=0; i<10; i++ ) {
+ snprintf( temp_filename, temp_filename_length, "%s%d", original_filename, i );
+ if( (stat( temp_filename, &statbuf )) && (outfile = fopen(temp_filename, WRITE_BINARY)) ) {
+ //fprintf(stderr, "opened temporary file '%s'\n", temp_filename);
+ break;
+ }
+ }
+ if( !outfile ) {
+ fprintf(stderr, "failed opening temporary file '%s'\n", temp_filename);
+ return(ERROR_TEMP_FILE);
+ }
+
+ if ((infile = fopen(original_filename, READ_BINARY)) == NULL) {
+ fclose( outfile );
+ fprintf(stderr, "can't open gif image '%s'\n", original_filename);
+ return(ERROR_NOT_A_JPEG);
+ }
+ /* Let's do it */
+ output = TRUE;
+ verbose = FALSE;
+ debug = FALSE;
+ skipcomment = TRUE;
+ global_comment = comment;
+ rc = giftrans( infile, outfile );
+ fclose( infile );
+ fsync( fileno( outfile) ); /* Flush it to disk. IMPORTANT!! */
+ /* We really should also flush the directory */
+
+ /* If everything is OK, and if the new file validates, move
+ it over the top of the original */
+ if ( fclose( outfile ) || validate_gif_structure( temp_filename ) ) {
+ fprintf(stderr, "error in temporary file '%s'\n", temp_filename);
+ return(ERROR_TEMP_FILE);
+ }
+ if( rc ) {
+ unlink( temp_filename );
+ return( rc );
+ }
+ if( rename( temp_filename, original_filename ) ) {
+ fprintf(stderr, "error renaming '%s' to '%s'\n", temp_filename, original_filename);
+ return(ERROR_TEMP_FILE);
+ }
+
+ return(0);
+}
+
+
+/*****************************************************************************/
+#ifdef STANDALONE_COMPILE
+int
+main (int argc, char **argv)
+{
+ char * progname;
+ char * filename;
+ char * comment;
+ FILE * fp;
+ int error;
+
+ /* Process command line arguments... */
+ progname = argv[0];
+ if (progname == NULL || progname[0] == 0)
+ progname = "gif-info"; /* in case C library doesn't provide it */
+ if( argc < 2 || argc > 3) {
+ fprintf(stderr, "Usage: %s <filename> [\"<comment>\"]\nReads gif image info or sets comment.\n", progname);
+ return(5);
+ }
+ filename = argv[1];
+ comment = argv[2];
+
+
+ /* Check if file is readable... */
+ if ((fp = fopen(filename, READ_BINARY)) == NULL) {
+ fprintf(stderr, "Error: Can't open file '%s'\n", filename);
+ return(5);
+ }
+ fclose(fp);
+
+ /* Check if we really have a commentable image file here... */
+ if( validate_gif_structure( filename ) ) {
+ fprintf(stderr, "Error: error parsing file '%s' as a gif image\n", filename);
+ return(5);
+ }
+
+ if( argc == 2 ) {
+ get_gif_info( filename );
+ }
+ else {
+ set_gif_comment( filename, comment );
+ }
+
+ return( 0 );
+}
+#endif
+
diff --git a/tdefile-plugins/gif/tdefile_gif.cpp b/tdefile-plugins/gif/tdefile_gif.cpp
new file mode 100644
index 00000000..9cc522dc
--- /dev/null
+++ b/tdefile-plugins/gif/tdefile_gif.cpp
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the KDE project, added by Bryce Nesbitt
+ *
+ * This is a plugin for Konqeror/KFile which processes 'extra' information
+ * contained in a .gif image file (In particular the comment, and resolution).
+ *
+ **************************************
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include "tdefile_gif.h"
+
+#include <kurl.h>
+#include <kprocess.h>
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <kdebug.h>
+
+#include <tqcstring.h>
+#include <tqfile.h>
+#include <tqdatetime.h>
+#include <tqdict.h>
+#include <tqvalidator.h>
+#include <tqimage.h>
+
+typedef KGenericFactory<KGifPlugin> GifFactory;
+
+K_EXPORT_COMPONENT_FACTORY(tdefile_gif, GifFactory("tdefile_gif"))
+
+KGifPlugin::KGifPlugin(TQObject *parent, const char *name,
+ const TQStringList &args)
+ : KFilePlugin(parent, name, args)
+{
+ kdDebug(7034) << "gif KFileMetaInfo plugin\n";
+
+ KFileMimeTypeInfo* info = addMimeTypeInfo( "image/gif" );
+
+ KFileMimeTypeInfo::GroupInfo* group = 0L;
+
+ group = addGroupInfo(info, "General", i18n("General"));
+
+ KFileMimeTypeInfo::ItemInfo* item;
+
+ item = addItemInfo(group, "Version", i18n("Version"), TQVariant::String);
+
+ item = addItemInfo( group, "Dimensions", i18n("Dimensions"), TQVariant::Size );
+ setHint( item, KFileMimeTypeInfo::Size );
+ setUnit( item, KFileMimeTypeInfo::Pixels );
+
+ item = addItemInfo(group, "BitDepth", i18n("Bit Depth"), TQVariant::Int);
+ setUnit(item, KFileMimeTypeInfo::BitsPerPixel);
+
+}
+
+bool KGifPlugin::readInfo( KFileMetaInfo& info, uint what )
+{
+ Q_UNUSED( what );
+
+ kdDebug(7034) << "gif KFileMetaInfo readInfo\n";
+
+ TQFile file(info.path());
+
+ if (!file.open(IO_ReadOnly)) {
+ kdDebug(7034) << "Couldn't open " << TQFile::encodeName(info.path()).data() << endl;
+ return false;
+ }
+
+ TQDataStream fstream(&file);
+
+ bool isGIF87a = false;
+ char magic[7];
+ TQ_UINT16 width = 0;
+ TQ_UINT16 height = 0;
+ TQ_UINT8 miscInfo = 0;
+
+ fstream.readRawBytes( magic, 6 );
+ magic[6] = 0x00; // null terminate
+
+ // I have special requirements...
+ fstream.setByteOrder( TQDataStream::LittleEndian );
+ fstream >> width;
+ fstream >> height;
+ fstream >> miscInfo;
+
+ KFileMetaInfoGroup group = appendGroup(info, "General");
+
+ if ( 0 == strncmp( magic, "GIF89a", 6 ) ) {
+ appendItem( group, "Version", i18n("GIF Version 89a") );
+ } else if ( 0 == strncmp( magic, "GIF87a", 6 ) ) {
+ appendItem( group, "Version", i18n("GIF Version 87a") );
+ isGIF87a = true;
+ } else {
+ appendItem( group, "Version", i18n("Unknown") );
+ }
+
+ appendItem( group, "Dimensions", TQSize(width, height) );
+
+ if ( isGIF87a ) {
+ appendItem( group, "BitDepth", ( (miscInfo & 0x07) + 1) );
+ }
+
+ file.close();
+
+ return true;
+}
+
+#include "tdefile_gif.moc"
diff --git a/tdefile-plugins/gif/tdefile_gif.desktop b/tdefile-plugins/gif/tdefile_gif.desktop
new file mode 100644
index 00000000..d6e3bfb3
--- /dev/null
+++ b/tdefile-plugins/gif/tdefile_gif.desktop
@@ -0,0 +1,65 @@
+[Desktop Entry]
+Type=Service
+Name=GIF Info
+Name[af]=Gif Inligting
+Name[ar]=معلومات GIF
+Name[br]=Titouroù GIF
+Name[ca]=Informació de GIF
+Name[cs]=GIF info
+Name[cy]=Gwybodaeth GIF
+Name[da]=GIF-info
+Name[de]=GIF-Info
+Name[el]=Πληροφορίες GIF
+Name[eo]=GIF-informo
+Name[es]=Info GIF
+Name[et]=GIF info
+Name[fa]=اطلاعات GIF
+Name[fi]=GIF-tiedot
+Name[fr]=Informations GIF
+Name[ga]=Eolas faoi GIF
+Name[gl]=Inf. Gif
+Name[he]=מידע GIF
+Name[hi]=GIF जानकारी
+Name[hr]=GIF Informacije
+Name[hu]=GIF-jellemzők
+Name[is]=GIF upplýsingar
+Name[it]=Informazioni GIF
+Name[ja]=GIF 情報
+Name[kk]=GIF мәліметі
+Name[km]=ព័ត៌មាន GIF
+Name[lt]=GIF informacija
+Name[ms]=Maklumat GIF
+Name[nds]=GIF-Info
+Name[ne]=GIF सूचना
+Name[nl]=GIF-info
+Name[nn]=GIF-info
+Name[nso]=Tshedimoso ya GIF
+Name[pa]=GIF ਜਾਣਕਾਰੀ
+Name[pl]=Informacja o pliku GIF
+Name[pt]=Informação do GIF
+Name[pt_BR]=Informação sobre GIF
+Name[ro]=Informaţii GIF
+Name[ru]=Информация о GIF
+Name[se]=GIF-dieđut
+Name[sl]=Podatki o GIF
+Name[sr]=GIF информације
+Name[sr@Latn]=GIF informacije
+Name[sv]=Gif-information
+Name[ta]=GIF தகவல்
+Name[tg]=Иттилоот оиди GIF
+Name[th]=ข้อมูลแฟ้ม GIF
+Name[tr]=GIF Bilgisi
+Name[uk]=Інформація по GIF
+Name[uz]=GIF haqida maʼlumot
+Name[uz@cyrillic]=GIF ҳақида маълумот
+Name[ven]=Mafhungo a GIF
+Name[wa]=Informåcion sol imådje GIF
+Name[xh]=Ulwazi lwe GIF
+Name[zh_CN]=GIF 信息
+Name[zh_HK]=GIF 資訊
+Name[zh_TW]=GIF 資訊
+Name[zu]=Ulwazi lwe-GIF
+ServiceTypes=KFilePlugin
+X-TDE-Library=tdefile_gif
+MimeType=image/gif
+PreferredItems=Comment,Resolution
diff --git a/tdefile-plugins/gif/tdefile_gif.h b/tdefile-plugins/gif/tdefile_gif.h
new file mode 100644
index 00000000..37588e7a
--- /dev/null
+++ b/tdefile-plugins/gif/tdefile_gif.h
@@ -0,0 +1,38 @@
+/* This file is part of the KDE project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __KFILE_GIF_H__
+#define __KFILE_GIF_H__
+
+#include <tdefilemetainfo.h>
+#include <kurl.h>
+
+class TQStringList;
+
+class KGifPlugin: public KFilePlugin
+{
+ Q_OBJECT
+
+
+public:
+ KGifPlugin( TQObject *parent, const char *name, const TQStringList& args );
+
+ virtual bool readInfo ( KFileMetaInfo& info, uint what );
+};
+
+#endif