📄 exif.c
字号:
int count; image_info_data *list;} image_info_list;/* }}} *//* {{{ exif_get_sectionname Returns the name of a section*/#define SECTION_FILE 0#define SECTION_COMPUTED 1#define SECTION_ANY_TAG 2#define SECTION_IFD0 3#define SECTION_THUMBNAIL 4#define SECTION_COMMENT 5#define SECTION_APP0 6#define SECTION_EXIF 7#define SECTION_FPIX 8#define SECTION_GPS 9#define SECTION_INTEROP 10#define SECTION_APP12 11#define SECTION_WINXP 12#define SECTION_MAKERNOTE 13#define SECTION_COUNT 14#define FOUND_FILE (1<<SECTION_FILE)#define FOUND_COMPUTED (1<<SECTION_COMPUTED)#define FOUND_ANY_TAG (1<<SECTION_ANY_TAG)#define FOUND_IFD0 (1<<SECTION_IFD0)#define FOUND_THUMBNAIL (1<<SECTION_THUMBNAIL)#define FOUND_COMMENT (1<<SECTION_COMMENT)#define FOUND_APP0 (1<<SECTION_APP0)#define FOUND_EXIF (1<<SECTION_EXIF)#define FOUND_FPIX (1<<SECTION_FPIX)#define FOUND_GPS (1<<SECTION_GPS)#define FOUND_INTEROP (1<<SECTION_INTEROP)#define FOUND_APP12 (1<<SECTION_APP12)#define FOUND_WINXP (1<<SECTION_WINXP)#define FOUND_MAKERNOTE (1<<SECTION_MAKERNOTE)static char *exif_get_sectionname(int section){ switch(section) { case SECTION_FILE: return "FILE"; case SECTION_COMPUTED: return "COMPUTED"; case SECTION_ANY_TAG: return "ANY_TAG"; case SECTION_IFD0: return "IFD0"; case SECTION_THUMBNAIL: return "THUMBNAIL"; case SECTION_COMMENT: return "COMMENT"; case SECTION_APP0: return "APP0"; case SECTION_EXIF: return "EXIF"; case SECTION_FPIX: return "FPIX"; case SECTION_GPS: return "GPS"; case SECTION_INTEROP: return "INTEROP"; case SECTION_APP12: return "APP12"; case SECTION_WINXP: return "WINXP"; case SECTION_MAKERNOTE: return "MAKERNOTE"; } return "";}static tag_table_type exif_get_tag_table(int section){ switch(section) { case SECTION_FILE: return &tag_table_IFD[0]; case SECTION_COMPUTED: return &tag_table_IFD[0]; case SECTION_ANY_TAG: return &tag_table_IFD[0]; case SECTION_IFD0: return &tag_table_IFD[0]; case SECTION_THUMBNAIL: return &tag_table_IFD[0]; case SECTION_COMMENT: return &tag_table_IFD[0]; case SECTION_APP0: return &tag_table_IFD[0]; case SECTION_EXIF: return &tag_table_IFD[0]; case SECTION_FPIX: return &tag_table_IFD[0]; case SECTION_GPS: return &tag_table_GPS[0]; case SECTION_INTEROP: return &tag_table_IOP[0]; case SECTION_APP12: return &tag_table_IFD[0]; case SECTION_WINXP: return &tag_table_IFD[0]; } return &tag_table_IFD[0];}/* }}} *//* {{{ exif_get_sectionlist Return list of sectionnames specified by sectionlist. Return value must be freed*/static char *exif_get_sectionlist(int sectionlist TSRMLS_DC){ int i, len=0; char *sections; for(i=0; i<SECTION_COUNT; i++) { len += strlen(exif_get_sectionname(i))+2; } sections = safe_emalloc(len, 1, 1); sections[0] = '\0'; len = 0; for(i=0; i<SECTION_COUNT; i++) { if (sectionlist&(1<<i)) { sprintf(sections+len, "%s, ", exif_get_sectionname(i)); len = strlen(sections); } } if (len>2) sections[len-2] = '\0'; return sections;}/* }}} *//* {{{ struct image_info_type This structure stores Exif header image elements in a simple manner Used to store camera data as extracted from the various ways that it can be stored in a nexif header*/typedef struct { int type; size_t size; uchar *data;} file_section;typedef struct { int count; file_section *list;} file_section_list;typedef struct { image_filetype filetype; size_t width, height; size_t size; size_t offset; char *data;} thumbnail_data;typedef struct { char *value; size_t size; int tag;} xp_field_type;typedef struct { int count; xp_field_type *list;} xp_field_list;/* This structure is used to store a section of a Jpeg file. */typedef struct { php_stream *infile; char *FileName; time_t FileDateTime; size_t FileSize; image_filetype FileType; int Height, Width; int IsColor; char *make; char *model; float ApertureFNumber; float ExposureTime; double FocalplaneUnits; float CCDWidth; double FocalplaneXRes; size_t ExifImageWidth; float FocalLength; float Distance; int motorola_intel; /* 1 Motorola; 0 Intel */ char *UserComment; int UserCommentLength; char *UserCommentEncoding; char *encode_unicode; char *decode_unicode_be; char *decode_unicode_le; char *encode_jis; char *decode_jis_be; char *decode_jis_le; char *Copyright;/* EXIF standard defines Copyright as "<Photographer> [ '\0' <Editor> ] ['\0']" */ char *CopyrightPhotographer; char *CopyrightEditor; xp_field_list xp_fields; thumbnail_data Thumbnail; /* other */ int sections_found; /* FOUND_<marker> */ image_info_list info_list[SECTION_COUNT]; /* for parsing */ int read_thumbnail; int read_all; int ifd_nesting_level; /* internal */ file_section_list file;} image_info_type;/* }}} *//* {{{ exif_error_docref */static void exif_error_docref(const char *docref TSRMLS_DC, const image_info_type *ImageInfo, int type, const char *format, ...){ va_list args; va_start(args, format); php_verror(docref, ImageInfo->FileName?ImageInfo->FileName:"", type, format, args TSRMLS_CC); va_end(args);}/* }}} *//* {{{ jpeg_sof_info */typedef struct { int bits_per_sample; size_t width; size_t height; int num_components;} jpeg_sof_info;/* }}} *//* {{{ exif_file_sections_add Add a file_section to image_info returns the used block or -1. if size>0 and data == NULL buffer of size is allocated*/static int exif_file_sections_add(image_info_type *ImageInfo, int type, size_t size, uchar *data){ file_section *tmp; int count = ImageInfo->file.count; tmp = erealloc(ImageInfo->file.list, (count+1)*sizeof(file_section)); ImageInfo->file.list = tmp; ImageInfo->file.list[count].type = 0xFFFF; ImageInfo->file.list[count].data = NULL; ImageInfo->file.list[count].size = 0; ImageInfo->file.count = count+1; if (!size) { data = NULL; } else if (data == NULL) { data = emalloc(size); } ImageInfo->file.list[count].type = type; ImageInfo->file.list[count].data = data; ImageInfo->file.list[count].size = size; return count;}/* }}} *//* {{{ exif_file_sections_realloc Reallocate a file section returns 0 on success and -1 on failure*/static int exif_file_sections_realloc(image_info_type *ImageInfo, int section_index, size_t size TSRMLS_DC){ void *tmp; /* This is not a malloc/realloc check. It is a plausibility check for the * function parameters (requirements engineering). */ if (section_index >= ImageInfo->file.count) { EXIF_ERRLOG_FSREALLOC return -1; } tmp = erealloc(ImageInfo->file.list[section_index].data, size); ImageInfo->file.list[section_index].data = tmp; ImageInfo->file.list[section_index].size = size; return 0;}/* }}} *//* {{{ exif_file_section_free Discard all file_sections in ImageInfo*/static int exif_file_sections_free(image_info_type *ImageInfo){ int i; if (ImageInfo->file.count) { for (i=0; i<ImageInfo->file.count; i++) { EFREE_IF(ImageInfo->file.list[i].data); } } EFREE_IF(ImageInfo->file.list); ImageInfo->file.count = 0; return TRUE;}/* }}} *//* {{{ exif_iif_add_value Add a value to image_info*/static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, int motorola_intel TSRMLS_DC){ size_t idex; void *vptr; image_info_value *info_value; image_info_data *info_data; image_info_data *list; if (length >= LONG_MAX) { return; } list = erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1)*sizeof(image_info_data)); image_info->info_list[section_index].list = list; info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count]; memset(info_data, 0, sizeof(image_info_data)); info_data->tag = tag; info_data->format = format; info_data->length = length; info_data->name = estrdup(name); info_value = &info_data->value; switch (format) { case TAG_FMT_STRING: if (value) { length = php_strnlen(value, length); if (PG(magic_quotes_runtime)) { info_value->s = php_addslashes(value, length, &length, 0 TSRMLS_CC); } else { info_value->s = estrndup(value, length); } info_data->length = length; } else { info_data->length = 0; info_value->s = estrdup(""); } break; default: /* Standard says more types possible but skip them... * but allow users to handle data if they know how to * So not return but use type UNDEFINED * return; */ info_data->tag = TAG_FMT_UNDEFINED;/* otherwise not freed from memory */ case TAG_FMT_SBYTE: case TAG_FMT_BYTE: /* in contrast to strings bytes do not need to allocate buffer for NULL if length==0 */ if (!length) break; case TAG_FMT_UNDEFINED: if (value) { /* do not recompute length here */ if (PG(magic_quotes_runtime)) { info_value->s = php_addslashes(value, length, &length, 0 TSRMLS_CC); } else { info_value->s = estrndup(value, length); } info_data->length = length; } else { info_data->length = 0; info_value->s = estrdup(""); } break; case TAG_FMT_USHORT: case TAG_FMT_ULONG: case TAG_FMT_URATIONAL: case TAG_FMT_SSHORT: case TAG_FMT_SLONG: case TAG_FMT_SRATIONAL: case TAG_FMT_SINGLE: case TAG_FMT_DOUBLE: if (length==0) { break; } else if (length>1) { info_value->list = safe_emalloc(length, sizeof(image_info_value), 0); } else { info_value = &info_data->value; } for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) { if (length>1) { info_value = &info_data->value.list[idex]; } switch (format) { case TAG_FMT_USHORT: info_value->u = php_ifd_get16u(vptr, motorola_intel); break; case TAG_FMT_ULONG: info_value->u = php_ifd_get32u(vptr, motorola_intel); break; case TAG_FMT_URATIONAL: info_value->ur.num = php_ifd_get32u(vptr, motorola_intel); info_value->ur.den = php_ifd_get32u(4+(char *)vptr, motorola_intel); break; case TAG_FMT_SSHORT: info_value->i = php_ifd_get16s(vptr, motorola_intel); break; case TAG_FMT_SLONG: info_value->i = php_ifd_get32s(vptr, motorola_intel); break; case TAG_FMT_SRATIONAL: info_value->sr.num = php_ifd_get32u(vptr, motorola_intel); info_value->sr.den = php_ifd_get32u(4+(char *)vptr, motorola_intel); break; case TAG_FMT_SINGLE:#ifdef EXIF_DEBUG php_error_docref(NULL TSRMLS_CC, E_WARNING, "Found value of type single");#endif info_value->f = *(float *)value; case TAG_FMT_DOUBLE:#ifdef EXIF_DEBUG php_error_docref(NULL TSRMLS_CC, E_WARNING, "Found value of type double");#endif info_value->d = *(double *)value; break; } } } image_info->sections_found |= 1<<section_index; image_info->info_list[section_index].count++;}/* }}} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -