From 780c6e0a9cedb8dbecf5e4aca00996c73c0723d5 Mon Sep 17 00:00:00 2001 From: Pierre Joye Date: Wed, 20 Mar 2013 11:01:37 +0100 Subject: [PATCH] - add affine matrix helper for translate, scale, rotate and shear --- ext/gd/gd.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ ext/gd/libgd/gd.h | 10 ++++++ ext/gd/php_gd.h | 1 + 3 files changed, 94 insertions(+) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index c4cdea3118..038f7c4d4a 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -918,6 +918,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imageaffine, 0) ZEND_ARG_INFO(0, affine) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_imageaffinegetmatrix, 0) + ZEND_ARG_INFO(0, im) + ZEND_ARG_INFO(0, matrox) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_imagesetinterpolation, 0) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, method) @@ -988,6 +994,7 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagecropauto, arginfo_imagecropauto) PHP_FE(imagescale, arginfo_imagescale) PHP_FE(imageaffine, arginfo_imageaffine) + PHP_FE(imageaffinegetmatrix, arginfo_imageaffinegetmatrix) PHP_FE(imagesetinterpolation, arginfo_imagesetinterpolation) #endif @@ -5394,6 +5401,7 @@ PHP_FUNCTION(imageaffine) double affine[6]; int i, nelems; zval **zval_affine_elem = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|a", &IM, &z_affine, &z_rect) == FAILURE) { return; } @@ -5427,6 +5435,7 @@ PHP_FUNCTION(imageaffine) if (z_rect != NULL) { if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) { + convert_to_long_ex(tmp); rect.x = Z_LVAL_PP(tmp); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position"); @@ -5434,6 +5443,7 @@ PHP_FUNCTION(imageaffine) } if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) { + convert_to_long_ex(tmp); rect.y = Z_LVAL_PP(tmp); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position"); @@ -5441,6 +5451,7 @@ PHP_FUNCTION(imageaffine) } if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) { + convert_to_long_ex(tmp); rect.width = Z_LVAL_PP(tmp); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width"); @@ -5448,6 +5459,7 @@ PHP_FUNCTION(imageaffine) } if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) { + convert_to_long_ex(tmp); rect.height = Z_LVAL_PP(tmp); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height"); @@ -5476,6 +5488,77 @@ PHP_FUNCTION(imageaffine) } /* }}} */ +/* {{{ proto array imageaffinegetmatrix(type[, options]) + Return an image containing the affine tramsformed src image, using an optional clipping area */ +PHP_FUNCTION(imageaffinegetmatrix) +{ + double affine[6]; + gdAffineStandardMatrix type; + zval *options; + zval **tmp; + int args_required; + int res; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &type, &options) == FAILURE) { + return; + } + + switch(type) { + case GD_AFFINE_TRANSLATE: + case GD_AFFINE_SCALE: { + double x, y; + args_required = 2; + if (Z_TYPE_P(options) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options"); + } + if (zend_hash_find(HASH_OF(options), "x", sizeof("x"), (void **)&tmp) != FAILURE) { + convert_to_double_ex(tmp); + x = Z_DVAL_PP(tmp); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position"); + RETURN_FALSE; + } + + if (zend_hash_find(HASH_OF(options), "y", sizeof("y"), (void **)&tmp) != FAILURE) { + convert_to_double_ex(tmp); + y = Z_DVAL_PP(tmp); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position"); + RETURN_FALSE; + } + + if (type == GD_AFFINE_TRANSLATE) { + res = gdAffineTranslate(affine, x, y); + } else { + res = gdAffineScale(affine, x, y); + } + break; + } + + case GD_AFFINE_ROTATE: + case GD_AFFINE_SHEAR_HORIZONTAL: + case GD_AFFINE_SHEAR_VERTICAL: { + double angle; + + convert_to_double_ex(&options); + angle = Z_DVAL_P(options); + + if (type == GD_AFFINE_SHEAR_HORIZONTAL) { + res = gdAffineShearHorizontal(affine, angle); + } else if (type == GD_AFFINE_SHEAR_VERTICAL) { + res = gdAffineShearVertical(affine, angle); + } else { + res = gdAffineRotate(affine, angle); + } + break; + } + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", type); + RETURN_FALSE; + } +} + /* {{{ proto resource imagesetinterpolation(resource im, [, method]]) Set the default interpolation method, passing -1 or 0 sets it to the libgd default (bilinear). */ PHP_FUNCTION(imagesetinterpolation) diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 5209a49c19..28c8562f66 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -845,6 +845,16 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const int bgColor); gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor); + + +typedef enum { + GD_AFFINE_TRANSLATE = 0, + GD_AFFINE_SCALE, + GD_AFFINE_ROTATE, + GD_AFFINE_SHEAR_HORIZONTAL, + GD_AFFINE_SHEAR_VERTICAL, +} gdAffineStandardMatrix; + int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, const double affine[6]); int gdAffineInvert (double dst[6], const double src[6]); int gdAffineFlip (double dst_affine[6], const double src_affine[6], const int flip_h, const int flip_v); diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 044277c6c8..fd6836c583 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -130,6 +130,7 @@ PHP_FUNCTION(imagecrop); PHP_FUNCTION(imagecropauto); PHP_FUNCTION(imagescale); PHP_FUNCTION(imageaffine); +PHP_FUNCTION(imageaffinegetmatrix); PHP_FUNCTION(imagesetinterpolation); #endif -- 2.40.0