33#define EXIFERR_DC , const char *_file, size_t _line
34#define EXIFERR_CC , __FILE__, __LINE__
40#define USE_MBSTRING zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)
53#ifdef __SANITIZE_ADDRESS__
54# include <sanitizer/asan_interface.h>
57typedef unsigned char uchar;
60# define max(a,b) ((a)>(b) ? (a) : (b))
63#define EFREE_IF(ptr) if (ptr) efree(ptr)
65#define MAX_IFD_NESTING_LEVEL 10
66#define MAX_IFD_TAGS 1000
82 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");
100#define EXIF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(exif, v)
102#if defined(ZTS) && defined(COMPILE_DL_EXIF)
110 if (new_value &&
ZSTR_LEN(new_value)) {
114 &return_list, &return_size, 0)) {
118 pefree((
void *) return_list, 0);
120 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
129 &return_list, &return_size, 0)) {
133 pefree((
void *) return_list, 0);
135 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
151#if defined(COMPILE_DL_EXIF) && defined(ZTS)
154 exif_globals->encode_unicode =
NULL;
155 exif_globals->decode_unicode_be =
NULL;
156 exif_globals->decode_unicode_le =
NULL;
157 exif_globals->encode_jis =
NULL;
158 exif_globals->decode_jis_be =
NULL;
159 exif_globals->decode_jis_le =
NULL;
160 exif_globals->tag_table_cache =
NULL;
169 register_exif_symbols(module_number);
214#ifdef COMPILE_DL_EXIF
221static ssize_t exif_read_from_stream_file_looped(
php_stream *stream,
char *
buf,
size_t count)
223 size_t total_read = 0;
224 while (total_read <
count) {
240static const char *
const EXIF_ERROR_FILEEOF =
"Unexpected end of file reached";
241static const char *
const EXIF_ERROR_CORRUPT =
"File structure corrupted";
242static const char *
const EXIF_ERROR_THUMBEOF =
"Thumbnail goes IFD boundary or end of file reached";
243static const char *
const EXIF_ERROR_FSREALLOC =
"Illegal reallocating of undefined file section";
245#define EXIF_ERRLOG_FILEEOF(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FILEEOF);
246#define EXIF_ERRLOG_CORRUPT(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_CORRUPT);
247#define EXIF_ERRLOG_THUMBEOF(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_THUMBEOF);
248#define EXIF_ERRLOG_FSREALLOC(ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_FSREALLOC);
254static const int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1};
255#define NUM_FORMATS 13
257#define TAG_FMT_BYTE 1
258#define TAG_FMT_STRING 2
259#define TAG_FMT_USHORT 3
260#define TAG_FMT_ULONG 4
261#define TAG_FMT_URATIONAL 5
262#define TAG_FMT_SBYTE 6
263#define TAG_FMT_UNDEFINED 7
264#define TAG_FMT_SSHORT 8
265#define TAG_FMT_SLONG 9
266#define TAG_FMT_SRATIONAL 10
267#define TAG_FMT_SINGLE 11
268#define TAG_FMT_DOUBLE 12
269#define TAG_FMT_IFD 13
272static char *exif_get_tagformat(
int format)
294#define TAG_GPS_VERSION_ID 0x0000
295#define TAG_GPS_LATITUDE_REF 0x0001
296#define TAG_GPS_LATITUDE 0x0002
297#define TAG_GPS_LONGITUDE_REF 0x0003
298#define TAG_GPS_LONGITUDE 0x0004
299#define TAG_GPS_ALTITUDE_REF 0x0005
300#define TAG_GPS_ALTITUDE 0x0006
301#define TAG_GPS_TIME_STAMP 0x0007
302#define TAG_GPS_SATELLITES 0x0008
303#define TAG_GPS_STATUS 0x0009
304#define TAG_GPS_MEASURE_MODE 0x000A
305#define TAG_GPS_DOP 0x000B
306#define TAG_GPS_SPEED_REF 0x000C
307#define TAG_GPS_SPEED 0x000D
308#define TAG_GPS_TRACK_REF 0x000E
309#define TAG_GPS_TRACK 0x000F
310#define TAG_GPS_IMG_DIRECTION_REF 0x0010
311#define TAG_GPS_IMG_DIRECTION 0x0011
312#define TAG_GPS_MAP_DATUM 0x0012
313#define TAG_GPS_DEST_LATITUDE_REF 0x0013
314#define TAG_GPS_DEST_LATITUDE 0x0014
315#define TAG_GPS_DEST_LONGITUDE_REF 0x0015
316#define TAG_GPS_DEST_LONGITUDE 0x0016
317#define TAG_GPS_DEST_BEARING_REF 0x0017
318#define TAG_GPS_DEST_BEARING 0x0018
319#define TAG_GPS_DEST_DISTANCE_REF 0x0019
320#define TAG_GPS_DEST_DISTANCE 0x001A
321#define TAG_GPS_PROCESSING_METHOD 0x001B
322#define TAG_GPS_AREA_INFORMATION 0x001C
323#define TAG_GPS_DATE_STAMP 0x001D
324#define TAG_GPS_DIFFERENTIAL 0x001E
325#define TAG_TIFF_COMMENT 0x00FE
326#define TAG_NEW_SUBFILE 0x00FE
327#define TAG_SUBFILE_TYPE 0x00FF
328#define TAG_IMAGEWIDTH 0x0100
329#define TAG_IMAGEHEIGHT 0x0101
330#define TAG_BITS_PER_SAMPLE 0x0102
331#define TAG_COMPRESSION 0x0103
332#define TAG_PHOTOMETRIC_INTERPRETATION 0x0106
333#define TAG_TRESHHOLDING 0x0107
334#define TAG_CELL_WIDTH 0x0108
335#define TAG_CELL_HEIGHT 0x0109
336#define TAG_FILL_ORDER 0x010A
337#define TAG_DOCUMENT_NAME 0x010D
338#define TAG_IMAGE_DESCRIPTION 0x010E
339#define TAG_MAKE 0x010F
340#define TAG_MODEL 0x0110
341#define TAG_STRIP_OFFSETS 0x0111
342#define TAG_ORIENTATION 0x0112
343#define TAG_SAMPLES_PER_PIXEL 0x0115
344#define TAG_ROWS_PER_STRIP 0x0116
345#define TAG_STRIP_BYTE_COUNTS 0x0117
346#define TAG_MIN_SAMPPLE_VALUE 0x0118
347#define TAG_MAX_SAMPLE_VALUE 0x0119
348#define TAG_X_RESOLUTION 0x011A
349#define TAG_Y_RESOLUTION 0x011B
350#define TAG_PLANAR_CONFIGURATION 0x011C
351#define TAG_PAGE_NAME 0x011D
352#define TAG_X_POSITION 0x011E
353#define TAG_Y_POSITION 0x011F
354#define TAG_FREE_OFFSETS 0x0120
355#define TAG_FREE_BYTE_COUNTS 0x0121
356#define TAG_GRAY_RESPONSE_UNIT 0x0122
357#define TAG_GRAY_RESPONSE_CURVE 0x0123
358#define TAG_RESOLUTION_UNIT 0x0128
359#define TAG_PAGE_NUMBER 0x0129
360#define TAG_TRANSFER_FUNCTION 0x012D
361#define TAG_SOFTWARE 0x0131
362#define TAG_DATETIME 0x0132
363#define TAG_ARTIST 0x013B
364#define TAG_HOST_COMPUTER 0x013C
365#define TAG_PREDICTOR 0x013D
366#define TAG_WHITE_POINT 0x013E
367#define TAG_PRIMARY_CHROMATICITIES 0x013F
368#define TAG_COLOR_MAP 0x0140
369#define TAG_HALFTONE_HINTS 0x0141
370#define TAG_TILE_WIDTH 0x0142
371#define TAG_TILE_LENGTH 0x0143
372#define TAG_TILE_OFFSETS 0x0144
373#define TAG_TILE_BYTE_COUNTS 0x0145
374#define TAG_SUB_IFD 0x014A
375#define TAG_INK_SETMPUTER 0x014C
376#define TAG_INK_NAMES 0x014D
377#define TAG_NUMBER_OF_INKS 0x014E
378#define TAG_DOT_RANGE 0x0150
379#define TAG_TARGET_PRINTER 0x0151
380#define TAG_EXTRA_SAMPLE 0x0152
381#define TAG_SAMPLE_FORMAT 0x0153
382#define TAG_S_MIN_SAMPLE_VALUE 0x0154
383#define TAG_S_MAX_SAMPLE_VALUE 0x0155
384#define TAG_TRANSFER_RANGE 0x0156
385#define TAG_JPEG_TABLES 0x015B
386#define TAG_JPEG_PROC 0x0200
387#define TAG_JPEG_INTERCHANGE_FORMAT 0x0201
388#define TAG_JPEG_INTERCHANGE_FORMAT_LEN 0x0202
389#define TAG_JPEG_RESTART_INTERVAL 0x0203
390#define TAG_JPEG_LOSSLESS_PREDICTOR 0x0205
391#define TAG_JPEG_POINT_TRANSFORMS 0x0206
392#define TAG_JPEG_Q_TABLES 0x0207
393#define TAG_JPEG_DC_TABLES 0x0208
394#define TAG_JPEG_AC_TABLES 0x0209
395#define TAG_YCC_COEFFICIENTS 0x0211
396#define TAG_YCC_SUB_SAMPLING 0x0212
397#define TAG_YCC_POSITIONING 0x0213
398#define TAG_REFERENCE_BLACK_WHITE 0x0214
409#define TAG_COPYRIGHT 0x8298
410#define TAG_EXPOSURETIME 0x829A
411#define TAG_FNUMBER 0x829D
412#define TAG_EXIF_IFD_POINTER 0x8769
413#define TAG_ICC_PROFILE 0x8773
414#define TAG_EXPOSURE_PROGRAM 0x8822
415#define TAG_SPECTRAL_SENSITY 0x8824
416#define TAG_GPS_IFD_POINTER 0x8825
417#define TAG_ISOSPEED 0x8827
418#define TAG_OPTOELECTRIC_CONVERSION_F 0x8828
420#define TAG_EXIFVERSION 0x9000
421#define TAG_DATE_TIME_ORIGINAL 0x9003
422#define TAG_DATE_TIME_DIGITIZED 0x9004
423#define TAG_COMPONENT_CONFIG 0x9101
424#define TAG_COMPRESSED_BITS_PER_PIXEL 0x9102
425#define TAG_SHUTTERSPEED 0x9201
426#define TAG_APERTURE 0x9202
427#define TAG_BRIGHTNESS_VALUE 0x9203
428#define TAG_EXPOSURE_BIAS_VALUE 0x9204
429#define TAG_MAX_APERTURE 0x9205
430#define TAG_SUBJECT_DISTANCE 0x9206
431#define TAG_METRIC_MODULE 0x9207
432#define TAG_LIGHT_SOURCE 0x9208
433#define TAG_FLASH 0x9209
434#define TAG_FOCAL_LENGTH 0x920A
437#define TAG_SUBJECT_AREA 0x9214
438#define TAG_MAKER_NOTE 0x927C
439#define TAG_USERCOMMENT 0x9286
440#define TAG_SUB_SEC_TIME 0x9290
441#define TAG_SUB_SEC_TIME_ORIGINAL 0x9291
442#define TAG_SUB_SEC_TIME_DIGITIZED 0x9292
445#define TAG_XP_TITLE 0x9C9B
446#define TAG_XP_COMMENTS 0x9C9C
447#define TAG_XP_AUTHOR 0x9C9D
448#define TAG_XP_KEYWORDS 0x9C9E
449#define TAG_XP_SUBJECT 0x9C9F
450#define TAG_FLASH_PIX_VERSION 0xA000
451#define TAG_COLOR_SPACE 0xA001
452#define TAG_COMP_IMAGE_WIDTH 0xA002
453#define TAG_COMP_IMAGE_HEIGHT 0xA003
454#define TAG_RELATED_SOUND_FILE 0xA004
455#define TAG_INTEROP_IFD_POINTER 0xA005
456#define TAG_FLASH_ENERGY 0xA20B
457#define TAG_SPATIAL_FREQUENCY_RESPONSE 0xA20C
458#define TAG_FOCALPLANE_X_RES 0xA20E
459#define TAG_FOCALPLANE_Y_RES 0xA20F
460#define TAG_FOCALPLANE_RESOLUTION_UNIT 0xA210
461#define TAG_SUBJECT_LOCATION 0xA214
462#define TAG_EXPOSURE_INDEX 0xA215
463#define TAG_SENSING_METHOD 0xA217
464#define TAG_FILE_SOURCE 0xA300
465#define TAG_SCENE_TYPE 0xA301
466#define TAG_CFA_PATTERN 0xA302
467#define TAG_CUSTOM_RENDERED 0xA401
468#define TAG_EXPOSURE_MODE 0xA402
469#define TAG_WHITE_BALANCE 0xA403
470#define TAG_DIGITAL_ZOOM_RATIO 0xA404
471#define TAG_FOCAL_LENGTH_IN_35_MM_FILM 0xA405
472#define TAG_SCENE_CAPTURE_TYPE 0xA406
473#define TAG_GAIN_CONTROL 0xA407
474#define TAG_CONTRAST 0xA408
475#define TAG_SATURATION 0xA409
476#define TAG_SHARPNESS 0xA40A
477#define TAG_DEVICE_SETTING_DESCRIPTION 0xA40B
478#define TAG_SUBJECT_DISTANCE_RANGE 0xA40C
479#define TAG_IMAGE_UNIQUE_ID 0xA420
482#define TAG_OLYMPUS_SPECIALMODE 0x0200
483#define TAG_OLYMPUS_JPEGQUAL 0x0201
484#define TAG_OLYMPUS_MACRO 0x0202
485#define TAG_OLYMPUS_DIGIZOOM 0x0204
486#define TAG_OLYMPUS_SOFTWARERELEASE 0x0207
487#define TAG_OLYMPUS_PICTINFO 0x0208
488#define TAG_OLYMPUS_CAMERAID 0x0209
493#define TAG_COMPUTED_VALUE -2
494#define TAG_END_OF_LIST 0xFFFD
497#define PMI_BLACK_IS_ZERO 0
498#define PMI_WHITE_IS_ZERO 1
500#define PMI_PALETTE_COLOR 3
501#define PMI_TRANSPARENCY_MASK 4
502#define PMI_SEPARATED 5
509typedef const struct {
517#define TAG_TABLE_END \
518 {TAG_NONE, "No tag value"},\
519 {TAG_COMPUTED_VALUE, "Computed value"},\
520 {TAG_END_OF_LIST, ""}
523 { 0x000B,
"ACDComment"},
524 { 0x00FE,
"NewSubFile"},
525 { 0x00FF,
"SubFile"},
526 { 0x0100,
"ImageWidth"},
527 { 0x0101,
"ImageLength"},
528 { 0x0102,
"BitsPerSample"},
529 { 0x0103,
"Compression"},
530 { 0x0106,
"PhotometricInterpretation"},
531 { 0x010A,
"FillOrder"},
532 { 0x010D,
"DocumentName"},
533 { 0x010E,
"ImageDescription"},
536 { 0x0111,
"StripOffsets"},
537 { 0x0112,
"Orientation"},
538 { 0x0115,
"SamplesPerPixel"},
539 { 0x0116,
"RowsPerStrip"},
540 { 0x0117,
"StripByteCounts"},
541 { 0x0118,
"MinSampleValue"},
542 { 0x0119,
"MaxSampleValue"},
543 { 0x011A,
"XResolution"},
544 { 0x011B,
"YResolution"},
545 { 0x011C,
"PlanarConfiguration"},
546 { 0x011D,
"PageName"},
547 { 0x011E,
"XPosition"},
548 { 0x011F,
"YPosition"},
549 { 0x0120,
"FreeOffsets"},
550 { 0x0121,
"FreeByteCounts"},
551 { 0x0122,
"GrayResponseUnit"},
552 { 0x0123,
"GrayResponseCurve"},
553 { 0x0124,
"T4Options"},
554 { 0x0125,
"T6Options"},
555 { 0x0128,
"ResolutionUnit"},
556 { 0x0129,
"PageNumber"},
557 { 0x012D,
"TransferFunction"},
558 { 0x0131,
"Software"},
559 { 0x0132,
"DateTime"},
561 { 0x013C,
"HostComputer"},
562 { 0x013D,
"Predictor"},
563 { 0x013E,
"WhitePoint"},
564 { 0x013F,
"PrimaryChromaticities"},
565 { 0x0140,
"ColorMap"},
566 { 0x0141,
"HalfToneHints"},
567 { 0x0142,
"TileWidth"},
568 { 0x0143,
"TileLength"},
569 { 0x0144,
"TileOffsets"},
570 { 0x0145,
"TileByteCounts"},
573 { 0x014D,
"InkNames"},
574 { 0x014E,
"NumberOfInks"},
575 { 0x0150,
"DotRange"},
576 { 0x0151,
"TargetPrinter"},
577 { 0x0152,
"ExtraSample"},
578 { 0x0153,
"SampleFormat"},
579 { 0x0154,
"SMinSampleValue"},
580 { 0x0155,
"SMaxSampleValue"},
581 { 0x0156,
"TransferRange"},
582 { 0x0157,
"ClipPath"},
583 { 0x0158,
"XClipPathUnits"},
584 { 0x0159,
"YClipPathUnits"},
585 { 0x015A,
"Indexed"},
586 { 0x015B,
"JPEGTables"},
587 { 0x015F,
"OPIProxy"},
588 { 0x0200,
"JPEGProc"},
589 { 0x0201,
"JPEGInterchangeFormat"},
590 { 0x0202,
"JPEGInterchangeFormatLength"},
591 { 0x0203,
"JPEGRestartInterval"},
592 { 0x0205,
"JPEGLosslessPredictors"},
593 { 0x0206,
"JPEGPointTransforms"},
594 { 0x0207,
"JPEGQTables"},
595 { 0x0208,
"JPEGDCTables"},
596 { 0x0209,
"JPEGACTables"},
597 { 0x0211,
"YCbCrCoefficients"},
598 { 0x0212,
"YCbCrSubSampling"},
599 { 0x0213,
"YCbCrPositioning"},
600 { 0x0214,
"ReferenceBlackWhite"},
601 { 0x02BC,
"ExtensibleMetadataPlatform"},
603 { 0x0302,
"ICCProfileDescriptor"},
604 { 0x0303,
"SRGBRenderingIntent"},
605 { 0x0320,
"ImageTitle"},
606 { 0x5001,
"ResolutionXUnit"},
607 { 0x5002,
"ResolutionYUnit"},
608 { 0x5003,
"ResolutionXLengthUnit"},
609 { 0x5004,
"ResolutionYLengthUnit"},
610 { 0x5005,
"PrintFlags"},
611 { 0x5006,
"PrintFlagsVersion"},
612 { 0x5007,
"PrintFlagsCrop"},
613 { 0x5008,
"PrintFlagsBleedWidth"},
614 { 0x5009,
"PrintFlagsBleedWidthScale"},
615 { 0x500A,
"HalftoneLPI"},
616 { 0x500B,
"HalftoneLPIUnit"},
617 { 0x500C,
"HalftoneDegree"},
618 { 0x500D,
"HalftoneShape"},
619 { 0x500E,
"HalftoneMisc"},
620 { 0x500F,
"HalftoneScreen"},
621 { 0x5010,
"JPEGQuality"},
622 { 0x5011,
"GridSize"},
623 { 0x5012,
"ThumbnailFormat"},
624 { 0x5013,
"ThumbnailWidth"},
625 { 0x5014,
"ThumbnailHeight"},
626 { 0x5015,
"ThumbnailColorDepth"},
627 { 0x5016,
"ThumbnailPlanes"},
628 { 0x5017,
"ThumbnailRawBytes"},
629 { 0x5018,
"ThumbnailSize"},
630 { 0x5019,
"ThumbnailCompressedSize"},
631 { 0x501A,
"ColorTransferFunction"},
632 { 0x501B,
"ThumbnailData"},
633 { 0x5020,
"ThumbnailImageWidth"},
634 { 0x5021,
"ThumbnailImageHeight"},
635 { 0x5022,
"ThumbnailBitsPerSample"},
636 { 0x5023,
"ThumbnailCompression"},
637 { 0x5024,
"ThumbnailPhotometricInterp"},
638 { 0x5025,
"ThumbnailImageDescription"},
639 { 0x5026,
"ThumbnailEquipMake"},
640 { 0x5027,
"ThumbnailEquipModel"},
641 { 0x5028,
"ThumbnailStripOffsets"},
642 { 0x5029,
"ThumbnailOrientation"},
643 { 0x502A,
"ThumbnailSamplesPerPixel"},
644 { 0x502B,
"ThumbnailRowsPerStrip"},
645 { 0x502C,
"ThumbnailStripBytesCount"},
646 { 0x502D,
"ThumbnailResolutionX"},
647 { 0x502E,
"ThumbnailResolutionY"},
648 { 0x502F,
"ThumbnailPlanarConfig"},
649 { 0x5030,
"ThumbnailResolutionUnit"},
650 { 0x5031,
"ThumbnailTransferFunction"},
651 { 0x5032,
"ThumbnailSoftwareUsed"},
652 { 0x5033,
"ThumbnailDateTime"},
653 { 0x5034,
"ThumbnailArtist"},
654 { 0x5035,
"ThumbnailWhitePoint"},
655 { 0x5036,
"ThumbnailPrimaryChromaticities"},
656 { 0x5037,
"ThumbnailYCbCrCoefficients"},
657 { 0x5038,
"ThumbnailYCbCrSubsampling"},
658 { 0x5039,
"ThumbnailYCbCrPositioning"},
659 { 0x503A,
"ThumbnailRefBlackWhite"},
660 { 0x503B,
"ThumbnailCopyRight"},
661 { 0x5090,
"LuminanceTable"},
662 { 0x5091,
"ChrominanceTable"},
663 { 0x5100,
"FrameDelay"},
664 { 0x5101,
"LoopCount"},
665 { 0x5110,
"PixelUnit"},
666 { 0x5111,
"PixelPerUnitX"},
667 { 0x5112,
"PixelPerUnitY"},
668 { 0x5113,
"PaletteHistogram"},
669 { 0x1000,
"RelatedImageFileFormat"},
670 { 0x800D,
"ImageID"},
671 { 0x80E3,
"Matteing"},
672 { 0x80E4,
"DataType"},
673 { 0x80E5,
"ImageDepth"},
674 { 0x80E6,
"TileDepth"},
675 { 0x828D,
"CFARepeatPatternDim"},
676 { 0x828E,
"CFAPattern"},
677 { 0x828F,
"BatteryLevel"},
678 { 0x8298,
"Copyright"},
679 { 0x829A,
"ExposureTime"},
680 { 0x829D,
"FNumber"},
681 { 0x83BB,
"IPTC/NAA"},
682 { 0x84E3,
"IT8RasterPadding"},
683 { 0x84E5,
"IT8ColorTable"},
684 { 0x8649,
"ImageResourceInformation"},
685 { 0x8769,
"Exif_IFD_Pointer"},
686 { 0x8773,
"ICC_Profile"},
687 { 0x8822,
"ExposureProgram"},
688 { 0x8824,
"SpectralSensity"},
689 { 0x8825,
"GPS_IFD_Pointer"},
690 { 0x8827,
"ISOSpeedRatings"},
692 { 0x9000,
"ExifVersion"},
693 { 0x9003,
"DateTimeOriginal"},
694 { 0x9004,
"DateTimeDigitized"},
695 { 0x9101,
"ComponentsConfiguration"},
696 { 0x9102,
"CompressedBitsPerPixel"},
697 { 0x9201,
"ShutterSpeedValue"},
698 { 0x9202,
"ApertureValue"},
699 { 0x9203,
"BrightnessValue"},
700 { 0x9204,
"ExposureBiasValue"},
701 { 0x9205,
"MaxApertureValue"},
702 { 0x9206,
"SubjectDistance"},
703 { 0x9207,
"MeteringMode"},
704 { 0x9208,
"LightSource"},
706 { 0x920A,
"FocalLength"},
707 { 0x920B,
"FlashEnergy"},
708 { 0x920C,
"SpatialFrequencyResponse"},
710 { 0x920E,
"FocalPlaneXResolution"},
711 { 0x920F,
"FocalPlaneYResolution"},
712 { 0x9210,
"FocalPlaneResolutionUnit"},
713 { 0x9211,
"ImageNumber"},
714 { 0x9212,
"SecurityClassification"},
715 { 0x9213,
"ImageHistory"},
716 { 0x9214,
"SubjectLocation"},
717 { 0x9215,
"ExposureIndex"},
718 { 0x9216,
"TIFF/EPStandardID"},
719 { 0x9217,
"SensingMethod"},
720 { 0x923F,
"StoNits"},
721 { 0x927C,
"MakerNote"},
722 { 0x9286,
"UserComment"},
723 { 0x9290,
"SubSecTime"},
724 { 0x9291,
"SubSecTimeOriginal"},
725 { 0x9292,
"SubSecTimeDigitized"},
726 { 0x935C,
"ImageSourceData"},
728 { 0x9c9c,
"Comments" },
729 { 0x9c9d,
"Author" },
730 { 0x9c9e,
"Keywords" },
731 { 0x9c9f,
"Subject" },
732 { 0xA000,
"FlashPixVersion"},
733 { 0xA001,
"ColorSpace"},
734 { 0xA002,
"ExifImageWidth"},
735 { 0xA003,
"ExifImageLength"},
736 { 0xA004,
"RelatedSoundFile"},
737 { 0xA005,
"InteroperabilityOffset"},
738 { 0xA20B,
"FlashEnergy"},
739 { 0xA20C,
"SpatialFrequencyResponse"},
741 { 0xA20E,
"FocalPlaneXResolution"},
742 { 0xA20F,
"FocalPlaneYResolution"},
743 { 0xA210,
"FocalPlaneResolutionUnit"},
744 { 0xA211,
"ImageNumber"},
745 { 0xA212,
"SecurityClassification"},
746 { 0xA213,
"ImageHistory"},
747 { 0xA214,
"SubjectLocation"},
748 { 0xA215,
"ExposureIndex"},
749 { 0xA216,
"TIFF/EPStandardID"},
750 { 0xA217,
"SensingMethod"},
751 { 0xA300,
"FileSource"},
752 { 0xA301,
"SceneType"},
753 { 0xA302,
"CFAPattern"},
754 { 0xA401,
"CustomRendered"},
755 { 0xA402,
"ExposureMode"},
756 { 0xA403,
"WhiteBalance"},
757 { 0xA404,
"DigitalZoomRatio"},
758 { 0xA405,
"FocalLengthIn35mmFilm"},
759 { 0xA406,
"SceneCaptureType"},
760 { 0xA407,
"GainControl"},
761 { 0xA408,
"Contrast"},
762 { 0xA409,
"Saturation"},
763 { 0xA40A,
"Sharpness"},
764 { 0xA40B,
"DeviceSettingDescription"},
765 { 0xA40C,
"SubjectDistanceRange"},
766 { 0xA420,
"ImageUniqueID"},
771 { 0x0000,
"GPSVersion"},
772 { 0x0001,
"GPSLatitudeRef"},
773 { 0x0002,
"GPSLatitude"},
774 { 0x0003,
"GPSLongitudeRef"},
775 { 0x0004,
"GPSLongitude"},
776 { 0x0005,
"GPSAltitudeRef"},
777 { 0x0006,
"GPSAltitude"},
778 { 0x0007,
"GPSTimeStamp"},
779 { 0x0008,
"GPSSatellites"},
780 { 0x0009,
"GPSStatus"},
781 { 0x000A,
"GPSMeasureMode"},
783 { 0x000C,
"GPSSpeedRef"},
784 { 0x000D,
"GPSSpeed"},
785 { 0x000E,
"GPSTrackRef"},
786 { 0x000F,
"GPSTrack"},
787 { 0x0010,
"GPSImgDirectionRef"},
788 { 0x0011,
"GPSImgDirection"},
789 { 0x0012,
"GPSMapDatum"},
790 { 0x0013,
"GPSDestLatitudeRef"},
791 { 0x0014,
"GPSDestLatitude"},
792 { 0x0015,
"GPSDestLongitudeRef"},
793 { 0x0016,
"GPSDestLongitude"},
794 { 0x0017,
"GPSDestBearingRef"},
795 { 0x0018,
"GPSDestBearing"},
796 { 0x0019,
"GPSDestDistanceRef"},
797 { 0x001A,
"GPSDestDistance"},
798 { 0x001B,
"GPSProcessingMode"},
799 { 0x001C,
"GPSAreaInformation"},
800 { 0x001D,
"GPSDateStamp"},
801 { 0x001E,
"GPSDifferential"},
806 { 0x0001,
"InterOperabilityIndex"},
807 { 0x0002,
"InterOperabilityVersion"},
808 { 0x1000,
"RelatedFileFormat"},
809 { 0x1001,
"RelatedImageWidth"},
810 { 0x1002,
"RelatedImageHeight"},
815 { 0x0001,
"ModeArray"},
816 { 0x0004,
"ImageInfo"},
817 { 0x0006,
"ImageType"},
818 { 0x0007,
"FirmwareVersion"},
819 { 0x0008,
"ImageNumber"},
820 { 0x0009,
"OwnerName"},
822 { 0x000F,
"CustomFunctions"},
827 { 0x0001,
"RecordingMode"},
828 { 0x0002,
"Quality"},
829 { 0x0003,
"FocusingMode"},
830 { 0x0004,
"FlashMode"},
831 { 0x0005,
"FlashIntensity"},
832 { 0x0006,
"ObjectDistance"},
833 { 0x0007,
"WhiteBalance"},
834 { 0x000A,
"DigitalZoom"},
835 { 0x000B,
"Sharpness"},
836 { 0x000C,
"Contrast"},
837 { 0x000D,
"Saturation"},
838 { 0x0014,
"CCDSensitivity"},
843 { 0x0000,
"Version"},
844 { 0x1000,
"Quality"},
845 { 0x1001,
"Sharpness"},
846 { 0x1002,
"WhiteBalance"},
849 { 0x1010,
"FlashMode"},
850 { 0x1011,
"FlashStrength"},
852 { 0x1021,
"FocusMode"},
853 { 0x1030,
"SlowSync"},
854 { 0x1031,
"PictureMode"},
855 { 0x1100,
"ContTake"},
856 { 0x1300,
"BlurWarning"},
857 { 0x1301,
"FocusWarning"},
858 { 0x1302,
"AEWarning "},
863 { 0x0003,
"Quality"},
864 { 0x0004,
"ColorMode"},
865 { 0x0005,
"ImageAdjustment"},
866 { 0x0006,
"CCDSensitivity"},
867 { 0x0007,
"WhiteBalance"},
869 { 0x000a,
"DigitalZoom"},
870 { 0x000b,
"Converter"},
875 { 0x0001,
"Version"},
876 { 0x0002,
"ISOSetting"},
877 { 0x0003,
"ColorMode"},
878 { 0x0004,
"Quality"},
879 { 0x0005,
"WhiteBalance"},
880 { 0x0006,
"ImageSharpening"},
881 { 0x0007,
"FocusMode"},
882 { 0x0008,
"FlashSetting"},
883 { 0x000F,
"ISOSelection"},
884 { 0x0080,
"ImageAdjustment"},
885 { 0x0082,
"AuxiliaryLens"},
886 { 0x0085,
"ManualFocusDistance"},
887 { 0x0086,
"DigitalZoom"},
888 { 0x0088,
"AFFocusPosition"},
889 { 0x0010,
"DataDump"},
894 { 0x0200,
"SpecialMode"},
895 { 0x0201,
"JPEGQuality"},
897 { 0x0204,
"DigitalZoom"},
898 { 0x0207,
"SoftwareRelease"},
899 { 0x0208,
"PictureInfo"},
900 { 0x0209,
"CameraId"},
901 { 0x0F00,
"DataDump"},
906 { 0x0001,
"Version"},
907 { 0x0021,
"PictureWizard"},
908 { 0x0030,
"LocalLocationName"},
909 { 0x0031,
"LocationName"},
910 { 0x0035,
"Preview"},
911 { 0x0043,
"CameraTemperature"},
912 { 0xa001,
"FirmwareName"},
913 { 0xa003,
"LensType"},
914 { 0xa004,
"LensFirmware"},
915 { 0xa010,
"SensorAreas"},
916 { 0xa011,
"ColorSpace"},
917 { 0xa012,
"SmartRange"},
918 { 0xa013,
"ExposureBiasValue"},
920 { 0xa018,
"ExposureTime"},
921 { 0xa019,
"FNumber"},
922 { 0xa01a,
"FocalLengthIn35mmFormat"},
923 { 0xa020,
"EncryptionKey"},
924 { 0xa021,
"WB_RGGBLevelsUncorrected"},
925 { 0xa022,
"WB_RGGBLevelsAuto"},
926 { 0xa023,
"WB_RGGBLevelsIlluminator1"},
927 { 0xa024,
"WB_RGGBLevelsIlluminator2"},
928 { 0xa028,
"WB_RGGBLevelsBlack"},
929 { 0xa030,
"ColorMatrix"},
930 { 0xa031,
"ColorMatrixSRGB"},
931 { 0xa032,
"ColorMatrixAdobeRGB"},
932 { 0xa040,
"ToneCurve1"},
933 { 0xa041,
"ToneCurve2"},
934 { 0xa042,
"ToneCurve3"},
935 { 0xa043,
"ToneCurve4"},
940 { 0x0001,
"Quality"},
941 { 0x0002,
"FirmwareVersion"},
942 { 0x0003,
"WhiteBalance"},
943 { 0x0007,
"FocusMode"},
945 { 0x001a,
"ImageStabilization"},
947 { 0x001f,
"ShootingMode"},
949 { 0x0021,
"DataDump"},
950 { 0x0023,
"WhiteBalanceBias"},
951 { 0x0024,
"FlashBias"},
952 { 0x0025,
"InternalSerialNumber"},
953 { 0x0026,
"ExifVersion"},
954 { 0x0028,
"ColorEffect"},
955 { 0x0029,
"TimeSincePowerOn"},
956 { 0x002a,
"BurstMode"},
957 { 0x002b,
"SequenceNumber"},
958 { 0x002c,
"Contrast"},
959 { 0x002d,
"NoiseReduction"},
960 { 0x002e,
"SelfTimer"},
961 { 0x0030,
"Rotation"},
962 { 0x0031,
"AFAssistLamp"},
963 { 0x0032,
"ColorMode"},
964 { 0x0033,
"BabyAge1"},
965 { 0x0034,
"OpticalZoomMode"},
966 { 0x0035,
"ConversionLens"},
967 { 0x0036,
"TravelDay"},
968 { 0x0039,
"Contrast"},
969 { 0x003a,
"WorldTimeLocation"},
970 { 0x003b,
"TextStamp1"},
971 { 0x003c,
"ProgramISO"},
972 { 0x003d,
"AdvancedSceneType"},
973 { 0x003e,
"TextStamp2"},
974 { 0x003f,
"FacesDetected"},
975 { 0x0040,
"Saturation"},
976 { 0x0041,
"Sharpness"},
977 { 0x0042,
"FilmMode"},
978 { 0x0044,
"ColorTempKelvin"},
979 { 0x0045,
"BracketSettings"},
980 { 0x0046,
"WBAdjustAB"},
981 { 0x0047,
"WBAdjustGM"},
982 { 0x0048,
"FlashCurtain"},
983 { 0x0049,
"LongShutterNoiseReduction"},
984 { 0x004b,
"ImageWidth"},
985 { 0x004c,
"ImageHeight"},
986 { 0x004d,
"AFPointPosition"},
987 { 0x004e,
"FaceDetInfo"},
988 { 0x0051,
"LensType"},
989 { 0x0052,
"LensSerialNumber"},
990 { 0x0053,
"AccessoryType"},
991 { 0x0054,
"AccessorySerialNumber"},
992 { 0x0059,
"Transform1"},
993 { 0x005d,
"IntelligentExposure"},
994 { 0x0060,
"LensFirmwareVersion"},
995 { 0x0061,
"FaceRecInfo"},
996 { 0x0062,
"FlashWarning"},
998 { 0x0066,
"BabyName"},
999 { 0x0067,
"Location"},
1000 { 0x0069,
"Country"},
1003 { 0x006f,
"Landmark"},
1004 { 0x0070,
"IntelligentResolution"},
1005 { 0x0077,
"BurstSheed"},
1006 { 0x0079,
"IntelligentDRange"},
1007 { 0x007c,
"ClearRetouch"},
1009 { 0x0086,
"ManometerPressure"},
1010 { 0x0089,
"PhotoStyle"},
1011 { 0x008a,
"ShadingCompensation"},
1012 { 0x008c,
"AccelerometerZ"},
1013 { 0x008d,
"AccelerometerX"},
1014 { 0x008e,
"AccelerometerY"},
1015 { 0x008f,
"CameraOrientation"},
1016 { 0x0090,
"RollAngle"},
1017 { 0x0091,
"PitchAngle"},
1018 { 0x0093,
"SweepPanoramaDirection"},
1019 { 0x0094,
"PanoramaFieldOfView"},
1020 { 0x0096,
"TimerRecording"},
1021 { 0x009d,
"InternalNDFilter"},
1023 { 0x009f,
"ShutterType"},
1024 { 0x00a3,
"ClearRetouchValue"},
1025 { 0x00ab,
"TouchAE"},
1026 { 0x0e00,
"PrintIM"},
1027 { 0x8000,
"MakerNoteVersion"},
1028 { 0x8001,
"SceneMode"},
1029 { 0x8004,
"WBRedLevel"},
1030 { 0x8005,
"WBGreenLevel"},
1031 { 0x8006,
"WBBlueLevel"},
1032 { 0x8007,
"FlashFired"},
1033 { 0x8008,
"TextStamp3"},
1034 { 0x8009,
"TextStamp4"},
1035 { 0x8010,
"BabyAge2"},
1036 { 0x8012,
"Transform2"},
1042 { 0x0003,
"SpeedX"},
1043 { 0x0004,
"SpeedY"},
1044 { 0x0005,
"SpeedZ"},
1048 { 0x0009,
"CameraPitch"},
1049 { 0x000a,
"CameraYaw"},
1050 { 0x000b,
"CameraRoll"},
1055 { 0x0102,
"Quality"},
1056 { 0x0104,
"FlashExposureComp"},
1057 { 0x0105,
"Teleconverter"},
1058 { 0x0112,
"WhiteBalanceFineTune"},
1059 { 0x0114,
"CameraSettings"},
1060 { 0x0115,
"WhiteBalance"},
1061 { 0x0116,
"ExtraInfo"},
1062 { 0x0e00,
"PrintIM"},
1063 { 0x1000,
"MultiBurstMode"},
1064 { 0x1001,
"MultiBurstImageWidth"},
1065 { 0x1002,
"MultiBurstImageHeight"},
1066 { 0x1003,
"Panorama"},
1067 { 0x2001,
"PreviewImage"},
1068 { 0x2002,
"Rating"},
1069 { 0x2004,
"Contrast"},
1070 { 0x2005,
"Saturation"},
1071 { 0x2006,
"Sharpness"},
1072 { 0x2007,
"Brightness"},
1073 { 0x2008,
"LongExposureNoiseReduction"},
1074 { 0x2009,
"HighISONoiseReduction"},
1075 { 0x200a,
"AutoHDR"},
1076 { 0x3000,
"ShotInfo"},
1077 { 0xb000,
"FileFormat"},
1078 { 0xb001,
"SonyModelID"},
1079 { 0xb020,
"ColorReproduction"},
1080 { 0xb021,
"ColorTemperature"},
1081 { 0xb022,
"ColorCompensationFilter"},
1082 { 0xb023,
"SceneMode"},
1083 { 0xb024,
"ZoneMatching"},
1084 { 0xb025,
"DynamicRangeOptimizer"},
1085 { 0xb026,
"ImageStabilization"},
1086 { 0xb027,
"LensID"},
1087 { 0xb028,
"MinoltaMakerNote"},
1088 { 0xb029,
"ColorMode"},
1089 { 0xb02b,
"FullImageSize"},
1090 { 0xb02c,
"PreviewImageSize"},
1092 { 0xb041,
"ExposureMode"},
1093 { 0xb042,
"FocusMode"},
1094 { 0xb043,
"AFMode"},
1095 { 0xb044,
"AFIlluminator"},
1096 { 0xb047,
"JPEGQuality"},
1097 { 0xb048,
"FlashLevel"},
1098 { 0xb049,
"ReleaseMode"},
1099 { 0xb04a,
"SequenceNumber"},
1100 { 0xb04b,
"AntiBlur"},
1101 { 0xb04e,
"FocusMode"},
1102 { 0xb04f,
"DynamicRangeOptimizer"},
1103 { 0xb050,
"HighISONoiseReduction2"},
1104 { 0xb052,
"IntelligentAuto"},
1105 { 0xb054,
"WhiteBalance2"},
1110 { 0x0000,
"Version"},
1112 { 0x0002,
"PreviewResolution"},
1113 { 0x0003,
"PreviewLength"},
1114 { 0x0004,
"PreviewOffset"},
1115 { 0x0005,
"ModelID"},
1118 { 0x0008,
"Quality"},
1122 { 0x000e,
"AFPoint"},
1123 { 0x000f,
"AFPointInFocus"},
1124 { 0x0012,
"ExposureTime"},
1125 { 0x0013,
"FNumber"},
1127 { 0x0016,
"ExposureCompensation"},
1128 { 0x0017,
"MeteringMode"},
1129 { 0x0018,
"AutoBracketing"},
1130 { 0x0019,
"WhiteBalance"},
1131 { 0x001a,
"WhiteBalanceMode"},
1132 { 0x001b,
"BlueBalance"},
1133 { 0x001c,
"RedBalance"},
1134 { 0x001d,
"FocalLength"},
1135 { 0x001e,
"DigitalZoom"},
1136 { 0x001f,
"Saturation"},
1137 { 0x0020,
"Contrast"},
1138 { 0x0021,
"Sharpness"},
1139 { 0x0022,
"Location"},
1140 { 0x0023,
"Hometown"},
1141 { 0x0024,
"Destination"},
1142 { 0x0025,
"HometownDST"},
1143 { 0x0026,
"DestinationDST"},
1144 { 0x0027,
"DSPFirmwareVersion"},
1145 { 0x0028,
"CPUFirmwareVersion"},
1146 { 0x0029,
"FrameNumber"},
1147 { 0x002d,
"EffectiveLV"},
1148 { 0x0032,
"ImageProcessing"},
1149 { 0x0033,
"PictureMode"},
1150 { 0x0034,
"DriveMode"},
1151 { 0x0037,
"ColorSpace"},
1152 { 0x0038,
"ImageAreaOffset"},
1153 { 0x0039,
"RawImageSize"},
1154 { 0x003e,
"PreviewImageBorders"},
1155 { 0x003f,
"LensType"},
1156 { 0x0040,
"SensitivityAdjust"},
1157 { 0x0041,
"DigitalFilter"},
1158 { 0x0047,
"Temperature"},
1159 { 0x0048,
"AELock"},
1160 { 0x0049,
"NoiseReduction"},
1161 { 0x004d,
"FlashExposureCompensation"},
1162 { 0x004f,
"ImageTone"},
1163 { 0x0050,
"ColorTemperature"},
1164 { 0x005c,
"ShakeReduction"},
1165 { 0x005d,
"ShutterCount"},
1166 { 0x0069,
"DynamicRangeExpansion"},
1167 { 0x0071,
"HighISONoiseReduction"},
1168 { 0x0072,
"AFAdjustment"},
1169 { 0x0200,
"BlackPoint"},
1170 { 0x0201,
"WhitePoint"},
1171 { 0x0205,
"ShotInfo"},
1172 { 0x0206,
"AEInfo"},
1173 { 0x0207,
"LensInfo"},
1174 { 0x0208,
"FlashInfo"},
1175 { 0x0209,
"AEMeteringSegments"},
1176 { 0x020a,
"FlashADump"},
1177 { 0x020b,
"FlashBDump"},
1178 { 0x020d,
"WB_RGGBLevelsDaylight"},
1179 { 0x020e,
"WB_RGGBLevelsShade"},
1180 { 0x020f,
"WB_RGGBLevelsCloudy"},
1181 { 0x0210,
"WB_RGGBLevelsTungsten"},
1182 { 0x0211,
"WB_RGGBLevelsFluorescentD"},
1183 { 0x0212,
"WB_RGGBLevelsFluorescentN"},
1184 { 0x0213,
"WB_RGGBLevelsFluorescentW"},
1185 { 0x0214,
"WB_RGGBLevelsFlash"},
1186 { 0x0215,
"CameraInfo"},
1187 { 0x0216,
"BatteryInfo"},
1188 { 0x021f,
"AFInfo"},
1189 { 0x0222,
"ColorInfo"},
1190 { 0x0229,
"SerialNumber"},
1195 { 0x0000,
"Version"},
1196 { 0x0001,
"CameraSettingsStdOld"},
1197 { 0x0003,
"CameraSettingsStdNew"},
1198 { 0x0004,
"CameraSettings7D"},
1199 { 0x0018,
"ImageStabilizationData"},
1200 { 0x0020,
"WBInfoA100"},
1201 { 0x0040,
"CompressedImageSize"},
1202 { 0x0081,
"Thumbnail"},
1203 { 0x0088,
"ThumbnailOffset"},
1204 { 0x0089,
"ThumbnailLength"},
1205 { 0x0100,
"SceneMode"},
1206 { 0x0101,
"ColorMode"},
1207 { 0x0102,
"Quality"},
1208 { 0x0104,
"FlashExposureComp"},
1209 { 0x0105,
"Teleconverter"},
1210 { 0x0107,
"ImageStabilization"},
1211 { 0x0109,
"RawAndJpgRecording"},
1212 { 0x010a,
"ZoneMatching"},
1213 { 0x010b,
"ColorTemperature"},
1214 { 0x010c,
"LensID"},
1215 { 0x0111,
"ColorCompensationFilter"},
1216 { 0x0112,
"WhiteBalanceFineTune"},
1217 { 0x0113,
"ImageStabilizationA100"},
1218 { 0x0114,
"CameraSettings5D"},
1219 { 0x0115,
"WhiteBalance"},
1220 { 0x0e00,
"PrintIM"},
1221 { 0x0f00,
"CameraSettingsZ1"},
1226 { 0x0002,
"SerialNumber"},
1227 { 0x0003,
"DriveMode"},
1228 { 0x0004,
"ResolutionMode"},
1229 { 0x0005,
"AutofocusMode"},
1230 { 0x0006,
"FocusSetting"},
1231 { 0x0007,
"WhiteBalance"},
1232 { 0x0008,
"ExposureMode"},
1233 { 0x0009,
"MeteringMode"},
1234 { 0x000a,
"LensRange"},
1235 { 0x000b,
"ColorSpace"},
1236 { 0x000c,
"Exposure"},
1237 { 0x000d,
"Contrast"},
1238 { 0x000e,
"Shadow"},
1239 { 0x000f,
"Highlight"},
1240 { 0x0010,
"Saturation"},
1241 { 0x0011,
"Sharpness"},
1242 { 0x0012,
"FillLight"},
1243 { 0x0014,
"ColorAdjustment"},
1244 { 0x0015,
"AdjustmentMode"},
1245 { 0x0016,
"Quality"},
1246 { 0x0017,
"Firmware"},
1247 { 0x0018,
"Software"},
1248 { 0x0019,
"AutoBracket"},
1253 { 0x0001,
"FormatThumbnail"},
1254 { 0x0E00,
"PrintImageMatchingInfo"},
1259 { 0x0001,
"MakerNoteDataType"},
1260 { 0x0002,
"Version"},
1261 { 0x0E00,
"PrintImageMatchingInfo"},
1262 { 0x2001,
"RicohCameraInfoMakerNoteSubIFD"},
1288#define REQUIRES_CUSTOM_PARSING NULL
1323 if (!zend_hash_index_add_ptr(
ht, tag_table->
Tag, tag_table->
Desc)) {
1331static void exif_tag_ht_dtor(
zval *
zv)
1352 ht = exif_make_tag_ht(tag_table);
1359static char *exif_get_tagname(
int tag_num,
tag_table_type tag_table)
1361 return zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
1365static char *exif_get_tagname_debug(
int tag_num,
tag_table_type tag_table)
1367 char *desc = zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
1371 return "UndefinedTag";
1374static char *exif_get_tagname_key(
int tag_num,
char *
buf,
size_t buf_size,
tag_table_type tag_table)
1376 char *desc = zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
1380 snprintf(
buf, buf_size,
"UndefinedTag:0x%04X", tag_num);
1387static char* exif_char_dump(
char *
addr,
int len,
int offset)
1389 static char buf[4096+1];
1390 static char tmp[20];
1391 int c, i,
p=0,
n = 5+31;
1395 for(i=0; i<
len+15 &&
p+
n<=
sizeof(
buf); i++) {
1400 c = *((
unsigned char *)
addr++);
1402 tmp[i%16] = c>=32 ? c :
'.';
1403 tmp[(i%16)+1] =
'\0';
1415 buf[
sizeof(
buf)-1] =
'\0';
1424static int php_jpg_get16(
void *
value)
1432static int php_ifd_get16u(
void *
value,
int motorola_intel)
1434 if (motorola_intel) {
1444static signed short php_ifd_get16s(
void *
value,
int motorola_intel)
1446 return (
signed short)php_ifd_get16u(
value, motorola_intel);
1452static unsigned php_ifd_get32u(
void *void_value,
int motorola_intel)
1455 if (motorola_intel) {
1456 return ((
unsigned)
value[0] << 24)
1457 | ((unsigned)
value[1] << 16)
1458 | ((
unsigned)
value[2] << 8 )
1459 | ((unsigned)
value[3] );
1461 return ((
unsigned)
value[3] << 24)
1462 | ((unsigned)
value[2] << 16)
1463 | ((
unsigned)
value[1] << 8 )
1464 | ((unsigned)
value[0] );
1471static uint64_t php_ifd_get64u(
void *void_value,
int motorola_intel)
1474 if (motorola_intel) {
1475 return ((uint64_t)
value[0] << 56)
1476 | ((uint64_t)
value[1] << 48)
1477 | ((uint64_t)
value[2] << 40)
1478 | ((uint64_t)
value[3] << 32)
1479 | ((uint64_t)
value[4] << 24)
1480 | ((uint64_t)
value[5] << 16)
1481 | ((uint64_t)
value[6] << 8 )
1482 | ((uint64_t)
value[7] );
1484 return ((uint64_t)
value[7] << 56)
1485 | ((uint64_t)
value[6] << 48)
1486 | ((uint64_t)
value[5] << 40)
1487 | ((uint64_t)
value[4] << 32)
1488 | ((uint64_t)
value[3] << 24)
1489 | ((uint64_t)
value[2] << 16)
1490 | ((uint64_t)
value[1] << 8 )
1491 | ((uint64_t)
value[0] );
1498static unsigned php_ifd_get32s(
void *
value,
int motorola_intel)
1500 return (
int) php_ifd_get32u(
value, motorola_intel);
1506static void php_ifd_set16u(
char *
data,
unsigned int value,
int motorola_intel)
1508 if (motorola_intel) {
1520static void php_ifd_set32u(
char *
data,
size_t value,
int motorola_intel)
1522 if (motorola_intel) {
1524 data[1] = (char) ((
value & 0x00FF0000) >> 16);
1529 data[2] = (char) ((
value & 0x00FF0000) >> 16);
1536static float php_ifd_get_float(
char *
data) {
1537 union { uint32_t i;
float f; }
u;
1538 u.i = php_ifd_get32u(
data, 0);
1542static double php_ifd_get_double(
char *
data) {
1543 union { uint64_t i;
double f; }
u;
1544 u.i = php_ifd_get64u(
data, 0);
1549char * exif_dump_data(
int *dump_free,
int format,
int components,
int motorola_intel,
char *
value_ptr)
1559 return "<undefined>";
1565 return "<not implemented>";
1568 if (components > 1) {
1573 while(components > 0) {
1606 if (components > 0) {
1624static double exif_convert_any_format(
void *
value,
int format,
int motorola_intel)
1637 u_den = php_ifd_get32u(4+(
char *)
value, motorola_intel);
1641 return (
double)php_ifd_get32u(
value, motorola_intel) / u_den;
1645 s_den = php_ifd_get32s(4+(
char *)
value, motorola_intel);
1649 return (
double)php_ifd_get32s(
value, motorola_intel) / s_den;
1660 return (
double) php_ifd_get_float(
value);
1665 return php_ifd_get_double(
value);
1673static int exif_rewrite_tag_format_to_unsigned(
int format)
1686static size_t float_to_size_t(
float x) {
1696static size_t double_to_size_t(
double x) {
1699 }
else if (x > (
double)
SIZE_MAX) {
1708static size_t exif_convert_any_to_int(
void *
value,
int format,
int motorola_intel)
1718 unsigned u_den = php_ifd_get32u(4+(
char *)
value, motorola_intel);
1722 return php_ifd_get32u(
value, motorola_intel) / u_den;
1727 int s_num = php_ifd_get32s(
value, motorola_intel);
1728 int s_den = php_ifd_get32s(4+(
char *)
value, motorola_intel);
1731 }
else if (s_num ==
INT_MIN && s_den == -1) {
1734 return s_num / s_den;
1746 return float_to_size_t(php_ifd_get_float(
value));
1751 return double_to_size_t(php_ifd_get_double(
value));
1759#define WORD unsigned short
1762#define DWORD unsigned int
1805#define SECTION_FILE 0
1806#define SECTION_COMPUTED 1
1807#define SECTION_ANY_TAG 2
1808#define SECTION_IFD0 3
1809#define SECTION_THUMBNAIL 4
1810#define SECTION_COMMENT 5
1811#define SECTION_APP0 6
1812#define SECTION_EXIF 7
1813#define SECTION_FPIX 8
1814#define SECTION_GPS 9
1815#define SECTION_INTEROP 10
1816#define SECTION_APP12 11
1817#define SECTION_WINXP 12
1818#define SECTION_MAKERNOTE 13
1819#define SECTION_COUNT 14
1821#define FOUND_FILE (1<<SECTION_FILE)
1822#define FOUND_COMPUTED (1<<SECTION_COMPUTED)
1823#define FOUND_ANY_TAG (1<<SECTION_ANY_TAG)
1824#define FOUND_IFD0 (1<<SECTION_IFD0)
1825#define FOUND_THUMBNAIL (1<<SECTION_THUMBNAIL)
1826#define FOUND_COMMENT (1<<SECTION_COMMENT)
1827#define FOUND_APP0 (1<<SECTION_APP0)
1828#define FOUND_EXIF (1<<SECTION_EXIF)
1829#define FOUND_FPIX (1<<SECTION_FPIX)
1830#define FOUND_GPS (1<<SECTION_GPS)
1831#define FOUND_INTEROP (1<<SECTION_INTEROP)
1832#define FOUND_APP12 (1<<SECTION_APP12)
1833#define FOUND_WINXP (1<<SECTION_WINXP)
1834#define FOUND_MAKERNOTE (1<<SECTION_MAKERNOTE)
1836static char *exif_get_sectionname(
int section)
1874 return &tag_table_IFD[0];
1881static char *exif_get_sectionlist(
int sectionlist)
1887 ml +=
strlen(exif_get_sectionname(i))+2;
1893 if (sectionlist&(1<<i)) {
1899 sections[
len-2] =
'\0';
1997#define EXIF_MAX_ERRORS 10
1999#define EXIF_MAX_ERRORS 100000
2011 "Further exif parsing errors have been suppressed");
2017 va_start(
args, format);
2022 spprintf(&
buf, 0,
"%s(%ld): %s", _file, _line, format);
2051 return UINTPTR_MAX - (uintptr_t)
ptr <
offset;
2054static inline void exif_offset_info_init(
2055 exif_offset_info *info,
char *offset_base,
char *valid_start,
size_t valid_length) {
2056 ZEND_ASSERT(!ptr_offset_overflows(valid_start, valid_length));
2057#ifdef __SANITIZE_ADDRESS__
2058 ZEND_ASSERT(!__asan_region_is_poisoned(valid_start, valid_length));
2062 info->
valid_end = valid_start + valid_length;
2066static inline char *exif_offset_info_try_get(
2074 if (ptr_offset_overflows(
start, length)) {
2086static inline bool exif_offset_info_contains(
2089 if (ptr_offset_overflows(
start, length)) {
2139static int exif_file_sections_realloc(
image_info_type *ImageInfo,
int section_index,
size_t size)
2146 if (section_index >= ImageInfo->
file.
count) {
2165 for (i=0; i<ImageInfo->
file.
count; i++) {
2182 return &info_list->
list[info_list->
count++];
2188static void exif_iif_add_value(
image_info_type *image_info,
int section_index,
char *
name,
int tag,
int format,
size_t length,
void*
value,
size_t value_len,
int motorola_intel)
2191 void *vptr, *vptr_end;
2195 info_data = exif_alloc_image_info_data(&image_info->
info_list[section_index]);
2197 info_data->
tag = tag;
2198 info_data->
format = format;
2199 info_data->
length = length;
2201 info_value = &info_data->
value;
2205 if (length > value_len) {
2206 exif_error_docref(
"exif_iif_add_value" EXIFERR_CC, image_info,
E_WARNING,
"length > value_len: %d > %zu", length, value_len);
2210 length = zend_strnlen(
value, length);
2212 info_data->
length = length;
2235 if (length > value_len) {
2236 exif_error_docref(
"exif_iif_add_value" EXIFERR_CC, image_info,
E_WARNING,
"length > value_len: %d > %zu", length, value_len);
2241 length = zend_strnlen(
value, length);
2246 info_data->
length = length;
2267 info_value = &info_data->
value;
2269 vptr_end = (
char *)
value + value_len;
2270 for (idex=0,vptr=
value; idex<length; idex++,vptr=(
char *) vptr + php_tiff_bytes_per_format[format]) {
2271 if ((
char *) vptr_end - (
char *) vptr < php_tiff_bytes_per_format[format]) {
2272 exif_error_docref(
"exif_iif_add_value" EXIFERR_CC, image_info,
E_WARNING,
"Value too short");
2276 info_value = &info_data->
value.
list[idex];
2280 info_value->
u = php_ifd_get16u(vptr, motorola_intel);
2284 info_value->
u = php_ifd_get32u(vptr, motorola_intel);
2288 info_value->
ur.
num = php_ifd_get32u(vptr, motorola_intel);
2289 info_value->
ur.
den = php_ifd_get32u(4+(
char *)vptr, motorola_intel);
2293 info_value->
i = php_ifd_get16s(vptr, motorola_intel);
2297 info_value->
i = php_ifd_get32s(vptr, motorola_intel);
2301 info_value->
sr.
num = php_ifd_get32u(vptr, motorola_intel);
2302 info_value->
sr.
den = php_ifd_get32u(4+(
char *)vptr, motorola_intel);
2309 info_value->
f = php_ifd_get_float(
value);
2315 info_value->
d = php_ifd_get_double(
value);
2327static void exif_iif_add_tag(
image_info_type *image_info,
int section_index,
char *
name,
int tag,
int format,
size_t length,
void*
value,
size_t value_len)
2329 exif_iif_add_value(image_info, section_index,
name, tag, format, length,
value, value_len, image_info->
motorola_intel);
2355 exif_alloc_image_info_data(&image_info->
info_list[section_index]);
2374 va_start(arglist,
value);
2377 exif_iif_add_str(image_info, section_index,
name, tmp);
2387static void exif_iif_add_buffer(
image_info_type *image_info,
int section_index,
char *
name,
int length,
char *
value)
2391 exif_alloc_image_info_data(&image_info->
info_list[section_index]);
2394 info_data->
length = length;
2398 info_data->
value.
s[length] = 0;
2407static void exif_iif_free(
image_info_type *image_info,
int section_index) {
2453 char buffer[64], uname[64];
2454 int idx = 0, unknown = 0;
2467 for (
int i = 0; i<image_info->
info_list[section_index].
count; i++) {
2470 const char *
name = info_data->
name;
2472 snprintf(uname,
sizeof(uname),
"%d", unknown++);
2476 if (info_data->
length == 0) {
2477 add_assoc_null(&tmpi,
name);
2479 switch (info_data->
format) {
2489 if (!info_value->
s) {
2490 add_assoc_stringl(&tmpi,
name,
"", 0);
2492 add_assoc_stringl(&tmpi,
name, info_value->
s, info_data->
length);
2497 const char *
val = info_value->
s ? info_value->
s :
"";
2501 add_assoc_string(&tmpi,
name,
val);
2516 int l = info_data->
length;
2520 for (
int ap = 0; ap < l; ap++) {
2522 info_value = &info_data->
value.
list[ap];
2524 switch (info_data->
format) {
2527 info_value = &info_data->
value;
2528 for (
int b = 0; b < l; b++) {
2537 add_assoc_long(&tmpi,
name, (
int)info_value->
u);
2554 info_value = &info_data->
value;
2555 for (
int b = 0; b < l; b++) {
2564 add_assoc_long(&tmpi,
name, info_value->
i);
2581 add_assoc_double(&tmpi,
name, info_value->
f);
2589 add_assoc_double(&tmpi,
name, info_value->
d);
2597 add_assoc_zval(&tmpi,
name, &array);
2605 add_assoc_zval(
value, exif_get_sectionname(section_index), &tmpi);
2682#define M_PSEUDO 0x123
2701 result->bits_per_sample = Data[2];
2702 result->height = php_jpg_get16(Data+3);
2703 result->width = php_jpg_get16(Data+5);
2704 result->num_components = Data[7];
2709static bool exif_process_IFD_in_JPEG(
image_info_type *ImageInfo,
char *dir_start,
const exif_offset_info *info,
size_t displacement,
int section_index,
int tag);
2711static bool exif_process_IFD_in_TIFF(
image_info_type *ImageInfo,
size_t dir_offset,
int section_index);
2716static char * exif_get_markername(
int marker)
2719 case 0xC0:
return "SOF0";
2720 case 0xC1:
return "SOF1";
2721 case 0xC2:
return "SOF2";
2722 case 0xC3:
return "SOF3";
2723 case 0xC4:
return "DHT";
2724 case 0xC5:
return "SOF5";
2725 case 0xC6:
return "SOF6";
2726 case 0xC7:
return "SOF7";
2727 case 0xC9:
return "SOF9";
2728 case 0xCA:
return "SOF10";
2729 case 0xCB:
return "SOF11";
2730 case 0xCD:
return "SOF13";
2731 case 0xCE:
return "SOF14";
2732 case 0xCF:
return "SOF15";
2733 case 0xD8:
return "SOI";
2734 case 0xD9:
return "EOI";
2735 case 0xDA:
return "SOS";
2736 case 0xDB:
return "DQT";
2737 case 0xDC:
return "DNL";
2738 case 0xDD:
return "DRI";
2739 case 0xDE:
return "DHP";
2740 case 0xDF:
return "EXP";
2741 case 0xE0:
return "APP0";
2742 case 0xE1:
return "EXIF";
2743 case 0xE2:
return "FPIX";
2744 case 0xE3:
return "APP3";
2745 case 0xE4:
return "APP4";
2746 case 0xE5:
return "APP5";
2747 case 0xE6:
return "APP6";
2748 case 0xE7:
return "APP7";
2749 case 0xE8:
return "APP8";
2750 case 0xE9:
return "APP9";
2751 case 0xEA:
return "APP10";
2752 case 0xEB:
return "APP11";
2753 case 0xEC:
return "APP12";
2754 case 0xED:
return "APP13";
2755 case 0xEE:
return "APP14";
2756 case 0xEF:
return "APP15";
2757 case 0xF0:
return "JPG0";
2758 case 0xFD:
return "JPG13";
2759 case 0xFE:
return "COM";
2760 case 0x01:
return "TEM";
2777 szTemp = exif_get_tagname(tag, tag_table_IFD);
2778 if (tag < 0 || !szTemp) {
2788static void* exif_ifd_make_value(
image_info_data *info_data,
int motorola_intel) {
2795 byte_count = php_tiff_bytes_per_format[info_data->
format] * info_data->
length;
2798 if (!info_data->
length) {
2814 for(i=0; i<info_data->
length; i++) {
2815 if (info_data->
length==1) {
2816 info_value = &info_data->
value;
2820 switch(info_data->
format) {
2822 php_ifd_set16u(data_ptr, info_value->
u, motorola_intel);
2826 php_ifd_set32u(data_ptr, info_value->
u, motorola_intel);
2830 php_ifd_set16u(data_ptr, info_value->
i, motorola_intel);
2834 php_ifd_set32u(data_ptr, info_value->
i, motorola_intel);
2838 php_ifd_set32u(data_ptr, info_value->
sr.
num, motorola_intel);
2839 php_ifd_set32u(data_ptr+4, info_value->
sr.
den, motorola_intel);
2843 php_ifd_set32u(data_ptr, info_value->
ur.
num, motorola_intel);
2844 php_ifd_set32u(data_ptr+4, info_value->
ur.
den, motorola_intel);
2848 memcpy(data_ptr, &info_value->
f, 4);
2852 memcpy(data_ptr, &info_value->
d, 8);
2865 size_t new_size, new_move, new_value;
2886 new_size = 8 + 2 + info_list->
count * 12 + 4;
2888 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Thumbnail: size of signature + directory(%d): 0x%02X", info_list->
count, new_size);
2890 new_value= new_size;
2891 for (i=0; i<info_list->
count; i++) {
2892 info_data = &info_list->
list[i];
2893 byte_count = php_tiff_bytes_per_format[info_data->
format] * info_data->
length;
2894 if (byte_count > 4) {
2895 new_size += byte_count;
2898 new_move = new_size;
2905 memcpy(new_data,
"MM\x00\x2a\x00\x00\x00\x08", 8);
2907 memcpy(new_data,
"II\x2a\x00\x08\x00\x00\x00", 8);
2912 for (i=0; i<info_list->
count; i++) {
2913 info_data = &info_list->
list[i];
2914 byte_count = php_tiff_bytes_per_format[info_data->
format] * info_data->
length;
2922 php_ifd_set32u(new_data + 8, new_move, ImageInfo->
motorola_intel);
2928 if (byte_count <= 4) {
2931 php_ifd_set32u(new_data+8, new_value, ImageInfo->
motorola_intel);
2933 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Thumbnail: writing with value offset: 0x%04X + 0x%02X", new_value, byte_count);
2936 new_value += byte_count;
2955 exif_error_docref(
"exif_read_data#error_mult_thumb" EXIFERR_CC, ImageInfo,
E_WARNING,
"Multiple possible thumbnails");
2970 char *thumbnail = exif_offset_info_try_get(
2977 exif_thumbnail_build(ImageInfo);
2983static int exif_process_undefined(
char **
result,
char *
value,
size_t byte_count) {
2991 return byte_count+1;
2999static int exif_process_string_raw(
char **
result,
char *
value,
size_t byte_count) {
3007 (*result)[byte_count] =
'\0';
3008 return byte_count+1;
3017static int exif_process_string(
char **
result,
char *
value,
size_t byte_count) {
3025 if ((byte_count=zend_strnlen(
value, byte_count)) > 0) {
3026 return exif_process_undefined(
result,
value, byte_count);
3029 return byte_count+1;
3035static int exif_process_user_comment(
image_info_type *ImageInfo,
char **pszInfoPtr,
char **pszEncoding,
char *szValuePtr,
int ByteCount)
3041 *pszEncoding =
NULL;
3045 if (!memcmp(szValuePtr,
"UNICODE\0", 8)) {
3046 *pszEncoding =
estrdup((
const char*)szValuePtr);
3047 szValuePtr = szValuePtr+8;
3052 if (ByteCount >=2 && !memcmp(szValuePtr,
"\xFE\xFF", 2)) {
3054 szValuePtr = szValuePtr+2;
3056 }
else if (ByteCount >=2 && !memcmp(szValuePtr,
"\xFF\xFE", 2)) {
3058 szValuePtr = szValuePtr+2;
3069 (
unsigned char**)pszInfoPtr,
3071 (
unsigned char*)szValuePtr,
3074 from) == (
size_t)-1) {
3075 len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
3078 }
else if (!memcmp(szValuePtr,
"ASCII\0\0\0", 8)) {
3079 *pszEncoding =
estrdup((
const char*)szValuePtr);
3080 szValuePtr = szValuePtr+8;
3082 }
else if (!memcmp(szValuePtr,
"JIS\0\0\0\0\0", 8)) {
3084 *pszEncoding =
estrdup((
const char*)szValuePtr);
3085 szValuePtr = szValuePtr+8;
3091 (
unsigned char**)pszInfoPtr,
3093 (
unsigned char*)szValuePtr,
3096 from) == (
size_t)-1) {
3097 len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
3100 }
else if (!memcmp(szValuePtr,
"\0\0\0\0\0\0\0\0", 8)) {
3102 *pszEncoding =
estrdup(
"UNDEFINED");
3103 szValuePtr = szValuePtr+8;
3110 for (
a=ByteCount-1;
a && szValuePtr[
a]==
' ';
a--) {
3111 (szValuePtr)[
a] =
'\0';
3116 exif_process_string(pszInfoPtr, szValuePtr, ByteCount);
3117 return strlen(*pszInfoPtr);
3125 xp_field->
tag = tag;
3129 (
unsigned char**)&xp_field->
value,
3131 (
unsigned char*)szValuePtr,
3136 xp_field->
size = exif_process_string_raw(&xp_field->
value, szValuePtr, ByteCount);
3138 return xp_field->
size;
3148 int NumDirEntries, old_motorola_intel;
3162 maker_note = maker_note_array+i;
3172 if (value_len < 2 || maker_note->
offset >= value_len - 1) {
3174 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->
offset);
3187 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Process %s @0x%04X + 0x%04X=%d: %s", exif_get_sectionname(section_index), (intptr_t)dir_start-(intptr_t)info->
offset_base+maker_note->
offset+displacement, value_len, value_len, exif_char_dump(
value_ptr, value_len, (intptr_t)dir_start-(intptr_t)info->
offset_base+maker_note->
offset+displacement));
3205 NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->
motorola_intel);
3208 if ((2+NumDirEntries*12) > value_len) {
3209 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Potentially invalid endianess, trying again with different endianness before imminent failure.");
3212 NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->
motorola_intel);
3215 if ((2+NumDirEntries*12) > value_len) {
3216 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
3219 if ((dir_start -
value_ptr) > value_len - (2+NumDirEntries*12)) {
3220 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD size: 0x%04X > 0x%04X", (dir_start -
value_ptr) + (2+NumDirEntries*12), value_len);
3234 for (de=0;de<NumDirEntries;de++) {
3235 size_t offset = 2 + 12 * de;
3236 if (!exif_process_IFD_TAG(ImageInfo, dir_start +
offset,
3237 info, displacement, section_index, 0, maker_note->
tag_table)) {
3250#define REQUIRE_NON_EMPTY() do { \
3251 if (byte_count == 0) { \
3252 exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Cannot be empty", tag, exif_get_tagname_debug(tag, tag_table)); \
3263 unsigned int tag, format, components;
3265 size_t byte_count, offset_val, fpos, fgot;
3266 int64_t byte_count_signed;
3275 components = php_ifd_get32u(dir_entry+4, ImageInfo->
motorola_intel);
3279 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Process tag(x%04X=%s): Illegal format code 0x%04X, suppose BYTE", tag, exif_get_tagname_debug(tag, tag_table), format);
3283 byte_count_signed = (int64_t)components * php_tiff_bytes_per_format[format];
3285 if (byte_count_signed < 0 || (byte_count_signed > INT32_MAX)) {
3286 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Process tag(x%04X=%s): Illegal byte_count", tag, exif_get_tagname_debug(tag, tag_table));
3290 byte_count = (size_t)byte_count_signed;
3292 if (byte_count > 4) {
3294 offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->
motorola_intel);
3295 value_ptr = exif_offset_info_try_get(info, offset_val, byte_count);
3302 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname_debug(tag, tag_table), offset_val, byte_count, offset_val+byte_count, ImageInfo->
FileSize);
3305 if (byte_count>
sizeof(cbuf)) {
3315 memset(&cbuf, 0,
sizeof(cbuf));
3322 if (fgot!=displacement+offset_val) {
3324 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"Wrong file pointer: 0x%08X != 0x%08X", fgot, displacement+offset_val);
3327 fgot = exif_read_from_stream_file_looped(ImageInfo->
infile,
value_ptr, byte_count);
3329 if (fgot != byte_count) {
3346 "Process tag(x%04X=%s,@0x%04X + x%04X(=%d)): %s%s %s",
3347 tag, exif_get_tagname_debug(tag, tag_table), offset_val+displacement, byte_count, byte_count, (components>1)&&format!=
TAG_FMT_UNDEFINED&&format!=
TAG_FMT_STRING?
"ARRAY OF ":
"", exif_get_tagformat(format), dump_data);
3399 if (byte_count>1 && (length=zend_strnlen(
value_ptr, byte_count)) > 0) {
3400 if (length<byte_count-1) {
3524 if (!exif_process_IFD_in_MAKERNOTE(ImageInfo,
value_ptr, byte_count, info, displacement)) {
3536 int sub_section_index = 0;
3561 Subdir_start = exif_offset_info_try_get(info, offset_val, 0);
3562 if (!Subdir_start) {
3563 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD Pointer");
3567 if (!exif_process_IFD_in_JPEG(ImageInfo, Subdir_start, info, displacement, sub_section_index, tag)) {
3572 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Subsection %s done", exif_get_sectionname(sub_section_index));
3577 exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname_key(tag, tagname,
sizeof(tagname), tag_table), tag, format, components,
value_ptr, byte_count);
3588 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"corrupt EXIF header: maximum IFD tag count reached");
3592 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"corrupt EXIF header: maximum directory nesting level reached");
3596 result = exif_process_IFD_TAG_impl(ImageInfo, dir_entry, info, displacement, section_index, ReadNextIFD, tag_table);
3603static bool exif_process_IFD_in_JPEG(
image_info_type *ImageInfo,
char *dir_start,
const exif_offset_info *info,
size_t displacement,
int section_index,
int tag)
3607 int NextDirOffset = 0;
3610 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Process %s (x%04X(=%d))", exif_get_sectionname(section_index), exif_offset_info_length(info), exif_offset_info_length(info));
3615 if (!exif_offset_info_contains(info, dir_start, 2)) {
3616 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD size");
3620 NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->
motorola_intel);
3622 if (!exif_offset_info_contains(info, dir_start+2, NumDirEntries*12)) {
3623 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD size: x%04X + 2 + x%04X*12 = x%04X > x%04X", (
int)((
size_t)dir_start+2-(
size_t)info->
valid_start), NumDirEntries, (
int)((
size_t)dir_start+2+NumDirEntries*12-(
size_t)info->
valid_start), info->
valid_end - info->
valid_start);
3627 for (de=0;de<NumDirEntries;de++) {
3628 if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
3629 info, displacement, section_index, 1, exif_get_tag_table(section_index))) {
3643 if (!exif_offset_info_contains(info, dir_start+2+NumDirEntries*12, 4)) {
3644 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD size");
3649 NextDirOffset = php_ifd_get32u(dir_start+2+12*de, ImageInfo->
motorola_intel);
3652 if (NextDirOffset) {
3653 char *next_dir_start = exif_offset_info_try_get(info, NextDirOffset, 0);
3654 if (!next_dir_start) {
3655 exif_error_docref(
"exif_read_data#error_ifd" EXIFERR_CC, ImageInfo,
E_WARNING,
"Illegal IFD offset");
3662 if (exif_process_IFD_in_JPEG(ImageInfo, next_dir_start, info, displacement,
SECTION_THUMBNAIL, 0)) {
3671 exif_thumbnail_extract(ImageInfo, info);
3685static void exif_process_TIFF_in_JPEG(
image_info_type *ImageInfo,
char *CharBuf,
size_t length,
size_t displacement)
3687 unsigned exif_value_2a, offset_of_ifd;
3696 if (memcmp(CharBuf,
"II", 2) == 0) {
3698 }
else if (memcmp(CharBuf,
"MM", 2) == 0) {
3710 exif_value_2a = php_ifd_get16u(CharBuf+2, ImageInfo->
motorola_intel);
3711 offset_of_ifd = php_ifd_get32u(CharBuf+4, ImageInfo->
motorola_intel);
3712 if (exif_value_2a != 0x2a || offset_of_ifd < 0x08) {
3716 if (offset_of_ifd > length) {
3723 exif_offset_info_init(&info, CharBuf, CharBuf, length);
3724 exif_process_IFD_in_JPEG(ImageInfo, CharBuf+offset_of_ifd, &info, displacement,
SECTION_IFD0, 0);
3741static void exif_process_APP1(
image_info_type *ImageInfo,
char *CharBuf,
size_t length,
size_t displacement)
3744 static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
3745 if (length <= 8 || memcmp(CharBuf+2, ExifHeader, 6)) {
3749 exif_process_TIFF_in_JPEG(ImageInfo, CharBuf + 8, length - 8, displacement+8);
3763 if ((l1 = zend_strnlen(
buffer+2, length-2)) > 0) {
3765 if (length > 2+l1+1) {
3766 l2 = zend_strnlen(
buffer+2+l1+1, length-2-l1-1);
3771 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Process section APP12 with l1=%d, l2=%d done", l1, l2);
3781 int marker = 0, last_marker =
M_PSEUDO, comment_correction=1;
3782 unsigned int ll, lh;
3784 size_t fpos,
size, got, itemlen;
3796 if (last_marker==
M_COM && comment_correction) {
3797 comment_correction = 2;
3804 if (last_marker==
M_COM && comment_correction>0) {
3807 comment_correction--;
3812 }
while (marker == 0xff);
3813 if (last_marker==
M_COM && !comment_correction) {
3814 exif_error_docref(
"exif_read_data#error_mcom" EXIFERR_CC, ImageInfo,
E_NOTICE,
"Image has corrupt COM section: some software set wrong length information");
3816 if (last_marker==
M_COM && comment_correction)
3834 itemlen = (lh << 8) | ll;
3838 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"%s, Section length: 0x%02X%02X", EXIF_ERROR_CORRUPT, lh, ll);
3845 sn = exif_file_sections_add(ImageInfo, marker, itemlen,
NULL);
3849 Data[0] = (
uchar)lh;
3850 Data[1] = (
uchar)ll;
3852 got = exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)(Data+2), itemlen-2);
3853 if (got != itemlen-2) {
3854 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"Error reading from file: got=x%04X(=%d) != itemlen-2=x%04X(=%d)", got, got, itemlen-2, itemlen-2);
3859 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Process section(x%02X=%s) @ x%04X + x%04X(=%d)", marker, exif_get_markername(marker), fpos, itemlen, itemlen);
3870 got = exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)Data,
size);
3883 exif_process_COM(ImageInfo, (
char *)Data, itemlen);
3891 exif_process_APP1(ImageInfo, (
char *)Data, itemlen, fpos);
3896 exif_process_APP12(ImageInfo, (
char *)Data, itemlen);
3913 if ((itemlen - 2) < 6) {
3917 exif_process_SOFn(Data, marker, &sof_info);
3932 last_marker = marker;
3947 size_t length=2,
pos=0;
3953 if (memcmp(
data,
"\xFF\xD8\xFF", 3)) {
3970 while ((c =
data[
pos++]) == 0xFF &&
n--) {
3980 length = php_jpg_get16(
data+
pos);
3985 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Thumbnail: process section(x%02X=%s) @ x%04X + x%04X", marker, exif_get_markername(marker),
pos, length);
4002 if (length < 8 || ImageInfo->Thumbnail.size - 8 <
pos) {
4006 exif_process_SOFn(
data+
pos, marker, &sof_info);
4033static bool exif_process_IFD_in_TIFF_impl(
image_info_type *ImageInfo,
size_t dir_offset,
int section_index)
4035 int i, sn, num_entries, sub_section_index = 0;
4036 unsigned char *dir_entry;
4037 size_t ifd_size, dir_size, entry_offset, next_offset, entry_length, entry_value=0, fgot;
4038 int entry_tag , entry_type;
4042 sn = exif_file_sections_add(ImageInfo,
M_PSEUDO, 2,
NULL);
4044 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X)", ImageInfo->
FileSize, dir_offset, 2);
4051 dir_size = 2 +12*(size_t)num_entries +4;
4052 if (ImageInfo->
FileSize >= dir_size && ImageInfo->
FileSize - dir_size >= dir_offset) {
4054 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X), IFD entries(%d)", ImageInfo->
FileSize, dir_offset+2, dir_size-2, num_entries);
4056 if (exif_file_sections_realloc(ImageInfo, sn, dir_size)) {
4059 if (
UNEXPECTED(exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)(ImageInfo->
file.
list[sn].
data+2), dir_size-2) != dir_size - 2)) {
4064 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read from TIFF done, next offset x%04X", next_offset);
4067 ifd_size = dir_size;
4068 for(i=0;i<num_entries;i++) {
4070 entry_tag = php_ifd_get16u(dir_entry+0, ImageInfo->
motorola_intel);
4071 entry_type = php_ifd_get16u(dir_entry+2, ImageInfo->
motorola_intel);
4073 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read from TIFF: tag(0x%04X,%12s): Illegal format code 0x%04X, switching to BYTE", entry_tag, exif_get_tagname_debug(entry_tag, tag_table), entry_type);
4081 entry_length = php_ifd_get32u(dir_entry+4, ImageInfo->
motorola_intel) * php_tiff_bytes_per_format[entry_type];
4082 if (entry_length <= 4) {
4083 switch(entry_type) {
4085 entry_value = php_ifd_get16u(dir_entry+8, ImageInfo->
motorola_intel);
4088 entry_value = php_ifd_get16s(dir_entry+8, ImageInfo->
motorola_intel);
4091 entry_value = php_ifd_get32u(dir_entry+8, ImageInfo->
motorola_intel);
4094 entry_value = php_ifd_get32s(dir_entry+8, ImageInfo->
motorola_intel);
4100 ImageInfo->
Width = entry_value;
4104 ImageInfo->
Height = entry_value;
4107 switch (entry_value) {
4124 entry_offset = php_ifd_get32u(dir_entry+8, ImageInfo->
motorola_intel);
4127 if (entry_offset + entry_length > dir_offset + ifd_size
4128 && entry_offset == dir_offset + ifd_size) {
4129 ifd_size = entry_offset + entry_length - dir_offset;
4131 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Resize struct: x%04X + x%04X - x%04X = x%04X", entry_offset, entry_length, dir_offset, ifd_size);
4137 if (ifd_size > dir_size) {
4138 if (ImageInfo->
FileSize < ifd_size || dir_offset > ImageInfo->
FileSize - ifd_size) {
4139 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->
FileSize, dir_offset, ifd_size);
4142 if (exif_file_sections_realloc(ImageInfo, sn, ifd_size)) {
4147 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read from TIFF: filesize(x%04X), IFD(x%04X + x%04X)", ImageInfo->
FileSize, dir_offset, ifd_size);
4149 exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)(ImageInfo->
file.
list[sn].
data+dir_size), ifd_size-dir_size);
4155 for(i=0;i<num_entries;i++) {
4157 entry_tag = php_ifd_get16u(dir_entry+0, ImageInfo->
motorola_intel);
4158 entry_type = php_ifd_get16u(dir_entry+2, ImageInfo->
motorola_intel);
4183 entry_offset = php_ifd_get32u(dir_entry+8, ImageInfo->
motorola_intel);
4185 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Next IFD: %s @0x%04X", exif_get_sectionname(sub_section_index), entry_offset);
4187 exif_process_IFD_in_TIFF(ImageInfo, entry_offset, sub_section_index);
4207 exif_thumbnail_build(ImageInfo);
4213 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Next IFD: %s done", exif_get_sectionname(sub_section_index));
4217 exif_offset_info_init(&info,
4220 if (!exif_process_IFD_TAG(ImageInfo, (
char*)dir_entry, &info,
4221 0, section_index, 0, tag_table)) {
4231 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_NOTICE,
"Read next IFD (THUMBNAIL) at x%04X", next_offset);
4246 exif_thumbnail_build(ImageInfo);
4259 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->
FileSize, dir_offset+dir_size);
4263 exif_error_docref(
NULL EXIFERR_CC, ImageInfo,
E_WARNING,
"Error in TIFF: filesize(x%04X) less than start of IFD dir(x%04X)", ImageInfo->
FileSize, dir_offset+2);
4269static bool exif_process_IFD_in_TIFF(
image_info_type *ImageInfo,
size_t dir_offset,
int section_index)
4279 result = exif_process_IFD_in_TIFF_impl(ImageInfo, dir_offset, section_index);
4288 unsigned char file_header[8];
4295 if (exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)file_header, 2) != 2) {
4298 if ((file_header[0]==0xff) && (file_header[1]==
M_SOI)) {
4300 if (exif_scan_JPEG_header(ImageInfo)) {
4305 }
else if (ImageInfo->
FileSize >= 8) {
4306 if (exif_read_from_stream_file_looped(ImageInfo->
infile, (
char*)(file_header+2), 6) != 6) {
4309 if (!memcmp(file_header,
"II\x2A\x00", 4)) {
4316 if (exif_process_IFD_in_TIFF(ImageInfo,
4323 }
else if (!memcmp(file_header,
"MM\x00\x2a", 4)) {
4330 if (exif_process_IFD_in_TIFF(ImageInfo,
4376 exif_iif_free(ImageInfo, i);
4378 exif_file_sections_free(ImageInfo);
4379 memset(ImageInfo, 0,
sizeof(*ImageInfo));
4391 memset(ImageInfo, 0,
sizeof(*ImageInfo));
4394 ImageInfo->
infile = stream;
4400 if ((st.st_mode & S_IFMT) != S_IFREG) {
4441 ret = exif_scan_FILE_header(ImageInfo);
4457 ret = exif_read_from_impl(ImageInfo, stream, read_thumbnail, read_all);
4468static bool exif_read_from_file(
image_info_type *ImageInfo,
char *FileName,
int read_thumbnail,
int read_all)
4476 memset(&ImageInfo, 0,
sizeof(ImageInfo));
4483 ret = exif_read_from_stream(ImageInfo, stream, read_thumbnail, read_all);
4495 bool sub_arrays = 0, read_thumbnail = 0, read_all = 0;
4498 int i, sections_needed = 0;
4500 char tmp[64], *sections_str, *
s;
4511 memset(&ImageInfo, 0,
sizeof(ImageInfo));
4513 if (z_sections_needed) {
4524 snprintf(tmp,
sizeof(tmp),
",%s,", exif_get_sectionname(i));
4525 if (
strstr(sections_str, tmp)) {
4526 sections_needed |= 1<<i;
4532 sections_str = exif_get_sectionlist(sections_needed);
4533 if (!sections_str) {
4536 exif_error_docref(
NULL EXIFERR_CC, &ImageInfo,
E_NOTICE,
"Sections needed: %s", sections_str[0] ? sections_str :
"None");
4546 ret = exif_read_from_stream(&ImageInfo, p_stream, read_thumbnail, read_all);
4548 if (!try_convert_to_string(stream)) {
4562 ret = exif_read_from_file(&ImageInfo,
Z_STRVAL_P(stream), read_thumbnail, read_all);
4569 exif_error_docref(
NULL EXIFERR_CC, &ImageInfo,
E_NOTICE,
"Sections found: %s", sections_str[0] ? sections_str :
"None");
4575 if (
ret ==
false || (sections_needed && !(sections_needed&ImageInfo.
sections_found))) {
4577 exif_discard_imageinfo(&ImageInfo);
4594 exif_iif_add_str(&ImageInfo,
SECTION_FILE,
"SectionsFound", sections_str ? sections_str :
"NONE");
4619 float recip_exposure_time = 0.5f + 1.0f/ImageInfo.
ExposureTime;
4631 exif_iif_add_str(&ImageInfo,
SECTION_COMPUTED,
"FocusDistance",
"Infinite");
4651 if (read_thumbnail) {
4657 exif_scan_thumbnail(&ImageInfo);
4690 exif_discard_imageinfo(&ImageInfo);
4716 memset(&ImageInfo, 0,
sizeof(ImageInfo));
4723 ret = exif_read_from_stream(&ImageInfo, p_stream, 1, 0);
4725 if (!try_convert_to_string(stream)) {
4739 ret = exif_read_from_file(&ImageInfo,
Z_STRVAL_P(stream), 1, 0);
4743 exif_discard_imageinfo(&ImageInfo);
4751 exif_discard_imageinfo(&ImageInfo);
4762 if (!exif_scan_thumbnail(&ImageInfo)) {
4777 exif_discard_imageinfo(&ImageInfo);
4789 size_t imagefile_len;
4799 if (stream ==
NULL) {
count(Countable|array $value, int $mode=COUNT_NORMAL)
strstr(string $haystack, string $needle, bool $before_needle=false)
#define TAG_PHOTOMETRIC_INTERPRETATION
#define EXIF_ERRLOG_CORRUPT(ImageInfo)
tag_info_type * tag_table_type
#define EXIF_ERRLOG_FSREALLOC(ImageInfo)
#define TAG_FMT_URATIONAL
#define TAG_JPEG_INTERCHANGE_FORMAT_LEN
union _image_info_value image_info_value
#define EXIF_ERRLOG_THUMBEOF(ImageInfo)
#define TAG_FMT_UNDEFINED
#define TAG_INTEROP_IFD_POINTER
#define TAG_COMP_IMAGE_HEIGHT
#define PMI_PALETTE_COLOR
#define TAG_COMP_IMAGE_WIDTH
#define TAG_COMPUTED_VALUE
#define TAG_FMT_SRATIONAL
#define TAG_EXIF_IFD_POINTER
#define TAG_FOCALPLANE_RESOLUTION_UNIT
#define REQUIRE_NON_EMPTY()
HashTable * tag_table_cache
#define EXIF_ERRLOG_FILEEOF(ImageInfo)
#define TAG_STRIP_BYTE_COUNTS
#define TAG_STRIP_OFFSETS
#define MAX_IFD_NESTING_LEVEL
#define REQUIRES_CUSTOM_PARSING
#define PMI_WHITE_IS_ZERO
#define TAG_FOCALPLANE_X_RES
tag_info_type tag_info_array[]
zend_module_entry exif_module_entry
#define PMI_TRANSPARENCY_MASK
#define SECTION_MAKERNOTE
#define TAG_SUBJECT_DISTANCE
#define PMI_BLACK_IS_ZERO
#define SECTION_THUMBNAIL
#define TAG_JPEG_INTERCHANGE_FORMAT
#define TAG_GPS_IFD_POINTER
exif_imagetype(string $filename)
exif_thumbnail($file, &$width=null, &$height=null, &$image_type=null)
exif_read_data($file, ?string $required_sections=null, bool $as_arrays=false, bool $read_thumbnail=false)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
PHPAPI char * php_image_type_to_mime_type(int image_type)
PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetype)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format,...)
PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args)
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_MINFO_FUNCTION
#define PHP_GINIT_FUNCTION
#define PHP_MODULE_GLOBALS
unsigned const char * end
unsigned const char * pos
#define STD_PHP_INI_ENTRY
#define PHP_STREAM_IS_STDIO
struct _php_stream php_stream
#define php_stream_read(stream, buf, count)
#define php_stream_getc(stream)
#define php_stream_seek(stream, offset, whence)
#define php_stream_close(stream)
#define php_stream_is(stream, anops)
#define php_stream_tell(stream)
#define php_stream_from_res(xstr, res)
#define php_stream_open_wrapper(path, mode, options, opened)
PHPAPI zend_string * php_basename(const char *s, size_t len, const char *suffix, size_t sufflen)
char * UserCommentEncoding
char * CopyrightPhotographer
image_info_list info_list[SECTION_COUNT]
mn_offset_mode_t offset_mode
mn_byte_order_t byte_order
union _image_info_value * list
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
#define ZEND_TSRMLS_CACHE_UPDATE()
#define ZEND_TSRMLS_CACHE_DEFINE()
ZEND_API void add_index_string(zval *arg, zend_ulong index, const char *str)
ZEND_API void add_index_double(zval *arg, zend_ulong index, double d)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API void add_index_long(zval *arg, zend_ulong index, zend_long n)
#define CHECK_NULL_PATH(p, l)
#define ZEND_PARSE_PARAMETERS_END()
#define Z_PARAM_STR_OR_NULL(dest)
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define ZEND_GET_MODULE(name)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define ZEND_END_MODULE_GLOBALS(module_name)
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
#define Z_PARAM_BOOL(dest)
#define Z_PARAM_ZVAL(dest)
#define ZVAL_STRINGL(z, s, l)
#define ZEND_BEGIN_MODULE_GLOBALS(module_name)
#define safe_erealloc(ptr, nmemb, size, offset)
#define estrndup(s, length)
#define pefree(ptr, persistent)
#define erealloc(ptr, size)
#define safe_emalloc(nmemb, size, offset)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define UNREGISTER_INI_ENTRIES()
#define REGISTER_INI_ENTRIES()
#define DISPLAY_INI_ENTRIES()
#define ZEND_INI_MH(name)
struct _zend_string zend_string
#define ZEND_MOD_OPTIONAL(name)
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_PROPERTIES_EX
#define STANDARD_MODULE_HEADER_EX
ZEND_API const zend_encoding * zend_multibyte_fetch_encoding(const char *name)
ZEND_API size_t zend_multibyte_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const zend_encoding *encoding_to, const zend_encoding *encoding_from)
ZEND_API zend_result zend_multibyte_parse_encoding_list(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, bool persistent)
struct _zend_encoding zend_encoding
#define zend_always_inline
#define UNEXPECTED(condition)
#define Z_STRVAL_P(zval_p)
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
#define ZVAL_COPY_VALUE(z, v)
#define VCWD_STAT(path, buff)