📄 exif.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf <rasmus@php.net> | | Marcus Boerger <helly@php.net> | +----------------------------------------------------------------------+ *//* $Id: exif.c,v 1.118.2.37.2.7 2007/01/09 11:38:04 tony2001 Exp $ *//* ToDos * * See if example images from http://www.exif.org have illegal * thumbnail sizes or if code is corrupt. * Create/Update exif headers. * Create/Remove/Update image thumbnails. *//* Security * * At current time i do not see any security problems but a potential * attacker could generate an image with recursive ifd pointers...(Marcus) */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "ext/standard/file.h"#if HAVE_EXIF/* When EXIF_DEBUG is defined the module generates a lot of debug messages * that help understanding what is going on. This can and should be used * while extending the module as it shows if you are at the right position. * You are always considered to have a copy of TIFF6.0 and EXIF2.10 standard. */#undef EXIF_DEBUG#undef EXIF_JPEG2000#include "php_exif.h"#include <math.h>#include "php_ini.h"#include "ext/standard/php_string.h"#include "ext/standard/php_image.h"#include "ext/standard/info.h" #if defined(PHP_WIN32) || (HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING))#define EXIF_USE_MBSTRING 1#else#define EXIF_USE_MBSTRING 0#endif#if EXIF_USE_MBSTRING#include "ext/mbstring/mbstring.h"#endif/* needed for ssize_t definition */#include <sys/types.h>#if defined(PHP_WIN32) && !defined(ssize_t)typedef SSIZE_T ssize_t;#endiftypedef unsigned char uchar;#ifndef safe_emalloc# define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))#endif#ifndef TRUE# define TRUE 1# define FALSE 0#endif#ifndef max# define max(a,b) ((a)>(b) ? (a) : (b))#endif#define EFREE_IF(ptr) if (ptr) efree(ptr)#define MAX_IFD_NESTING_LEVEL 100static unsigned char exif_thumbnail_force_ref[] = {2, BYREF_NONE, BYREF_FORCE_REST};/* {{{ exif_functions[] */function_entry exif_functions[] = { PHP_FE(exif_read_data, NULL) PHP_FALIAS(read_exif_data, exif_read_data, NULL) PHP_FE(exif_tagname, NULL) PHP_FE(exif_thumbnail, exif_thumbnail_force_ref) PHP_FE(exif_imagetype, NULL) {NULL, NULL, NULL}};/* }}} */#define EXIF_VERSION "1.4 $Id: exif.c,v 1.118.2.37.2.7 2007/01/09 11:38:04 tony2001 Exp $"/* {{{ PHP_MINFO_FUNCTION */PHP_MINFO_FUNCTION(exif){ php_info_print_table_start(); php_info_print_table_row(2, "EXIF Support", "enabled"); php_info_print_table_row(2, "EXIF Version", EXIF_VERSION); php_info_print_table_row(2, "Supported EXIF Version", "0220"); php_info_print_table_row(2, "Supported filetypes", "JPEG,TIFF"); php_info_print_table_end();}/* }}} */ZEND_BEGIN_MODULE_GLOBALS(exif) char * encode_unicode; char * decode_unicode_be; char * decode_unicode_le; char * encode_jis; char * decode_jis_be; char * decode_jis_le;ZEND_END_MODULE_GLOBALS(exif) ZEND_DECLARE_MODULE_GLOBALS(exif)#ifdef ZTS#define EXIF_G(v) TSRMG(exif_globals_id, zend_exif_globals *, v)#else#define EXIF_G(v) (exif_globals.v)#endif /* {{{ PHP_INI */ZEND_INI_MH(OnUpdateEncode){#if EXIF_USE_MBSTRING if (new_value && strlen(new_value) && !php_mb_check_encoding_list(new_value TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal encoding ignored: '%s'", new_value); return FAILURE; }#endif return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);}ZEND_INI_MH(OnUpdateDecode){#if EXIF_USE_MBSTRING if (!php_mb_check_encoding_list(new_value TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal encoding ignored: '%s'", new_value); return FAILURE; }#endif return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);}PHP_INI_BEGIN() STD_PHP_INI_ENTRY("exif.encode_unicode", "ISO-8859-15", PHP_INI_ALL, OnUpdateEncode, encode_unicode, zend_exif_globals, exif_globals) STD_PHP_INI_ENTRY("exif.decode_unicode_motorola", "UCS-2BE", PHP_INI_ALL, OnUpdateDecode, decode_unicode_be, zend_exif_globals, exif_globals) STD_PHP_INI_ENTRY("exif.decode_unicode_intel", "UCS-2LE", PHP_INI_ALL, OnUpdateDecode, decode_unicode_le, zend_exif_globals, exif_globals) STD_PHP_INI_ENTRY("exif.encode_jis", "", PHP_INI_ALL, OnUpdateEncode, encode_jis, zend_exif_globals, exif_globals) STD_PHP_INI_ENTRY("exif.decode_jis_motorola", "JIS", PHP_INI_ALL, OnUpdateDecode, decode_jis_be, zend_exif_globals, exif_globals) STD_PHP_INI_ENTRY("exif.decode_jis_intel", "JIS", PHP_INI_ALL, OnUpdateDecode, decode_jis_le, zend_exif_globals, exif_globals)PHP_INI_END()/* }}} */ /* {{{ php_extname_init_globals */static void php_exif_init_globals(zend_exif_globals *exif_globals){ exif_globals->encode_unicode = NULL; exif_globals->decode_unicode_be = NULL; exif_globals->decode_unicode_le = NULL; exif_globals->encode_jis = NULL; exif_globals->decode_jis_be = NULL; exif_globals->decode_jis_le = NULL;}/* }}} *//* {{{ PHP_MINIT_FUNCTION(exif) Get the size of an image as 4-element array */PHP_MINIT_FUNCTION(exif){ ZEND_INIT_MODULE_GLOBALS(exif, php_exif_init_globals, NULL); REGISTER_INI_ENTRIES(); REGISTER_LONG_CONSTANT("EXIF_USE_MBSTRING", EXIF_USE_MBSTRING, CONST_CS | CONST_PERSISTENT); return SUCCESS;}/* }}} *//* {{{ PHP_MSHUTDOWN_FUNCTION */PHP_MSHUTDOWN_FUNCTION(exif){ UNREGISTER_INI_ENTRIES(); return SUCCESS;}/* }}} *//* {{{ exif_module_entry */zend_module_entry exif_module_entry = {#if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER,#endif "exif", exif_functions, PHP_MINIT(exif), PHP_MSHUTDOWN(exif), NULL, NULL, PHP_MINFO(exif),#if ZEND_MODULE_API_NO >= 20010901 EXIF_VERSION,#endif STANDARD_MODULE_PROPERTIES};/* }}} */#ifdef COMPILE_DL_EXIFZEND_GET_MODULE(exif)#endif/* {{{ php_strnlen * get length of string if buffer if less than buffer size or buffer size */static size_t php_strnlen(char* str, size_t maxlen) { size_t len = 0; if (str && maxlen && *str) { do { len++; } while (--maxlen && *(++str)); } return len;}/* }}} *//* {{{ error messages*/static const char * EXIF_ERROR_FILEEOF = "Unexpected end of file reached";static const char * EXIF_ERROR_CORRUPT = "File structure corrupted";static const char * EXIF_ERROR_THUMBEOF = "Thumbnail goes IFD boundary or end of file reached";static const char * EXIF_ERROR_FSREALLOC = "Illegal reallocating of undefined file section";#define EXIF_ERRLOG_FILEEOF php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", EXIF_ERROR_FILEEOF);#define EXIF_ERRLOG_CORRUPT php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", EXIF_ERROR_CORRUPT);#define EXIF_ERRLOG_THUMBEOF php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", EXIF_ERROR_THUMBEOF);#define EXIF_ERRLOG_FSREALLOC php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", EXIF_ERROR_FSREALLOC);/* }}} *//* {{{ format description defines Describes format descriptor*/static int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1};#define NUM_FORMATS 13#define TAG_FMT_BYTE 1#define TAG_FMT_STRING 2#define TAG_FMT_USHORT 3#define TAG_FMT_ULONG 4#define TAG_FMT_URATIONAL 5#define TAG_FMT_SBYTE 6#define TAG_FMT_UNDEFINED 7#define TAG_FMT_SSHORT 8#define TAG_FMT_SLONG 9#define TAG_FMT_SRATIONAL 10#define TAG_FMT_SINGLE 11#define TAG_FMT_DOUBLE 12#define TAG_FMT_IFD 13#ifdef EXIF_DEBUGstatic char *exif_get_tagformat(int format){ switch(format) { case TAG_FMT_BYTE: return "BYTE"; case TAG_FMT_STRING: return "STRING"; case TAG_FMT_USHORT: return "USHORT"; case TAG_FMT_ULONG: return "ULONG"; case TAG_FMT_URATIONAL: return "URATIONAL"; case TAG_FMT_SBYTE: return "SBYTE"; case TAG_FMT_UNDEFINED: return "UNDEFINED"; case TAG_FMT_SSHORT: return "SSHORT"; case TAG_FMT_SLONG: return "SLONG"; case TAG_FMT_SRATIONAL: return "SRATIONAL"; case TAG_FMT_SINGLE: return "SINGLE"; case TAG_FMT_DOUBLE: return "DOUBLE"; case TAG_FMT_IFD: return "IFD"; } return "*Illegal";}#endif/* Describes tag values */#define TAG_GPS_VERSION_ID 0x0000#define TAG_GPS_LATITUDE_REF 0x0001#define TAG_GPS_LATITUDE 0x0002#define TAG_GPS_LONGITUDE_REF 0x0003#define TAG_GPS_LONGITUDE 0x0004#define TAG_GPS_ALTITUDE_REF 0x0005#define TAG_GPS_ALTITUDE 0x0006#define TAG_GPS_TIME_STAMP 0x0007#define TAG_GPS_SATELLITES 0x0008#define TAG_GPS_STATUS 0x0009#define TAG_GPS_MEASURE_MODE 0x000A#define TAG_GPS_DOP 0x000B#define TAG_GPS_SPEED_REF 0x000C#define TAG_GPS_SPEED 0x000D#define TAG_GPS_TRACK_REF 0x000E#define TAG_GPS_TRACK 0x000F#define TAG_GPS_IMG_DIRECTION_REF 0x0010#define TAG_GPS_IMG_DIRECTION 0x0011#define TAG_GPS_MAP_DATUM 0x0012#define TAG_GPS_DEST_LATITUDE_REF 0x0013#define TAG_GPS_DEST_LATITUDE 0x0014#define TAG_GPS_DEST_LONGITUDE_REF 0x0015#define TAG_GPS_DEST_LONGITUDE 0x0016#define TAG_GPS_DEST_BEARING_REF 0x0017#define TAG_GPS_DEST_BEARING 0x0018#define TAG_GPS_DEST_DISTANCE_REF 0x0019#define TAG_GPS_DEST_DISTANCE 0x001A#define TAG_GPS_PROCESSING_METHOD 0x001B#define TAG_GPS_AREA_INFORMATION 0x001C#define TAG_GPS_DATE_STAMP 0x001D#define TAG_GPS_DIFFERENTIAL 0x001E#define TAG_TIFF_COMMENT 0x00FE /* SHOUDLNT HAPPEN */#define TAG_NEW_SUBFILE 0x00FE /* New version of subfile tag */#define TAG_SUBFILE_TYPE 0x00FF /* Old version of subfile tag */#define TAG_IMAGEWIDTH 0x0100#define TAG_IMAGEHEIGHT 0x0101#define TAG_BITS_PER_SAMPLE 0x0102#define TAG_COMPRESSION 0x0103#define TAG_PHOTOMETRIC_INTERPRETATION 0x0106#define TAG_TRESHHOLDING 0x0107#define TAG_CELL_WIDTH 0x0108#define TAG_CELL_HEIGHT 0x0109#define TAG_FILL_ORDER 0x010A#define TAG_DOCUMENT_NAME 0x010D#define TAG_IMAGE_DESCRIPTION 0x010E#define TAG_MAKE 0x010F#define TAG_MODEL 0x0110#define TAG_STRIP_OFFSETS 0x0111#define TAG_ORIENTATION 0x0112#define TAG_SAMPLES_PER_PIXEL 0x0115#define TAG_ROWS_PER_STRIP 0x0116#define TAG_STRIP_BYTE_COUNTS 0x0117#define TAG_MIN_SAMPPLE_VALUE 0x0118#define TAG_MAX_SAMPLE_VALUE 0x0119#define TAG_X_RESOLUTION 0x011A#define TAG_Y_RESOLUTION 0x011B#define TAG_PLANAR_CONFIGURATION 0x011C#define TAG_PAGE_NAME 0x011D#define TAG_X_POSITION 0x011E#define TAG_Y_POSITION 0x011F#define TAG_FREE_OFFSETS 0x0120#define TAG_FREE_BYTE_COUNTS 0x0121#define TAG_GRAY_RESPONSE_UNIT 0x0122#define TAG_GRAY_RESPONSE_CURVE 0x0123#define TAG_RESOLUTION_UNIT 0x0128#define TAG_PAGE_NUMBER 0x0129#define TAG_TRANSFER_FUNCTION 0x012D#define TAG_SOFTWARE 0x0131#define TAG_DATETIME 0x0132#define TAG_ARTIST 0x013B#define TAG_HOST_COMPUTER 0x013C#define TAG_PREDICTOR 0x013D#define TAG_WHITE_POINT 0x013E#define TAG_PRIMARY_CHROMATICITIES 0x013F#define TAG_COLOR_MAP 0x0140#define TAG_HALFTONE_HINTS 0x0141#define TAG_TILE_WIDTH 0x0142#define TAG_TILE_LENGTH 0x0143#define TAG_TILE_OFFSETS 0x0144#define TAG_TILE_BYTE_COUNTS 0x0145#define TAG_SUB_IFD 0x014A#define TAG_INK_SETMPUTER 0x014C#define TAG_INK_NAMES 0x014D#define TAG_NUMBER_OF_INKS 0x014E#define TAG_DOT_RANGE 0x0150#define TAG_TARGET_PRINTER 0x0151#define TAG_EXTRA_SAMPLE 0x0152#define TAG_SAMPLE_FORMAT 0x0153#define TAG_S_MIN_SAMPLE_VALUE 0x0154#define TAG_S_MAX_SAMPLE_VALUE 0x0155#define TAG_TRANSFER_RANGE 0x0156#define TAG_JPEG_TABLES 0x015B#define TAG_JPEG_PROC 0x0200#define TAG_JPEG_INTERCHANGE_FORMAT 0x0201#define TAG_JPEG_INTERCHANGE_FORMAT_LEN 0x0202#define TAG_JPEG_RESTART_INTERVAL 0x0203#define TAG_JPEG_LOSSLESS_PREDICTOR 0x0205#define TAG_JPEG_POINT_TRANSFORMS 0x0206#define TAG_JPEG_Q_TABLES 0x0207#define TAG_JPEG_DC_TABLES 0x0208#define TAG_JPEG_AC_TABLES 0x0209#define TAG_YCC_COEFFICIENTS 0x0211#define TAG_YCC_SUB_SAMPLING 0x0212#define TAG_YCC_POSITIONING 0x0213#define TAG_REFERENCE_BLACK_WHITE 0x0214/* 0x0301 - 0x0302 *//* 0x0320 *//* 0x0343 *//* 0x5001 - 0x501B *//* 0x5021 - 0x503B *//* 0x5090 - 0x5091 *//* 0x5100 - 0x5101 *//* 0x5110 - 0x5113 *//* 0x80E3 - 0x80E6 *//* 0x828d - 0x828F */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -