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