libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

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 */