diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/Makefile.am | 23 | ||||
-rw-r--r-- | src/plugins/old/tiff_extractor.c | 262 | ||||
-rw-r--r-- | src/plugins/test_tiff.c | 121 | ||||
-rw-r--r-- | src/plugins/testdata/tiff_haute.tiff | bin | 0 -> 65536 bytes | |||
-rw-r--r-- | src/plugins/tiff_extractor.c | 244 |
5 files changed, 387 insertions, 263 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index fdfbd18..3e0f60a 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am | |||
@@ -35,7 +35,8 @@ EXTRA_DIST = template_extractor.c \ | |||
35 | testdata/deb_bzip2.deb \ | 35 | testdata/deb_bzip2.deb \ |
36 | testdata/nsf_arkanoid.nsf \ | 36 | testdata/nsf_arkanoid.nsf \ |
37 | testdata/nsfe_classics.nsfe \ | 37 | testdata/nsfe_classics.nsfe \ |
38 | testdata/xm_diesel.xm | 38 | testdata/xm_diesel.xm \ |
39 | testdata/tiff_haute.tiff | ||
39 | 40 | ||
40 | if HAVE_VORBISFILE | 41 | if HAVE_VORBISFILE |
41 | PLUGIN_OGG=libextractor_ogg.la | 42 | PLUGIN_OGG=libextractor_ogg.la |
@@ -68,6 +69,11 @@ PLUGIN_FLAC=libextractor_flac.la | |||
68 | TEST_FLAC=test_flac | 69 | TEST_FLAC=test_flac |
69 | endif | 70 | endif |
70 | 71 | ||
72 | if HAVE_TIFF | ||
73 | PLUGIN_TIFF=libextractor_tiff.la | ||
74 | TEST_TIFF=test_tiff | ||
75 | endif | ||
76 | |||
71 | if HAVE_MPEG2 | 77 | if HAVE_MPEG2 |
72 | PLUGIN_MPEG=libextractor_mpeg.la | 78 | PLUGIN_MPEG=libextractor_mpeg.la |
73 | TEST_MPEG=test_mpeg | 79 | TEST_MPEG=test_mpeg |
@@ -108,6 +114,7 @@ plugin_LTLIBRARIES = \ | |||
108 | $(PLUGIN_ZLIB) \ | 114 | $(PLUGIN_ZLIB) \ |
109 | $(PLUGIN_OGG) \ | 115 | $(PLUGIN_OGG) \ |
110 | $(PLUGIN_MIME) \ | 116 | $(PLUGIN_MIME) \ |
117 | $(PLUGIN_TIFF) \ | ||
111 | $(PLUGIN_GIF) \ | 118 | $(PLUGIN_GIF) \ |
112 | $(PLUGIN_RPM) \ | 119 | $(PLUGIN_RPM) \ |
113 | $(PLUGIN_FLAC) \ | 120 | $(PLUGIN_FLAC) \ |
@@ -134,6 +141,7 @@ check_PROGRAMS = \ | |||
134 | $(TEST_GTK) \ | 141 | $(TEST_GTK) \ |
135 | $(TEST_OGG) \ | 142 | $(TEST_OGG) \ |
136 | $(TEST_MIME) \ | 143 | $(TEST_MIME) \ |
144 | $(TEST_TIFF) \ | ||
137 | $(TEST_GIF) \ | 145 | $(TEST_GIF) \ |
138 | $(TEST_RPM) \ | 146 | $(TEST_RPM) \ |
139 | $(TEST_FLAC) \ | 147 | $(TEST_FLAC) \ |
@@ -397,6 +405,19 @@ test_exiv2_LDADD = \ | |||
397 | $(top_builddir)/src/plugins/libtest.la | 405 | $(top_builddir)/src/plugins/libtest.la |
398 | 406 | ||
399 | 407 | ||
408 | libextractor_tiff_la_SOURCES = \ | ||
409 | tiff_extractor.c | ||
410 | libextractor_tiff_la_LDFLAGS = \ | ||
411 | $(PLUGINFLAGS) | ||
412 | libextractor_tiff_la_LIBADD = \ | ||
413 | -ltiff | ||
414 | |||
415 | test_tiff_SOURCES = \ | ||
416 | test_tiff.c | ||
417 | test_tiff_LDADD = \ | ||
418 | $(top_builddir)/src/plugins/libtest.la | ||
419 | |||
420 | |||
400 | libextractor_ole2_la_SOURCES = \ | 421 | libextractor_ole2_la_SOURCES = \ |
401 | ole2_extractor.c | 422 | ole2_extractor.c |
402 | libextractor_ole2_la_CFLAGS = \ | 423 | libextractor_ole2_la_CFLAGS = \ |
diff --git a/src/plugins/old/tiff_extractor.c b/src/plugins/old/tiff_extractor.c deleted file mode 100644 index d944be1..0000000 --- a/src/plugins/old/tiff_extractor.c +++ /dev/null | |||
@@ -1,262 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (C) 2004, 2009 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 2, 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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include "platform.h" | ||
22 | #include "extractor.h" | ||
23 | #include "pack.h" | ||
24 | |||
25 | #define DEBUG 0 | ||
26 | |||
27 | static int | ||
28 | addKeyword (EXTRACTOR_MetaDataProcessor proc, | ||
29 | void *proc_cls, | ||
30 | const char *keyword, | ||
31 | enum EXTRACTOR_MetaType type) | ||
32 | { | ||
33 | if (keyword == NULL) | ||
34 | return 0; | ||
35 | return proc (proc_cls, | ||
36 | "tiff", | ||
37 | type, | ||
38 | EXTRACTOR_METAFORMAT_UTF8, | ||
39 | "text/plain", | ||
40 | keyword, | ||
41 | strlen(keyword)+1); | ||
42 | } | ||
43 | |||
44 | typedef struct | ||
45 | { | ||
46 | unsigned short byteorder; | ||
47 | unsigned short fourty_two; | ||
48 | unsigned int ifd_offset; | ||
49 | } TIFF_HEADER; | ||
50 | #define TIFF_HEADER_SIZE 8 | ||
51 | #define TIFF_HEADER_FIELDS(p) \ | ||
52 | &(p)->byteorder, \ | ||
53 | &(p)->fourty_two, \ | ||
54 | &(p)->ifd_offset | ||
55 | static char *TIFF_HEADER_SPECS[] = { | ||
56 | "hhw", | ||
57 | "HHW", | ||
58 | }; | ||
59 | |||
60 | typedef struct | ||
61 | { | ||
62 | unsigned short tag; | ||
63 | unsigned short type; | ||
64 | unsigned int count; | ||
65 | unsigned int value_or_offset; | ||
66 | } DIRECTORY_ENTRY; | ||
67 | #define DIRECTORY_ENTRY_SIZE 12 | ||
68 | #define DIRECTORY_ENTRY_FIELDS(p) \ | ||
69 | &(p)->tag, \ | ||
70 | &(p)->type, \ | ||
71 | &(p)->count, \ | ||
72 | &(p)->value_or_offset | ||
73 | static char *DIRECTORY_ENTRY_SPECS[] = { | ||
74 | "hhww", | ||
75 | "HHWW" | ||
76 | }; | ||
77 | |||
78 | #define TAG_LENGTH 0x101 | ||
79 | #define TAG_WIDTH 0x100 | ||
80 | #define TAG_SOFTWARE 0x131 | ||
81 | #define TAG_DAYTIME 0x132 | ||
82 | #define TAG_ARTIST 0x315 | ||
83 | #define TAG_COPYRIGHT 0x8298 | ||
84 | #define TAG_DESCRIPTION 0x10E | ||
85 | #define TAG_DOCUMENT_NAME 0x10D | ||
86 | #define TAG_HOST 0x13C | ||
87 | #define TAG_SCANNER 0x110 | ||
88 | #define TAG_ORIENTATION 0x112 | ||
89 | |||
90 | #define TYPE_BYTE 1 | ||
91 | #define TYPE_ASCII 2 | ||
92 | #define TYPE_SHORT 3 | ||
93 | #define TYPE_LONG 4 | ||
94 | #define TYPE_RATIONAL 5 | ||
95 | |||
96 | static int | ||
97 | addASCII (EXTRACTOR_MetaDataProcessor proc, | ||
98 | void *proc_cls, | ||
99 | const char *data, | ||
100 | size_t size, DIRECTORY_ENTRY * entry, | ||
101 | enum EXTRACTOR_MetaType type) | ||
102 | { | ||
103 | if (entry->count > size) | ||
104 | return 0; /* invalid! */ | ||
105 | if (entry->type != TYPE_ASCII) | ||
106 | return 0; /* huh? */ | ||
107 | if (entry->count + entry->value_or_offset > size) | ||
108 | return 0; | ||
109 | if (data[entry->value_or_offset + entry->count - 1] != 0) | ||
110 | return 0; | ||
111 | return addKeyword (proc, proc_cls, | ||
112 | &data[entry->value_or_offset], type); | ||
113 | } | ||
114 | |||
115 | |||
116 | int | ||
117 | EXTRACTOR_tiff_extract (const char *data, | ||
118 | size_t size, | ||
119 | EXTRACTOR_MetaDataProcessor proc, | ||
120 | void *proc_cls, | ||
121 | const char *options) | ||
122 | { | ||
123 | TIFF_HEADER hdr; | ||
124 | int byteOrder; /* 0: do not convert; | ||
125 | 1: do convert */ | ||
126 | unsigned int current_ifd; | ||
127 | unsigned int length = -1; | ||
128 | unsigned int width = -1; | ||
129 | |||
130 | if (size < TIFF_HEADER_SIZE) | ||
131 | return 0; /* can not be tiff */ | ||
132 | if ((data[0] == 0x49) && (data[1] == 0x49)) | ||
133 | byteOrder = 0; | ||
134 | else if ((data[0] == 0x4D) && (data[1] == 0x4D)) | ||
135 | byteOrder = 1; | ||
136 | else | ||
137 | return 0; /* can not be tiff */ | ||
138 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
139 | byteOrder = 1 - byteOrder; | ||
140 | #endif | ||
141 | EXTRACTOR_common_cat_unpack (data, TIFF_HEADER_SPECS[byteOrder], TIFF_HEADER_FIELDS (&hdr)); | ||
142 | if (hdr.fourty_two != 42) | ||
143 | return 0; /* can not be tiff */ | ||
144 | if (hdr.ifd_offset + 6 > size) | ||
145 | return 0; /* malformed tiff */ | ||
146 | if (0 != addKeyword (proc, proc_cls, "image/tiff", EXTRACTOR_METATYPE_MIMETYPE)) | ||
147 | return 1; | ||
148 | current_ifd = hdr.ifd_offset; | ||
149 | while (current_ifd != 0) | ||
150 | { | ||
151 | unsigned short len; | ||
152 | unsigned int off; | ||
153 | int i; | ||
154 | if ( (current_ifd + 6 > size) || | ||
155 | (current_ifd + 6 < current_ifd) ) | ||
156 | return 0; | ||
157 | if (byteOrder == 0) | ||
158 | len = data[current_ifd + 1] << 8 | data[current_ifd]; | ||
159 | else | ||
160 | len = data[current_ifd] << 8 | data[current_ifd + 1]; | ||
161 | if (len * DIRECTORY_ENTRY_SIZE + 2 + 4 + current_ifd > size) | ||
162 | { | ||
163 | #if DEBUG | ||
164 | printf ("WARNING: malformed tiff\n"); | ||
165 | #endif | ||
166 | return 0; | ||
167 | } | ||
168 | for (i = 0; i < len; i++) | ||
169 | { | ||
170 | DIRECTORY_ENTRY entry; | ||
171 | off = current_ifd + 2 + DIRECTORY_ENTRY_SIZE * i; | ||
172 | |||
173 | EXTRACTOR_common_cat_unpack (&data[off], | ||
174 | DIRECTORY_ENTRY_SPECS[byteOrder], | ||
175 | DIRECTORY_ENTRY_FIELDS (&entry)); | ||
176 | switch (entry.tag) | ||
177 | { | ||
178 | case TAG_LENGTH: | ||
179 | if ((entry.type == TYPE_SHORT) && (byteOrder == 1)) | ||
180 | { | ||
181 | length = entry.value_or_offset >> 16; | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | length = entry.value_or_offset; | ||
186 | } | ||
187 | if (width != -1) | ||
188 | { | ||
189 | char tmp[128]; | ||
190 | snprintf (tmp, | ||
191 | sizeof(tmp), "%ux%u", | ||
192 | width, length); | ||
193 | addKeyword (proc, | ||
194 | proc_cls, | ||
195 | tmp, | ||
196 | EXTRACTOR_METATYPE_IMAGE_DIMENSIONS); | ||
197 | } | ||
198 | break; | ||
199 | case TAG_WIDTH: | ||
200 | if ((entry.type == TYPE_SHORT) && (byteOrder == 1)) | ||
201 | width = entry.value_or_offset >> 16; | ||
202 | else | ||
203 | width = entry.value_or_offset; | ||
204 | if (length != -1) | ||
205 | { | ||
206 | char tmp[128]; | ||
207 | snprintf (tmp, | ||
208 | sizeof(tmp), | ||
209 | "%ux%u", | ||
210 | width, length); | ||
211 | addKeyword (proc, proc_cls, | ||
212 | tmp, | ||
213 | EXTRACTOR_METATYPE_IMAGE_DIMENSIONS); | ||
214 | } | ||
215 | break; | ||
216 | case TAG_SOFTWARE: | ||
217 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE)) | ||
218 | return 1; | ||
219 | break; | ||
220 | case TAG_ARTIST: | ||
221 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_ARTIST)) | ||
222 | return 1; | ||
223 | break; | ||
224 | case TAG_DOCUMENT_NAME: | ||
225 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_TITLE)) | ||
226 | return 1; | ||
227 | break; | ||
228 | case TAG_COPYRIGHT: | ||
229 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_COPYRIGHT)) | ||
230 | return 1; | ||
231 | break; | ||
232 | case TAG_DESCRIPTION: | ||
233 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_DESCRIPTION)) | ||
234 | return 1; | ||
235 | break; | ||
236 | case TAG_HOST: | ||
237 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_BUILDHOST)) | ||
238 | return 1; | ||
239 | break; | ||
240 | case TAG_SCANNER: | ||
241 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_SOURCE)) | ||
242 | return 1; | ||
243 | break; | ||
244 | case TAG_DAYTIME: | ||
245 | if (0 != addASCII (proc, proc_cls, data, size, &entry, EXTRACTOR_METATYPE_CREATION_DATE)) | ||
246 | return 1; | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | off = current_ifd + 2 + DIRECTORY_ENTRY_SIZE * len; | ||
252 | if (byteOrder == 0) | ||
253 | current_ifd = | ||
254 | data[off + 3] << 24 | data[off + 2] << 16 | | ||
255 | data[off + 1] << 8 | data[off]; | ||
256 | else | ||
257 | current_ifd = | ||
258 | data[off] << 24 | data[off + 1] << 16 | | ||
259 | data[off + 2] << 8 | data[off + 3]; | ||
260 | } | ||
261 | return 0; | ||
262 | } | ||
diff --git a/src/plugins/test_tiff.c b/src/plugins/test_tiff.c new file mode 100644 index 0000000..ce72de5 --- /dev/null +++ b/src/plugins/test_tiff.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file plugins/test_tiff.c | ||
22 | * @brief testcase for tiff plugin | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "test_lib.h" | ||
27 | |||
28 | |||
29 | |||
30 | /** | ||
31 | * Main function for the TIFF testcase. | ||
32 | * | ||
33 | * @param argc number of arguments (ignored) | ||
34 | * @param argv arguments (ignored) | ||
35 | * @return 0 on success | ||
36 | */ | ||
37 | int | ||
38 | main (int argc, char *argv[]) | ||
39 | { | ||
40 | struct SolutionData tiff_haute_sol[] = | ||
41 | { | ||
42 | { | ||
43 | EXTRACTOR_METATYPE_MIMETYPE, | ||
44 | EXTRACTOR_METAFORMAT_UTF8, | ||
45 | "text/plain", | ||
46 | "image/tiff", | ||
47 | strlen ("image/tiff") + 1, | ||
48 | 0 | ||
49 | }, | ||
50 | { | ||
51 | EXTRACTOR_METATYPE_ARTIST, | ||
52 | EXTRACTOR_METAFORMAT_UTF8, | ||
53 | "text/plain", | ||
54 | "Anders Espersen", | ||
55 | strlen ("Anders Espersen") + 1, | ||
56 | 0 | ||
57 | }, | ||
58 | { | ||
59 | EXTRACTOR_METATYPE_CREATION_DATE, | ||
60 | EXTRACTOR_METAFORMAT_UTF8, | ||
61 | "text/plain", | ||
62 | "2012:05:15 10:51:47", | ||
63 | strlen ("2012:05:15 10:51:47") + 1, | ||
64 | 0 | ||
65 | }, | ||
66 | { | ||
67 | EXTRACTOR_METATYPE_COPYRIGHT, | ||
68 | EXTRACTOR_METAFORMAT_UTF8, | ||
69 | "text/plain", | ||
70 | "© Anders Espersen", | ||
71 | strlen ("© Anders Espersen") + 1, | ||
72 | 0 | ||
73 | }, | ||
74 | { | ||
75 | EXTRACTOR_METATYPE_CAMERA_MAKE, | ||
76 | EXTRACTOR_METAFORMAT_UTF8, | ||
77 | "text/plain", | ||
78 | "Hasselblad", | ||
79 | strlen ("Hasselblad") + 1, | ||
80 | 0 | ||
81 | }, | ||
82 | { | ||
83 | EXTRACTOR_METATYPE_CAMERA_MODEL, | ||
84 | EXTRACTOR_METAFORMAT_UTF8, | ||
85 | "text/plain", | ||
86 | "Hasselblad H4D-31", | ||
87 | strlen ("Hasselblad H4D-31") + 1, | ||
88 | 0 | ||
89 | }, | ||
90 | { | ||
91 | EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE, | ||
92 | EXTRACTOR_METAFORMAT_UTF8, | ||
93 | "text/plain", | ||
94 | "Adobe Photoshop CS5 Macintosh", | ||
95 | strlen ("Adobe Photoshop CS5 Macintosh") + 1, | ||
96 | 0 | ||
97 | }, | ||
98 | { | ||
99 | EXTRACTOR_METATYPE_IMAGE_DIMENSIONS, | ||
100 | EXTRACTOR_METAFORMAT_UTF8, | ||
101 | "text/plain", | ||
102 | "4872x6496", | ||
103 | strlen ("4872x6496") + 1, | ||
104 | 0 | ||
105 | }, | ||
106 | { 0, 0, NULL, NULL, 0, -1 } | ||
107 | }; | ||
108 | struct ProblemSet ps[] = | ||
109 | { | ||
110 | /* note that the original test image was almost | ||
111 | 100 MB large; so for SVN it was cut down to | ||
112 | only contain the first 64 KB, which still parse | ||
113 | fine and give use the meta data */ | ||
114 | { "testdata/tiff_haute.tiff", | ||
115 | tiff_haute_sol }, | ||
116 | { NULL, NULL } | ||
117 | }; | ||
118 | return ET_main ("tiff", ps); | ||
119 | } | ||
120 | |||
121 | /* end of test_tiff.c */ | ||
diff --git a/src/plugins/testdata/tiff_haute.tiff b/src/plugins/testdata/tiff_haute.tiff new file mode 100644 index 0000000..734f2e8 --- /dev/null +++ b/src/plugins/testdata/tiff_haute.tiff | |||
Binary files differ | |||
diff --git a/src/plugins/tiff_extractor.c b/src/plugins/tiff_extractor.c new file mode 100644 index 0000000..28af340 --- /dev/null +++ b/src/plugins/tiff_extractor.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, 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 | /* end of tiff_extractor.c */ | ||