gif_extractor.c (4024B)
1 /* 2 This file is part of libextractor. 3 Copyright (C) 2012 Vidyut Samanta and Christian Grothoff 4 5 libextractor is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 libextractor is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libextractor; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file plugins/gif_extractor.c 22 * @brief plugin to support GIF files 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 #include "extractor.h" 27 #include <gif_lib.h> 28 29 30 /** 31 * Callback invoked by libgif to read data. 32 * 33 * @param ft the file handle, including our extract context 34 * @param bt where to write the data 35 * @param arg number of bytes to read 36 * @return -1 on error, otherwise number of bytes read 37 */ 38 static int 39 gif_READ_func (GifFileType *ft, 40 GifByteType *bt, 41 int arg) 42 { 43 struct EXTRACTOR_ExtractContext *ec = ft->UserData; 44 void *data; 45 ssize_t ret; 46 47 ret = ec->read (ec->cls, 48 &data, 49 arg); 50 if (-1 == ret) 51 return -1; 52 memcpy (bt, data, ret); 53 return ret; 54 } 55 56 57 /** 58 * Main entry method for the 'image/gif' extraction plugin. 59 * 60 * @param ec extraction context provided to the plugin 61 */ 62 void 63 EXTRACTOR_gif_extract_method (struct EXTRACTOR_ExtractContext *ec) 64 { 65 GifFileType *gif_file; 66 GifRecordType gif_type; 67 GifByteType *ext; 68 int et; 69 char dims[128]; 70 #if defined (GIF_LIB_VERSION) || GIFLIB_MAJOR <= 4 71 if (NULL == (gif_file = DGifOpen (ec, &gif_READ_func))) 72 return; /* not a GIF */ 73 #else 74 int gif_error; 75 76 gif_error = 0; 77 gif_file = DGifOpen (ec, &gif_READ_func, &gif_error); 78 if ((gif_file == NULL) || (gif_error != 0)) 79 { 80 if (gif_file != NULL) 81 #if GIFLIB_MAJOR < 5 || GIFLIB_MINOR < 1 82 EGifCloseFile (gif_file); 83 #else 84 EGifCloseFile (gif_file, NULL); 85 #endif 86 return; /* not a GIF */ 87 } 88 #endif 89 if (0 != 90 ec->proc (ec->cls, 91 "gif", 92 EXTRACTOR_METATYPE_MIMETYPE, 93 EXTRACTOR_METAFORMAT_UTF8, 94 "text/plain", 95 "image/gif", 96 strlen ("image/gif") + 1)) 97 return; 98 snprintf (dims, 99 sizeof (dims), 100 "%dx%d", 101 gif_file->SHeight, 102 gif_file->SWidth); 103 if (0 != 104 ec->proc (ec->cls, 105 "gif", 106 EXTRACTOR_METATYPE_IMAGE_DIMENSIONS, 107 EXTRACTOR_METAFORMAT_UTF8, 108 "text/plain", 109 dims, 110 strlen (dims) + 1)) 111 return; 112 while (1) 113 { 114 if (GIF_OK != 115 DGifGetRecordType (gif_file, 116 &gif_type)) 117 break; 118 if (UNDEFINED_RECORD_TYPE == gif_type) 119 break; 120 if (EXTENSION_RECORD_TYPE != gif_type) 121 continue; 122 if (GIF_OK != 123 DGifGetExtension (gif_file, &et, &ext)) 124 continue; 125 if (NULL == ext) 126 continue; 127 if (COMMENT_EXT_FUNC_CODE == et) 128 { 129 ec->proc (ec->cls, 130 "gif", 131 EXTRACTOR_METATYPE_COMMENT, 132 EXTRACTOR_METAFORMAT_C_STRING, 133 "text/plain", 134 (char*) &ext[1], 135 (uint8_t) ext[0]); 136 break; 137 } 138 while ( (GIF_ERROR != 139 DGifGetExtensionNext (gif_file, &ext)) && 140 (NULL != ext) ) 141 ; /* keep going */ 142 } 143 #if defined (GIF_LIB_VERSION) || GIFLIB_MAJOR < 5 || GIFLIB_MINOR < 1 144 DGifCloseFile (gif_file); 145 #else 146 DGifCloseFile (gif_file, NULL); 147 #endif 148 } 149 150 151 /* end of gif_extractor.c */