gif_extractor.c (4098B)
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 void 66 EXTRACTOR_gif_extract_method (struct EXTRACTOR_ExtractContext *ec) 67 { 68 GifFileType *gif_file; 69 GifRecordType gif_type; 70 GifByteType *ext; 71 int et; 72 char dims[128]; 73 #if defined (GIF_LIB_VERSION) || GIFLIB_MAJOR <= 4 74 if (NULL == (gif_file = DGifOpen (ec, &gif_READ_func))) 75 return; /* not a GIF */ 76 #else 77 int gif_error; 78 79 gif_error = 0; 80 gif_file = DGifOpen (ec, &gif_READ_func, &gif_error); 81 if ((gif_file == NULL) || (gif_error != 0)) 82 { 83 if (gif_file != NULL) 84 #if GIFLIB_MAJOR < 5 || GIFLIB_MINOR < 1 85 EGifCloseFile (gif_file); 86 #else 87 EGifCloseFile (gif_file, NULL); 88 #endif 89 return; /* not a GIF */ 90 } 91 #endif 92 if (0 != 93 ec->proc (ec->cls, 94 "gif", 95 EXTRACTOR_METATYPE_MIMETYPE, 96 EXTRACTOR_METAFORMAT_UTF8, 97 "text/plain", 98 "image/gif", 99 strlen ("image/gif") + 1)) 100 return; 101 snprintf (dims, 102 sizeof (dims), 103 "%dx%d", 104 gif_file->SHeight, 105 gif_file->SWidth); 106 if (0 != 107 ec->proc (ec->cls, 108 "gif", 109 EXTRACTOR_METATYPE_IMAGE_DIMENSIONS, 110 EXTRACTOR_METAFORMAT_UTF8, 111 "text/plain", 112 dims, 113 strlen (dims) + 1)) 114 return; 115 while (1) 116 { 117 if (GIF_OK != 118 DGifGetRecordType (gif_file, 119 &gif_type)) 120 break; 121 if (UNDEFINED_RECORD_TYPE == gif_type) 122 break; 123 if (EXTENSION_RECORD_TYPE != gif_type) 124 continue; 125 if (GIF_OK != 126 DGifGetExtension (gif_file, &et, &ext)) 127 continue; 128 if (NULL == ext) 129 continue; 130 if (COMMENT_EXT_FUNC_CODE == et) 131 { 132 ec->proc (ec->cls, 133 "gif", 134 EXTRACTOR_METATYPE_COMMENT, 135 EXTRACTOR_METAFORMAT_C_STRING, 136 "text/plain", 137 (char*) &ext[1], 138 (uint8_t) ext[0]); 139 break; 140 } 141 while ( (GIF_ERROR != 142 DGifGetExtensionNext (gif_file, &ext)) && 143 (NULL != ext) ) 144 ; /* keep going */ 145 } 146 #if defined (GIF_LIB_VERSION) || GIFLIB_MAJOR < 5 || GIFLIB_MINOR < 1 147 DGifCloseFile (gif_file); 148 #else 149 DGifCloseFile (gif_file, NULL); 150 #endif 151 } 152 153 154 /* end of gif_extractor.c */