Skip to content

Commit

Permalink
Added ImagickKernel class and morphology function, as well as all the…
Browse files Browse the repository at this point in the history
… constants needed to use them.
  • Loading branch information
Danack committed Feb 10, 2015
1 parent eb25498 commit a3cc177
Show file tree
Hide file tree
Showing 8 changed files with 718 additions and 6 deletions.
2 changes: 1 addition & 1 deletion config.m4
Expand Up @@ -48,6 +48,6 @@ IM_FIND_IMAGEMAGICK([6.2.4], [$PHP_IMAGICK])

PHP_SUBST(IMAGICK_SHARED_LIBADD)
AC_DEFINE(HAVE_IMAGICK,1,[ ])
PHP_NEW_EXTENSION(imagick, imagick_file.c imagick_class.c imagickdraw_class.c imagickpixel_class.c imagickpixeliterator_class.c imagick_helpers.c imagick.c, $ext_shared,, $IM_IMAGEMAGICK_CFLAGS)
PHP_NEW_EXTENSION(imagick, imagick_file.c imagick_class.c imagickdraw_class.c imagickpixel_class.c imagickpixeliterator_class.c imagick_helpers.c imagick.c imagickkernel_class.c, $ext_shared,, $IM_IMAGEMAGICK_CFLAGS)
PHP_INSTALL_HEADERS([ext/imagick], [php_imagick_shared.h])
fi
2 changes: 1 addition & 1 deletion config.w32
Expand Up @@ -8,7 +8,7 @@ if (PHP_IMAGICK != "no") {
)
{
ADD_FLAG("CFLAGS_IMAGICK", "/D IMAGICK_USE_NEW_HEADER /D _MAGICKMOD_ /D _VISUALC_ /D NeedFunctionPrototypes /D _LIB");
EXTENSION('imagick', 'imagick_class.c imagickdraw_class.c imagickpixel_class.c imagickpixeliterator_class.c imagick_helpers.c imagick_file.c imagick.c');
EXTENSION('imagick', 'imagick_class.c imagickdraw_class.c imagickpixel_class.c imagickpixeliterator_class.c imagick_helpers.c imagick_file.c imagick.c imagickkernel_class.c');
AC_DEFINE('HAVE_IMAGICK', 1);
AC_DEFINE('IMAGICK_EXPORTS', 1);
} else {
Expand Down
127 changes: 126 additions & 1 deletion imagick.c
Expand Up @@ -41,6 +41,8 @@ zend_class_entry *php_imagickpixel_sc_entry;
zend_class_entry *php_imagickpixel_exception_class_entry;
zend_class_entry *php_imagickpixeliterator_sc_entry;
zend_class_entry *php_imagickpixeliterator_exception_class_entry;
zend_class_entry *php_imagickkernel_sc_entry;
zend_class_entry *php_imagickkernel_exception_class_entry;

#if defined(ZTS) && defined(PHP_WIN32)
static MUTEX_T imagick_mutex;
Expand All @@ -52,6 +54,7 @@ static zend_object_handlers imagick_object_handlers;
static zend_object_handlers imagickdraw_object_handlers;
static zend_object_handlers imagickpixel_object_handlers;
static zend_object_handlers imagickpixeliterator_object_handlers;
static zend_object_handlers imagickkernel_object_handlers;

/* External API */
PHP_IMAGICK_API zend_class_entry *php_imagick_get_class_entry()
Expand Down Expand Up @@ -607,6 +610,13 @@ PHP_IMAGICK_API zend_class_entry *php_imagickpixel_get_class_entry()
ZEND_ARG_INFO(0, frame)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagick_morphology_args, 0, 0, 3)
ZEND_ARG_INFO(0, morphologyMethod)
ZEND_ARG_INFO(0, iterations)
ZEND_ARG_OBJ_INFO(0, ImagickKernel, ImagickKernel, 0)
ZEND_ARG_INFO(0, CHANNEL)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagick_identifyimage_args, 0, 0, 0)
ZEND_ARG_INFO(0, appendRawOutput)
ZEND_END_ARG_INFO()
Expand Down Expand Up @@ -1845,6 +1855,22 @@ PHP_IMAGICK_API zend_class_entry *php_imagickpixel_get_class_entry()
ZEND_ARG_INFO(0, row)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagickkernel_zero_args, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagickkernel_fromarray_args, 0, 0, 1)
ZEND_ARG_INFO(0, array)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagickkernel_frombuiltin_args, 0, 0, 2)
ZEND_ARG_INFO(0, kerneltype)
ZEND_ARG_INFO(0, paramstring)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(imagickkernel_addkernel_args, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, Imagick, Imagick, 0)
ZEND_END_ARG_INFO()

