diff options
Diffstat (limited to 'kfile-plugins/gif/gif-info.c')
-rw-r--r-- | kfile-plugins/gif/gif-info.c | 561 |
1 files changed, 0 insertions, 561 deletions
diff --git a/kfile-plugins/gif/gif-info.c b/kfile-plugins/gif/gif-info.c deleted file mode 100644 index 2f64a2f2..00000000 --- a/kfile-plugins/gif/gif-info.c +++ /dev/null @@ -1,561 +0,0 @@ -/* -** $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 - |