libextractor

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

tiff_extractor.c (5958B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2012 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/tiff_extractor.c
     22  * @brief plugin to support TIFF files
     23  * @author Christian Grothoff
     24  */
     25 #include "platform.h"
     26 #include "extractor.h"
     27 #include <tiffio.h>
     28 
     29 
     30 /**
     31  * Error handler for libtiff.  Does nothing.
     32  *
     33  * @param module where did the error arise?
     34  * @param fmt format string
     35  * @param ap arguments for fmt
     36  */
     37 static void
     38 error_cb (const char *module,
     39           const char *fmt,
     40           va_list ap)
     41 {
     42   /* do nothing */
     43 }
     44 
     45 
     46 /**
     47  * Callback invoked by TIFF lib for reading.
     48  *
     49  * @param ctx the 'struct EXTRACTOR_ExtractContext'
     50  * @param data where to write data
     51  * @param size number of bytes to read
     52  * @return number of bytes read
     53  */
     54 static tsize_t
     55 read_cb (thandle_t ctx,
     56          tdata_t data,
     57          tsize_t size)
     58 {
     59   struct EXTRACTOR_ExtractContext *ec = ctx;
     60   void *ptr;
     61   ssize_t ret;
     62 
     63   ret = ec->read (ec->cls, &ptr, size);
     64   if (ret > 0)
     65     memcpy (data, ptr, ret);
     66   return ret;
     67 }
     68 
     69 
     70 /**
     71  * Callback invoked by TIFF lib for writing.  Always fails.
     72  *
     73  * @param ctx the 'struct EXTRACTOR_ExtractContext'
     74  * @param data where to write data
     75  * @param size number of bytes to read
     76  * @return -1 (error)
     77  */
     78 static tsize_t
     79 write_cb (thandle_t ctx,
     80           tdata_t data,
     81           tsize_t size)
     82 {
     83   return -1;
     84 }
     85 
     86 
     87 /**
     88  * Callback invoked by TIFF lib for seeking.
     89  *
     90  * @param ctx the 'struct EXTRACTOR_ExtractContext'
     91  * @param offset target offset
     92  * @param whence target is relative to where
     93  * @return new offset
     94  */
     95 static toff_t
     96 seek_cb (thandle_t ctx,
     97          toff_t offset,
     98          int whence)
     99 {
    100   struct EXTRACTOR_ExtractContext *ec = ctx;
    101 
    102   return ec->seek (ec->cls, offset, whence);
    103 }
    104 
    105 
    106 /**
    107  * Callback invoked by TIFF lib for getting the file size.
    108  *
    109  * @param ctx the 'struct EXTRACTOR_ExtractContext'
    110  * @return file size
    111  */
    112 static toff_t
    113 size_cb (thandle_t ctx)
    114 {
    115   struct EXTRACTOR_ExtractContext *ec = ctx;
    116 
    117   return ec->get_size (ec->cls);
    118 }
    119 
    120 
    121 /**
    122  * Callback invoked by TIFF lib for closing the file. Does nothing.
    123  *
    124  * @param ctx the 'struct EXTRACTOR_ExtractContext'
    125  */
    126 static int
    127 close_cb (thandle_t ctx)
    128 {
    129   return 0; /* success */
    130 }
    131 
    132 
    133 /**
    134  * A mapping from TIFF Tag to extractor types.
    135  */
    136 struct Matches
    137 {
    138   /**
    139    * TIFF Tag.
    140    */
    141   ttag_t tag;
    142 
    143   /**
    144    * Corresponding LE type.
    145    */
    146   enum EXTRACTOR_MetaType type;
    147 };
    148 
    149 
    150 /**
    151  * Mapping of TIFF tags to LE types.
    152  * NULL-terminated.
    153  */
    154 static struct Matches tmap[] = {
    155   { TIFFTAG_ARTIST, EXTRACTOR_METATYPE_ARTIST },
    156   { TIFFTAG_COPYRIGHT, EXTRACTOR_METATYPE_COPYRIGHT },
    157   { TIFFTAG_DATETIME, EXTRACTOR_METATYPE_CREATION_DATE },
    158   { TIFFTAG_DOCUMENTNAME, EXTRACTOR_METATYPE_TITLE },
    159   { TIFFTAG_HOSTCOMPUTER, EXTRACTOR_METATYPE_BUILDHOST },
    160   { TIFFTAG_IMAGEDESCRIPTION, EXTRACTOR_METATYPE_DESCRIPTION },
    161   { TIFFTAG_MAKE, EXTRACTOR_METATYPE_CAMERA_MAKE },
    162   { TIFFTAG_MODEL, EXTRACTOR_METATYPE_CAMERA_MODEL },
    163   { TIFFTAG_PAGENAME, EXTRACTOR_METATYPE_PAGE_RANGE },
    164   { TIFFTAG_SOFTWARE, EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE },
    165   { TIFFTAG_TARGETPRINTER, EXTRACTOR_METATYPE_TARGET_ARCHITECTURE },
    166   { 0, 0 }
    167 };
    168 
    169 
    170 /**
    171  * Main entry method for the 'image/tiff' extraction plugin.
    172  *
    173  * @param ec extraction context provided to the plugin
    174  */
    175 void
    176 EXTRACTOR_tiff_extract_method (struct EXTRACTOR_ExtractContext *ec)
    177 {
    178   TIFF *tiff;
    179   unsigned int i;
    180   char *meta;
    181   char format[128];
    182   uint32_t width;
    183   uint32_t height;
    184 
    185   TIFFSetErrorHandler (&error_cb);
    186   TIFFSetWarningHandler (&error_cb);
    187   tiff = TIFFClientOpen ("<no filename>",
    188                          "rm", /* read-only, no mmap */
    189                          ec,
    190                          &read_cb,
    191                          &write_cb,
    192                          &seek_cb,
    193                          &close_cb,
    194                          &size_cb,
    195                          NULL, NULL);
    196   if (NULL == tiff)
    197     return;
    198   for (i = 0; 0 != tmap[i].tag; i++)
    199     if ( (1 ==
    200           TIFFGetField (tiff, tmap[i].tag, &meta)) &&
    201          (0 !=
    202           ec->proc (ec->cls,
    203                     "tiff",
    204                     tmap[i].type,
    205                     EXTRACTOR_METAFORMAT_UTF8,
    206                     "text/plain",
    207                     meta,
    208                     strlen (meta) + 1)) )
    209       goto CLEANUP;
    210   if ( (1 ==
    211         TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width)) &&
    212        (1 ==
    213         TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height)) )
    214   {
    215     snprintf (format,
    216               sizeof (format),
    217               "%ux%u",
    218               (unsigned int) width,
    219               (unsigned int) height);
    220     if (0 !=
    221         ec->proc (ec->cls,
    222                   "tiff",
    223                   EXTRACTOR_METATYPE_IMAGE_DIMENSIONS,
    224                   EXTRACTOR_METAFORMAT_UTF8,
    225                   "text/plain",
    226                   format,
    227                   strlen (format) + 1))
    228       goto CLEANUP;
    229     if (0 !=
    230         ec->proc (ec->cls,
    231                   "tiff",
    232                   EXTRACTOR_METATYPE_MIMETYPE,
    233                   EXTRACTOR_METAFORMAT_UTF8,
    234                   "text/plain",
    235                   "image/tiff",
    236                   strlen ("image/tiff") + 1))
    237       goto CLEANUP;
    238   }
    239 
    240 CLEANUP:
    241   TIFFClose (tiff);
    242 }
    243 
    244 
    245 /* end of tiff_extractor.c */