static zend_function_entry php_imagick_functions[] =
{
{ NULL, NULL, NULL }
Expand Down Expand Up @@ -2517,9 +2543,22 @@ static zend_function_entry php_imagick_class_methods[] =
PHP_ME(imagick, setregistry, imagick_setregistry_args, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
PHP_ME(imagick, getregistry, imagick_getregistry_args, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
PHP_ME(imagick, listregistry, imagick_zero_args, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
PHP_ME(imagick, morphology, imagick_morphology_args, ZEND_ACC_PUBLIC)

{ NULL, NULL, NULL }
};

static zend_function_entry php_imagickkernel_class_methods[] =
{
PHP_ME(imagickkernel, fromarray, imagickkernel_fromarray_args, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
PHP_ME(imagickkernel, frombuiltin, imagickkernel_frombuiltin_args, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
PHP_ME(imagickkernel, addkernel, imagickkernel_addkernel_args, ZEND_ACC_PUBLIC)
PHP_ME(imagickkernel, getvalues, imagick_zero_args, ZEND_ACC_PUBLIC)
PHP_ME(imagickkernel, separate, imagick_zero_args, ZEND_ACC_PUBLIC)
{ NULL, NULL, NULL }
};


static void php_imagick_object_free_storage(void *object TSRMLS_DC)
{
php_imagick_object *intern = (php_imagick_object *)object;
Expand Down Expand Up @@ -2588,6 +2627,21 @@ static void php_imagickpixel_object_free_storage(void *object TSRMLS_DC)
efree(intern);
}

static void php_imagickkernel_object_free_storage(void *object TSRMLS_DC)
{
php_imagickkernel_object *intern = (php_imagickkernel_object *)object;

if (!intern) {
return;
}

intern->kernel_info = DestroyKernelInfo(intern->kernel_info);

zend_object_std_dtor(&intern->zo TSRMLS_CC);
efree(intern);
}


#if PHP_VERSION_ID < 50399
# define object_properties_init(zo, class_type) { \
zval *tmp; \
Expand Down Expand Up @@ -2748,6 +2802,41 @@ static zend_object_value php_imagickpixel_object_new(zend_class_entry *class_typ
return php_imagickpixel_object_new_ex(class_type, NULL TSRMLS_CC);
}


static zend_object_value php_imagickkernel_object_new_ex(zend_class_entry *class_type, php_imagickkernel_object **ptr TSRMLS_DC)
{
zend_object_value retval;
php_imagickkernel_object *intern;

/* Allocate memory for it */
intern = (php_imagickkernel_object *) emalloc(sizeof(php_imagickkernel_object));
memset(&intern->zo, 0, sizeof(zend_object));

if (ptr) {
*ptr = intern;
}

/* Set the kernel */
intern->kernel_info = NULL;

/* ALLOC_HASHTABLE(intern->zo.properties); */
zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
object_properties_init(&intern->zo, class_type);

retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_imagickkernel_object_free_storage, NULL TSRMLS_CC);
retval.handlers = (zend_object_handlers *) &imagickkernel_object_handlers;
return retval;
}

#undef object_properties_init

static zend_object_value php_imagickkernel_object_new(zend_class_entry *class_type TSRMLS_DC)
{
return php_imagickkernel_object_new_ex(class_type, NULL TSRMLS_CC);
}



PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("imagick.locale_fix", "0", PHP_INI_ALL, OnUpdateBool, locale_fix, zend_imagick_globals, imagick_globals)
STD_PHP_INI_ENTRY("imagick.progress_monitor", "0", PHP_INI_SYSTEM, OnUpdateBool, progress_monitor, zend_imagick_globals, imagick_globals)
Expand Down Expand Up @@ -2904,6 +2993,26 @@ static zend_object_value php_imagick_clone_imagickpixel_object(zval *this_ptr TS
return new_ov;
}

static zend_object_value php_imagick_clone_imagickkernel_object(zval *this_ptr TSRMLS_DC)
{
KernelInfo *kernel_info_copy = NULL;

php_imagickkernel_object *new_obj = NULL;
php_imagickkernel_object *old_obj = (php_imagickkernel_object *) zend_object_store_get_object(this_ptr TSRMLS_CC);
zend_object_value new_ov = php_imagickkernel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
kernel_info_copy = CloneKernelInfo(old_obj->kernel_info);

if (!kernel_info_copy) {
zend_error(E_ERROR, "Failed to clone ImagickKernel object");
} else {
new_obj->kernel_info = kernel_info_copy;

}
return new_ov;
}


static int checkImagickVersion()
{
//This gets the version that Imagick was compiled against.
Expand Down Expand Up @@ -2956,6 +3065,7 @@ PHP_MINIT_FUNCTION(imagick)
memcpy(&imagickdraw_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
memcpy(&imagickpixeliterator_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
memcpy(&imagickpixel_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
memcpy(&imagickkernel_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));

/* Set custom allocators */
MagickWandGenesis();
Expand Down Expand Up @@ -2987,6 +3097,13 @@ PHP_MINIT_FUNCTION(imagick)
INIT_CLASS_ENTRY(ce, PHP_IMAGICKPIXEL_EXCEPTION_SC_NAME, NULL);
php_imagickpixel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
php_imagickpixel_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;

/*
Initialize exceptions (ImagickKernel exception)
*/
INIT_CLASS_ENTRY(ce, PHP_IMAGICKKERNEL_EXCEPTION_SC_NAME, NULL);
php_imagickkernel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
php_imagickkernel_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;

/*
Initialize the class (Imagick)
Expand Down Expand Up @@ -3028,6 +3145,14 @@ PHP_MINIT_FUNCTION(imagick)
imagickpixel_object_handlers.clone_obj = php_imagick_clone_imagickpixel_object;
php_imagickpixel_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);

/*
Initialize the class (ImagickKernel)
*/
INIT_CLASS_ENTRY(ce, PHP_IMAGICKKERNEL_SC_NAME, php_imagickkernel_class_methods);
ce.create_object = php_imagickkernel_object_new;
imagickkernel_object_handlers.clone_obj = php_imagick_clone_imagickkernel_object;
php_imagickkernel_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);

php_imagick_initialize_constants (TSRMLS_C);

#if defined(ZTS) && defined(PHP_WIN32)
Expand All @@ -3053,7 +3178,7 @@ PHP_MINFO_FUNCTION(imagick)
php_info_print_table_start();
php_info_print_table_header(2, "imagick module", "enabled");
php_info_print_table_row(2, "imagick module version", PHP_IMAGICK_VERSION);
php_info_print_table_row(2, "imagick classes", "Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator");
php_info_print_table_row(2, "imagick classes", "Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel");
php_info_print_table_row(2, "ImageMagick version", MagickGetVersion(&version_number));
php_info_print_table_row(2, "ImageMagick copyright", MagickGetCopyright());
php_info_print_table_row(2, "ImageMagick release date", MagickGetReleaseDate());
Expand Down
39 changes: 39 additions & 0 deletions imagick_class.c
Expand Up @@ -11494,5 +11494,44 @@ PHP_METHOD(imagick, listregistry)
}
/* }}} */

/* {{{ proto bool Imagick::morphology(int morphologyMethod, int iterations, kernel, [int CHANNEL] )
Applies a user supplied kernel to the image according to the given mophology method.
iterations - A value of -1 means loop until no change found. How this is applied may depend on the morphology method. Typically this is a value of 1.
*/
PHP_METHOD(imagick, morphology)
{
zval *objvar;
php_imagick_object *intern;
php_imagickkernel_object *kernel;
long morphologyMethod, iterations;
MagickBooleanType status;
long channel = DefaultChannels;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llO|l", &morphologyMethod, &iterations, &objvar, php_imagickkernel_sc_entry, &channel) == FAILURE) {
return;
}

intern = (php_imagick_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
kernel = (php_imagickkernel_object *)zend_object_store_get_object(objvar TSRMLS_CC);

if (channel == DefaultChannels) {
status = MagickMorphologyImage(intern->magick_wand,
morphologyMethod, iterations, kernel->kernel_info);
}
else {
status = MagickMorphologyImageChannel(intern->magick_wand,
channel, morphologyMethod, iterations, kernel->kernel_info);
}

// No magick is going to happen
if (status == MagickFalse) {
php_imagick_convert_imagick_exception(intern->magick_wand, "Unable to morphology image" TSRMLS_CC);
return;
}

RETURN_TRUE;
}
/* }}} */

/* end of Imagick */
80 changes: 80 additions & 0 deletions imagick_helpers.c
Expand Up @@ -523,6 +523,11 @@ void php_imagick_throw_exception (php_imagick_class_type_t type, const char *des
ce = php_imagickpixel_exception_class_entry;
code = 4;
break;

case IMAGICKKERNEL_CLASS:
ce = php_imagickkernel_exception_class_entry;
code = 5;
break;
}
zend_throw_exception(ce, description, code TSRMLS_CC);
}
Expand Down Expand Up @@ -1390,6 +1395,81 @@ void php_imagick_initialize_constants(TSRMLS_D)
IMAGICK_REGISTER_CONST_LONG("STATISTIC_STANDARD_DEVIATION", StandardDeviationStatistic);
#endif

/* Convolve / Correlate weighted sums */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_CONVOLVE", ConvolveMorphology); /* Weighted Sum with reflected kernel */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_CORRELATE", CorrelateMorphology); /* Weighted Sum using a sliding window */
/* Low-level Morphology methods */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_ERODE", ErodeMorphology); /* Minimum Value in Neighbourhood */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_DILATE", DilateMorphology); /* Maximum Value in Neighbourhood */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_ERODE_INTENSITY", ErodeIntensityMorphology); /* Pixel Pick using GreyScale Erode */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_DILATE_INTENSITY", DilateIntensityMorphology); /* Pixel Pick using GreyScale Dialate */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_DISTANCE", DistanceMorphology); /* Add Kernel Value, take Minimum */
/* Second-level Morphology methods */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_OPEN", OpenMorphology); /* Dilate then Erode */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_CLOSE", CloseMorphology); /* Erode then Dilate */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_OPEN_INTENSITY", OpenIntensityMorphology); /* Pixel Pick using GreyScale Open */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_CLOSE_INTENSITY", CloseIntensityMorphology); /* Pixel Pick using GreyScale Close */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_SMOOTH", SmoothMorphology); /* Open then Close */
/* Difference Morphology methods */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_EDGE_IN", EdgeInMorphology); /* Dilate difference from Original */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_EDGE_OUT", EdgeOutMorphology); /* Erode difference from Original */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_EDGE", EdgeMorphology); /* Dilate difference with Erode */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_TOP_HAT", TopHatMorphology); /* Close difference from Original */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_BOTTOM_HAT", BottomHatMorphology); /* Open difference from Original */
/* Recursive Morphology methods */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_HIT_AND_MISS", HitAndMissMorphology); /* Foreground/Background pattern matching */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_THINNING", ThinningMorphology); /* Remove matching pixels from image */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_THICKEN", ThickenMorphology); /* Add matching pixels from image */
/* Experimental Morphology methods */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_VORONOI", VoronoiMorphology); /* distance matte channel copy nearest color */
IMAGICK_REGISTER_CONST_LONG("MORPHOLOGY_ITERATIVE", IterativeDistanceMorphology); /* Add Kernel Value, take Minimum */


