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