Skip to content

Commit 780c6e0

Browse files
committed
- add affine matrix helper for translate, scale, rotate and shear
1 parent a46065e commit 780c6e0

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

ext/gd/gd.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imageaffine, 0)
918918
ZEND_ARG_INFO(0, affine)
919919
ZEND_END_ARG_INFO()
920920

921+
ZEND_BEGIN_ARG_INFO(arginfo_imageaffinegetmatrix, 0)
922+
ZEND_ARG_INFO(0, im)
923+
ZEND_ARG_INFO(0, matrox)
924+
ZEND_ARG_INFO(0, options)
925+
ZEND_END_ARG_INFO()
926+
921927
ZEND_BEGIN_ARG_INFO(arginfo_imagesetinterpolation, 0)
922928
ZEND_ARG_INFO(0, im)
923929
ZEND_ARG_INFO(0, method)
@@ -988,6 +994,7 @@ const zend_function_entry gd_functions[] = {
988994
PHP_FE(imagecropauto, arginfo_imagecropauto)
989995
PHP_FE(imagescale, arginfo_imagescale)
990996
PHP_FE(imageaffine, arginfo_imageaffine)
997+
PHP_FE(imageaffinegetmatrix, arginfo_imageaffinegetmatrix)
991998
PHP_FE(imagesetinterpolation, arginfo_imagesetinterpolation)
992999
#endif
9931000

@@ -5394,6 +5401,7 @@ PHP_FUNCTION(imageaffine)
53945401
double affine[6];
53955402
int i, nelems;
53965403
zval **zval_affine_elem = NULL;
5404+
53975405
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|a", &IM, &z_affine, &z_rect) == FAILURE) {
53985406
return;
53995407
}
@@ -5427,27 +5435,31 @@ PHP_FUNCTION(imageaffine)
54275435

54285436
if (z_rect != NULL) {
54295437
if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
5438+
convert_to_long_ex(tmp);
54305439
rect.x = Z_LVAL_PP(tmp);
54315440
} else {
54325441
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
54335442
RETURN_FALSE;
54345443
}
54355444

54365445
if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) {
5446+
convert_to_long_ex(tmp);
54375447
rect.y = Z_LVAL_PP(tmp);
54385448
} else {
54395449
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
54405450
RETURN_FALSE;
54415451
}
54425452

54435453
if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) {
5454+
convert_to_long_ex(tmp);
54445455
rect.width = Z_LVAL_PP(tmp);
54455456
} else {
54465457
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width");
54475458
RETURN_FALSE;
54485459
}
54495460

54505461
if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) {
5462+
convert_to_long_ex(tmp);
54515463
rect.height = Z_LVAL_PP(tmp);
54525464
} else {
54535465
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height");
@@ -5476,6 +5488,77 @@ PHP_FUNCTION(imageaffine)
54765488
}
54775489
/* }}} */
54785490

5491+
/* {{{ proto array imageaffinegetmatrix(type[, options])
5492+
Return an image containing the affine tramsformed src image, using an optional clipping area */
5493+
PHP_FUNCTION(imageaffinegetmatrix)
5494+
{
5495+
double affine[6];
5496+
gdAffineStandardMatrix type;
5497+
zval *options;
5498+
zval **tmp;
5499+
int args_required;
5500+
int res;
5501+
5502+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &type, &options) == FAILURE) {
5503+
return;
5504+
}
5505+
5506+
switch(type) {
5507+
case GD_AFFINE_TRANSLATE:
5508+
case GD_AFFINE_SCALE: {
5509+
double x, y;
5510+
args_required = 2;
5511+
if (Z_TYPE_P(options) != IS_ARRAY) {
5512+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options");
5513+
}
5514+
if (zend_hash_find(HASH_OF(options), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
5515+
convert_to_double_ex(tmp);
5516+
x = Z_DVAL_PP(tmp);
5517+
} else {
5518+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
5519+
RETURN_FALSE;
5520+
}
5521+
5522+
if (zend_hash_find(HASH_OF(options), "y", sizeof("y"), (void **)&tmp) != FAILURE) {
5523+
convert_to_double_ex(tmp);
5524+
y = Z_DVAL_PP(tmp);
5525+
} else {
5526+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
5527+
RETURN_FALSE;
5528+
}
5529+
5530+
if (type == GD_AFFINE_TRANSLATE) {
5531+
res = gdAffineTranslate(affine, x, y);
5532+
} else {
5533+
res = gdAffineScale(affine, x, y);
5534+
}
5535+
break;
5536+
}
5537+
5538+
case GD_AFFINE_ROTATE:
5539+
case GD_AFFINE_SHEAR_HORIZONTAL:
5540+
case GD_AFFINE_SHEAR_VERTICAL: {
5541+
double angle;
5542+
5543+
convert_to_double_ex(&options);
5544+
angle = Z_DVAL_P(options);
5545+
5546+
if (type == GD_AFFINE_SHEAR_HORIZONTAL) {
5547+
res = gdAffineShearHorizontal(affine, angle);
5548+
} else if (type == GD_AFFINE_SHEAR_VERTICAL) {
5549+
res = gdAffineShearVertical(affine, angle);
5550+
} else {
5551+
res = gdAffineRotate(affine, angle);
5552+
}
5553+
break;
5554+
}
5555+
5556+
default:
5557+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", type);
5558+
RETURN_FALSE;
5559+
}
5560+
}
5561+
54795562
/* {{{ proto resource imagesetinterpolation(resource im, [, method]])
54805563
Set the default interpolation method, passing -1 or 0 sets it to the libgd default (bilinear). */
54815564
PHP_FUNCTION(imagesetinterpolation)

ext/gd/libgd/gd.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,16 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
845845
gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const int bgColor);
846846
gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor);
847847

848+
849+
850+
typedef enum {
851+
GD_AFFINE_TRANSLATE = 0,
852+
GD_AFFINE_SCALE,
853+
GD_AFFINE_ROTATE,
854+
GD_AFFINE_SHEAR_HORIZONTAL,
855+
GD_AFFINE_SHEAR_VERTICAL,
856+
} gdAffineStandardMatrix;
857+
848858
int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, const double affine[6]);
849859
int gdAffineInvert (double dst[6], const double src[6]);
850860
int gdAffineFlip (double dst_affine[6], const double src_affine[6], const int flip_h, const int flip_v);

ext/gd/php_gd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ PHP_FUNCTION(imagecrop);
130130
PHP_FUNCTION(imagecropauto);
131131
PHP_FUNCTION(imagescale);
132132
PHP_FUNCTION(imageaffine);
133+
PHP_FUNCTION(imageaffinegetmatrix);
133134
PHP_FUNCTION(imagesetinterpolation);
134135
#endif
135136

0 commit comments

Comments
 (0)