/* The no-op or 'original image' kernel */
IMAGICK_REGISTER_CONST_LONG("KERNEL_UNITY", UnityKernel);
/* Convolution Kernels, Gaussian Based */
IMAGICK_REGISTER_CONST_LONG("KERNEL_GAUSSIAN", GaussianKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_DIFFERENCE_OF_GAUSSIANS", DoGKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_LAPLACIAN_OF_GAUSSIANS", LoGKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_BLUR", BlurKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_COMET", CometKernel);
/* Convolution Kernels, by Name */
IMAGICK_REGISTER_CONST_LONG("KERNEL_LAPLACIAN", LaplacianKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_SOBEL", SobelKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_FREI_CHEN", FreiChenKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_ROBERTS", RobertsKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_PREWITT", PrewittKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_COMPASS", CompassKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_KIRSCH", KirschKernel);
/* Shape Kernels */
IMAGICK_REGISTER_CONST_LONG("KERNEL_DIAMOND", DiamondKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_SQUARE", SquareKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_RECTANGLE", RectangleKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_OCTAGON", OctagonKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_DISK", DiskKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_PLUS", PlusKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_CROSS", CrossKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_RING", RingKernel);
/* Hit And Miss Kernels */
IMAGICK_REGISTER_CONST_LONG("KERNEL_PEAKS", PeaksKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_EDGES", EdgesKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_CORNERS", CornersKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_DIAGONALS", DiagonalsKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_LINE_ENDS", LineEndsKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_LINE_JUNCTIONS", LineJunctionsKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_RIDGES", RidgesKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_CONVEX_HULL", ConvexHullKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_THIN_SE", ThinSEKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_SKELETON", SkeletonKernel);
/* Distance Measuring Kernels */
IMAGICK_REGISTER_CONST_LONG("KERNEL_CHEBYSHEV", ChebyshevKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_MANHATTAN", ManhattanKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_OCTAGONAL", OctagonalKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_EUCLIDEAN", EuclideanKernel);
/* User Specified Kernel Array */
IMAGICK_REGISTER_CONST_LONG("KERNEL_USER_DEFINED", UserDefinedKernel);
IMAGICK_REGISTER_CONST_LONG("KERNEL_BINOMIAL", BinomialKernel);

#undef IMAGICK_REGISTER_CONST_LONG
#undef IMAGICK_REGISTER_CONST_STRING
}

0 comments on commit a3cc177

Please sign in to comment.