📄 image.c
字号:
/* loop chunks to find BMHD chunk */ do { if (php_stream_read(stream, a, 8) != 8) { return NULL; } chunkId = php_ifd_get32s(a+0, 1); size = php_ifd_get32s(a+4, 1); if (size < 0) { return NULL; } if ((size & 1) == 1) { size++; } if (chunkId == 0x424d4844) { /* BMHD chunk */ if (size < 9 || php_stream_read(stream, a, 9) != 9) { return NULL; } width = php_ifd_get16s(a+0, 1); height = php_ifd_get16s(a+2, 1); bits = a[8] & 0xff; if (width > 0 && height > 0 && bits > 0 && bits < 33) { result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); result->width = width; result->height = height; result->bits = bits; result->channels = 0; return result; } } else { if (php_stream_seek(stream, size, SEEK_CUR)) { return NULL; } } } while (1);}/* }}} *//* {{{ php_get_wbmp * int WBMP file format type * byte Header Type * byte Extended Header * byte Header Data (type 00 = multibyte) * byte Header Data (type 11 = name/pairs) * int Number of columns * int Number of rows */static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check TSRMLS_DC){ int i, width = 0, height = 0; if (php_stream_rewind(stream)) { return 0; } /* get type */ if (php_stream_getc(stream) != 0) { return 0; } /* skip header */ do { i = php_stream_getc(stream); if (i < 0) { return 0; } } while (i & 0x80); /* get width */ do { i = php_stream_getc(stream); if (i < 0) { return 0; } width = (width << 7) | (i & 0x7f); } while (i & 0x80); /* get height */ do { i = php_stream_getc(stream); if (i < 0) { return 0; } height = (height << 7) | (i & 0x7f); } while (i & 0x80); /* maximum valid sizes for wbmp (although 127x127 may be a more accurate one) */ if (!height || !width || height > 2048 || width > 2048) { return 0; } if (!check) { (*result)->width = width; (*result)->height = height; } return IMAGE_FILETYPE_WBMP;}/* }}} *//* {{{ php_handle_wbmp*/static struct gfxinfo *php_handle_wbmp(php_stream * stream TSRMLS_DC){ struct gfxinfo *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); if (!php_get_wbmp(stream, &result, 0 TSRMLS_CC)) { efree(result); return NULL; } return result;}/* }}} *//* {{{ php_get_xbm */static int php_get_xbm(php_stream *stream, struct gfxinfo **result TSRMLS_DC){ char *fline; char *iname; char *type; int value; unsigned int width = 0, height = 0; if (result) { *result = NULL; } if (php_stream_rewind(stream)) { return 0; } while ((fline=php_stream_gets(stream, NULL, 0)) != NULL) { iname = estrdup(fline); /* simple way to get necessary buffer of required size */ if (sscanf(fline, "#define %s %d", iname, &value) == 2) { if (!(type = strrchr(iname, '_'))) { type = iname; } else { type++; } if (!strcmp("width", type)) { width = (unsigned int) value; if (height) { efree(iname); break; } } if (!strcmp("height", type)) { height = (unsigned int) value; if (width) { efree(iname); break; } } } efree(fline); efree(iname); } if (fline) { efree(fline); } if (width && height) { if (result) { *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); (*result)->width = width; (*result)->height = height; } return IMAGE_FILETYPE_XBM; } return 0;}/* }}} *//* {{{ php_handle_xbm */static struct gfxinfo *php_handle_xbm(php_stream * stream TSRMLS_DC){ struct gfxinfo *result; php_get_xbm(stream, &result TSRMLS_CC); return result;}/* }}} *//* {{{ php_image_type_to_mime_type * Convert internal image_type to mime type */PHPAPI char * php_image_type_to_mime_type(int image_type){ switch( image_type) { case IMAGE_FILETYPE_GIF: return "image/gif"; case IMAGE_FILETYPE_JPEG: return "image/jpeg"; case IMAGE_FILETYPE_PNG: return "image/png"; case IMAGE_FILETYPE_SWF: case IMAGE_FILETYPE_SWC: return "application/x-shockwave-flash"; case IMAGE_FILETYPE_PSD: return "image/psd"; case IMAGE_FILETYPE_BMP: return "image/bmp"; case IMAGE_FILETYPE_TIFF_II: case IMAGE_FILETYPE_TIFF_MM: return "image/tiff"; case IMAGE_FILETYPE_IFF: return "image/iff"; case IMAGE_FILETYPE_WBMP: return "image/vnd.wap.wbmp"; case IMAGE_FILETYPE_JPC: return "application/octet-stream"; case IMAGE_FILETYPE_JP2: return "image/jp2"; case IMAGE_FILETYPE_XBM: return "image/xbm"; default: case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ }}/* }}} *//* {{{ proto string image_type_to_mime_type(int imagetype) Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */PHP_FUNCTION(image_type_to_mime_type){ zval **p_image_type; int arg_c = ZEND_NUM_ARGS(); if ((arg_c!=1) || zend_get_parameters_ex(arg_c, &p_image_type) == FAILURE) { RETVAL_FALSE; WRONG_PARAM_COUNT; } convert_to_long_ex(p_image_type); ZVAL_STRING(return_value, (char*)php_image_type_to_mime_type(Z_LVAL_PP(p_image_type)), 1);}/* }}} *//* {{{ php_imagetype detect filetype from first bytes */PHPAPI int php_getimagetype(php_stream * stream, char *filetype TSRMLS_DC){ char tmp[12]; if ( !filetype) filetype = tmp; if((php_stream_read(stream, filetype, 3)) != 3) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!"); return IMAGE_FILETYPE_UNKNOWN; }/* BYTES READ: 3 */ if (!memcmp(filetype, php_sig_gif, 3)) { return IMAGE_FILETYPE_GIF; } else if (!memcmp(filetype, php_sig_jpg, 3)) { return IMAGE_FILETYPE_JPEG; } else if (!memcmp(filetype, php_sig_png, 3)) { if (php_stream_read(stream, filetype+3, 5) != 5) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!"); return IMAGE_FILETYPE_UNKNOWN; } if (!memcmp(filetype, php_sig_png, 8)) { return IMAGE_FILETYPE_PNG; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PNG file corrupted by ASCII conversion"); return IMAGE_FILETYPE_UNKNOWN; } } else if (!memcmp(filetype, php_sig_swf, 3)) { return IMAGE_FILETYPE_SWF; } else if (!memcmp(filetype, php_sig_swc, 3)) { return IMAGE_FILETYPE_SWC; } else if (!memcmp(filetype, php_sig_psd, 3)) { return IMAGE_FILETYPE_PSD; } else if (!memcmp(filetype, php_sig_bmp, 2)) { return IMAGE_FILETYPE_BMP; } else if (!memcmp(filetype, php_sig_jpc, 3)) { return IMAGE_FILETYPE_JPC; } if (php_stream_read(stream, filetype+3, 1) != 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!"); return IMAGE_FILETYPE_UNKNOWN; }/* BYTES READ: 4 */ if (!memcmp(filetype, php_sig_tif_ii, 4)) { return IMAGE_FILETYPE_TIFF_II; } else if (!memcmp(filetype, php_sig_tif_mm, 4)) { return IMAGE_FILETYPE_TIFF_MM; } if (!memcmp(filetype, php_sig_iff, 4)) { return IMAGE_FILETYPE_IFF; } if (php_stream_read(stream, filetype+4, 8) != 8) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!"); return IMAGE_FILETYPE_UNKNOWN; }/* BYTES READ: 12 */ if (!memcmp(filetype, php_sig_jp2, 12)) { return IMAGE_FILETYPE_JP2; }/* AFTER ALL ABOVE FAILED */ if (php_get_wbmp(stream, NULL, 1 TSRMLS_CC)) { return IMAGE_FILETYPE_WBMP; } if (php_get_xbm(stream, NULL TSRMLS_CC)) { return IMAGE_FILETYPE_XBM; } return IMAGE_FILETYPE_UNKNOWN;}/* }}} *//* {{{ proto array getimagesize(string imagefile [, array info]) Get the size of an image as 4-element array */PHP_FUNCTION(getimagesize){ zval **arg1, **info = NULL; int itype = 0; char *temp; struct gfxinfo *result = NULL; php_stream * stream = NULL; switch(ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &arg1) == FAILURE) { RETVAL_FALSE; WRONG_PARAM_COUNT; } convert_to_string_ex(arg1); break; case 2: if (zend_get_parameters_ex(2, &arg1, &info) == FAILURE) { RETVAL_FALSE; WRONG_PARAM_COUNT; } zval_dtor(*info); array_init(*info); convert_to_string_ex(arg1); break; default: RETVAL_FALSE; WRONG_PARAM_COUNT; } stream = php_stream_open_wrapper(Z_STRVAL_PP(arg1), "rb", STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); if (!stream) { RETURN_FALSE; } itype = php_getimagetype(stream, NULL TSRMLS_CC); switch( itype) { case IMAGE_FILETYPE_GIF: result = php_handle_gif (stream TSRMLS_CC); break; case IMAGE_FILETYPE_JPEG: if (info) { result = php_handle_jpeg(stream, *info TSRMLS_CC); } else { result = php_handle_jpeg(stream, NULL TSRMLS_CC); } break; case IMAGE_FILETYPE_PNG: result = php_handle_png(stream TSRMLS_CC); break; case IMAGE_FILETYPE_SWF: result = php_handle_swf(stream TSRMLS_CC); break; case IMAGE_FILETYPE_SWC:#if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB) result = php_handle_swc(stream TSRMLS_CC);#else php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The image is a compressed SWF file, but you do not have a static version of the zlib extension enabled.");#endif break; case IMAGE_FILETYPE_PSD: result = php_handle_psd(stream TSRMLS_CC); break; case IMAGE_FILETYPE_BMP: result = php_handle_bmp(stream TSRMLS_CC); break; case IMAGE_FILETYPE_TIFF_II: result = php_handle_tiff(stream, NULL, 0 TSRMLS_CC); break; case IMAGE_FILETYPE_TIFF_MM: result = php_handle_tiff(stream, NULL, 1 TSRMLS_CC); break; case IMAGE_FILETYPE_JPC: result = php_handle_jpc(stream TSRMLS_CC); break; case IMAGE_FILETYPE_JP2: result = php_handle_jp2(stream TSRMLS_CC); break; case IMAGE_FILETYPE_IFF: result = php_handle_iff(stream TSRMLS_CC); break; case IMAGE_FILETYPE_WBMP: result = php_handle_wbmp(stream TSRMLS_CC); break; case IMAGE_FILETYPE_XBM: result = php_handle_xbm(stream TSRMLS_CC); break; default: case IMAGE_FILETYPE_UNKNOWN: break; } php_stream_close(stream); if (result) { array_init(return_value); add_index_long(return_value, 0, result->width); add_index_long(return_value, 1, result->height); add_index_long(return_value, 2, itype); spprintf(&temp, 0, "width=\"%d\" height=\"%d\"", result->width, result->height); add_index_string(return_value, 3, temp, 0); if (result->bits != 0) { add_assoc_long(return_value, "bits", result->bits); } if (result->channels != 0) { add_assoc_long(return_value, "channels", result->channels); } add_assoc_string(return_value, "mime", (char*)php_image_type_to_mime_type(itype), 1); efree(result); } else { RETURN_FALSE; }}/* }}} *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -