PageRenderTime 66ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/exif/exif.c

http://github.com/php/php-src
C | 4774 lines | 3938 code | 389 blank | 447 comment | 551 complexity | dcd51ab244edc17aa4832200838a8ba3 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | http://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Rasmus Lerdorf <rasmus@php.net> |
  14. | Marcus Boerger <helly@php.net> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include "php.h"
  21. #include "ext/standard/file.h"
  22. #if HAVE_EXIF
  23. /* When EXIF_DEBUG is defined the module generates a lot of debug messages
  24. * that help understanding what is going on. This can and should be used
  25. * while extending the module as it shows if you are at the right position.
  26. * You are always considered to have a copy of TIFF6.0 and EXIF2.10 standard.
  27. */
  28. #undef EXIF_DEBUG
  29. #ifdef EXIF_DEBUG
  30. #define EXIFERR_DC , const char *_file, size_t _line
  31. #define EXIFERR_CC , __FILE__, __LINE__
  32. #else
  33. #define EXIFERR_DC
  34. #define EXIFERR_CC
  35. #endif
  36. #include "php_exif.h"
  37. #include "exif_arginfo.h"
  38. #include <math.h>
  39. #include "php_ini.h"
  40. #include "ext/standard/php_string.h"
  41. #include "ext/standard/php_image.h"
  42. #include "ext/standard/info.h"
  43. /* needed for ssize_t definition */
  44. #include <sys/types.h>
  45. #ifdef __SANITIZE_ADDRESS__
  46. # include <sanitizer/asan_interface.h>
  47. #endif
  48. typedef unsigned char uchar;
  49. #ifndef TRUE
  50. # define TRUE 1
  51. # define FALSE 0
  52. #endif
  53. #ifndef max
  54. # define max(a,b) ((a)>(b) ? (a) : (b))
  55. #endif
  56. #define EFREE_IF(ptr) if (ptr) efree(ptr)
  57. #define MAX_IFD_NESTING_LEVEL 150
  58. /* {{{ PHP_MINFO_FUNCTION
  59. */
  60. PHP_MINFO_FUNCTION(exif)
  61. {
  62. php_info_print_table_start();
  63. php_info_print_table_row(2, "EXIF Support", "enabled");
  64. php_info_print_table_row(2, "Supported EXIF Version", "0220");
  65. php_info_print_table_row(2, "Supported filetypes", "JPEG, TIFF");
  66. if (zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)) {
  67. php_info_print_table_row(2, "Multibyte decoding support using mbstring", "enabled");
  68. } else {
  69. php_info_print_table_row(2, "Multibyte decoding support using mbstring", "disabled");
  70. }
  71. 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");
  72. php_info_print_table_end();
  73. DISPLAY_INI_ENTRIES();
  74. }
  75. /* }}} */
  76. ZEND_BEGIN_MODULE_GLOBALS(exif)
  77. char * encode_unicode;
  78. char * decode_unicode_be;
  79. char * decode_unicode_le;
  80. char * encode_jis;
  81. char * decode_jis_be;
  82. char * decode_jis_le;
  83. HashTable *tag_table_cache;
  84. ZEND_END_MODULE_GLOBALS(exif)
  85. ZEND_DECLARE_MODULE_GLOBALS(exif)
  86. #define EXIF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(exif, v)
  87. #if defined(ZTS) && defined(COMPILE_DL_EXIF)
  88. ZEND_TSRMLS_CACHE_DEFINE()
  89. #endif
  90. /* {{{ PHP_INI
  91. */
  92. ZEND_INI_MH(OnUpdateEncode)
  93. {
  94. if (new_value && ZSTR_LEN(new_value)) {
  95. const zend_encoding **return_list;
  96. size_t return_size;
  97. if (FAILURE == zend_multibyte_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value),
  98. &return_list, &return_size, 0)) {
  99. php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value));
  100. return FAILURE;
  101. }
  102. pefree((void *) return_list, 0);
  103. }
  104. return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
  105. }
  106. ZEND_INI_MH(OnUpdateDecode)
  107. {
  108. if (new_value) {
  109. const zend_encoding **return_list;
  110. size_t return_size;
  111. if (FAILURE == zend_multibyte_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value),
  112. &return_list, &return_size, 0)) {
  113. php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value));
  114. return FAILURE;
  115. }
  116. pefree((void *) return_list, 0);
  117. }
  118. return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
  119. }
  120. PHP_INI_BEGIN()
  121. STD_PHP_INI_ENTRY("exif.encode_unicode", "ISO-8859-15", PHP_INI_ALL, OnUpdateEncode, encode_unicode, zend_exif_globals, exif_globals)
  122. STD_PHP_INI_ENTRY("exif.decode_unicode_motorola", "UCS-2BE", PHP_INI_ALL, OnUpdateDecode, decode_unicode_be, zend_exif_globals, exif_globals)
  123. STD_PHP_INI_ENTRY("exif.decode_unicode_intel", "UCS-2LE", PHP_INI_ALL, OnUpdateDecode, decode_unicode_le, zend_exif_globals, exif_globals)
  124. STD_PHP_INI_ENTRY("exif.encode_jis", "", PHP_INI_ALL, OnUpdateEncode, encode_jis, zend_exif_globals, exif_globals)
  125. STD_PHP_INI_ENTRY("exif.decode_jis_motorola", "JIS", PHP_INI_ALL, OnUpdateDecode, decode_jis_be, zend_exif_globals, exif_globals)
  126. STD_PHP_INI_ENTRY("exif.decode_jis_intel", "JIS", PHP_INI_ALL, OnUpdateDecode, decode_jis_le, zend_exif_globals, exif_globals)
  127. PHP_INI_END()
  128. /* }}} */
  129. /* {{{ PHP_GINIT_FUNCTION
  130. */
  131. static PHP_GINIT_FUNCTION(exif)
  132. {
  133. #if defined(COMPILE_DL_EXIF) && defined(ZTS)
  134. ZEND_TSRMLS_CACHE_UPDATE();
  135. #endif
  136. exif_globals->encode_unicode = NULL;
  137. exif_globals->decode_unicode_be = NULL;
  138. exif_globals->decode_unicode_le = NULL;
  139. exif_globals->encode_jis = NULL;
  140. exif_globals->decode_jis_be = NULL;
  141. exif_globals->decode_jis_le = NULL;
  142. exif_globals->tag_table_cache = NULL;
  143. }
  144. /* }}} */
  145. /* {{{ PHP_MINIT_FUNCTION(exif)
  146. */
  147. PHP_MINIT_FUNCTION(exif)
  148. {
  149. REGISTER_INI_ENTRIES();
  150. if (zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)) {
  151. REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", 1, CONST_CS | CONST_PERSISTENT);
  152. } else {
  153. REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", 0, CONST_CS | CONST_PERSISTENT);
  154. }
  155. return SUCCESS;
  156. }
  157. /* }}} */
  158. /* {{{ PHP_MSHUTDOWN_FUNCTION
  159. */
  160. PHP_MSHUTDOWN_FUNCTION(exif)
  161. {
  162. UNREGISTER_INI_ENTRIES();
  163. if (EXIF_G(tag_table_cache)) {
  164. zend_hash_destroy(EXIF_G(tag_table_cache));
  165. free(EXIF_G(tag_table_cache));
  166. }
  167. return SUCCESS;
  168. }
  169. /* }}} */
  170. /* {{{ exif dependencies */
  171. static const zend_module_dep exif_module_deps[] = {
  172. ZEND_MOD_REQUIRED("standard")
  173. ZEND_MOD_OPTIONAL("mbstring")
  174. ZEND_MOD_END
  175. };
  176. /* }}} */
  177. /* {{{ exif_module_entry
  178. */
  179. zend_module_entry exif_module_entry = {
  180. STANDARD_MODULE_HEADER_EX, NULL,
  181. exif_module_deps,
  182. "exif",
  183. ext_functions,
  184. PHP_MINIT(exif),
  185. PHP_MSHUTDOWN(exif),
  186. NULL, NULL,
  187. PHP_MINFO(exif),
  188. PHP_EXIF_VERSION,
  189. PHP_MODULE_GLOBALS(exif),
  190. PHP_GINIT(exif),
  191. NULL,
  192. NULL,
  193. STANDARD_MODULE_PROPERTIES_EX
  194. };
  195. /* }}} */
  196. #ifdef COMPILE_DL_EXIF
  197. ZEND_GET_MODULE(exif)
  198. #endif
  199. /* {{{ php_strnlen
  200. * get length of string if buffer if less than buffer size or buffer size */
  201. static size_t php_strnlen(char* str, size_t maxlen) {
  202. size_t len = 0;
  203. if (str && maxlen && *str) {
  204. do {
  205. len++;
  206. } while (--maxlen && *(++str));
  207. }
  208. return len;
  209. }
  210. /* }}} */
  211. /* {{{ error messages
  212. */
  213. static const char * EXIF_ERROR_FILEEOF = "Unexpected end of file reached";
  214. static const char * EXIF_ERROR_CORRUPT = "File structure corrupted";
  215. static const char * EXIF_ERROR_THUMBEOF = "Thumbnail goes IFD boundary or end of file reached";
  216. static const char * EXIF_ERROR_FSREALLOC = "Illegal reallocating of undefined file section";
  217. #define EXIF_ERRLOG_FILEEOF(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FILEEOF);
  218. #define EXIF_ERRLOG_CORRUPT(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_CORRUPT);
  219. #define EXIF_ERRLOG_THUMBEOF(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_THUMBEOF);
  220. #define EXIF_ERRLOG_FSREALLOC(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FSREALLOC);
  221. /* }}} */
  222. /* {{{ format description defines
  223. Describes format descriptor
  224. */
  225. static int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1};
  226. #define NUM_FORMATS 13
  227. #define TAG_FMT_BYTE 1
  228. #define TAG_FMT_STRING 2
  229. #define TAG_FMT_USHORT 3
  230. #define TAG_FMT_ULONG 4
  231. #define TAG_FMT_URATIONAL 5
  232. #define TAG_FMT_SBYTE 6
  233. #define TAG_FMT_UNDEFINED 7
  234. #define TAG_FMT_SSHORT 8
  235. #define TAG_FMT_SLONG 9
  236. #define TAG_FMT_SRATIONAL 10
  237. #define TAG_FMT_SINGLE 11
  238. #define TAG_FMT_DOUBLE 12
  239. #define TAG_FMT_IFD 13
  240. #ifdef EXIF_DEBUG
  241. static char *exif_get_tagformat(int format)
  242. {
  243. switch(format) {
  244. case TAG_FMT_BYTE: return "BYTE";
  245. case TAG_FMT_STRING: return "STRING";
  246. case TAG_FMT_USHORT: return "USHORT";
  247. case TAG_FMT_ULONG: return "ULONG";
  248. case TAG_FMT_URATIONAL: return "URATIONAL";
  249. case TAG_FMT_SBYTE: return "SBYTE";
  250. case TAG_FMT_UNDEFINED: return "UNDEFINED";
  251. case TAG_FMT_SSHORT: return "SSHORT";
  252. case TAG_FMT_SLONG: return "SLONG";
  253. case TAG_FMT_SRATIONAL: return "SRATIONAL";
  254. case TAG_FMT_SINGLE: return "SINGLE";
  255. case TAG_FMT_DOUBLE: return "DOUBLE";
  256. case TAG_FMT_IFD: return "IFD";
  257. }
  258. return "*Illegal";
  259. }
  260. #endif
  261. /* Describes tag values */
  262. #define TAG_GPS_VERSION_ID 0x0000
  263. #define TAG_GPS_LATITUDE_REF 0x0001
  264. #define TAG_GPS_LATITUDE 0x0002
  265. #define TAG_GPS_LONGITUDE_REF 0x0003
  266. #define TAG_GPS_LONGITUDE 0x0004
  267. #define TAG_GPS_ALTITUDE_REF 0x0005
  268. #define TAG_GPS_ALTITUDE 0x0006
  269. #define TAG_GPS_TIME_STAMP 0x0007
  270. #define TAG_GPS_SATELLITES 0x0008
  271. #define TAG_GPS_STATUS 0x0009
  272. #define TAG_GPS_MEASURE_MODE 0x000A
  273. #define TAG_GPS_DOP 0x000B
  274. #define TAG_GPS_SPEED_REF 0x000C
  275. #define TAG_GPS_SPEED 0x000D
  276. #define TAG_GPS_TRACK_REF 0x000E
  277. #define TAG_GPS_TRACK 0x000F
  278. #define TAG_GPS_IMG_DIRECTION_REF 0x0010
  279. #define TAG_GPS_IMG_DIRECTION 0x0011
  280. #define TAG_GPS_MAP_DATUM 0x0012
  281. #define TAG_GPS_DEST_LATITUDE_REF 0x0013
  282. #define TAG_GPS_DEST_LATITUDE 0x0014
  283. #define TAG_GPS_DEST_LONGITUDE_REF 0x0015
  284. #define TAG_GPS_DEST_LONGITUDE 0x0016
  285. #define TAG_GPS_DEST_BEARING_REF 0x0017
  286. #define TAG_GPS_DEST_BEARING 0x0018
  287. #define TAG_GPS_DEST_DISTANCE_REF 0x0019
  288. #define TAG_GPS_DEST_DISTANCE 0x001A
  289. #define TAG_GPS_PROCESSING_METHOD 0x001B
  290. #define TAG_GPS_AREA_INFORMATION 0x001C
  291. #define TAG_GPS_DATE_STAMP 0x001D
  292. #define TAG_GPS_DIFFERENTIAL 0x001E
  293. #define TAG_TIFF_COMMENT 0x00FE /* SHOULDN'T HAPPEN */
  294. #define TAG_NEW_SUBFILE 0x00FE /* New version of subfile tag */
  295. #define TAG_SUBFILE_TYPE 0x00FF /* Old version of subfile tag */
  296. #define TAG_IMAGEWIDTH 0x0100
  297. #define TAG_IMAGEHEIGHT 0x0101
  298. #define TAG_BITS_PER_SAMPLE 0x0102
  299. #define TAG_COMPRESSION 0x0103
  300. #define TAG_PHOTOMETRIC_INTERPRETATION 0x0106
  301. #define TAG_TRESHHOLDING 0x0107
  302. #define TAG_CELL_WIDTH 0x0108
  303. #define TAG_CELL_HEIGHT 0x0109
  304. #define TAG_FILL_ORDER 0x010A
  305. #define TAG_DOCUMENT_NAME 0x010D
  306. #define TAG_IMAGE_DESCRIPTION 0x010E
  307. #define TAG_MAKE 0x010F
  308. #define TAG_MODEL 0x0110
  309. #define TAG_STRIP_OFFSETS 0x0111
  310. #define TAG_ORIENTATION 0x0112
  311. #define TAG_SAMPLES_PER_PIXEL 0x0115
  312. #define TAG_ROWS_PER_STRIP 0x0116
  313. #define TAG_STRIP_BYTE_COUNTS 0x0117
  314. #define TAG_MIN_SAMPPLE_VALUE 0x0118
  315. #define TAG_MAX_SAMPLE_VALUE 0x0119
  316. #define TAG_X_RESOLUTION 0x011A
  317. #define TAG_Y_RESOLUTION 0x011B
  318. #define TAG_PLANAR_CONFIGURATION 0x011C
  319. #define TAG_PAGE_NAME 0x011D
  320. #define TAG_X_POSITION 0x011E
  321. #define TAG_Y_POSITION 0x011F
  322. #define TAG_FREE_OFFSETS 0x0120
  323. #define TAG_FREE_BYTE_COUNTS 0x0121
  324. #define TAG_GRAY_RESPONSE_UNIT 0x0122
  325. #define TAG_GRAY_RESPONSE_CURVE 0x0123
  326. #define TAG_RESOLUTION_UNIT 0x0128
  327. #define TAG_PAGE_NUMBER 0x0129
  328. #define TAG_TRANSFER_FUNCTION 0x012D
  329. #define TAG_SOFTWARE 0x0131
  330. #define TAG_DATETIME 0x0132
  331. #define TAG_ARTIST 0x013B
  332. #define TAG_HOST_COMPUTER 0x013C
  333. #define TAG_PREDICTOR 0x013D
  334. #define TAG_WHITE_POINT 0x013E
  335. #define TAG_PRIMARY_CHROMATICITIES 0x013F
  336. #define TAG_COLOR_MAP 0x0140
  337. #define TAG_HALFTONE_HINTS 0x0141
  338. #define TAG_TILE_WIDTH 0x0142
  339. #define TAG_TILE_LENGTH 0x0143
  340. #define TAG_TILE_OFFSETS 0x0144
  341. #define TAG_TILE_BYTE_COUNTS 0x0145
  342. #define TAG_SUB_IFD 0x014A
  343. #define TAG_INK_SETMPUTER 0x014C
  344. #define TAG_INK_NAMES 0x014D
  345. #define TAG_NUMBER_OF_INKS 0x014E
  346. #define TAG_DOT_RANGE 0x0150
  347. #define TAG_TARGET_PRINTER 0x0151
  348. #define TAG_EXTRA_SAMPLE 0x0152
  349. #define TAG_SAMPLE_FORMAT 0x0153
  350. #define TAG_S_MIN_SAMPLE_VALUE 0x0154
  351. #define TAG_S_MAX_SAMPLE_VALUE 0x0155
  352. #define TAG_TRANSFER_RANGE 0x0156
  353. #define TAG_JPEG_TABLES 0x015B
  354. #define TAG_JPEG_PROC 0x0200
  355. #define TAG_JPEG_INTERCHANGE_FORMAT 0x0201
  356. #define TAG_JPEG_INTERCHANGE_FORMAT_LEN 0x0202
  357. #define TAG_JPEG_RESTART_INTERVAL 0x0203
  358. #define TAG_JPEG_LOSSLESS_PREDICTOR 0x0205
  359. #define TAG_JPEG_POINT_TRANSFORMS 0x0206
  360. #define TAG_JPEG_Q_TABLES 0x0207
  361. #define TAG_JPEG_DC_TABLES 0x0208
  362. #define TAG_JPEG_AC_TABLES 0x0209
  363. #define TAG_YCC_COEFFICIENTS 0x0211
  364. #define TAG_YCC_SUB_SAMPLING 0x0212
  365. #define TAG_YCC_POSITIONING 0x0213
  366. #define TAG_REFERENCE_BLACK_WHITE 0x0214
  367. /* 0x0301 - 0x0302 */
  368. /* 0x0320 */
  369. /* 0x0343 */
  370. /* 0x5001 - 0x501B */
  371. /* 0x5021 - 0x503B */
  372. /* 0x5090 - 0x5091 */
  373. /* 0x5100 - 0x5101 */
  374. /* 0x5110 - 0x5113 */
  375. /* 0x80E3 - 0x80E6 */
  376. /* 0x828d - 0x828F */
  377. #define TAG_COPYRIGHT 0x8298
  378. #define TAG_EXPOSURETIME 0x829A
  379. #define TAG_FNUMBER 0x829D
  380. #define TAG_EXIF_IFD_POINTER 0x8769
  381. #define TAG_ICC_PROFILE 0x8773
  382. #define TAG_EXPOSURE_PROGRAM 0x8822
  383. #define TAG_SPECTRAL_SENSITY 0x8824
  384. #define TAG_GPS_IFD_POINTER 0x8825
  385. #define TAG_ISOSPEED 0x8827
  386. #define TAG_OPTOELECTRIC_CONVERSION_F 0x8828
  387. /* 0x8829 - 0x882b */
  388. #define TAG_EXIFVERSION 0x9000
  389. #define TAG_DATE_TIME_ORIGINAL 0x9003
  390. #define TAG_DATE_TIME_DIGITIZED 0x9004
  391. #define TAG_COMPONENT_CONFIG 0x9101
  392. #define TAG_COMPRESSED_BITS_PER_PIXEL 0x9102
  393. #define TAG_SHUTTERSPEED 0x9201
  394. #define TAG_APERTURE 0x9202
  395. #define TAG_BRIGHTNESS_VALUE 0x9203
  396. #define TAG_EXPOSURE_BIAS_VALUE 0x9204
  397. #define TAG_MAX_APERTURE 0x9205
  398. #define TAG_SUBJECT_DISTANCE 0x9206
  399. #define TAG_METRIC_MODULE 0x9207
  400. #define TAG_LIGHT_SOURCE 0x9208
  401. #define TAG_FLASH 0x9209
  402. #define TAG_FOCAL_LENGTH 0x920A
  403. /* 0x920B - 0x920D */
  404. /* 0x9211 - 0x9216 */
  405. #define TAG_SUBJECT_AREA 0x9214
  406. #define TAG_MAKER_NOTE 0x927C
  407. #define TAG_USERCOMMENT 0x9286
  408. #define TAG_SUB_SEC_TIME 0x9290
  409. #define TAG_SUB_SEC_TIME_ORIGINAL 0x9291
  410. #define TAG_SUB_SEC_TIME_DIGITIZED 0x9292
  411. /* 0x923F */
  412. /* 0x935C */
  413. #define TAG_XP_TITLE 0x9C9B
  414. #define TAG_XP_COMMENTS 0x9C9C
  415. #define TAG_XP_AUTHOR 0x9C9D
  416. #define TAG_XP_KEYWORDS 0x9C9E
  417. #define TAG_XP_SUBJECT 0x9C9F
  418. #define TAG_FLASH_PIX_VERSION 0xA000
  419. #define TAG_COLOR_SPACE 0xA001
  420. #define TAG_COMP_IMAGE_WIDTH 0xA002 /* compressed images only */
  421. #define TAG_COMP_IMAGE_HEIGHT 0xA003
  422. #define TAG_RELATED_SOUND_FILE 0xA004
  423. #define TAG_INTEROP_IFD_POINTER 0xA005 /* IFD pointer */
  424. #define TAG_FLASH_ENERGY 0xA20B
  425. #define TAG_SPATIAL_FREQUENCY_RESPONSE 0xA20C
  426. #define TAG_FOCALPLANE_X_RES 0xA20E
  427. #define TAG_FOCALPLANE_Y_RES 0xA20F
  428. #define TAG_FOCALPLANE_RESOLUTION_UNIT 0xA210
  429. #define TAG_SUBJECT_LOCATION 0xA214
  430. #define TAG_EXPOSURE_INDEX 0xA215
  431. #define TAG_SENSING_METHOD 0xA217
  432. #define TAG_FILE_SOURCE 0xA300
  433. #define TAG_SCENE_TYPE 0xA301
  434. #define TAG_CFA_PATTERN 0xA302
  435. #define TAG_CUSTOM_RENDERED 0xA401
  436. #define TAG_EXPOSURE_MODE 0xA402
  437. #define TAG_WHITE_BALANCE 0xA403
  438. #define TAG_DIGITAL_ZOOM_RATIO 0xA404
  439. #define TAG_FOCAL_LENGTH_IN_35_MM_FILM 0xA405
  440. #define TAG_SCENE_CAPTURE_TYPE 0xA406
  441. #define TAG_GAIN_CONTROL 0xA407
  442. #define TAG_CONTRAST 0xA408
  443. #define TAG_SATURATION 0xA409
  444. #define TAG_SHARPNESS 0xA40A
  445. #define TAG_DEVICE_SETTING_DESCRIPTION 0xA40B
  446. #define TAG_SUBJECT_DISTANCE_RANGE 0xA40C
  447. #define TAG_IMAGE_UNIQUE_ID 0xA420
  448. /* Olympus specific tags */
  449. #define TAG_OLYMPUS_SPECIALMODE 0x0200
  450. #define TAG_OLYMPUS_JPEGQUAL 0x0201
  451. #define TAG_OLYMPUS_MACRO 0x0202
  452. #define TAG_OLYMPUS_DIGIZOOM 0x0204
  453. #define TAG_OLYMPUS_SOFTWARERELEASE 0x0207
  454. #define TAG_OLYMPUS_PICTINFO 0x0208
  455. #define TAG_OLYMPUS_CAMERAID 0x0209
  456. /* end Olympus specific tags */
  457. /* Internal */
  458. #define TAG_NONE -1 /* note that -1 <> 0xFFFF */
  459. #define TAG_COMPUTED_VALUE -2
  460. #define TAG_END_OF_LIST 0xFFFD
  461. /* Values for TAG_PHOTOMETRIC_INTERPRETATION */
  462. #define PMI_BLACK_IS_ZERO 0
  463. #define PMI_WHITE_IS_ZERO 1
  464. #define PMI_RGB 2
  465. #define PMI_PALETTE_COLOR 3
  466. #define PMI_TRANSPARENCY_MASK 4
  467. #define PMI_SEPARATED 5
  468. #define PMI_YCBCR 6
  469. #define PMI_CIELAB 8
  470. /* }}} */
  471. /* {{{ TabTable[]
  472. */
  473. typedef const struct {
  474. unsigned short Tag;
  475. char *Desc;
  476. } tag_info_type;
  477. typedef tag_info_type tag_info_array[];
  478. typedef tag_info_type *tag_table_type;
  479. #define TAG_TABLE_END \
  480. {TAG_NONE, "No tag value"},\
  481. {TAG_COMPUTED_VALUE, "Computed value"},\
  482. {TAG_END_OF_LIST, ""} /* Important for exif_get_tagname() IF value != "" function result is != false */
  483. static tag_info_array tag_table_IFD = {
  484. { 0x000B, "ACDComment"},
  485. { 0x00FE, "NewSubFile"}, /* better name it 'ImageType' ? */
  486. { 0x00FF, "SubFile"},
  487. { 0x0100, "ImageWidth"},
  488. { 0x0101, "ImageLength"},
  489. { 0x0102, "BitsPerSample"},
  490. { 0x0103, "Compression"},
  491. { 0x0106, "PhotometricInterpretation"},
  492. { 0x010A, "FillOrder"},
  493. { 0x010D, "DocumentName"},
  494. { 0x010E, "ImageDescription"},
  495. { 0x010F, "Make"},
  496. { 0x0110, "Model"},
  497. { 0x0111, "StripOffsets"},
  498. { 0x0112, "Orientation"},
  499. { 0x0115, "SamplesPerPixel"},
  500. { 0x0116, "RowsPerStrip"},
  501. { 0x0117, "StripByteCounts"},
  502. { 0x0118, "MinSampleValue"},
  503. { 0x0119, "MaxSampleValue"},
  504. { 0x011A, "XResolution"},
  505. { 0x011B, "YResolution"},
  506. { 0x011C, "PlanarConfiguration"},
  507. { 0x011D, "PageName"},
  508. { 0x011E, "XPosition"},
  509. { 0x011F, "YPosition"},
  510. { 0x0120, "FreeOffsets"},
  511. { 0x0121, "FreeByteCounts"},
  512. { 0x0122, "GrayResponseUnit"},
  513. { 0x0123, "GrayResponseCurve"},
  514. { 0x0124, "T4Options"},
  515. { 0x0125, "T6Options"},
  516. { 0x0128, "ResolutionUnit"},
  517. { 0x0129, "PageNumber"},
  518. { 0x012D, "TransferFunction"},
  519. { 0x0131, "Software"},
  520. { 0x0132, "DateTime"},
  521. { 0x013B, "Artist"},
  522. { 0x013C, "HostComputer"},
  523. { 0x013D, "Predictor"},
  524. { 0x013E, "WhitePoint"},
  525. { 0x013F, "PrimaryChromaticities"},
  526. { 0x0140, "ColorMap"},
  527. { 0x0141, "HalfToneHints"},
  528. { 0x0142, "TileWidth"},
  529. { 0x0143, "TileLength"},
  530. { 0x0144, "TileOffsets"},
  531. { 0x0145, "TileByteCounts"},
  532. { 0x014A, "SubIFD"},
  533. { 0x014C, "InkSet"},
  534. { 0x014D, "InkNames"},
  535. { 0x014E, "NumberOfInks"},
  536. { 0x0150, "DotRange"},
  537. { 0x0151, "TargetPrinter"},
  538. { 0x0152, "ExtraSample"},
  539. { 0x0153, "SampleFormat"},
  540. { 0x0154, "SMinSampleValue"},
  541. { 0x0155, "SMaxSampleValue"},
  542. { 0x0156, "TransferRange"},
  543. { 0x0157, "ClipPath"},
  544. { 0x0158, "XClipPathUnits"},
  545. { 0x0159, "YClipPathUnits"},
  546. { 0x015A, "Indexed"},
  547. { 0x015B, "JPEGTables"},
  548. { 0x015F, "OPIProxy"},
  549. { 0x0200, "JPEGProc"},
  550. { 0x0201, "JPEGInterchangeFormat"},
  551. { 0x0202, "JPEGInterchangeFormatLength"},
  552. { 0x0203, "JPEGRestartInterval"},
  553. { 0x0205, "JPEGLosslessPredictors"},
  554. { 0x0206, "JPEGPointTransforms"},
  555. { 0x0207, "JPEGQTables"},
  556. { 0x0208, "JPEGDCTables"},
  557. { 0x0209, "JPEGACTables"},
  558. { 0x0211, "YCbCrCoefficients"},
  559. { 0x0212, "YCbCrSubSampling"},
  560. { 0x0213, "YCbCrPositioning"},
  561. { 0x0214, "ReferenceBlackWhite"},
  562. { 0x02BC, "ExtensibleMetadataPlatform"}, /* XAP: Extensible Authoring Publishing, obsoleted by XMP: Extensible Metadata Platform */
  563. { 0x0301, "Gamma"},
  564. { 0x0302, "ICCProfileDescriptor"},
  565. { 0x0303, "SRGBRenderingIntent"},
  566. { 0x0320, "ImageTitle"},
  567. { 0x5001, "ResolutionXUnit"},
  568. { 0x5002, "ResolutionYUnit"},
  569. { 0x5003, "ResolutionXLengthUnit"},
  570. { 0x5004, "ResolutionYLengthUnit"},
  571. { 0x5005, "PrintFlags"},
  572. { 0x5006, "PrintFlagsVersion"},
  573. { 0x5007, "PrintFlagsCrop"},
  574. { 0x5008, "PrintFlagsBleedWidth"},
  575. { 0x5009, "PrintFlagsBleedWidthScale"},
  576. { 0x500A, "HalftoneLPI"},
  577. { 0x500B, "HalftoneLPIUnit"},
  578. { 0x500C, "HalftoneDegree"},
  579. { 0x500D, "HalftoneShape"},
  580. { 0x500E, "HalftoneMisc"},
  581. { 0x500F, "HalftoneScreen"},
  582. { 0x5010, "JPEGQuality"},
  583. { 0x5011, "GridSize"},
  584. { 0x5012, "ThumbnailFormat"},
  585. { 0x5013, "ThumbnailWidth"},
  586. { 0x5014, "ThumbnailHeight"},
  587. { 0x5015, "ThumbnailColorDepth"},
  588. { 0x5016, "ThumbnailPlanes"},
  589. { 0x5017, "ThumbnailRawBytes"},
  590. { 0x5018, "ThumbnailSize"},
  591. { 0x5019, "ThumbnailCompressedSize"},
  592. { 0x501A, "ColorTransferFunction"},
  593. { 0x501B, "ThumbnailData"},
  594. { 0x5020, "ThumbnailImageWidth"},
  595. { 0x5021, "ThumbnailImageHeight"},
  596. { 0x5022, "ThumbnailBitsPerSample"},
  597. { 0x5023, "ThumbnailCompression"},
  598. { 0x5024, "ThumbnailPhotometricInterp"},
  599. { 0x5025, "ThumbnailImageDescription"},
  600. { 0x5026, "ThumbnailEquipMake"},
  601. { 0x5027, "ThumbnailEquipModel"},
  602. { 0x5028, "ThumbnailStripOffsets"},
  603. { 0x5029, "ThumbnailOrientation"},
  604. { 0x502A, "ThumbnailSamplesPerPixel"},
  605. { 0x502B, "ThumbnailRowsPerStrip"},
  606. { 0x502C, "ThumbnailStripBytesCount"},
  607. { 0x502D, "ThumbnailResolutionX"},
  608. { 0x502E, "ThumbnailResolutionY"},
  609. { 0x502F, "ThumbnailPlanarConfig"},
  610. { 0x5030, "ThumbnailResolutionUnit"},
  611. { 0x5031, "ThumbnailTransferFunction"},
  612. { 0x5032, "ThumbnailSoftwareUsed"},
  613. { 0x5033, "ThumbnailDateTime"},
  614. { 0x5034, "ThumbnailArtist"},
  615. { 0x5035, "ThumbnailWhitePoint"},
  616. { 0x5036, "ThumbnailPrimaryChromaticities"},
  617. { 0x5037, "ThumbnailYCbCrCoefficients"},
  618. { 0x5038, "ThumbnailYCbCrSubsampling"},
  619. { 0x5039, "ThumbnailYCbCrPositioning"},
  620. { 0x503A, "ThumbnailRefBlackWhite"},
  621. { 0x503B, "ThumbnailCopyRight"},
  622. { 0x5090, "LuminanceTable"},
  623. { 0x5091, "ChrominanceTable"},
  624. { 0x5100, "FrameDelay"},
  625. { 0x5101, "LoopCount"},
  626. { 0x5110, "PixelUnit"},
  627. { 0x5111, "PixelPerUnitX"},
  628. { 0x5112, "PixelPerUnitY"},
  629. { 0x5113, "PaletteHistogram"},
  630. { 0x1000, "RelatedImageFileFormat"},
  631. { 0x800D, "ImageID"},
  632. { 0x80E3, "Matteing"}, /* obsoleted by ExtraSamples */
  633. { 0x80E4, "DataType"}, /* obsoleted by SampleFormat */
  634. { 0x80E5, "ImageDepth"},
  635. { 0x80E6, "TileDepth"},
  636. { 0x828D, "CFARepeatPatternDim"},
  637. { 0x828E, "CFAPattern"},
  638. { 0x828F, "BatteryLevel"},
  639. { 0x8298, "Copyright"},
  640. { 0x829A, "ExposureTime"},
  641. { 0x829D, "FNumber"},
  642. { 0x83BB, "IPTC/NAA"},
  643. { 0x84E3, "IT8RasterPadding"},
  644. { 0x84E5, "IT8ColorTable"},
  645. { 0x8649, "ImageResourceInformation"}, /* PhotoShop */
  646. { 0x8769, "Exif_IFD_Pointer"},
  647. { 0x8773, "ICC_Profile"},
  648. { 0x8822, "ExposureProgram"},
  649. { 0x8824, "SpectralSensity"},
  650. { 0x8825, "GPS_IFD_Pointer"},
  651. { 0x8827, "ISOSpeedRatings"},
  652. { 0x8828, "OECF"},
  653. { 0x9000, "ExifVersion"},
  654. { 0x9003, "DateTimeOriginal"},
  655. { 0x9004, "DateTimeDigitized"},
  656. { 0x9101, "ComponentsConfiguration"},
  657. { 0x9102, "CompressedBitsPerPixel"},
  658. { 0x9201, "ShutterSpeedValue"},
  659. { 0x9202, "ApertureValue"},
  660. { 0x9203, "BrightnessValue"},
  661. { 0x9204, "ExposureBiasValue"},
  662. { 0x9205, "MaxApertureValue"},
  663. { 0x9206, "SubjectDistance"},
  664. { 0x9207, "MeteringMode"},
  665. { 0x9208, "LightSource"},
  666. { 0x9209, "Flash"},
  667. { 0x920A, "FocalLength"},
  668. { 0x920B, "FlashEnergy"}, /* 0xA20B in JPEG */
  669. { 0x920C, "SpatialFrequencyResponse"}, /* 0xA20C - - */
  670. { 0x920D, "Noise"},
  671. { 0x920E, "FocalPlaneXResolution"}, /* 0xA20E - - */
  672. { 0x920F, "FocalPlaneYResolution"}, /* 0xA20F - - */
  673. { 0x9210, "FocalPlaneResolutionUnit"}, /* 0xA210 - - */
  674. { 0x9211, "ImageNumber"},
  675. { 0x9212, "SecurityClassification"},
  676. { 0x9213, "ImageHistory"},
  677. { 0x9214, "SubjectLocation"}, /* 0xA214 - - */
  678. { 0x9215, "ExposureIndex"}, /* 0xA215 - - */
  679. { 0x9216, "TIFF/EPStandardID"},
  680. { 0x9217, "SensingMethod"}, /* 0xA217 - - */
  681. { 0x923F, "StoNits"},
  682. { 0x927C, "MakerNote"},
  683. { 0x9286, "UserComment"},
  684. { 0x9290, "SubSecTime"},
  685. { 0x9291, "SubSecTimeOriginal"},
  686. { 0x9292, "SubSecTimeDigitized"},
  687. { 0x935C, "ImageSourceData"}, /* "Adobe Photoshop Document Data Block": 8BIM... */
  688. { 0x9c9b, "Title" }, /* Win XP specific, Unicode */
  689. { 0x9c9c, "Comments" }, /* Win XP specific, Unicode */
  690. { 0x9c9d, "Author" }, /* Win XP specific, Unicode */
  691. { 0x9c9e, "Keywords" }, /* Win XP specific, Unicode */
  692. { 0x9c9f, "Subject" }, /* Win XP specific, Unicode, not to be confused with SubjectDistance and SubjectLocation */
  693. { 0xA000, "FlashPixVersion"},
  694. { 0xA001, "ColorSpace"},
  695. { 0xA002, "ExifImageWidth"},
  696. { 0xA003, "ExifImageLength"},
  697. { 0xA004, "RelatedSoundFile"},
  698. { 0xA005, "InteroperabilityOffset"},
  699. { 0xA20B, "FlashEnergy"}, /* 0x920B in TIFF/EP */
  700. { 0xA20C, "SpatialFrequencyResponse"}, /* 0x920C - - */
  701. { 0xA20D, "Noise"},
  702. { 0xA20E, "FocalPlaneXResolution"}, /* 0x920E - - */
  703. { 0xA20F, "FocalPlaneYResolution"}, /* 0x920F - - */
  704. { 0xA210, "FocalPlaneResolutionUnit"}, /* 0x9210 - - */
  705. { 0xA211, "ImageNumber"},
  706. { 0xA212, "SecurityClassification"},
  707. { 0xA213, "ImageHistory"},
  708. { 0xA214, "SubjectLocation"}, /* 0x9214 - - */
  709. { 0xA215, "ExposureIndex"}, /* 0x9215 - - */
  710. { 0xA216, "TIFF/EPStandardID"},
  711. { 0xA217, "SensingMethod"}, /* 0x9217 - - */
  712. { 0xA300, "FileSource"},
  713. { 0xA301, "SceneType"},
  714. { 0xA302, "CFAPattern"},
  715. { 0xA401, "CustomRendered"},
  716. { 0xA402, "ExposureMode"},
  717. { 0xA403, "WhiteBalance"},
  718. { 0xA404, "DigitalZoomRatio"},
  719. { 0xA405, "FocalLengthIn35mmFilm"},
  720. { 0xA406, "SceneCaptureType"},
  721. { 0xA407, "GainControl"},
  722. { 0xA408, "Contrast"},
  723. { 0xA409, "Saturation"},
  724. { 0xA40A, "Sharpness"},
  725. { 0xA40B, "DeviceSettingDescription"},
  726. { 0xA40C, "SubjectDistanceRange"},
  727. { 0xA420, "ImageUniqueID"},
  728. TAG_TABLE_END
  729. } ;
  730. static tag_info_array tag_table_GPS = {
  731. { 0x0000, "GPSVersion"},
  732. { 0x0001, "GPSLatitudeRef"},
  733. { 0x0002, "GPSLatitude"},
  734. { 0x0003, "GPSLongitudeRef"},
  735. { 0x0004, "GPSLongitude"},
  736. { 0x0005, "GPSAltitudeRef"},
  737. { 0x0006, "GPSAltitude"},
  738. { 0x0007, "GPSTimeStamp"},
  739. { 0x0008, "GPSSatellites"},
  740. { 0x0009, "GPSStatus"},
  741. { 0x000A, "GPSMeasureMode"},
  742. { 0x000B, "GPSDOP"},
  743. { 0x000C, "GPSSpeedRef"},
  744. { 0x000D, "GPSSpeed"},
  745. { 0x000E, "GPSTrackRef"},
  746. { 0x000F, "GPSTrack"},
  747. { 0x0010, "GPSImgDirectionRef"},
  748. { 0x0011, "GPSImgDirection"},
  749. { 0x0012, "GPSMapDatum"},
  750. { 0x0013, "GPSDestLatitudeRef"},
  751. { 0x0014, "GPSDestLatitude"},
  752. { 0x0015, "GPSDestLongitudeRef"},
  753. { 0x0016, "GPSDestLongitude"},
  754. { 0x0017, "GPSDestBearingRef"},
  755. { 0x0018, "GPSDestBearing"},
  756. { 0x0019, "GPSDestDistanceRef"},
  757. { 0x001A, "GPSDestDistance"},
  758. { 0x001B, "GPSProcessingMode"},
  759. { 0x001C, "GPSAreaInformation"},
  760. { 0x001D, "GPSDateStamp"},
  761. { 0x001E, "GPSDifferential"},
  762. TAG_TABLE_END
  763. };
  764. static tag_info_array tag_table_IOP = {
  765. { 0x0001, "InterOperabilityIndex"}, /* should be 'R98' or 'THM' */
  766. { 0x0002, "InterOperabilityVersion"},
  767. { 0x1000, "RelatedFileFormat"},
  768. { 0x1001, "RelatedImageWidth"},
  769. { 0x1002, "RelatedImageHeight"},
  770. TAG_TABLE_END
  771. };
  772. static tag_info_array tag_table_VND_CANON = {
  773. { 0x0001, "ModeArray"}, /* guess */
  774. { 0x0004, "ImageInfo"}, /* guess */
  775. { 0x0006, "ImageType"},
  776. { 0x0007, "FirmwareVersion"},
  777. { 0x0008, "ImageNumber"},
  778. { 0x0009, "OwnerName"},
  779. { 0x000C, "Camera"},
  780. { 0x000F, "CustomFunctions"},
  781. TAG_TABLE_END
  782. };
  783. static tag_info_array tag_table_VND_CASIO = {
  784. { 0x0001, "RecordingMode"},
  785. { 0x0002, "Quality"},
  786. { 0x0003, "FocusingMode"},
  787. { 0x0004, "FlashMode"},
  788. { 0x0005, "FlashIntensity"},
  789. { 0x0006, "ObjectDistance"},
  790. { 0x0007, "WhiteBalance"},
  791. { 0x000A, "DigitalZoom"},
  792. { 0x000B, "Sharpness"},
  793. { 0x000C, "Contrast"},
  794. { 0x000D, "Saturation"},
  795. { 0x0014, "CCDSensitivity"},
  796. TAG_TABLE_END
  797. };
  798. static tag_info_array tag_table_VND_FUJI = {
  799. { 0x0000, "Version"},
  800. { 0x1000, "Quality"},
  801. { 0x1001, "Sharpness"},
  802. { 0x1002, "WhiteBalance"},
  803. { 0x1003, "Color"},
  804. { 0x1004, "Tone"},
  805. { 0x1010, "FlashMode"},
  806. { 0x1011, "FlashStrength"},
  807. { 0x1020, "Macro"},
  808. { 0x1021, "FocusMode"},
  809. { 0x1030, "SlowSync"},
  810. { 0x1031, "PictureMode"},
  811. { 0x1100, "ContTake"},
  812. { 0x1300, "BlurWarning"},
  813. { 0x1301, "FocusWarning"},
  814. { 0x1302, "AEWarning "},
  815. TAG_TABLE_END
  816. };
  817. static tag_info_array tag_table_VND_NIKON = {
  818. { 0x0003, "Quality"},
  819. { 0x0004, "ColorMode"},
  820. { 0x0005, "ImageAdjustment"},
  821. { 0x0006, "CCDSensitivity"},
  822. { 0x0007, "WhiteBalance"},
  823. { 0x0008, "Focus"},
  824. { 0x000a, "DigitalZoom"},
  825. { 0x000b, "Converter"},
  826. TAG_TABLE_END
  827. };
  828. static tag_info_array tag_table_VND_NIKON_990 = {
  829. { 0x0001, "Version"},
  830. { 0x0002, "ISOSetting"},
  831. { 0x0003, "ColorMode"},
  832. { 0x0004, "Quality"},
  833. { 0x0005, "WhiteBalance"},
  834. { 0x0006, "ImageSharpening"},
  835. { 0x0007, "FocusMode"},
  836. { 0x0008, "FlashSetting"},
  837. { 0x000F, "ISOSelection"},
  838. { 0x0080, "ImageAdjustment"},
  839. { 0x0082, "AuxiliaryLens"},
  840. { 0x0085, "ManualFocusDistance"},
  841. { 0x0086, "DigitalZoom"},
  842. { 0x0088, "AFFocusPosition"},
  843. { 0x0010, "DataDump"},
  844. TAG_TABLE_END
  845. };
  846. static tag_info_array tag_table_VND_OLYMPUS = {
  847. { 0x0200, "SpecialMode"},
  848. { 0x0201, "JPEGQuality"},
  849. { 0x0202, "Macro"},
  850. { 0x0204, "DigitalZoom"},
  851. { 0x0207, "SoftwareRelease"},
  852. { 0x0208, "PictureInfo"},
  853. { 0x0209, "CameraId"},
  854. { 0x0F00, "DataDump"},
  855. TAG_TABLE_END
  856. };
  857. static tag_info_array tag_table_VND_SAMSUNG = {
  858. { 0x0001, "Version"},
  859. { 0x0021, "PictureWizard"},
  860. { 0x0030, "LocalLocationName"},
  861. { 0x0031, "LocationName"},
  862. { 0x0035, "Preview"},
  863. { 0x0043, "CameraTemperature"},
  864. { 0xa001, "FirmwareName"},
  865. { 0xa003, "LensType"},
  866. { 0xa004, "LensFirmware"},
  867. { 0xa010, "SensorAreas"},
  868. { 0xa011, "ColorSpace"},
  869. { 0xa012, "SmartRange"},
  870. { 0xa013, "ExposureBiasValue"},
  871. { 0xa014, "ISO"},
  872. { 0xa018, "ExposureTime"},
  873. { 0xa019, "FNumber"},
  874. { 0xa01a, "FocalLengthIn35mmFormat"},
  875. { 0xa020, "EncryptionKey"},
  876. { 0xa021, "WB_RGGBLevelsUncorrected"},
  877. { 0xa022, "WB_RGGBLevelsAuto"},
  878. { 0xa023, "WB_RGGBLevelsIlluminator1"},
  879. { 0xa024, "WB_RGGBLevelsIlluminator2"},
  880. { 0xa028, "WB_RGGBLevelsBlack"},
  881. { 0xa030, "ColorMatrix"},
  882. { 0xa031, "ColorMatrixSRGB"},
  883. { 0xa032, "ColorMatrixAdobeRGB"},
  884. { 0xa040, "ToneCurve1"},
  885. { 0xa041, "ToneCurve2"},
  886. { 0xa042, "ToneCurve3"},
  887. { 0xa043, "ToneCurve4"},
  888. TAG_TABLE_END
  889. };
  890. static tag_info_array tag_table_VND_PANASONIC = {
  891. { 0x0001, "Quality"},
  892. { 0x0002, "FirmwareVersion"},
  893. { 0x0003, "WhiteBalance"},
  894. { 0x0007, "FocusMode"},
  895. { 0x000f, "AFMode"},
  896. { 0x001a, "ImageStabilization"},
  897. { 0x001c, "Macro"},
  898. { 0x001f, "ShootingMode"},
  899. { 0x0020, "Audio"},
  900. { 0x0021, "DataDump"},
  901. { 0x0023, "WhiteBalanceBias"},
  902. { 0x0024, "FlashBias"},
  903. { 0x0025, "InternalSerialNumber"},
  904. { 0x0026, "ExifVersion"},
  905. { 0x0028, "ColorEffect"},
  906. { 0x0029, "TimeSincePowerOn"},
  907. { 0x002a, "BurstMode"},
  908. { 0x002b, "SequenceNumber"},
  909. { 0x002c, "Contrast"},
  910. { 0x002d, "NoiseReduction"},
  911. { 0x002e, "SelfTimer"},
  912. { 0x0030, "Rotation"},
  913. { 0x0031, "AFAssistLamp"},
  914. { 0x0032, "ColorMode"},
  915. { 0x0033, "BabyAge1"},
  916. { 0x0034, "OpticalZoomMode"},
  917. { 0x0035, "ConversionLens"},
  918. { 0x0036, "TravelDay"},
  919. { 0x0039, "Contrast"},
  920. { 0x003a, "WorldTimeLocation"},
  921. { 0x003b, "TextStamp1"},
  922. { 0x003c, "ProgramISO"},
  923. { 0x003d, "AdvancedSceneType"},
  924. { 0x003e, "TextStamp2"},
  925. { 0x003f, "FacesDetected"},
  926. { 0x0040, "Saturation"},
  927. { 0x0041, "Sharpness"},
  928. { 0x0042, "FilmMode"},
  929. { 0x0044, "ColorTempKelvin"},
  930. { 0x0045, "BracketSettings"},
  931. { 0x0046, "WBAdjustAB"},
  932. { 0x0047, "WBAdjustGM"},
  933. { 0x0048, "FlashCurtain"},
  934. { 0x0049, "LongShutterNoiseReduction"},
  935. { 0x004b, "ImageWidth"},
  936. { 0x004c, "ImageHeight"},
  937. { 0x004d, "AFPointPosition"},
  938. { 0x004e, "FaceDetInfo"},
  939. { 0x0051, "LensType"},
  940. { 0x0052, "LensSerialNumber"},
  941. { 0x0053, "AccessoryType"},
  942. { 0x0054, "AccessorySerialNumber"},
  943. { 0x0059, "Transform1"},
  944. { 0x005d, "IntelligentExposure"},
  945. { 0x0060, "LensFirmwareVersion"},
  946. { 0x0061, "FaceRecInfo"},
  947. { 0x0062, "FlashWarning"},
  948. { 0x0065, "Title"},
  949. { 0x0066, "BabyName"},
  950. { 0x0067, "Location"},
  951. { 0x0069, "Country"},
  952. { 0x006b, "State"},
  953. { 0x006d, "City"},
  954. { 0x006f, "Landmark"},
  955. { 0x0070, "IntelligentResolution"},
  956. { 0x0077, "BurstSheed"},
  957. { 0x0079, "IntelligentDRange"},
  958. { 0x007c, "ClearRetouch"},
  959. { 0x0080, "City2"},
  960. { 0x0086, "ManometerPressure"},
  961. { 0x0089, "PhotoStyle"},
  962. { 0x008a, "ShadingCompensation"},
  963. { 0x008c, "AccelerometerZ"},
  964. { 0x008d, "AccelerometerX"},
  965. { 0x008e, "AccelerometerY"},
  966. { 0x008f, "CameraOrientation"},
  967. { 0x0090, "RollAngle"},
  968. { 0x0091, "PitchAngle"},
  969. { 0x0093, "SweepPanoramaDirection"},
  970. { 0x0094, "PanoramaFieldOfView"},
  971. { 0x0096, "TimerRecording"},
  972. { 0x009d, "InternalNDFilter"},
  973. { 0x009e, "HDR"},
  974. { 0x009f, "ShutterType"},
  975. { 0x00a3, "ClearRetouchValue"},
  976. { 0x00ab, "TouchAE"},
  977. { 0x0e00, "PrintIM"},
  978. { 0x8000, "MakerNoteVersion"},
  979. { 0x8001, "SceneMode"},
  980. { 0x8004, "WBRedLevel"},
  981. { 0x8005, "WBGreenLevel"},
  982. { 0x8006, "WBBlueLevel"},
  983. { 0x8007, "FlashFired"},
  984. { 0x8008, "TextStamp3"},
  985. { 0x8009, "TextStamp4"},
  986. { 0x8010, "BabyAge2"},
  987. { 0x8012, "Transform2"},
  988. TAG_TABLE_END
  989. };
  990. static tag_info_array tag_table_VND_DJI = {
  991. { 0x0001, "Make"},
  992. { 0x0003, "SpeedX"},
  993. { 0x0004, "SpeedY"},
  994. { 0x0005, "SpeedZ"},
  995. { 0x0006, "Pitch"},
  996. { 0x0007, "Yaw"},
  997. { 0x0008, "Roll"},
  998. { 0x0009, "CameraPitch"},
  999. { 0x000a, "CameraYaw"},
  1000. { 0x000b, "CameraRoll"},
  1001. TAG_TABLE_END
  1002. };
  1003. static tag_info_array tag_table_VND_SONY = {
  1004. { 0x0102, "Quality"},
  1005. { 0x0104, "FlashExposureComp"},
  1006. { 0x0105, "Teleconverter"},
  1007. { 0x0112, "WhiteBalanceFineTune"},
  1008. { 0x0114, "CameraSettings"},
  1009. { 0x0115, "WhiteBalance"},
  1010. { 0x0116, "ExtraInfo"},
  1011. { 0x0e00, "PrintIM"},
  1012. { 0x1000, "MultiBurstMode"},
  1013. { 0x1001, "MultiBurstImageWidth"},
  1014. { 0x1002, "MultiBurstImageHeight"},
  1015. { 0x1003, "Panorama"},
  1016. { 0x2001, "PreviewImage"},
  1017. { 0x2002, "Rating"},
  1018. { 0x2004, "Contrast"},
  1019. { 0x2005, "Saturation"},
  1020. { 0x2006, "Sharpness"},
  1021. { 0x2007, "Brightness"},
  1022. { 0x2008, "LongExposureNoiseReduction"},
  1023. { 0x2009, "HighISONoiseReduction"},
  1024. { 0x200a, "AutoHDR"},
  1025. { 0x3000, "ShotInfo"},
  1026. { 0xb000, "FileFormat"},
  1027. { 0xb001, "SonyModelID"},
  1028. { 0xb020, "ColorReproduction"},
  1029. { 0xb021, "ColorTemperature"},
  1030. { 0xb022, "ColorCompensationFilter"},
  1031. { 0xb023, "SceneMode"},
  1032. { 0xb024, "ZoneMatching"},
  1033. { 0xb025, "DynamicRangeOptimizer"},
  1034. { 0xb026, "ImageStabilization"},
  1035. { 0xb027, "LensID"},
  1036. { 0xb028, "MinoltaMakerNote"},
  1037. { 0xb029, "ColorMode"},
  1038. { 0xb02b, "FullImageSize"},
  1039. { 0xb02c, "PreviewImageSize"},
  1040. { 0xb040, "Macro"},
  1041. { 0xb041, "ExposureMode"},
  1042. { 0xb042, "FocusMode"},
  1043. { 0xb043, "AFMode"},
  1044. { 0xb044, "AFIlluminator"},
  1045. { 0xb047, "JPEGQuality"},
  1046. { 0xb048, "FlashLevel"},
  1047. { 0xb049, "ReleaseMode"},
  1048. { 0xb04a, "SequenceNumber"},
  1049. { 0xb04b, "AntiBlur"},
  1050. { 0xb04e, "FocusMode"},
  1051. { 0xb04f, "DynamicRangeOptimizer"},
  1052. { 0xb050, "HighISONoiseReduction2"},
  1053. { 0xb052, "IntelligentAuto"},
  1054. { 0xb054, "WhiteBalance2"},
  1055. TAG_TABLE_END
  1056. };
  1057. static tag_info_array tag_table_VND_PENTAX = {
  1058. { 0x0000, "Version"},
  1059. { 0x0001, "Mode"},
  1060. { 0x0002, "PreviewResolution"},
  1061. { 0x0003, "PreviewLength"},
  1062. { 0x0004, "PreviewOffset"},
  1063. { 0x0005, "ModelID"},
  1064. { 0x0006, "Date"},
  1065. { 0x0007, "Time"},
  1066. { 0x0008, "Quality"},
  1067. { 0x0009, "Size"},
  1068. { 0x000c, "Flash"},
  1069. { 0x000d, "Focus"},
  1070. { 0x000e, "AFPoint"},
  1071. { 0x000f, "AFPointInFocus"},
  1072. { 0x0012, "ExposureTime"},
  1073. { 0x0013, "FNumber"},
  1074. { 0x0014, "ISO"},
  1075. { 0x0016, "ExposureCompensation"},
  1076. { 0x0017, "MeteringMode"},
  1077. { 0x0018, "AutoBracketing"},
  1078. { 0x0019, "WhiteBalance"},
  1079. { 0x001a, "WhiteBalanceMode"},
  1080. { 0x001b, "BlueBalance"},
  1081. { 0x001c, "RedBalance"},
  1082. { 0x001d, "FocalLength"},
  1083. { 0x001e, "DigitalZoom"},
  1084. { 0x001f, "Saturation"},
  1085. { 0x0020, "Contrast"},
  1086. { 0x0021, "Sharpness"},
  1087. { 0x0022, "Location"},
  1088. { 0x0023, "Hometown"},
  1089. { 0x0024, "Destination"},
  1090. { 0x0025, "HometownDST"},
  1091. { 0x0026, "DestinationDST"},
  1092. { 0x0027, "DSPFirmwareVersion"},
  1093. { 0x0028, "CPUFirmwareVersion"},
  1094. { 0x0029, "FrameNumber"},
  1095. { 0x002d, "EffectiveLV"},
  1096. { 0x0032, "ImageProcessing"},
  1097. { 0x0033, "PictureMode"},
  1098. { 0x0034, "DriveMode"},
  1099. { 0x0037, "ColorSpace"},
  1100. { 0x0038, "ImageAreaOffset"},
  1101. { 0x0039, "RawImageSize"},
  1102. { 0x003e, "PreviewImageBorders"},
  1103. { 0x003f, "LensType"},
  1104. { 0x0040, "SensitivityAdjust"},
  1105. { 0x0041, "DigitalFilter"},
  1106. { 0x0047, "Temperature"},
  1107. { 0x0048, "AELock"},
  1108. { 0x0049, "NoiseReduction"},
  1109. { 0x004d, "FlashExposureCompensation"},
  1110. { 0x004f, "ImageTone"},
  1111. { 0x0050, "ColorTemperature"},
  1112. { 0x005c, "ShakeReduction"},
  1113. { 0x005d, "ShutterCount"},
  1114. { 0x0069, "DynamicRangeExpansion"},
  1115. { 0x0071, "HighISONoiseReduction"},
  1116. { 0x0072, "AFAdjustment"},
  1117. { 0x0200, "BlackPoint"},
  1118. { 0x0201, "WhitePoint"},
  1119. { 0x0205, "ShotInfo"},
  1120. { 0x0206, "AEInfo"},
  1121. { 0x0207, "LensInfo"},
  1122. { 0x0208, "FlashInfo"},
  1123. { 0x0209, "AEMeteringSegments"},
  1124. { 0x020a, "FlashADump"},
  1125. { 0x020b, "FlashBDump"},
  1126. { 0x020d, "WB_RGGBLevelsDaylight"},
  1127. { 0x020e, "WB_RGGBLevelsShade"},
  1128. { 0x020f, "WB_RGGBLevelsCloudy"},
  1129. { 0x0210, "WB_RGGBLevelsTungsten"},
  1130. { 0x0211, "WB_RGGBLevelsFluorescentD"},
  1131. { 0x0212, "WB_RGGBLevelsFluorescentN"},
  1132. { 0x0213, "WB_RGGBLevelsFluorescentW"},
  1133. { 0x0214, "WB_RGGBLevelsFlash"},
  1134. { 0x0215, "CameraInfo"},
  1135. { 0x0216, "BatteryInfo"},
  1136. { 0x021f, "AFInfo"},
  1137. { 0x0222, "ColorInfo"},
  1138. { 0x0229, "SerialNumber"},
  1139. TAG_TABLE_END
  1140. };
  1141. static tag_info_array tag_table_VND_MINOLTA = {
  1142. { 0x0000, "Version"},
  1143. { 0x0001, "CameraSettingsStdOld"},
  1144. { 0x0003, "CameraSettingsStdNew"},
  1145. { 0x0004, "CameraSettings7D"},
  1146. { 0x0018, "ImageStabilizationData"},
  1147. { 0x0020, "WBInfoA100"},
  1148. { 0x0040, "CompressedImageSize"},
  1149. { 0x0081, "Thumbnail"},
  1150. { 0x0088, "ThumbnailOffset"},
  1151. { 0x0089, "ThumbnailLength"},
  1152. { 0x0100, "SceneMode"},
  1153. { 0x0101, "ColorMode"},
  1154. { 0x0102, "Quality"},
  1155. { 0x0104, "FlashExposureComp"},
  1156. { 0x0105, "Teleconverter"},
  1157. { 0x0107, "ImageStabilization"},
  1158. { 0x0109, "RawAndJpgRecording"},
  1159. { 0x010a, "ZoneMatching"},
  1160. { 0x010b, "ColorTemperature"},
  1161. { 0x010c, "LensID"},
  1162. { 0x0111, "ColorCompensationFilter"},
  1163. { 0x0112, "WhiteBalanceFineTune"},
  1164. { 0x0113, "ImageStabilizationA100"},
  1165. { 0x0114, "CameraSettings5D"},
  1166. { 0x0115, "WhiteBalance"},
  1167. { 0x0e00, "PrintIM"},
  1168. { 0x0f00, "CameraSettingsZ1"},
  1169. TAG_TABLE_END
  1170. };
  1171. static tag_info_array tag_table_VND_SIGMA = {
  1172. { 0x0002, "SerialNumber"},
  1173. { 0x0003, "DriveMode"},
  1174. { 0x0004, "ResolutionMode"},
  1175. { 0x0005, "AutofocusMode"},
  1176. { 0x0006, "FocusSetting"},
  1177. { 0x0007, "WhiteBalance"},
  1178. { 0x0008, "ExposureMode"},
  1179. { 0x0009, "MeteringMode"},
  1180. { 0x000a, "LensRange"},
  1181. { 0x000b, "ColorSpace"},
  1182. { 0x000c, "Exposure"},
  1183. { 0x000d, "Contrast"},
  1184. { 0x000e, "Shadow"},
  1185. { 0x000f, "Highlight"},
  1186. { 0x0010, "Saturation"},
  1187. { 0x0011, "Sharpness"},
  1188. { 0x0012, "FillLight"},
  1189. { 0x0014, "ColorAdjustment"},
  1190. { 0x0015, "AdjustmentMode"},
  1191. { 0x0016, "Quality"},
  1192. { 0x0017, "Firmware"},
  1193. { 0x0018, "Software"},
  1194. { 0x0019, "AutoBracket"},
  1195. TAG_TABLE_END
  1196. };
  1197. static tag_info_array tag_table_VND_KYOCERA = {
  1198. { 0x0001, "FormatThumbnail"},
  1199. { 0x0E00, "PrintImageMatchingInfo"},
  1200. TAG_TABLE_END
  1201. };
  1202. static tag_info_array tag_table_VND_RICOH = {
  1203. { 0x0001, "MakerNoteDataType"},
  1204. { 0x0002, "Version"},
  1205. { 0x0E00, "PrintImageMatchingInfo"},
  1206. { 0x2001, "RicohCameraInfoMakerNoteSubIFD"},
  1207. TAG_TABLE_END
  1208. };
  1209. typedef enum mn_byte_order_t {
  1210. MN_ORDER_INTEL = 0,
  1211. MN_ORDER_MOTOROLA = 1,
  1212. MN_ORDER_NORMAL
  1213. } mn_byte_order_t;
  1214. typedef enum mn_offset_mode_t {
  1215. MN_OFFSET_NORMAL,
  1216. MN_OFFSET_MAKER
  1217. } mn_offset_mode_t;
  1218. typedef struct {
  1219. tag_table_type tag_table;
  1220. char * make;
  1221. char * id_string;
  1222. int id_string_len;
  1223. int offset;
  1224. mn_byte_order_t byte_order;
  1225. mn_offset_mode_t offset_mode;
  1226. } maker_note_type;
  1227. /* Remember to update PHP_MINFO if updated */
  1228. static const maker_note_type maker_note_array[] = {
  1229. { tag_table_VND_CANON, "Canon", NULL, 0, 0, MN_ORDER_INTEL, MN_OFFSET_NORMAL},
  1230. { tag_table_VND_CASIO, "CASIO", NULL, 0, 0, MN_ORDER_MOTOROLA, MN_OFFSET_NORMAL},
  1231. { tag_table_VND_FUJI, "FUJIFILM", "FUJIFILM\x0C\x00\x00\x00", 12, 12, MN_ORDER_INTEL, MN_OFFSET_MAKER},
  1232. { tag_table_VND_NIKON, "NIKON", "Nikon\x00\x01\x00", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1233. { tag_table_VND_NIKON_990, "NIKON", NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1234. { tag_table_VND_OLYMPUS, "OLYMPUS OPTICAL CO.,LTD", "OLYMP\x00\x01\x00", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1235. { tag_table_VND_SAMSUNG, "SAMSUNG", NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1236. { tag_table_VND_PANASONIC, "Panasonic", "Panasonic\x00\x00\x00", 12, 12, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1237. { tag_table_VND_DJI, "DJI", NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1238. { tag_table_VND_SONY, "SONY", "SONY DSC \x00\x00\x00", 12, 12, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1239. { tag_table_VND_SONY, "SONY", NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1240. { tag_table_VND_PENTAX, "PENTAX", "AOC\x00", 6, 6, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1241. { tag_table_VND_MINOLTA, "Minolta, KONICA MINOLTA", NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1242. { tag_table_VND_SIGMA, "SIGMA, FOVEON", "SIGMA\x00\x00\x00", 10, 10, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1243. { tag_table_VND_SIGMA, "SIGMA, FOVEON", "FOVEON\x00\x00\x00", 10, 10, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1244. { tag_table_VND_KYOCERA, "KYOCERA, CONTAX", "KYOCERA \x00\x00\x00", 22, 22, MN_ORDER_NORMAL, MN_OFFSET_MAKER},
  1245. { tag_table_VND_RICOH, "RICOH", "Ricoh", 5, 5, MN_ORDER_MOTOROLA, MN_OFFSET_NORMAL},
  1246. { tag_table_VND_RICOH, "RICOH", "RICOH", 5, 5, MN_ORDER_MOTOROLA, MN_OFFSET_NORMAL},
  1247. /* These re-uses existing formats */
  1248. { tag_table_VND_OLYMPUS, "AGFA", "AGFA \x00\x01", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},
  1249. { tag_table_VND_OLYMPUS, "EPSON", "EPSON\x00\x01\x00", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}
  1250. };
  1251. /* }}} */
  1252. static HashTable *exif_make_tag_ht(tag_info_type *tag_table)
  1253. {
  1254. HashTable *ht = malloc(sizeof(HashTable));
  1255. zend_hash_init(ht, 0, NULL, NULL, 1);
  1256. while (tag_table->Tag != TAG_END_OF_LIST) {
  1257. if (!zend_hash_index_add_ptr(ht, tag_table->Tag, tag_table->Desc)) {
  1258. zend_error(E_CORE_ERROR, "Duplicate tag %x", tag_table->Tag);
  1259. }
  1260. tag_table++;
  1261. }
  1262. return ht;
  1263. }
  1264. static void exif_tag_ht_dtor(zval *zv)
  1265. {
  1266. HashTable *ht = Z_PTR_P(zv);
  1267. zend_hash_destroy(ht);
  1268. free(ht);
  1269. }
  1270. static HashTable *exif_get_tag_ht(tag_info_type *tag_table)
  1271. {
  1272. HashTable *ht;
  1273. if (!EXIF_G(tag_table_cache)) {
  1274. EXIF_G(tag_table_cache) = malloc(sizeof(HashTable));
  1275. zend_hash_init(EXIF_G(tag_table_cache), 0, NULL, exif_tag_ht_dtor, 1);
  1276. }
  1277. ht = zend_hash_index_find_ptr(EXIF_G(tag_table_cache), (uintptr_t) tag_table);
  1278. if (ht) {
  1279. return ht;
  1280. }
  1281. ht = exif_make_tag_ht(tag_table);
  1282. zend_hash_index_add_new_ptr(EXIF_G(tag_table_cache), (uintptr_t) tag_table, ht);
  1283. return ht;
  1284. }
  1285. /* {{{ exif_get_tagname
  1286. Get headername for tag_num or NULL if not defined */
  1287. static char *exif_get_tagname(int tag_num, tag_table_type tag_table)
  1288. {
  1289. return zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
  1290. }
  1291. /* }}} */
  1292. static char *exif_get_tagname_debug(int tag_num, tag_table_type tag_table)
  1293. {
  1294. char *desc = zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
  1295. if (desc) {
  1296. return desc;
  1297. }
  1298. return "UndefinedTag";
  1299. }
  1300. static char *exif_get_tagname_key(int tag_num, char *buf, size_t buf_size, tag_table_type tag_table)
  1301. {
  1302. char *desc = zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
  1303. if (desc) {
  1304. return desc;
  1305. }
  1306. snprintf(buf, buf_size, "UndefinedTag:0x%04X", tag_num);
  1307. return buf;
  1308. }
  1309. /* {{{ exif_char_dump
  1310. * Do not use! This is a debug function... */
  1311. #ifdef EXIF_DEBUG
  1312. static unsigned char* exif_char_dump(unsigned char * addr, int len, int offset)
  1313. {
  1314. static unsigned char buf[4096+1];
  1315. static unsigned char tmp[20];
  1316. int c, i, p=0, n = 5+31;
  1317. p += slprintf(buf+p, sizeof(buf)-p, "\nDump Len: %08X (%d)", len, len);
  1318. if (len) {
  1319. for(i=0; i<len+15 && p+n<=sizeof(buf); i++) {
  1320. if (i%16==0) {
  1321. p += slprintf(buf+p, sizeof(buf)-p, "\n%08X: ", i+offset);
  1322. }
  1323. if (i<len) {
  1324. c = *addr++;
  1325. p += slprintf(buf+p, sizeof(buf)-p, "%02X ", c);
  1326. tmp[i%16] = c>=32 ? c : '.';
  1327. tmp[(i%16)+1] = '\0';
  1328. } else {
  1329. p += slprintf(buf+p, sizeof(buf)-p, " ");
  1330. }
  1331. if (i%16==15) {
  1332. p += slprintf(buf+p, sizeof(buf)-p, " %s", tmp);
  1333. if (i>=len) {
  1334. break;
  1335. }
  1336. }
  1337. }
  1338. }
  1339. buf[sizeof(buf)-1] = '\0';
  1340. return buf;
  1341. }
  1342. #endif
  1343. /* }}} */
  1344. /* {{{ php_jpg_get16
  1345. Get 16 bits motorola order (always) for jpeg header stuff.
  1346. */
  1347. static int php_jpg_get16(void *value)
  1348. {
  1349. return (((uchar *)value)[0] << 8) | ((uchar *)value)[1];
  1350. }
  1351. /* }}} */
  1352. /* {{{ php_ifd_get16u
  1353. * Convert a 16 bit unsigned value from file's native byte order */
  1354. static int php_ifd_get16u(void *value, int motorola_intel)
  1355. {
  1356. if (motorola_intel) {
  1357. return (((uchar *)value)[0] << 8) | ((uchar *)value)[1];
  1358. } else {
  1359. return (((uchar *)value)[1] << 8) | ((uchar *)value)[0];
  1360. }
  1361. }
  1362. /* }}} */
  1363. /* {{{ php_ifd_get16s
  1364. * Convert a 16 bit signed value from file's native byte order */
  1365. static signed short php_ifd_get16s(void *value, int motorola_intel)
  1366. {
  1367. return (signed short)php_ifd_get16u(value, motorola_intel);
  1368. }
  1369. /* }}} */
  1370. /* {{{ php_ifd_get32u
  1371. * Convert a 32 bit unsigned value from file's native byte order */
  1372. static unsigned php_ifd_get32u(void *void_value, int motorola_intel)
  1373. {
  1374. uchar *value = (uchar *) void_value;
  1375. if (motorola_intel) {
  1376. return ((unsigned)value[0] << 24)
  1377. | ((unsigned)value[1] << 16)
  1378. | ((unsigned)value[2] << 8 )
  1379. | ((unsigned)value[3] );
  1380. } else {
  1381. return ((unsigned)value[3] << 24)
  1382. | ((unsigned)value[2] << 16)
  1383. | ((unsigned)value[1] << 8 )
  1384. | ((unsigned)value[0] );
  1385. }
  1386. }
  1387. /* }}} */
  1388. /* {{{ php_ifd_get64u
  1389. * Convert a 64 bit unsigned value from file's native byte order */
  1390. static uint64_t php_ifd_get64u(void *void_value, int motorola_intel)
  1391. {
  1392. uchar *value = (uchar *) void_value;
  1393. if (motorola_intel) {
  1394. return ((uint64_t)value[0] << 56)
  1395. | ((uint64_t)value[1] << 48)
  1396. | ((uint64_t)value[2] << 40)
  1397. | ((uint64_t)value[3] << 32)
  1398. | ((uint64_t)value[4] << 24)
  1399. | ((uint64_t)value[5] << 16)
  1400. | ((uint64_t)value[6] << 8 )
  1401. | ((uint64_t)value[7] );
  1402. } else {
  1403. return ((uint64_t)value[7] << 56)
  1404. | ((uint64_t)value[6] << 48)
  1405. | ((uint64_t)value[5] << 40)
  1406. | ((uint64_t)value[4] << 32)
  1407. | ((uint64_t)value[3] << 24)
  1408. | ((uint64_t)value[2] << 16)
  1409. | ((uint64_t)value[1] << 8 )
  1410. | ((uint64_t)value[0] );
  1411. }
  1412. }
  1413. /* }}} */
  1414. /* {{{ php_ifd_get32u
  1415. * Convert a 32 bit signed value from file's native byte order */
  1416. static unsigned php_ifd_get32s(void *value, int motorola_intel)
  1417. {
  1418. return (int) php_ifd_get32u(value, motorola_intel);
  1419. }
  1420. /* }}} */
  1421. /* {{{ php_ifd_set16u
  1422. * Write 16 bit unsigned value to data */
  1423. static void php_ifd_set16u(char *data, unsigned int value, int motorola_intel)
  1424. {
  1425. if (motorola_intel) {
  1426. data[0] = (value & 0xFF00) >> 8;
  1427. data[1] = (value & 0x00FF);
  1428. } else {
  1429. data[1] = (value & 0xFF00) >> 8;
  1430. data[0] = (value & 0x00FF);
  1431. }
  1432. }
  1433. /* }}} */
  1434. /* {{{ php_ifd_set32u
  1435. * Convert a 32 bit unsigned value from file's native byte order */
  1436. static void php_ifd_set32u(char *data, size_t value, int motorola_intel)
  1437. {
  1438. if (motorola_intel) {
  1439. data[0] = (value & 0xFF000000) >> 24;
  1440. dat

Large files files are truncated, but you can click here to view the full file