📄 exif.c
字号:
/* {{{ exif_iif_add_tag Add a tag from IFD to image_info*/static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value TSRMLS_DC){ exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, image_info->motorola_intel TSRMLS_CC);}/* }}} *//* {{{ exif_iif_add_int Add an int value to image_info*/static void exif_iif_add_int(image_info_type *image_info, int section_index, char *name, int value TSRMLS_DC){ image_info_data *info_data; image_info_data *list; 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]; info_data->tag = TAG_NONE; info_data->format = TAG_FMT_SLONG; info_data->length = 1; info_data->name = estrdup(name); info_data->value.i = value; image_info->sections_found |= 1<<section_index; image_info->info_list[section_index].count++;}/* }}} *//* {{{ exif_iif_add_str Add a string value to image_info MUST BE NUL TERMINATED*/static void exif_iif_add_str(image_info_type *image_info, int section_index, char *name, char *value TSRMLS_DC){ image_info_data *info_data; image_info_data *list; if (value) { 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]; info_data->tag = TAG_NONE; info_data->format = TAG_FMT_STRING; info_data->length = 1; info_data->name = estrdup(name); if (PG(magic_quotes_runtime)) { info_data->value.s = php_addslashes(value, strlen(value), NULL, 0 TSRMLS_CC); } else { info_data->value.s = estrdup(value); } image_info->sections_found |= 1<<section_index; image_info->info_list[section_index].count++; }}/* }}} *//* {{{ exif_iif_add_fmt Add a format string value to image_info MUST BE NUL TERMINATED*/static void exif_iif_add_fmt(image_info_type *image_info, int section_index, char *name TSRMLS_DC, char *value, ...){ char *tmp; va_list arglist; va_start(arglist, value); if (value) { vspprintf(&tmp, 0, value, arglist); exif_iif_add_str(image_info, section_index, name, tmp TSRMLS_CC); efree(tmp); } va_end(arglist);}/* }}} *//* {{{ exif_iif_add_str Add a string value to image_info MUST BE NUL TERMINATED*/static void exif_iif_add_buffer(image_info_type *image_info, int section_index, char *name, int length, char *value TSRMLS_DC){ image_info_data *info_data; image_info_data *list; if (value) { 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]; info_data->tag = TAG_NONE; info_data->format = TAG_FMT_UNDEFINED; info_data->length = length; info_data->name = estrdup(name); if (PG(magic_quotes_runtime)) {#ifdef EXIF_DEBUG exif_error_docref(NULL TSRMLS_CC, image_info, E_NOTICE, "Adding %s as buffer%s", name, exif_char_dump(value, length, 0));#endif info_data->value.s = php_addslashes(value, length, &length, 0 TSRMLS_CC); info_data->length = length; } else { info_data->value.s = safe_emalloc(length, 1, 1); memcpy(info_data->value.s, value, length); info_data->value.s[length] = 0; } image_info->sections_found |= 1<<section_index; image_info->info_list[section_index].count++; }}/* }}} *//* {{{ exif_iif_free Free memory allocated for image_info*/static void exif_iif_free(image_info_type *image_info, int section_index) { int i; void *f; /* faster */ if (image_info->info_list[section_index].count) { for (i=0; i < image_info->info_list[section_index].count; i++) { if ((f=image_info->info_list[section_index].list[i].name) != NULL) { efree(f); } switch(image_info->info_list[section_index].list[i].format) { 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 (image_info->info_list[section_index].list[i].length<1) break; default: case TAG_FMT_UNDEFINED: case TAG_FMT_STRING: if ((f=image_info->info_list[section_index].list[i].value.s) != NULL) { efree(f); } 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: /* nothing to do here */ if (image_info->info_list[section_index].list[i].length > 1) { if ((f=image_info->info_list[section_index].list[i].value.list) != NULL) { efree(f); } } break; } } } EFREE_IF(image_info->info_list[section_index].list);}/* }}} *//* {{{ add_assoc_image_info * Add image_info to associative array value. */static void add_assoc_image_info(pval *value, int sub_array, image_info_type *image_info, int section_index TSRMLS_DC){ char buffer[64], *val, *name, uname[64]; int i, ap, l, b, idx=0, unknown=0;#ifdef EXIF_DEBUG int info_tag;#endif image_info_value *info_value; image_info_data *info_data; pval *tmpi, *array = NULL;#ifdef EXIF_DEBUG/* php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Adding %d infos from section %s", image_info->info_list[section_index].count, exif_get_sectionname(section_index));*/#endif if (image_info->info_list[section_index].count) { if (sub_array) { MAKE_STD_ZVAL(tmpi); array_init(tmpi); } else { tmpi = value; } for(i=0; i<image_info->info_list[section_index].count; i++) { info_data = &image_info->info_list[section_index].list[i];#ifdef EXIF_DEBUG info_tag = info_data->tag; /* conversion */#endif info_value = &info_data->value; if (!(name = info_data->name)) { snprintf(uname, sizeof(uname), "%d", unknown++); name = uname; }#ifdef EXIF_DEBUG/* php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Adding infos: tag(0x%04X,%12s,L=0x%04X): %s", info_tag, exif_get_tagname(info_tag, buffer, -12, exif_get_tag_table(section_index) TSRMLS_CC), info_data->length, info_data->format==TAG_FMT_STRING?(info_value&&info_value->s?info_value->s:"<no data>"):exif_get_tagformat(info_data->format));*/#endif if (info_data->length==0) { add_assoc_null(tmpi, name); } else { switch (info_data->format) { 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; */ case TAG_FMT_BYTE: case TAG_FMT_SBYTE: case TAG_FMT_UNDEFINED: if (!info_value->s) { add_assoc_stringl(tmpi, name, "", 0, 1); } else { add_assoc_stringl(tmpi, name, info_value->s, info_data->length, 1); } break; case TAG_FMT_STRING: if (!(val = info_value->s)) { val = ""; } if (section_index==SECTION_COMMENT) { add_index_string(tmpi, idx++, val, 1); } else { add_assoc_string(tmpi, name, val, 1); } break; case TAG_FMT_URATIONAL: case TAG_FMT_SRATIONAL: /*case TAG_FMT_BYTE: case TAG_FMT_SBYTE:*/ case TAG_FMT_USHORT: case TAG_FMT_SSHORT: case TAG_FMT_SINGLE: case TAG_FMT_DOUBLE: case TAG_FMT_ULONG: case TAG_FMT_SLONG: /* now the rest, first see if it becomes an array */ if ((l = info_data->length) > 1) { array = NULL; MAKE_STD_ZVAL(array); array_init(array); } for(ap=0; ap<l; ap++) { if (l>1) { info_value = &info_data->value.list[ap]; } switch (info_data->format) { case TAG_FMT_BYTE: if (l>1) { info_value = &info_data->value; for (b=0;b<l;b++) { add_index_long(array, b, (int)(info_value->s[b])); } break; } case TAG_FMT_USHORT: case TAG_FMT_ULONG: if (l==1) { add_assoc_long(tmpi, name, (int)info_value->u); } else { add_index_long(array, ap, (int)info_value->u); } break; case TAG_FMT_URATIONAL: snprintf(buffer, sizeof(buffer), "%i/%i", info_value->ur.num, info_value->ur.den); if (l==1) { add_assoc_string(tmpi, name, buffer, 1); } else { add_index_string(array, ap, buffer, 1); } break; case TAG_FMT_SBYTE: if (l>1) { info_value = &info_data->value; for (b=0;b<l;b++) { add_index_long(array, ap, (int)info_value->s[b]); } break; } case TAG_FMT_SSHORT: case TAG_FMT_SLONG: if (l==1) { add_assoc_long(tmpi, name, info_value->i); } else { add_index_long(array, ap, info_value->i); } break; case TAG_FMT_SRATIONAL: snprintf(buffer, sizeof(buffer), "%i/%i", info_value->sr.num, info_value->sr.den); if (l==1) { add_assoc_string(tmpi, name, buffer, 1); } else { add_index_string(array, ap, buffer, 1); } break; case TAG_FMT_SINGLE: if (l==1) { add_assoc_double(tmpi, name, info_value->f); } else { add_index_double(array, ap, info_value->f); } break; case TAG_FMT_DOUBLE: if (l==1) { add_assoc_double(tmpi, name, info_value->d); } else { add_index_double(array, ap, info_value->d); } break; } info_value = &info_data->value.list[ap]; } if (l>1) { add_assoc_zval(tmpi, name, array); } break; } } } if (sub_array) { add_assoc_zval(value, exif_get_sectionname(section_index), tmpi); } }}/* }}} *//* {{{ Markers JPEG markers consist of one or more 0xFF bytes, followed by a marker code byte (which is not an FF). Here are the marker codes of interest in this program. (See jdmarker.c for a more complete list.)*/#define M_TEM 0x01 /* temp for arithmetic coding */#define M_RES 0x02 /* reserved */#define M_SOF0 0xC0 /* Start Of Frame N */#define M_SOF1 0xC1 /* N indicates which compression process */#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */#define M_SOF3 0xC3#define M_DHT 0xC4#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */#define M_SOF6 0xC6#define M_SOF7 0xC7#define M_JPEG 0x08 /* reserved for extensions */#define M_SOF9 0xC9#define M_SOF10 0xCA#define M_SOF11 0xCB#define M_DAC 0xCC /* arithmetic table */#define M_SOF13 0xCD#define M_SOF14 0xCE#define M_SOF15 0xCF#define M_RST0 0xD0 /* restart segment */#define M_RST1 0xD1#define M_RST2 0xD2#define M_RST3 0xD3#define M_RST4 0xD4#define M_RST5 0xD5#define M_RST6 0xD6#define M_RST7 0xD7#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */#define M_EOI 0xD9 /* End Of Image (end of datastream) */#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */#define M_DQT 0xDB#define M_DNL 0xDC#define M_DRI 0xDD#define M_DHP 0xDE#define M_EXP 0xDF#define M_APP0 0xE0 /* JPEG: 'JFIFF' AND (additional 'JFXX') */#define M_EXIF 0xE1 /* Exif Attribute Information */#define M_APP2 0xE2 /* Flash Pix Extension Data? */#define M_APP3 0xE3#define M_APP4 0xE4#define M_APP5 0xE5#define M_APP6 0xE6#define M_APP7 0xE7#define M_APP8 0xE8#define M_APP9 0xE9#define M_APP10 0xEA#define M_APP11 0xEB#define M_APP12 0xEC#define M_APP13 0xED /* IPTC International Press Telecommunications Council */#define M_APP14 0xEE /* Software, Copyright? */#define M_APP15 0xEF#define M_JPG0 0xF0#define M_JPG1 0xF1#define M_JPG2 0xF2#define M_JPG3 0xF3#define M_JPG4 0xF4#define M_JPG5 0xF5#define M_JPG6 0xF6#define M_JPG7 0xF7#define M_JPG8 0xF8#define M_JPG9 0xF9#define M_JPG10 0xFA#define M_JPG11 0xFB#define M_JPG12 0xFC#define M_JPG13 0xFD#define M_COM 0xFE /* COMment */#define M_PSEUDO 0x123 /* Extra value. *//* }}} *//* {{{ jpeg2000 markers *//* Markers x30 - x3F do not have a segment *//* Markers x00, x01, xFE, xC0 - xDF ISO/IEC 10918-1 -> M_<xx> *//* Markers xF0 - xF7 ISO/IEC 10918-3 *//* Markers xF7 - xF8 ISO/IEC 14495-1 *//* XY=Main/Tile-hea
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -