libextractor

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

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