xref: /PHP-7.4/ext/exif/exif.c (revision 376bbbdf)
13c61d015SRasmus Lerdorf /*
23c61d015SRasmus Lerdorf    +----------------------------------------------------------------------+
3d0cb7153SJohannes Schlüter    | PHP Version 7                                                        |
43c61d015SRasmus Lerdorf    +----------------------------------------------------------------------+
5a6519d05SXinchen Hui    | Copyright (c) The PHP Group                                          |
63c61d015SRasmus Lerdorf    +----------------------------------------------------------------------+
75bd93221Sfoobar    | This source file is subject to version 3.01 of the PHP license,      |
83c61d015SRasmus Lerdorf    | that is bundled with this package in the file LICENSE, and is        |
9f68c7ff2SJames Cox    | available through the world-wide-web at the following url:           |
105bd93221Sfoobar    | http://www.php.net/license/3_01.txt                                  |
113c61d015SRasmus Lerdorf    | If you did not receive a copy of the PHP license and are unable to   |
123c61d015SRasmus Lerdorf    | obtain it through the world-wide-web, please send a note to          |
133c61d015SRasmus Lerdorf    | license@php.net so we can mail you a copy immediately.               |
143c61d015SRasmus Lerdorf    +----------------------------------------------------------------------+
153c61d015SRasmus Lerdorf    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
1698ebd1c2SMarcus Boerger    |          Marcus Boerger <helly@php.net>                              |
173c61d015SRasmus Lerdorf    +----------------------------------------------------------------------+
183c61d015SRasmus Lerdorf  */
1998ebd1c2SMarcus Boerger 
201beda9eeSStig Bakken #ifdef HAVE_CONFIG_H
211beda9eeSStig Bakken #include "config.h"
221beda9eeSStig Bakken #endif
231beda9eeSStig Bakken 
243c61d015SRasmus Lerdorf #include "php.h"
2568f4e7c3SMarcus Boerger #include "ext/standard/file.h"
263c61d015SRasmus Lerdorf 
27a9d4cf90SAndi Gutmans #if HAVE_EXIF
283c61d015SRasmus Lerdorf 
29a7403576SMarcus Boerger /* When EXIF_DEBUG is defined the module generates a lot of debug messages
30a7403576SMarcus Boerger  * that help understanding what is going on. This can and should be used
31a7403576SMarcus Boerger  * while extending the module as it shows if you are at the right position.
3206a24216SMarcus Boerger  * You are always considered to have a copy of TIFF6.0 and EXIF2.10 standard.
33a7403576SMarcus Boerger  */
34abb280e9SMarcus Boerger #undef EXIF_DEBUG
35642ab24dSMarcus Boerger 
36c5d4b5ddSMarcus Boerger #ifdef EXIF_DEBUG
37e112f6a0SAnatol Belski #define EXIFERR_DC , const char *_file, size_t _line
38e112f6a0SAnatol Belski #define EXIFERR_CC , __FILE__, __LINE__
39c5d4b5ddSMarcus Boerger #else
40e112f6a0SAnatol Belski #define EXIFERR_DC
41e112f6a0SAnatol Belski #define EXIFERR_CC
42c5d4b5ddSMarcus Boerger #endif
43c5d4b5ddSMarcus Boerger 
44e4f43867SMarcus Boerger #include "php_exif.h"
45e4f43867SMarcus Boerger #include <math.h>
463c61d015SRasmus Lerdorf #include "php_ini.h"
473c61d015SRasmus Lerdorf #include "ext/standard/php_string.h"
483c61d015SRasmus Lerdorf #include "ext/standard/php_image.h"
493c61d015SRasmus Lerdorf #include "ext/standard/info.h"
50be5908b0SMarcus Boerger 
51b7a7b1a6SStanislav Malyshev /* needed for ssize_t definition */
52d0de28ecSMarcus Boerger #include <sys/types.h>
531f06bb94SIlia Alshanetsky 
541f06bb94SIlia Alshanetsky typedef unsigned char uchar;
551f06bb94SIlia Alshanetsky 
563c61d015SRasmus Lerdorf #ifndef TRUE
573c61d015SRasmus Lerdorf #	define TRUE 1
583c61d015SRasmus Lerdorf #	define FALSE 0
59b3a96ba5SMarcus Boerger #endif
60b3a96ba5SMarcus Boerger 
613c61d015SRasmus Lerdorf #ifndef max
623c61d015SRasmus Lerdorf #	define max(a,b) ((a)>(b) ? (a) : (b))
6306a24216SMarcus Boerger #endif
64b3a96ba5SMarcus Boerger 
6506a24216SMarcus Boerger #define EFREE_IF(ptr)	if (ptr) efree(ptr)
663c61d015SRasmus Lerdorf 
6759f33280SMarcus Boerger #define MAX_IFD_NESTING_LEVEL 10
6859f33280SMarcus Boerger #define MAX_IFD_TAGS 1000
69*376bbbdfSNikita Popov 
70*376bbbdfSNikita Popov /* {{{ arginfo */
71ecb9f866SAndrei Zmievski ZEND_BEGIN_ARG_INFO(arginfo_exif_tagname, 0)
7231042330SHannes Magnusson 	ZEND_ARG_INFO(0, index)
7331042330SHannes Magnusson ZEND_END_ARG_INFO()
7431042330SHannes Magnusson 
7531042330SHannes Magnusson ZEND_BEGIN_ARG_INFO_EX(arginfo_exif_read_data, 0, 0, 1)
7631042330SHannes Magnusson 	ZEND_ARG_INFO(0, filename)
7731042330SHannes Magnusson 	ZEND_ARG_INFO(0, sections_needed)
7831042330SHannes Magnusson 	ZEND_ARG_INFO(0, sub_arrays)
7931042330SHannes Magnusson 	ZEND_ARG_INFO(0, read_thumbnail)
8031042330SHannes Magnusson ZEND_END_ARG_INFO()
8131042330SHannes Magnusson 
8231042330SHannes Magnusson ZEND_BEGIN_ARG_INFO_EX(arginfo_exif_thumbnail, 0, 0, 1)
8331042330SHannes Magnusson 	ZEND_ARG_INFO(0, filename)
8431042330SHannes Magnusson 	ZEND_ARG_INFO(1, width)
8531042330SHannes Magnusson 	ZEND_ARG_INFO(1, height)
8631042330SHannes Magnusson 	ZEND_ARG_INFO(1, imagetype)
8731042330SHannes Magnusson ZEND_END_ARG_INFO()
8831042330SHannes Magnusson 
8931042330SHannes Magnusson ZEND_BEGIN_ARG_INFO(arginfo_exif_imagetype, 0)
9031042330SHannes Magnusson 	ZEND_ARG_INFO(0, imagefile)
9131042330SHannes Magnusson ZEND_END_ARG_INFO()
9231042330SHannes Magnusson 
9331042330SHannes Magnusson /* }}} */
9431042330SHannes Magnusson 
9531042330SHannes Magnusson /* {{{ exif_functions[]
96538d58ddSZeev Suraski  */
9725c3a3a3SRasmus Lerdorf static const zend_function_entry exif_functions[] = {
9825c3a3a3SRasmus Lerdorf 	PHP_FE(exif_read_data, arginfo_exif_read_data)
999e709e2fSDmitry Stogov 	PHP_DEP_FALIAS(read_exif_data, exif_read_data, arginfo_exif_read_data)
10031042330SHannes Magnusson 	PHP_FE(exif_tagname, arginfo_exif_tagname)
101ba28d75cSKalle Sommer Nielsen 	PHP_FE(exif_thumbnail, arginfo_exif_thumbnail)
10231042330SHannes Magnusson 	PHP_FE(exif_imagetype, arginfo_exif_imagetype)
10331042330SHannes Magnusson 	PHP_FE_END
10431042330SHannes Magnusson };
105da376383SFelipe Pena /* }}} */
1063c61d015SRasmus Lerdorf 
10725c3a3a3SRasmus Lerdorf /* {{{ PHP_MINFO_FUNCTION
1083c61d015SRasmus Lerdorf  */
PHP_MINFO_FUNCTION(exif)10906a24216SMarcus Boerger PHP_MINFO_FUNCTION(exif)
11006a24216SMarcus Boerger {
11106a24216SMarcus Boerger 	php_info_print_table_start();
11206a24216SMarcus Boerger 	php_info_print_table_row(2, "EXIF Support", "enabled");
11306a24216SMarcus Boerger 	php_info_print_table_row(2, "Supported EXIF Version", "0220");
11459f33280SMarcus Boerger 	php_info_print_table_row(2, "Supported filetypes", "JPEG, TIFF");
11538247a79SMarcus Boerger 
116b0263db4SKalle Sommer Nielsen 	if (zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)) {
117b0263db4SKalle Sommer Nielsen 		php_info_print_table_row(2, "Multibyte decoding support using mbstring", "enabled");
11864002648SGabriel Caruso 	} else {
119b0263db4SKalle Sommer Nielsen 		php_info_print_table_row(2, "Multibyte decoding support using mbstring", "disabled");
120b0263db4SKalle Sommer Nielsen 	}
121b0263db4SKalle Sommer Nielsen 
122b0263db4SKalle Sommer Nielsen 	php_info_print_table_row(2, "Extended EXIF tag formats", "Canon, Casio, Fujifilm, Nikon, Olympus, Samsung, Panasonic, DJI, Sony, Pentax, Minolta, Sigma, Foveon, Kyocera, Ricoh, AGFA, Epson");
123b0263db4SKalle Sommer Nielsen 	php_info_print_table_end();
124818272aeSKalle Sommer Nielsen 
12506a24216SMarcus Boerger 	DISPLAY_INI_ENTRIES();
126818272aeSKalle Sommer Nielsen }
127f6cf54d2SHannes Magnusson /* }}} */
12806a24216SMarcus Boerger 
12906a24216SMarcus Boerger ZEND_BEGIN_MODULE_GLOBALS(exif)
13006a24216SMarcus Boerger 	char * encode_unicode;
13150d957cdSMarcus Boerger 	char * decode_unicode_be;
13250d957cdSMarcus Boerger 	char * decode_unicode_le;
13350d957cdSMarcus Boerger 	char * encode_jis;
13450d957cdSMarcus Boerger 	char * decode_jis_be;
13550d957cdSMarcus Boerger 	char * decode_jis_le;
13650d957cdSMarcus Boerger 	HashTable *tag_table_cache;
13750d957cdSMarcus Boerger ZEND_END_MODULE_GLOBALS(exif)
138b7a7b1a6SStanislav Malyshev 
ZEND_DECLARE_MODULE_GLOBALS(exif)13950d957cdSMarcus Boerger ZEND_DECLARE_MODULE_GLOBALS(exif)
1408581de0fSfoobar #define EXIF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(exif, v)
1414e66cce8SAnatol Belski 
1428581de0fSfoobar #if defined(ZTS) && defined(COMPILE_DL_EXIF)
1434e66cce8SAnatol Belski ZEND_TSRMLS_CACHE_DEFINE()
1441ac15293SNikita Popov #endif
1454fce2ae2SAnatol Belski 
146b7a7b1a6SStanislav Malyshev /* {{{ PHP_INI
14750d957cdSMarcus Boerger  */
14850d957cdSMarcus Boerger 
14950d957cdSMarcus Boerger ZEND_INI_MH(OnUpdateEncode)
150e92e7d47SEdin Kadribasic {
15150d957cdSMarcus Boerger 	if (new_value && ZSTR_LEN(new_value)) {
1524a2e40bbSDmitry Stogov 		const zend_encoding **return_list;
153e8b15906SMoriyoshi Koizumi 		size_t return_size;
154e8b15906SMoriyoshi Koizumi 		if (FAILURE == zend_multibyte_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value),
1554a2e40bbSDmitry Stogov 	&return_list, &return_size, 0)) {
156bdeb220fSAnatol Belski 			php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value));
1574a2e40bbSDmitry Stogov 			return FAILURE;
158e8b15906SMoriyoshi Koizumi 		}
159e8b15906SMoriyoshi Koizumi 		pefree((void *) return_list, 0);
1605db7f1eaSKalle Sommer Nielsen 	}
16150d957cdSMarcus Boerger 	return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
162bdeb220fSAnatol Belski }
16350d957cdSMarcus Boerger 
ZEND_INI_MH(OnUpdateDecode)16450d957cdSMarcus Boerger ZEND_INI_MH(OnUpdateDecode)
165e92e7d47SEdin Kadribasic {
16650d957cdSMarcus Boerger 	if (new_value) {
167e8b15906SMoriyoshi Koizumi 		const zend_encoding **return_list;
168e8b15906SMoriyoshi Koizumi 		size_t return_size;
169e8b15906SMoriyoshi Koizumi 		if (FAILURE == zend_multibyte_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value),
1704a2e40bbSDmitry Stogov 	&return_list, &return_size, 0)) {
171bdeb220fSAnatol Belski 			php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value));
1724a2e40bbSDmitry Stogov 			return FAILURE;
173e8b15906SMoriyoshi Koizumi 		}
174e8b15906SMoriyoshi Koizumi 		pefree((void *) return_list, 0);
1755db7f1eaSKalle Sommer Nielsen 	}
17650d957cdSMarcus Boerger 	return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
177bdeb220fSAnatol Belski }
17850d957cdSMarcus Boerger 
17950d957cdSMarcus Boerger PHP_INI_BEGIN()
18050d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.encode_unicode",          "ISO-8859-15", PHP_INI_ALL, OnUpdateEncode, encode_unicode,    zend_exif_globals, exif_globals)
18150d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.decode_unicode_motorola", "UCS-2BE",     PHP_INI_ALL, OnUpdateDecode, decode_unicode_be, zend_exif_globals, exif_globals)
18250d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.decode_unicode_intel",    "UCS-2LE",     PHP_INI_ALL, OnUpdateDecode, decode_unicode_le, zend_exif_globals, exif_globals)
18350d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.encode_jis",              "",            PHP_INI_ALL, OnUpdateEncode, encode_jis,        zend_exif_globals, exif_globals)
18450d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.decode_jis_motorola",     "JIS",         PHP_INI_ALL, OnUpdateDecode, decode_jis_be,     zend_exif_globals, exif_globals)
18550d957cdSMarcus Boerger     STD_PHP_INI_ENTRY("exif.decode_jis_intel",        "JIS",         PHP_INI_ALL, OnUpdateDecode, decode_jis_le,     zend_exif_globals, exif_globals)
PHP_INI_END()18650d957cdSMarcus Boerger PHP_INI_END()
18750d957cdSMarcus Boerger /* }}} */
18850d957cdSMarcus Boerger 
189b7a7b1a6SStanislav Malyshev /* {{{ PHP_GINIT_FUNCTION
1901dbaae27SDmitry Stogov  */
19150d957cdSMarcus Boerger static PHP_GINIT_FUNCTION(exif)
1921dbaae27SDmitry Stogov {
19350d957cdSMarcus Boerger #if defined(COMPILE_DL_EXIF) && defined(ZTS)
1944fce2ae2SAnatol Belski 	ZEND_TSRMLS_CACHE_UPDATE();
195af3ca745SAnatol Belski #endif
1964fce2ae2SAnatol Belski 	exif_globals->encode_unicode    = NULL;
19750d957cdSMarcus Boerger 	exif_globals->decode_unicode_be = NULL;
19850d957cdSMarcus Boerger 	exif_globals->decode_unicode_le = NULL;
19950d957cdSMarcus Boerger 	exif_globals->encode_jis        = NULL;
20050d957cdSMarcus Boerger 	exif_globals->decode_jis_be     = NULL;
20150d957cdSMarcus Boerger 	exif_globals->decode_jis_le     = NULL;
20250d957cdSMarcus Boerger 	exif_globals->tag_table_cache   = NULL;
20350d957cdSMarcus Boerger }
20450d957cdSMarcus Boerger /* }}} */
2058a388954SMarcus Boerger 
20606a24216SMarcus Boerger /* {{{ PHP_MINIT_FUNCTION(exif)
20794cc0c89SKalle Sommer Nielsen  */
PHP_MINIT_FUNCTION(exif)20806a24216SMarcus Boerger PHP_MINIT_FUNCTION(exif)
20906a24216SMarcus Boerger {
21050d957cdSMarcus Boerger 	REGISTER_INI_ENTRIES();
2116cab75aaSkrakjoe 	if (zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)) {
212b7a7b1a6SStanislav Malyshev 		REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", 1, CONST_CS | CONST_PERSISTENT);
213755c2cd0SDmitry Stogov 	} else {
214b7a7b1a6SStanislav Malyshev 		REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", 0, CONST_CS | CONST_PERSISTENT);
215755c2cd0SDmitry Stogov 	}
21606a24216SMarcus Boerger 	return SUCCESS;
21706a24216SMarcus Boerger }
21806a24216SMarcus Boerger /* }}} */
21906a24216SMarcus Boerger 
22050d957cdSMarcus Boerger /* {{{ PHP_MSHUTDOWN_FUNCTION
22150d957cdSMarcus Boerger  */
PHP_MSHUTDOWN_FUNCTION(exif)22250d957cdSMarcus Boerger PHP_MSHUTDOWN_FUNCTION(exif)
22350d957cdSMarcus Boerger {
22450d957cdSMarcus Boerger 	UNREGISTER_INI_ENTRIES();
22550d957cdSMarcus Boerger 	if (EXIF_G(tag_table_cache)) {
22650d957cdSMarcus Boerger 		zend_hash_destroy(EXIF_G(tag_table_cache));
22750d957cdSMarcus Boerger 		free(EXIF_G(tag_table_cache));
22850d957cdSMarcus Boerger 	}
229ec90d483SIlia Alshanetsky 	return SUCCESS;
230ec90d483SIlia Alshanetsky }
231ec90d483SIlia Alshanetsky /* }}} */
232755c2cd0SDmitry Stogov 
2339480eaceSFelipe Pena /* {{{ exif dependencies */
234ec90d483SIlia Alshanetsky static const zend_module_dep exif_module_deps[] = {
235ec90d483SIlia Alshanetsky 	ZEND_MOD_REQUIRED("standard")
236ec90d483SIlia Alshanetsky 	ZEND_MOD_OPTIONAL("mbstring")
23725c3a3a3SRasmus Lerdorf 	ZEND_MOD_END
23825c3a3a3SRasmus Lerdorf };
2393c61d015SRasmus Lerdorf /* }}} */
240ec90d483SIlia Alshanetsky 
241ec90d483SIlia Alshanetsky /* {{{ exif_module_entry
24205b13da5SMarcus Boerger  */
24305b13da5SMarcus Boerger zend_module_entry exif_module_entry = {
244b7a7b1a6SStanislav Malyshev 	STANDARD_MODULE_HEADER_EX, NULL,
24550d957cdSMarcus Boerger 	exif_module_deps,
24605b13da5SMarcus Boerger 	"exif",
24705b13da5SMarcus Boerger 	exif_functions,
248ec89c850SAnatol Belski 	PHP_MINIT(exif),
2491dbaae27SDmitry Stogov 	PHP_MSHUTDOWN(exif),
2501dbaae27SDmitry Stogov 	NULL, NULL,
2511dbaae27SDmitry Stogov 	PHP_MINFO(exif),
2521dbaae27SDmitry Stogov 	PHP_EXIF_VERSION,
2531dbaae27SDmitry Stogov 	PHP_MODULE_GLOBALS(exif),
2543c61d015SRasmus Lerdorf 	PHP_GINIT(exif),
25525c3a3a3SRasmus Lerdorf 	NULL,
2563c61d015SRasmus Lerdorf 	NULL,
2573c61d015SRasmus Lerdorf 	STANDARD_MODULE_PROPERTIES_EX
2583c61d015SRasmus Lerdorf };
2593c61d015SRasmus Lerdorf /* }}} */
2603c61d015SRasmus Lerdorf 
261088450efSMarcus Boerger #ifdef COMPILE_DL_EXIF
ZEND_GET_MODULE(exif)262088450efSMarcus Boerger ZEND_GET_MODULE(exif)
26359f33280SMarcus Boerger #endif
264088450efSMarcus Boerger 
26505b13da5SMarcus Boerger /* {{{ php_strnlen
26659f33280SMarcus Boerger  * get length of string if buffer if less than buffer size or buffer size */
267088450efSMarcus Boerger static size_t php_strnlen(char* str, size_t maxlen) {
268088450efSMarcus Boerger 	size_t len = 0;
26959f33280SMarcus Boerger 
27005b13da5SMarcus Boerger 	if (str && maxlen && *str) {
271088450efSMarcus Boerger 		do {
2723c61d015SRasmus Lerdorf 			len++;
27325c3a3a3SRasmus Lerdorf 		} while (--maxlen && *(++str));
2743c61d015SRasmus Lerdorf 	}
27542e478c7SMarcus Boerger 	return len;
27642e478c7SMarcus Boerger }
2774294f2a9SMarcus Boerger /* }}} */
2784294f2a9SMarcus Boerger 
2794294f2a9SMarcus Boerger /* {{{ error messages
280a3daf3bbSIlia Alshanetsky */
28142e478c7SMarcus Boerger static const char * EXIF_ERROR_FILEEOF   = "Unexpected end of file reached";
2824aaa2becSIlia Alshanetsky static const char * EXIF_ERROR_CORRUPT   = "File structure corrupted";
2834aaa2becSIlia Alshanetsky static const char * EXIF_ERROR_THUMBEOF  = "Thumbnail goes IFD boundary or end of file reached";
2844aaa2becSIlia Alshanetsky static const char * EXIF_ERROR_FSREALLOC = "Illegal reallocating of undefined file section";
2854aaa2becSIlia Alshanetsky 
28642e478c7SMarcus Boerger #define EXIF_ERRLOG_FILEEOF(ImageInfo)    exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FILEEOF);
28742e478c7SMarcus Boerger #define EXIF_ERRLOG_CORRUPT(ImageInfo)    exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_CORRUPT);
28825c3a3a3SRasmus Lerdorf #define EXIF_ERRLOG_THUMBEOF(ImageInfo)   exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_THUMBEOF);
2893c61d015SRasmus Lerdorf #define EXIF_ERRLOG_FSREALLOC(ImageInfo)  exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FSREALLOC);
2903c61d015SRasmus Lerdorf /* }}} */
2914a8dd125SMarcus Boerger 
2924a8dd125SMarcus Boerger /* {{{ format description defines
2933c61d015SRasmus Lerdorf    Describes format descriptor
2946b2a0743SMarcus Boerger */
2956b2a0743SMarcus Boerger static int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1};
2966b2a0743SMarcus Boerger #define NUM_FORMATS 13
2976b2a0743SMarcus Boerger 
2986b2a0743SMarcus Boerger #define TAG_FMT_BYTE       1
2996b2a0743SMarcus Boerger #define TAG_FMT_STRING     2
3006b2a0743SMarcus Boerger #define TAG_FMT_USHORT     3
3016b2a0743SMarcus Boerger #define TAG_FMT_ULONG      4
3026b2a0743SMarcus Boerger #define TAG_FMT_URATIONAL  5
3036b2a0743SMarcus Boerger #define TAG_FMT_SBYTE      6
3046b2a0743SMarcus Boerger #define TAG_FMT_UNDEFINED  7
3056b2a0743SMarcus Boerger #define TAG_FMT_SSHORT     8
3064a8dd125SMarcus Boerger #define TAG_FMT_SLONG      9
3073c61d015SRasmus Lerdorf #define TAG_FMT_SRATIONAL 10
30806a24216SMarcus Boerger #define TAG_FMT_SINGLE    11
3090ecd2f08SMarcus Boerger #define TAG_FMT_DOUBLE    12
3100ecd2f08SMarcus Boerger #define TAG_FMT_IFD       13
3110ecd2f08SMarcus Boerger 
3120ecd2f08SMarcus Boerger #ifdef EXIF_DEBUG
exif_get_tagformat(int format)3130ecd2f08SMarcus Boerger static char *exif_get_tagformat(int format)
3140ecd2f08SMarcus Boerger {
3150ecd2f08SMarcus Boerger 	switch(format) {
3160ecd2f08SMarcus Boerger 		case TAG_FMT_BYTE:      return "BYTE";
3170ecd2f08SMarcus Boerger 		case TAG_FMT_STRING:    return "STRING";
3180ecd2f08SMarcus Boerger 		case TAG_FMT_USHORT:    return "USHORT";
3190ecd2f08SMarcus Boerger 		case TAG_FMT_ULONG:     return "ULONG";
3200ecd2f08SMarcus Boerger 		case TAG_FMT_URATIONAL: return "URATIONAL";
3210ecd2f08SMarcus Boerger 		case TAG_FMT_SBYTE:     return "SBYTE";
3220ecd2f08SMarcus Boerger 		case TAG_FMT_UNDEFINED: return "UNDEFINED";
3230ecd2f08SMarcus Boerger 		case TAG_FMT_SSHORT:    return "SSHORT";
3244a8dd125SMarcus Boerger 		case TAG_FMT_SLONG:     return "SLONG";
3250ecd2f08SMarcus Boerger 		case TAG_FMT_SRATIONAL: return "SRATIONAL";
3260ecd2f08SMarcus Boerger 		case TAG_FMT_SINGLE:    return "SINGLE";
3270ecd2f08SMarcus Boerger 		case TAG_FMT_DOUBLE:    return "DOUBLE";
32806a24216SMarcus Boerger 		case TAG_FMT_IFD:       return "IFD";
3290ecd2f08SMarcus Boerger 	}
330088450efSMarcus Boerger 	return "*Illegal";
331b4c3a0f0SMarcus Boerger }
332b4c3a0f0SMarcus Boerger #endif
333b4c3a0f0SMarcus Boerger 
334b4c3a0f0SMarcus Boerger /* Describes tag values */
335b4c3a0f0SMarcus Boerger #define TAG_GPS_VERSION_ID              0x0000
336b4c3a0f0SMarcus Boerger #define TAG_GPS_LATITUDE_REF            0x0001
337b4c3a0f0SMarcus Boerger #define TAG_GPS_LATITUDE                0x0002
338b4c3a0f0SMarcus Boerger #define TAG_GPS_LONGITUDE_REF           0x0003
339b4c3a0f0SMarcus Boerger #define TAG_GPS_LONGITUDE               0x0004
340b4c3a0f0SMarcus Boerger #define TAG_GPS_ALTITUDE_REF            0x0005
341b4c3a0f0SMarcus Boerger #define TAG_GPS_ALTITUDE                0x0006
342b4c3a0f0SMarcus Boerger #define TAG_GPS_TIME_STAMP              0x0007
343b4c3a0f0SMarcus Boerger #define TAG_GPS_SATELLITES              0x0008
344b4c3a0f0SMarcus Boerger #define TAG_GPS_STATUS                  0x0009
345b4c3a0f0SMarcus Boerger #define TAG_GPS_MEASURE_MODE            0x000A
346b4c3a0f0SMarcus Boerger #define TAG_GPS_DOP                     0x000B
347b4c3a0f0SMarcus Boerger #define TAG_GPS_SPEED_REF               0x000C
348b4c3a0f0SMarcus Boerger #define TAG_GPS_SPEED                   0x000D
349b4c3a0f0SMarcus Boerger #define TAG_GPS_TRACK_REF               0x000E
350b4c3a0f0SMarcus Boerger #define TAG_GPS_TRACK                   0x000F
351b4c3a0f0SMarcus Boerger #define TAG_GPS_IMG_DIRECTION_REF       0x0010
352b4c3a0f0SMarcus Boerger #define TAG_GPS_IMG_DIRECTION           0x0011
353b4c3a0f0SMarcus Boerger #define TAG_GPS_MAP_DATUM               0x0012
354b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_LATITUDE_REF       0x0013
355b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_LATITUDE           0x0014
356b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_LONGITUDE_REF      0x0015
357b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_LONGITUDE          0x0016
358b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_BEARING_REF        0x0017
359b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_BEARING            0x0018
360b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_DISTANCE_REF       0x0019
361b4c3a0f0SMarcus Boerger #define TAG_GPS_DEST_DISTANCE           0x001A
362088450efSMarcus Boerger #define TAG_GPS_PROCESSING_METHOD       0x001B
363088450efSMarcus Boerger #define TAG_GPS_AREA_INFORMATION        0x001C
364088450efSMarcus Boerger #define TAG_GPS_DATE_STAMP              0x001D
365088450efSMarcus Boerger #define TAG_GPS_DIFFERENTIAL            0x001E
366088450efSMarcus Boerger #define TAG_TIFF_COMMENT                0x00FE /* SHOUDLNT HAPPEN */
367088450efSMarcus Boerger #define TAG_NEW_SUBFILE                 0x00FE /* New version of subfile tag */
368088450efSMarcus Boerger #define TAG_SUBFILE_TYPE                0x00FF /* Old version of subfile tag */
369088450efSMarcus Boerger #define TAG_IMAGEWIDTH                  0x0100
370088450efSMarcus Boerger #define TAG_IMAGEHEIGHT                 0x0101
371088450efSMarcus Boerger #define TAG_BITS_PER_SAMPLE             0x0102
372088450efSMarcus Boerger #define TAG_COMPRESSION                 0x0103
373088450efSMarcus Boerger #define TAG_PHOTOMETRIC_INTERPRETATION  0x0106
374088450efSMarcus Boerger #define TAG_TRESHHOLDING                0x0107
375088450efSMarcus Boerger #define TAG_CELL_WIDTH                  0x0108
376088450efSMarcus Boerger #define TAG_CELL_HEIGHT                 0x0109
377088450efSMarcus Boerger #define TAG_FILL_ORDER                  0x010A
378088450efSMarcus Boerger #define TAG_DOCUMENT_NAME               0x010D
379088450efSMarcus Boerger #define TAG_IMAGE_DESCRIPTION           0x010E
380088450efSMarcus Boerger #define TAG_MAKE                        0x010F
381088450efSMarcus Boerger #define TAG_MODEL                       0x0110
382088450efSMarcus Boerger #define TAG_STRIP_OFFSETS               0x0111
383088450efSMarcus Boerger #define TAG_ORIENTATION                 0x0112
384088450efSMarcus Boerger #define TAG_SAMPLES_PER_PIXEL           0x0115
385088450efSMarcus Boerger #define TAG_ROWS_PER_STRIP              0x0116
386088450efSMarcus Boerger #define TAG_STRIP_BYTE_COUNTS           0x0117
387088450efSMarcus Boerger #define TAG_MIN_SAMPPLE_VALUE           0x0118
388088450efSMarcus Boerger #define TAG_MAX_SAMPLE_VALUE            0x0119
389088450efSMarcus Boerger #define TAG_X_RESOLUTION                0x011A
390088450efSMarcus Boerger #define TAG_Y_RESOLUTION                0x011B
391088450efSMarcus Boerger #define TAG_PLANAR_CONFIGURATION        0x011C
392088450efSMarcus Boerger #define TAG_PAGE_NAME                   0x011D
393088450efSMarcus Boerger #define TAG_X_POSITION                  0x011E
394088450efSMarcus Boerger #define TAG_Y_POSITION                  0x011F
395088450efSMarcus Boerger #define TAG_FREE_OFFSETS                0x0120
396088450efSMarcus Boerger #define TAG_FREE_BYTE_COUNTS            0x0121
397088450efSMarcus Boerger #define TAG_GRAY_RESPONSE_UNIT          0x0122
398088450efSMarcus Boerger #define TAG_GRAY_RESPONSE_CURVE         0x0123
399088450efSMarcus Boerger #define TAG_RESOLUTION_UNIT             0x0128
400088450efSMarcus Boerger #define TAG_PAGE_NUMBER                 0x0129
401088450efSMarcus Boerger #define TAG_TRANSFER_FUNCTION           0x012D
402837fa41dSMarcus Boerger #define TAG_SOFTWARE                    0x0131
403088450efSMarcus Boerger #define TAG_DATETIME                    0x0132
404088450efSMarcus Boerger #define TAG_ARTIST                      0x013B
405088450efSMarcus Boerger #define TAG_HOST_COMPUTER               0x013C
406088450efSMarcus Boerger #define TAG_PREDICTOR                   0x013D
407088450efSMarcus Boerger #define TAG_WHITE_POINT                 0x013E
408088450efSMarcus Boerger #define TAG_PRIMARY_CHROMATICITIES      0x013F
409088450efSMarcus Boerger #define TAG_COLOR_MAP                   0x0140
410088450efSMarcus Boerger #define TAG_HALFTONE_HINTS              0x0141
4114a8dd125SMarcus Boerger #define TAG_TILE_WIDTH                  0x0142
412088450efSMarcus Boerger #define TAG_TILE_LENGTH                 0x0143
413088450efSMarcus Boerger #define TAG_TILE_OFFSETS                0x0144
414469266e4SMarcus Boerger #define TAG_TILE_BYTE_COUNTS            0x0145
415088450efSMarcus Boerger #define TAG_SUB_IFD                     0x014A
416088450efSMarcus Boerger #define TAG_INK_SETMPUTER               0x014C
417088450efSMarcus Boerger #define TAG_INK_NAMES                   0x014D
418088450efSMarcus Boerger #define TAG_NUMBER_OF_INKS              0x014E
419088450efSMarcus Boerger #define TAG_DOT_RANGE                   0x0150
420088450efSMarcus Boerger #define TAG_TARGET_PRINTER              0x0151
421088450efSMarcus Boerger #define TAG_EXTRA_SAMPLE                0x0152
422837fa41dSMarcus Boerger #define TAG_SAMPLE_FORMAT               0x0153
423088450efSMarcus Boerger #define TAG_S_MIN_SAMPLE_VALUE          0x0154
424088450efSMarcus Boerger #define TAG_S_MAX_SAMPLE_VALUE          0x0155
425088450efSMarcus Boerger #define TAG_TRANSFER_RANGE              0x0156
426088450efSMarcus Boerger #define TAG_JPEG_TABLES                 0x015B
427088450efSMarcus Boerger #define TAG_JPEG_PROC                   0x0200
428088450efSMarcus Boerger #define TAG_JPEG_INTERCHANGE_FORMAT     0x0201
429088450efSMarcus Boerger #define TAG_JPEG_INTERCHANGE_FORMAT_LEN 0x0202
430088450efSMarcus Boerger #define TAG_JPEG_RESTART_INTERVAL       0x0203
431088450efSMarcus Boerger #define TAG_JPEG_LOSSLESS_PREDICTOR     0x0205
432088450efSMarcus Boerger #define TAG_JPEG_POINT_TRANSFORMS       0x0206
433088450efSMarcus Boerger #define TAG_JPEG_Q_TABLES               0x0207
434088450efSMarcus Boerger #define TAG_JPEG_DC_TABLES              0x0208
435088450efSMarcus Boerger #define TAG_JPEG_AC_TABLES              0x0209
436469266e4SMarcus Boerger #define TAG_YCC_COEFFICIENTS            0x0211
437469266e4SMarcus Boerger #define TAG_YCC_SUB_SAMPLING            0x0212
4384a8dd125SMarcus Boerger #define TAG_YCC_POSITIONING             0x0213
439469266e4SMarcus Boerger #define TAG_REFERENCE_BLACK_WHITE       0x0214
440469266e4SMarcus Boerger /* 0x0301 - 0x0302 */
441469266e4SMarcus Boerger /* 0x0320 */
442469266e4SMarcus Boerger /* 0x0343 */
443469266e4SMarcus Boerger /* 0x5001 - 0x501B */
4448b853592SMarcus Boerger /* 0x5021 - 0x503B */
445837fa41dSMarcus Boerger /* 0x5090 - 0x5091 */
446088450efSMarcus Boerger /* 0x5100 - 0x5101 */
447088450efSMarcus Boerger /* 0x5110 - 0x5113 */
448088450efSMarcus Boerger /* 0x80E3 - 0x80E6 */
449088450efSMarcus Boerger /* 0x828d - 0x828F */
450469266e4SMarcus Boerger #define TAG_COPYRIGHT                   0x8298
451b4c3a0f0SMarcus Boerger #define TAG_EXPOSURETIME                0x829A
452b4c3a0f0SMarcus Boerger #define TAG_FNUMBER                     0x829D
453088450efSMarcus Boerger #define TAG_EXIF_IFD_POINTER            0x8769
454088450efSMarcus Boerger #define TAG_ICC_PROFILE                 0x8773
455b4c3a0f0SMarcus Boerger #define TAG_EXPOSURE_PROGRAM            0x8822
456837fa41dSMarcus Boerger #define TAG_SPECTRAL_SENSITY            0x8824
457088450efSMarcus Boerger #define TAG_GPS_IFD_POINTER             0x8825
458b4c3a0f0SMarcus Boerger #define TAG_ISOSPEED                    0x8827
459b4c3a0f0SMarcus Boerger #define TAG_OPTOELECTRIC_CONVERSION_F   0x8828
460b4c3a0f0SMarcus Boerger /* 0x8829 - 0x882b */
461b4c3a0f0SMarcus Boerger #define TAG_EXIFVERSION                 0x9000
462088450efSMarcus Boerger #define TAG_DATE_TIME_ORIGINAL          0x9003
463088450efSMarcus Boerger #define TAG_DATE_TIME_DIGITIZED         0x9004
464b4c3a0f0SMarcus Boerger #define TAG_COMPONENT_CONFIG            0x9101
465b4c3a0f0SMarcus Boerger #define TAG_COMPRESSED_BITS_PER_PIXEL   0x9102
466b4c3a0f0SMarcus Boerger #define TAG_SHUTTERSPEED                0x9201
467088450efSMarcus Boerger #define TAG_APERTURE                    0x9202
468b4c3a0f0SMarcus Boerger #define TAG_BRIGHTNESS_VALUE            0x9203
469088450efSMarcus Boerger #define TAG_EXPOSURE_BIAS_VALUE         0x9204
470088450efSMarcus Boerger #define TAG_MAX_APERTURE                0x9205
471b4c3a0f0SMarcus Boerger #define TAG_SUBJECT_DISTANCE            0x9206
472837fa41dSMarcus Boerger #define TAG_METRIC_MODULE               0x9207
473837fa41dSMarcus Boerger #define TAG_LIGHT_SOURCE                0x9208
474b4c3a0f0SMarcus Boerger #define TAG_FLASH                       0x9209
4759455657aSMarcus Boerger #define TAG_FOCAL_LENGTH                0x920A
476088450efSMarcus Boerger /* 0x920B - 0x920D */
477b4c3a0f0SMarcus Boerger /* 0x9211 - 0x9216 */
478b4c3a0f0SMarcus Boerger #define TAG_SUBJECT_AREA                0x9214
479b4c3a0f0SMarcus Boerger #define TAG_MAKER_NOTE                  0x927C
4808b853592SMarcus Boerger #define TAG_USERCOMMENT                 0x9286
4818b853592SMarcus Boerger #define TAG_SUB_SEC_TIME                0x9290
482b4c3a0f0SMarcus Boerger #define TAG_SUB_SEC_TIME_ORIGINAL       0x9291
483b4c3a0f0SMarcus Boerger #define TAG_SUB_SEC_TIME_DIGITIZED      0x9292
484b4c3a0f0SMarcus Boerger /* 0x923F */
485b4c3a0f0SMarcus Boerger /* 0x935C */
486b4c3a0f0SMarcus Boerger #define TAG_XP_TITLE                    0x9C9B
487088450efSMarcus Boerger #define TAG_XP_COMMENTS                 0x9C9C
488088450efSMarcus Boerger #define TAG_XP_AUTHOR                   0x9C9D
489b4c3a0f0SMarcus Boerger #define TAG_XP_KEYWORDS                 0x9C9E
490b4c3a0f0SMarcus Boerger #define TAG_XP_SUBJECT                  0x9C9F
491b4c3a0f0SMarcus Boerger #define TAG_FLASH_PIX_VERSION           0xA000
492088450efSMarcus Boerger #define TAG_COLOR_SPACE                 0xA001
493b4c3a0f0SMarcus Boerger #define TAG_COMP_IMAGE_WIDTH            0xA002 /* compressed images only */
494b4c3a0f0SMarcus Boerger #define TAG_COMP_IMAGE_HEIGHT           0xA003
495b4c3a0f0SMarcus Boerger #define TAG_RELATED_SOUND_FILE          0xA004
496b4c3a0f0SMarcus Boerger #define TAG_INTEROP_IFD_POINTER         0xA005 /* IFD pointer */
497b4c3a0f0SMarcus Boerger #define TAG_FLASH_ENERGY                0xA20B
498b4c3a0f0SMarcus Boerger #define TAG_SPATIAL_FREQUENCY_RESPONSE  0xA20C
499b4c3a0f0SMarcus Boerger #define TAG_FOCALPLANE_X_RES            0xA20E
500b4c3a0f0SMarcus Boerger #define TAG_FOCALPLANE_Y_RES            0xA20F
501b4c3a0f0SMarcus Boerger #define TAG_FOCALPLANE_RESOLUTION_UNIT  0xA210
502b4c3a0f0SMarcus Boerger #define TAG_SUBJECT_LOCATION            0xA214
503b4c3a0f0SMarcus Boerger #define TAG_EXPOSURE_INDEX              0xA215
504b4c3a0f0SMarcus Boerger #define TAG_SENSING_METHOD              0xA217
505b4c3a0f0SMarcus Boerger #define TAG_FILE_SOURCE                 0xA300
506b4c3a0f0SMarcus Boerger #define TAG_SCENE_TYPE                  0xA301
507b4c3a0f0SMarcus Boerger #define TAG_CFA_PATTERN                 0xA302
508b4c3a0f0SMarcus Boerger #define TAG_CUSTOM_RENDERED             0xA401
509b4c3a0f0SMarcus Boerger #define TAG_EXPOSURE_MODE               0xA402
510b4c3a0f0SMarcus Boerger #define TAG_WHITE_BALANCE               0xA403
511b4c3a0f0SMarcus Boerger #define TAG_DIGITAL_ZOOM_RATIO          0xA404
512b4c3a0f0SMarcus Boerger #define TAG_FOCAL_LENGTH_IN_35_MM_FILM  0xA405
513b4c3a0f0SMarcus Boerger #define TAG_SCENE_CAPTURE_TYPE          0xA406
514b4c3a0f0SMarcus Boerger #define TAG_GAIN_CONTROL                0xA407
515b4c3a0f0SMarcus Boerger #define TAG_CONTRAST                    0xA408
516b4c3a0f0SMarcus Boerger #define TAG_SATURATION                  0xA409
517ebd9e89fSRasmus Lerdorf #define TAG_SHARPNESS                   0xA40A
518b8f6e9ddSRasmus Lerdorf #define TAG_DEVICE_SETTING_DESCRIPTION  0xA40B
519088450efSMarcus Boerger #define TAG_SUBJECT_DISTANCE_RANGE      0xA40C
520088450efSMarcus Boerger #define TAG_IMAGE_UNIQUE_ID             0xA420
521088450efSMarcus Boerger 
522088450efSMarcus Boerger /* Olympus specific tags */
523088450efSMarcus Boerger #define TAG_OLYMPUS_SPECIALMODE         0x0200
524088450efSMarcus Boerger #define TAG_OLYMPUS_JPEGQUAL            0x0201
525088450efSMarcus Boerger #define TAG_OLYMPUS_MACRO               0x0202
526b8f6e9ddSRasmus Lerdorf #define TAG_OLYMPUS_DIGIZOOM            0x0204
527ebd9e89fSRasmus Lerdorf #define TAG_OLYMPUS_SOFTWARERELEASE     0x0207
5280ecd2f08SMarcus Boerger #define TAG_OLYMPUS_PICTINFO            0x0208
5290ecd2f08SMarcus Boerger #define TAG_OLYMPUS_CAMERAID            0x0209
5300ecd2f08SMarcus Boerger /* end Olympus specific tags */
531b4c3a0f0SMarcus Boerger 
5326b2a0743SMarcus Boerger /* Internal */
533088450efSMarcus Boerger #define TAG_NONE               			-1 /* note that -1 <> 0xFFFF */
5340fd73221SMarcus Boerger #define TAG_COMPUTED_VALUE     			-2
5350fd73221SMarcus Boerger #define TAG_END_OF_LIST                 0xFFFD
5366b2a0743SMarcus Boerger 
5370fd73221SMarcus Boerger /* Values for TAG_PHOTOMETRIC_INTERPRETATION */
5386b2a0743SMarcus Boerger #define PMI_BLACK_IS_ZERO       0
5396b2a0743SMarcus Boerger #define PMI_WHITE_IS_ZERO       1
5406b2a0743SMarcus Boerger #define PMI_RGB          	    2
5416b2a0743SMarcus Boerger #define PMI_PALETTE_COLOR       3
54298ebd1c2SMarcus Boerger #define PMI_TRANSPARENCY_MASK   4
54325c3a3a3SRasmus Lerdorf #define PMI_SEPARATED           5
5443c61d015SRasmus Lerdorf #define PMI_YCBCR               6
54525c3a3a3SRasmus Lerdorf #define PMI_CIELAB              8
54625c3a3a3SRasmus Lerdorf 
547837fa41dSMarcus Boerger /* }}} */
54805b13da5SMarcus Boerger 
54905b13da5SMarcus Boerger /* {{{ TabTable[]
550837fa41dSMarcus Boerger  */
551837fa41dSMarcus Boerger typedef const struct {
552837fa41dSMarcus Boerger 	unsigned short Tag;
553837fa41dSMarcus Boerger 	char *Desc;
554837fa41dSMarcus Boerger } tag_info_type;
555837fa41dSMarcus Boerger 
556837fa41dSMarcus Boerger typedef tag_info_type  tag_info_array[];
557837fa41dSMarcus Boerger typedef tag_info_type  *tag_table_type;
558255c6a71SMarcus Boerger 
559837fa41dSMarcus Boerger #define TAG_TABLE_END \
560dfe1a65fSMarcus Boerger   {TAG_NONE,           "No tag value"},\
561837fa41dSMarcus Boerger   {TAG_COMPUTED_VALUE, "Computed value"},\
562837fa41dSMarcus Boerger   {TAG_END_OF_LIST,    ""}  /* Important for exif_get_tagname() IF value != "" function result is != false */
563088450efSMarcus Boerger 
5640fd73221SMarcus Boerger static tag_info_array tag_table_IFD = {
5650fd73221SMarcus Boerger   { 0x000B, "ACDComment"},
5660fd73221SMarcus Boerger   { 0x00FE, "NewSubFile"}, /* better name it 'ImageType' ? */
5670fd73221SMarcus Boerger   { 0x00FF, "SubFile"},
5680fd73221SMarcus Boerger   { 0x0100, "ImageWidth"},
5690fd73221SMarcus Boerger   { 0x0101, "ImageLength"},
5700fd73221SMarcus Boerger   { 0x0102, "BitsPerSample"},
5710fd73221SMarcus Boerger   { 0x0103, "Compression"},
5720fd73221SMarcus Boerger   { 0x0106, "PhotometricInterpretation"},
5730fd73221SMarcus Boerger   { 0x010A, "FillOrder"},
5740fd73221SMarcus Boerger   { 0x010D, "DocumentName"},
5750fd73221SMarcus Boerger   { 0x010E, "ImageDescription"},
5760fd73221SMarcus Boerger   { 0x010F, "Make"},
5770fd73221SMarcus Boerger   { 0x0110, "Model"},
5780fd73221SMarcus Boerger   { 0x0111, "StripOffsets"},
5790fd73221SMarcus Boerger   { 0x0112, "Orientation"},
5800fd73221SMarcus Boerger   { 0x0115, "SamplesPerPixel"},
5810fd73221SMarcus Boerger   { 0x0116, "RowsPerStrip"},
5820fd73221SMarcus Boerger   { 0x0117, "StripByteCounts"},
5830fd73221SMarcus Boerger   { 0x0118, "MinSampleValue"},
5840fd73221SMarcus Boerger   { 0x0119, "MaxSampleValue"},
5850fd73221SMarcus Boerger   { 0x011A, "XResolution"},
5860fd73221SMarcus Boerger   { 0x011B, "YResolution"},
5870fd73221SMarcus Boerger   { 0x011C, "PlanarConfiguration"},
5880fd73221SMarcus Boerger   { 0x011D, "PageName"},
5890fd73221SMarcus Boerger   { 0x011E, "XPosition"},
5900fd73221SMarcus Boerger   { 0x011F, "YPosition"},
5910fd73221SMarcus Boerger   { 0x0120, "FreeOffsets"},
5920fd73221SMarcus Boerger   { 0x0121, "FreeByteCounts"},
5930fd73221SMarcus Boerger   { 0x0122, "GrayResponseUnit"},
5940fd73221SMarcus Boerger   { 0x0123, "GrayResponseCurve"},
5950fd73221SMarcus Boerger   { 0x0124, "T4Options"},
5960fd73221SMarcus Boerger   { 0x0125, "T6Options"},
5970fd73221SMarcus Boerger   { 0x0128, "ResolutionUnit"},
5980fd73221SMarcus Boerger   { 0x0129, "PageNumber"},
5990fd73221SMarcus Boerger   { 0x012D, "TransferFunction"},
6000fd73221SMarcus Boerger   { 0x0131, "Software"},
6010fd73221SMarcus Boerger   { 0x0132, "DateTime"},
6020fd73221SMarcus Boerger   { 0x013B, "Artist"},
6030fd73221SMarcus Boerger   { 0x013C, "HostComputer"},
6040fd73221SMarcus Boerger   { 0x013D, "Predictor"},
6050fd73221SMarcus Boerger   { 0x013E, "WhitePoint"},
6060fd73221SMarcus Boerger   { 0x013F, "PrimaryChromaticities"},
6070fd73221SMarcus Boerger   { 0x0140, "ColorMap"},
6080fd73221SMarcus Boerger   { 0x0141, "HalfToneHints"},
6094a8dd125SMarcus Boerger   { 0x0142, "TileWidth"},
6100fd73221SMarcus Boerger   { 0x0143, "TileLength"},
6110fd73221SMarcus Boerger   { 0x0144, "TileOffsets"},
6120fd73221SMarcus Boerger   { 0x0145, "TileByteCounts"},
6130fd73221SMarcus Boerger   { 0x014A, "SubIFD"},
6140fd73221SMarcus Boerger   { 0x014C, "InkSet"},
6150fd73221SMarcus Boerger   { 0x014D, "InkNames"},
6160fd73221SMarcus Boerger   { 0x014E, "NumberOfInks"},
6170fd73221SMarcus Boerger   { 0x0150, "DotRange"},
6180fd73221SMarcus Boerger   { 0x0151, "TargetPrinter"},
6190fd73221SMarcus Boerger   { 0x0152, "ExtraSample"},
6204a8dd125SMarcus Boerger   { 0x0153, "SampleFormat"},
6214a8dd125SMarcus Boerger   { 0x0154, "SMinSampleValue"},
6224a8dd125SMarcus Boerger   { 0x0155, "SMaxSampleValue"},
6234a8dd125SMarcus Boerger   { 0x0156, "TransferRange"},
624837fa41dSMarcus Boerger   { 0x0157, "ClipPath"},
6254a8dd125SMarcus Boerger   { 0x0158, "XClipPathUnits"},
6260fd73221SMarcus Boerger   { 0x0159, "YClipPathUnits"},
6270fd73221SMarcus Boerger   { 0x015A, "Indexed"},
6280fd73221SMarcus Boerger   { 0x015B, "JPEGTables"},
6290fd73221SMarcus Boerger   { 0x015F, "OPIProxy"},
6300fd73221SMarcus Boerger   { 0x0200, "JPEGProc"},
6310fd73221SMarcus Boerger   { 0x0201, "JPEGInterchangeFormat"},
6320fd73221SMarcus Boerger   { 0x0202, "JPEGInterchangeFormatLength"},
6330fd73221SMarcus Boerger   { 0x0203, "JPEGRestartInterval"},
6340fd73221SMarcus Boerger   { 0x0205, "JPEGLosslessPredictors"},
6350fd73221SMarcus Boerger   { 0x0206, "JPEGPointTransforms"},
6360fd73221SMarcus Boerger   { 0x0207, "JPEGQTables"},
6370fd73221SMarcus Boerger   { 0x0208, "JPEGDCTables"},
6380fd73221SMarcus Boerger   { 0x0209, "JPEGACTables"},
6398b853592SMarcus Boerger   { 0x0211, "YCbCrCoefficients"},
640b7a7b1a6SStanislav Malyshev   { 0x0212, "YCbCrSubSampling"},
641b7a7b1a6SStanislav Malyshev   { 0x0213, "YCbCrPositioning"},
642b7a7b1a6SStanislav Malyshev   { 0x0214, "ReferenceBlackWhite"},
643b7a7b1a6SStanislav Malyshev   { 0x02BC, "ExtensibleMetadataPlatform"}, /* XAP: Extensible Authoring Publishing, obsoleted by XMP: Extensible Metadata Platform */
644b7a7b1a6SStanislav Malyshev   { 0x0301, "Gamma"},
645b7a7b1a6SStanislav Malyshev   { 0x0302, "ICCProfileDescriptor"},
646b7a7b1a6SStanislav Malyshev   { 0x0303, "SRGBRenderingIntent"},
647b7a7b1a6SStanislav Malyshev   { 0x0320, "ImageTitle"},
648b7a7b1a6SStanislav Malyshev   { 0x5001, "ResolutionXUnit"},
649b7a7b1a6SStanislav Malyshev   { 0x5002, "ResolutionYUnit"},
650b7a7b1a6SStanislav Malyshev   { 0x5003, "ResolutionXLengthUnit"},
651b7a7b1a6SStanislav Malyshev   { 0x5004, "ResolutionYLengthUnit"},
652b7a7b1a6SStanislav Malyshev   { 0x5005, "PrintFlags"},
653b7a7b1a6SStanislav Malyshev   { 0x5006, "PrintFlagsVersion"},
654b7a7b1a6SStanislav Malyshev   { 0x5007, "PrintFlagsCrop"},
655b7a7b1a6SStanislav Malyshev   { 0x5008, "PrintFlagsBleedWidth"},
656b7a7b1a6SStanislav Malyshev   { 0x5009, "PrintFlagsBleedWidthScale"},
657b7a7b1a6SStanislav Malyshev   { 0x500A, "HalftoneLPI"},
658b7a7b1a6SStanislav Malyshev   { 0x500B, "HalftoneLPIUnit"},
659b7a7b1a6SStanislav Malyshev   { 0x500C, "HalftoneDegree"},
660b7a7b1a6SStanislav Malyshev   { 0x500D, "HalftoneShape"},
661b7a7b1a6SStanislav Malyshev   { 0x500E, "HalftoneMisc"},
662b7a7b1a6SStanislav Malyshev   { 0x500F, "HalftoneScreen"},
663b7a7b1a6SStanislav Malyshev   { 0x5010, "JPEGQuality"},
664b7a7b1a6SStanislav Malyshev   { 0x5011, "GridSize"},
665b7a7b1a6SStanislav Malyshev   { 0x5012, "ThumbnailFormat"},
666b7a7b1a6SStanislav Malyshev   { 0x5013, "ThumbnailWidth"},
667b7a7b1a6SStanislav Malyshev   { 0x5014, "ThumbnailHeight"},
668b7a7b1a6SStanislav Malyshev   { 0x5015, "ThumbnailColorDepth"},
669b7a7b1a6SStanislav Malyshev   { 0x5016, "ThumbnailPlanes"},
670b7a7b1a6SStanislav Malyshev   { 0x5017, "ThumbnailRawBytes"},
671b7a7b1a6SStanislav Malyshev   { 0x5018, "ThumbnailSize"},
672b7a7b1a6SStanislav Malyshev   { 0x5019, "ThumbnailCompressedSize"},
673b7a7b1a6SStanislav Malyshev   { 0x501A, "ColorTransferFunction"},
674b7a7b1a6SStanislav Malyshev   { 0x501B, "ThumbnailData"},
675b7a7b1a6SStanislav Malyshev   { 0x5020, "ThumbnailImageWidth"},
676b7a7b1a6SStanislav Malyshev   { 0x5021, "ThumbnailImageHeight"},
677b7a7b1a6SStanislav Malyshev   { 0x5022, "ThumbnailBitsPerSample"},
678b7a7b1a6SStanislav Malyshev   { 0x5023, "ThumbnailCompression"},
679b7a7b1a6SStanislav Malyshev   { 0x5024, "ThumbnailPhotometricInterp"},
680b7a7b1a6SStanislav Malyshev   { 0x5025, "ThumbnailImageDescription"},
681b7a7b1a6SStanislav Malyshev   { 0x5026, "ThumbnailEquipMake"},
682b7a7b1a6SStanislav Malyshev   { 0x5027, "ThumbnailEquipModel"},
683b7a7b1a6SStanislav Malyshev   { 0x5028, "ThumbnailStripOffsets"},
684b7a7b1a6SStanislav Malyshev   { 0x5029, "ThumbnailOrientation"},
685b7a7b1a6SStanislav Malyshev   { 0x502A, "ThumbnailSamplesPerPixel"},
686b7a7b1a6SStanislav Malyshev   { 0x502B, "ThumbnailRowsPerStrip"},
687b7a7b1a6SStanislav Malyshev   { 0x502C, "ThumbnailStripBytesCount"},
688b7a7b1a6SStanislav Malyshev   { 0x502D, "ThumbnailResolutionX"},
689b7a7b1a6SStanislav Malyshev   { 0x502E, "ThumbnailResolutionY"},
690b7a7b1a6SStanislav Malyshev   { 0x502F, "ThumbnailPlanarConfig"},
691b7a7b1a6SStanislav Malyshev   { 0x5030, "ThumbnailResolutionUnit"},
692b7a7b1a6SStanislav Malyshev   { 0x5031, "ThumbnailTransferFunction"},
693b7a7b1a6SStanislav Malyshev   { 0x5032, "ThumbnailSoftwareUsed"},
694b7a7b1a6SStanislav Malyshev   { 0x5033, "ThumbnailDateTime"},
695b7a7b1a6SStanislav Malyshev   { 0x5034, "ThumbnailArtist"},
696b7a7b1a6SStanislav Malyshev   { 0x5035, "ThumbnailWhitePoint"},
697b7a7b1a6SStanislav Malyshev   { 0x5036, "ThumbnailPrimaryChromaticities"},
698b7a7b1a6SStanislav Malyshev   { 0x5037, "ThumbnailYCbCrCoefficients"},
699b7a7b1a6SStanislav Malyshev   { 0x5038, "ThumbnailYCbCrSubsampling"},
700b7a7b1a6SStanislav Malyshev   { 0x5039, "ThumbnailYCbCrPositioning"},
701b7a7b1a6SStanislav Malyshev   { 0x503A, "ThumbnailRefBlackWhite"},
702b7a7b1a6SStanislav Malyshev   { 0x503B, "ThumbnailCopyRight"},
703b7a7b1a6SStanislav Malyshev   { 0x5090, "LuminanceTable"},
704b7a7b1a6SStanislav Malyshev   { 0x5091, "ChrominanceTable"},
705b7a7b1a6SStanislav Malyshev   { 0x5100, "FrameDelay"},
706b7a7b1a6SStanislav Malyshev   { 0x5101, "LoopCount"},
707b8f6e9ddSRasmus Lerdorf   { 0x5110, "PixelUnit"},
7084a8dd125SMarcus Boerger   { 0x5111, "PixelPerUnitX"},
7098b853592SMarcus Boerger   { 0x5112, "PixelPerUnitY"},
7108b853592SMarcus Boerger   { 0x5113, "PaletteHistogram"},
7118b853592SMarcus Boerger   { 0x1000, "RelatedImageFileFormat"},
7128b853592SMarcus Boerger   { 0x800D, "ImageID"},
7130fd73221SMarcus Boerger   { 0x80E3, "Matteing"},   /* obsoleted by ExtraSamples */
7140fd73221SMarcus Boerger   { 0x80E4, "DataType"},   /* obsoleted by SampleFormat */
7150fd73221SMarcus Boerger   { 0x80E5, "ImageDepth"},
7160fd73221SMarcus Boerger   { 0x80E6, "TileDepth"},
7170fd73221SMarcus Boerger   { 0x828D, "CFARepeatPatternDim"},
7180fd73221SMarcus Boerger   { 0x828E, "CFAPattern"},
7190fd73221SMarcus Boerger   { 0x828F, "BatteryLevel"},
7204a8dd125SMarcus Boerger   { 0x8298, "Copyright"},
7214a8dd125SMarcus Boerger   { 0x829A, "ExposureTime"},
7224a8dd125SMarcus Boerger   { 0x829D, "FNumber"},
7230fd73221SMarcus Boerger   { 0x83BB, "IPTC/NAA"},
724469266e4SMarcus Boerger   { 0x84E3, "IT8RasterPadding"},
7250fd73221SMarcus Boerger   { 0x84E5, "IT8ColorTable"},
726837fa41dSMarcus Boerger   { 0x8649, "ImageResourceInformation"}, /* PhotoShop */
727837fa41dSMarcus Boerger   { 0x8769, "Exif_IFD_Pointer"},
7280fd73221SMarcus Boerger   { 0x8773, "ICC_Profile"},
7290fd73221SMarcus Boerger   { 0x8822, "ExposureProgram"},
7300fd73221SMarcus Boerger   { 0x8824, "SpectralSensity"},
7310fd73221SMarcus Boerger   { 0x8825, "GPS_IFD_Pointer"},
7320fd73221SMarcus Boerger   { 0x8827, "ISOSpeedRatings"},
7330fd73221SMarcus Boerger   { 0x8828, "OECF"},
7340fd73221SMarcus Boerger   { 0x9000, "ExifVersion"},
7350fd73221SMarcus Boerger   { 0x9003, "DateTimeOriginal"},
7360fd73221SMarcus Boerger   { 0x9004, "DateTimeDigitized"},
7370fd73221SMarcus Boerger   { 0x9101, "ComponentsConfiguration"},
7380fd73221SMarcus Boerger   { 0x9102, "CompressedBitsPerPixel"},
7390fd73221SMarcus Boerger   { 0x9201, "ShutterSpeedValue"},
7400fd73221SMarcus Boerger   { 0x9202, "ApertureValue"},
7410fd73221SMarcus Boerger   { 0x9203, "BrightnessValue"},
7420fd73221SMarcus Boerger   { 0x9204, "ExposureBiasValue"},
7430fd73221SMarcus Boerger   { 0x9205, "MaxApertureValue"},
7440fd73221SMarcus Boerger   { 0x9206, "SubjectDistance"},
7450fd73221SMarcus Boerger   { 0x9207, "MeteringMode"},
7460fd73221SMarcus Boerger   { 0x9208, "LightSource"},
7470fd73221SMarcus Boerger   { 0x9209, "Flash"},
748837fa41dSMarcus Boerger   { 0x920A, "FocalLength"},
7490fd73221SMarcus Boerger   { 0x920B, "FlashEnergy"},                 /* 0xA20B  in JPEG   */
7500fd73221SMarcus Boerger   { 0x920C, "SpatialFrequencyResponse"},    /* 0xA20C    -  -    */
7510fd73221SMarcus Boerger   { 0x920D, "Noise"},
752837fa41dSMarcus Boerger   { 0x920E, "FocalPlaneXResolution"},       /* 0xA20E    -  -    */
753837fa41dSMarcus Boerger   { 0x920F, "FocalPlaneYResolution"},       /* 0xA20F    -  -    */
754837fa41dSMarcus Boerger   { 0x9210, "FocalPlaneResolutionUnit"},    /* 0xA210    -  -    */
7550fd73221SMarcus Boerger   { 0x9211, "ImageNumber"},
7560fd73221SMarcus Boerger   { 0x9212, "SecurityClassification"},
757837fa41dSMarcus Boerger   { 0x9213, "ImageHistory"},
7580fd73221SMarcus Boerger   { 0x9214, "SubjectLocation"},             /* 0xA214    -  -    */
7598b853592SMarcus Boerger   { 0x9215, "ExposureIndex"},               /* 0xA215    -  -    */
7600fd73221SMarcus Boerger   { 0x9216, "TIFF/EPStandardID"},
7610fd73221SMarcus Boerger   { 0x9217, "SensingMethod"},               /* 0xA217    -  -    */
7620fd73221SMarcus Boerger   { 0x923F, "StoNits"},
7630fd73221SMarcus Boerger   { 0x927C, "MakerNote"},
7640fd73221SMarcus Boerger   { 0x9286, "UserComment"},
7658b853592SMarcus Boerger   { 0x9290, "SubSecTime"},
766ef5c0f7cSMarcus Boerger   { 0x9291, "SubSecTimeOriginal"},
767ef5c0f7cSMarcus Boerger   { 0x9292, "SubSecTimeDigitized"},
768ef5c0f7cSMarcus Boerger   { 0x935C, "ImageSourceData"},             /* "Adobe Photoshop Document Data Block": 8BIM... */
769ef5c0f7cSMarcus Boerger   { 0x9c9b, "Title" },                      /* Win XP specific, Unicode  */
770ef5c0f7cSMarcus Boerger   { 0x9c9c, "Comments" },                   /* Win XP specific, Unicode  */
7710fd73221SMarcus Boerger   { 0x9c9d, "Author" },                     /* Win XP specific, Unicode  */
7720fd73221SMarcus Boerger   { 0x9c9e, "Keywords" },                   /* Win XP specific, Unicode  */
7730fd73221SMarcus Boerger   { 0x9c9f, "Subject" },                    /* Win XP specific, Unicode, not to be confused with SubjectDistance and SubjectLocation */
7740fd73221SMarcus Boerger   { 0xA000, "FlashPixVersion"},
775b4c3a0f0SMarcus Boerger   { 0xA001, "ColorSpace"},
7760fd73221SMarcus Boerger   { 0xA002, "ExifImageWidth"},
7770fd73221SMarcus Boerger   { 0xA003, "ExifImageLength"},
7780fd73221SMarcus Boerger   { 0xA004, "RelatedSoundFile"},
779837fa41dSMarcus Boerger   { 0xA005, "InteroperabilityOffset"},
7800fd73221SMarcus Boerger   { 0xA20B, "FlashEnergy"},                 /* 0x920B in TIFF/EP */
7810fd73221SMarcus Boerger   { 0xA20C, "SpatialFrequencyResponse"},    /* 0x920C    -  -    */
7820fd73221SMarcus Boerger   { 0xA20D, "Noise"},
783837fa41dSMarcus Boerger   { 0xA20E, "FocalPlaneXResolution"},    	/* 0x920E    -  -    */
784837fa41dSMarcus Boerger   { 0xA20F, "FocalPlaneYResolution"},       /* 0x920F    -  -    */
785837fa41dSMarcus Boerger   { 0xA210, "FocalPlaneResolutionUnit"},    /* 0x9210    -  -    */
7860fd73221SMarcus Boerger   { 0xA211, "ImageNumber"},
7870fd73221SMarcus Boerger   { 0xA212, "SecurityClassification"},
788837fa41dSMarcus Boerger   { 0xA213, "ImageHistory"},
7890fd73221SMarcus Boerger   { 0xA214, "SubjectLocation"},             /* 0x9214    -  -    */
7900fd73221SMarcus Boerger   { 0xA215, "ExposureIndex"},               /* 0x9215    -  -    */
7910fd73221SMarcus Boerger   { 0xA216, "TIFF/EPStandardID"},
792b4c3a0f0SMarcus Boerger   { 0xA217, "SensingMethod"},               /* 0x9217    -  -    */
793b4c3a0f0SMarcus Boerger   { 0xA300, "FileSource"},
794b4c3a0f0SMarcus Boerger   { 0xA301, "SceneType"},
795b4c3a0f0SMarcus Boerger   { 0xA302, "CFAPattern"},
796b4c3a0f0SMarcus Boerger   { 0xA401, "CustomRendered"},
797b4c3a0f0SMarcus Boerger   { 0xA402, "ExposureMode"},
798b4c3a0f0SMarcus Boerger   { 0xA403, "WhiteBalance"},
799b4c3a0f0SMarcus Boerger   { 0xA404, "DigitalZoomRatio"},
800b4c3a0f0SMarcus Boerger   { 0xA405, "FocalLengthIn35mmFilm"},
801b4c3a0f0SMarcus Boerger   { 0xA406, "SceneCaptureType"},
802b4c3a0f0SMarcus Boerger   { 0xA407, "GainControl"},
803b4c3a0f0SMarcus Boerger   { 0xA408, "Contrast"},
804b4c3a0f0SMarcus Boerger   { 0xA409, "Saturation"},
805b4c3a0f0SMarcus Boerger   { 0xA40A, "Sharpness"},
806837fa41dSMarcus Boerger   { 0xA40B, "DeviceSettingDescription"},
8073c61d015SRasmus Lerdorf   { 0xA40C, "SubjectDistanceRange"},
8080ecd2f08SMarcus Boerger   { 0xA420, "ImageUniqueID"},
809dfe1a65fSMarcus Boerger   TAG_TABLE_END
810837fa41dSMarcus Boerger } ;
811837fa41dSMarcus Boerger 
812837fa41dSMarcus Boerger static tag_info_array tag_table_GPS = {
813aa4c85ddSIlia Alshanetsky   { 0x0000, "GPSVersion"},
814aa4c85ddSIlia Alshanetsky   { 0x0001, "GPSLatitudeRef"},
815837fa41dSMarcus Boerger   { 0x0002, "GPSLatitude"},
816837fa41dSMarcus Boerger   { 0x0003, "GPSLongitudeRef"},
817837fa41dSMarcus Boerger   { 0x0004, "GPSLongitude"},
818837fa41dSMarcus Boerger   { 0x0005, "GPSAltitudeRef"},
819837fa41dSMarcus Boerger   { 0x0006, "GPSAltitude"},
820837fa41dSMarcus Boerger   { 0x0007, "GPSTimeStamp"},
821837fa41dSMarcus Boerger   { 0x0008, "GPSSatellites"},
822837fa41dSMarcus Boerger   { 0x0009, "GPSStatus"},
823837fa41dSMarcus Boerger   { 0x000A, "GPSMeasureMode"},
824837fa41dSMarcus Boerger   { 0x000B, "GPSDOP"},
825837fa41dSMarcus Boerger   { 0x000C, "GPSSpeedRef"},
826837fa41dSMarcus Boerger   { 0x000D, "GPSSpeed"},
827837fa41dSMarcus Boerger   { 0x000E, "GPSTrackRef"},
828837fa41dSMarcus Boerger   { 0x000F, "GPSTrack"},
829837fa41dSMarcus Boerger   { 0x0010, "GPSImgDirectionRef"},
830837fa41dSMarcus Boerger   { 0x0011, "GPSImgDirection"},
831837fa41dSMarcus Boerger   { 0x0012, "GPSMapDatum"},
832837fa41dSMarcus Boerger   { 0x0013, "GPSDestLatitudeRef"},
833837fa41dSMarcus Boerger   { 0x0014, "GPSDestLatitude"},
834837fa41dSMarcus Boerger   { 0x0015, "GPSDestLongitudeRef"},
835837fa41dSMarcus Boerger   { 0x0016, "GPSDestLongitude"},
836837fa41dSMarcus Boerger   { 0x0017, "GPSDestBearingRef"},
837837fa41dSMarcus Boerger   { 0x0018, "GPSDestBearing"},
838837fa41dSMarcus Boerger   { 0x0019, "GPSDestDistanceRef"},
839837fa41dSMarcus Boerger   { 0x001A, "GPSDestDistance"},
840837fa41dSMarcus Boerger   { 0x001B, "GPSProcessingMode"},
841837fa41dSMarcus Boerger   { 0x001C, "GPSAreaInformation"},
842837fa41dSMarcus Boerger   { 0x001D, "GPSDateStamp"},
843837fa41dSMarcus Boerger   { 0x001E, "GPSDifferential"},
844dfe1a65fSMarcus Boerger   TAG_TABLE_END
845837fa41dSMarcus Boerger };
846837fa41dSMarcus Boerger 
847837fa41dSMarcus Boerger static tag_info_array tag_table_IOP = {
848837fa41dSMarcus Boerger   { 0x0001, "InterOperabilityIndex"}, /* should be 'R98' or 'THM' */
849837fa41dSMarcus Boerger   { 0x0002, "InterOperabilityVersion"},
850837fa41dSMarcus Boerger   { 0x1000, "RelatedFileFormat"},
851837fa41dSMarcus Boerger   { 0x1001, "RelatedImageWidth"},
852837fa41dSMarcus Boerger   { 0x1002, "RelatedImageHeight"},
853dfe1a65fSMarcus Boerger   TAG_TABLE_END
85403834268SMarcus Boerger };
85503834268SMarcus Boerger 
85603834268SMarcus Boerger static tag_info_array tag_table_VND_CANON = {
85703834268SMarcus Boerger   { 0x0001, "ModeArray"}, /* guess */
85803834268SMarcus Boerger   { 0x0004, "ImageInfo"}, /* guess */
85903834268SMarcus Boerger   { 0x0006, "ImageType"},
86003834268SMarcus Boerger   { 0x0007, "FirmwareVersion"},
86103834268SMarcus Boerger   { 0x0008, "ImageNumber"},
86203834268SMarcus Boerger   { 0x0009, "OwnerName"},
86303834268SMarcus Boerger   { 0x000C, "Camera"},
86403834268SMarcus Boerger   { 0x000F, "CustomFunctions"},
865dfe1a65fSMarcus Boerger   TAG_TABLE_END
86603834268SMarcus Boerger };
86703834268SMarcus Boerger 
86803834268SMarcus Boerger static tag_info_array tag_table_VND_CASIO = {
86903834268SMarcus Boerger   { 0x0001, "RecordingMode"},
87003834268SMarcus Boerger   { 0x0002, "Quality"},
87103834268SMarcus Boerger   { 0x0003, "FocusingMode"},
87203834268SMarcus Boerger   { 0x0004, "FlashMode"},
87303834268SMarcus Boerger   { 0x0005, "FlashIntensity"},
87403834268SMarcus Boerger   { 0x0006, "ObjectDistance"},
87503834268SMarcus Boerger   { 0x0007, "WhiteBalance"},
87603834268SMarcus Boerger   { 0x000A, "DigitalZoom"},
87703834268SMarcus Boerger   { 0x000B, "Sharpness"},
87803834268SMarcus Boerger   { 0x000C, "Contrast"},
87903834268SMarcus Boerger   { 0x000D, "Saturation"},
88003834268SMarcus Boerger   { 0x0014, "CCDSensitivity"},
881dfe1a65fSMarcus Boerger   TAG_TABLE_END
88203834268SMarcus Boerger };
88303834268SMarcus Boerger 
88403834268SMarcus Boerger static tag_info_array tag_table_VND_FUJI = {
88503834268SMarcus Boerger   { 0x0000, "Version"},
88603834268SMarcus Boerger   { 0x1000, "Quality"},
88703834268SMarcus Boerger   { 0x1001, "Sharpness"},
88803834268SMarcus Boerger   { 0x1002, "WhiteBalance"},
88903834268SMarcus Boerger   { 0x1003, "Color"},
89003834268SMarcus Boerger   { 0x1004, "Tone"},
89103834268SMarcus Boerger   { 0x1010, "FlashMode"},
89203834268SMarcus Boerger   { 0x1011, "FlashStrength"},
89303834268SMarcus Boerger   { 0x1020, "Macro"},
89403834268SMarcus Boerger   { 0x1021, "FocusMode"},
89503834268SMarcus Boerger   { 0x1030, "SlowSync"},
89603834268SMarcus Boerger   { 0x1031, "PictureMode"},
89703834268SMarcus Boerger   { 0x1100, "ContTake"},
89803834268SMarcus Boerger   { 0x1300, "BlurWarning"},
89903834268SMarcus Boerger   { 0x1301, "FocusWarning"},
90003834268SMarcus Boerger   { 0x1302, "AEWarning "},
901dfe1a65fSMarcus Boerger   TAG_TABLE_END
90203834268SMarcus Boerger };
90303834268SMarcus Boerger 
90403834268SMarcus Boerger static tag_info_array tag_table_VND_NIKON = {
90503834268SMarcus Boerger   { 0x0003, "Quality"},
90603834268SMarcus Boerger   { 0x0004, "ColorMode"},
90703834268SMarcus Boerger   { 0x0005, "ImageAdjustment"},
90803834268SMarcus Boerger   { 0x0006, "CCDSensitivity"},
90903834268SMarcus Boerger   { 0x0007, "WhiteBalance"},
91003834268SMarcus Boerger   { 0x0008, "Focus"},
91103834268SMarcus Boerger   { 0x000a, "DigitalZoom"},
912b7a7b1a6SStanislav Malyshev   { 0x000b, "Converter"},
913dfe1a65fSMarcus Boerger   TAG_TABLE_END
91403834268SMarcus Boerger };
91503834268SMarcus Boerger 
91603834268SMarcus Boerger static tag_info_array tag_table_VND_NIKON_990 = {
91703834268SMarcus Boerger   { 0x0001, "Version"},
91803834268SMarcus Boerger   { 0x0002, "ISOSetting"},
91903834268SMarcus Boerger   { 0x0003, "ColorMode"},
92003834268SMarcus Boerger   { 0x0004, "Quality"},
92103834268SMarcus Boerger   { 0x0005, "WhiteBalance"},
92203834268SMarcus Boerger   { 0x0006, "ImageSharpening"},
92303834268SMarcus Boerger   { 0x0007, "FocusMode"},
92403834268SMarcus Boerger   { 0x0008, "FlashSetting"},
92503834268SMarcus Boerger   { 0x000F, "ISOSelection"},
92603834268SMarcus Boerger   { 0x0080, "ImageAdjustment"},
92703834268SMarcus Boerger   { 0x0082, "AuxiliaryLens"},
92803834268SMarcus Boerger   { 0x0085, "ManualFocusDistance"},
92903834268SMarcus Boerger   { 0x0086, "DigitalZoom"},
93003834268SMarcus Boerger   { 0x0088, "AFFocusPosition"},
931b7a7b1a6SStanislav Malyshev   { 0x0010, "DataDump"},
932dfe1a65fSMarcus Boerger   TAG_TABLE_END
933837fa41dSMarcus Boerger };
934837fa41dSMarcus Boerger 
935837fa41dSMarcus Boerger static tag_info_array tag_table_VND_OLYMPUS = {
936837fa41dSMarcus Boerger   { 0x0200, "SpecialMode"},
937837fa41dSMarcus Boerger   { 0x0201, "JPEGQuality"},
938837fa41dSMarcus Boerger   { 0x0202, "Macro"},
939837fa41dSMarcus Boerger   { 0x0204, "DigitalZoom"},
940837fa41dSMarcus Boerger   { 0x0207, "SoftwareRelease"},
941837fa41dSMarcus Boerger   { 0x0208, "PictureInfo"},
94203834268SMarcus Boerger   { 0x0209, "CameraId"},
94303834268SMarcus Boerger   { 0x0F00, "DataDump"},
9449c8c3785SKalle Sommer Nielsen   TAG_TABLE_END
94564002648SGabriel Caruso };
94664002648SGabriel Caruso 
94764002648SGabriel Caruso static tag_info_array tag_table_VND_SAMSUNG = {
94864002648SGabriel Caruso   { 0x0001, "Version"},
94964002648SGabriel Caruso   { 0x0021, "PictureWizard"},
95064002648SGabriel Caruso   { 0x0030, "LocalLocationName"},
95164002648SGabriel Caruso   { 0x0031, "LocationName"},
95264002648SGabriel Caruso   { 0x0035, "Preview"},
95364002648SGabriel Caruso   { 0x0043, "CameraTemperature"},
95464002648SGabriel Caruso   { 0xa001, "FirmwareName"},
95564002648SGabriel Caruso   { 0xa003, "LensType"},
95664002648SGabriel Caruso   { 0xa004, "LensFirmware"},
95764002648SGabriel Caruso   { 0xa010, "SensorAreas"},
95864002648SGabriel Caruso   { 0xa011, "ColorSpace"},
95964002648SGabriel Caruso   { 0xa012, "SmartRange"},
96064002648SGabriel Caruso   { 0xa013, "ExposureBiasValue"},
96164002648SGabriel Caruso   { 0xa014, "ISO"},
96264002648SGabriel Caruso   { 0xa018, "ExposureTime"},
96364002648SGabriel Caruso   { 0xa019, "FNumber"},
96464002648SGabriel Caruso   { 0xa01a, "FocalLengthIn35mmFormat"},
96564002648SGabriel Caruso   { 0xa020, "EncryptionKey"},
96664002648SGabriel Caruso   { 0xa021, "WB_RGGBLevelsUncorrected"},
96764002648SGabriel Caruso   { 0xa022, "WB_RGGBLevelsAuto"},
96864002648SGabriel Caruso   { 0xa023, "WB_RGGBLevelsIlluminator1"},
96964002648SGabriel Caruso   { 0xa024, "WB_RGGBLevelsIlluminator2"},
97064002648SGabriel Caruso   { 0xa028, "WB_RGGBLevelsBlack"},
97164002648SGabriel Caruso   { 0xa030, "ColorMatrix"},
97264002648SGabriel Caruso   { 0xa031, "ColorMatrixSRGB"},
97364002648SGabriel Caruso   { 0xa032, "ColorMatrixAdobeRGB"},
97464002648SGabriel Caruso   { 0xa040, "ToneCurve1"},
975fbb16901SKalle Sommer Nielsen   { 0xa041, "ToneCurve2"},
976fbb16901SKalle Sommer Nielsen   { 0xa042, "ToneCurve3"},
977fbb16901SKalle Sommer Nielsen   { 0xa043, "ToneCurve4"},
978fbb16901SKalle Sommer Nielsen   TAG_TABLE_END
979fbb16901SKalle Sommer Nielsen };
980fbb16901SKalle Sommer Nielsen 
981fbb16901SKalle Sommer Nielsen static tag_info_array tag_table_VND_PANASONIC = {
982fbb16901SKalle Sommer Nielsen   { 0x0001, "Quality"},
983fbb16901SKalle Sommer Nielsen   { 0x0002, "FirmwareVersion"},
984fbb16901SKalle Sommer Nielsen   { 0x0003, "WhiteBalance"},
985fbb16901SKalle Sommer Nielsen   { 0x0007, "FocusMode"},
986fbb16901SKalle Sommer Nielsen   { 0x000f, "AFMode"},
987fbb16901SKalle Sommer Nielsen   { 0x001a, "ImageStabilization"},
988