1335 lines
41 KiB
C
1335 lines
41 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP Version 5 / Imagick |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2006-2013 Mikko Koppanen, Scott MacVicar |
|
|
| ImageMagick (c) ImageMagick Studio LLC |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Author: Mikko Kopppanen <mkoppanen@php.net> |
|
|
| Scott MacVicar <scottmac@php.net> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#include "php_imagick.h"
|
|
#include "php_imagick_defs.h"
|
|
#include "php_imagick_macros.h"
|
|
#include "php_imagick_helpers.h"
|
|
#include "php_imagick_shared.h"
|
|
|
|
#if PHP_VERSION_ID >= 70200
|
|
#include "Zend/zend_smart_string.h"
|
|
#elif PHP_VERSION_ID >= 70000
|
|
#include "ext/standard/php_smart_string.h"
|
|
#else
|
|
#include "ext/standard/php_smart_str.h"
|
|
#endif
|
|
|
|
#if PHP_VERSION_ID < 70200
|
|
///* For the countable interface */
|
|
#include "ext/spl/spl_iterators.h"
|
|
#endif
|
|
|
|
#include "shim_php7_to_php8.h"
|
|
|
|
#if HAVE_OMP_PAUSE_RESOURCE_ALL
|
|
#include <omp.h>
|
|
#endif
|
|
|
|
ZEND_DECLARE_MODULE_GLOBALS(imagick)
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
#if PHP_VERSION_ID >= 80000
|
|
HashTable* php_imagickkernel_get_debug_info(zend_object *obj, int *is_temp TSRMLS_DC); /* {{{ */
|
|
#else
|
|
HashTable* php_imagickkernel_get_debug_info(zval *obj, int *is_temp TSRMLS_DC); /* {{{ */
|
|
#endif
|
|
#endif
|
|
|
|
#if MAGICKCORE_HDRI_ENABLE
|
|
#define IMAGICK_QUANTUM_TYPE IS_DOUBLE
|
|
#else
|
|
#define IMAGICK_QUANTUM_TYPE IS_LONG
|
|
#endif
|
|
|
|
zend_class_entry *php_imagick_sc_entry;
|
|
zend_class_entry *php_imagick_exception_class_entry;
|
|
zend_class_entry *php_imagickdraw_sc_entry;
|
|
zend_class_entry *php_imagickdraw_exception_class_entry;
|
|
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;
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
zend_class_entry *php_imagickkernel_sc_entry;
|
|
zend_class_entry *php_imagickkernel_exception_class_entry;
|
|
#endif
|
|
|
|
#if defined(ZTS) && defined(PHP_WIN32)
|
|
static MUTEX_T imagick_mutex;
|
|
static THREAD_T imagick_thread_id;
|
|
#endif
|
|
|
|
/* Handlers */
|
|
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;
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
static zend_object_handlers imagickkernel_object_handlers;
|
|
#endif
|
|
|
|
/* External API */
|
|
PHP_IMAGICK_API zend_class_entry *php_imagick_get_class_entry()
|
|
{
|
|
return php_imagick_sc_entry;
|
|
}
|
|
|
|
PHP_IMAGICK_API zend_class_entry *php_imagickdraw_get_class_entry()
|
|
{
|
|
return php_imagickdraw_sc_entry;
|
|
}
|
|
|
|
PHP_IMAGICK_API zend_class_entry *php_imagickpixel_get_class_entry()
|
|
{
|
|
return php_imagickpixel_sc_entry;
|
|
}
|
|
|
|
static zend_function_entry php_imagick_functions[] =
|
|
{
|
|
PHP_FE_END,
|
|
};
|
|
|
|
|
|
#include "ImagickDraw_arginfo.h"
|
|
const zend_function_entry *php_imagickdraw_class_methods = class_ImagickDraw_methods;
|
|
|
|
#include "ImagickPixelIterator_arginfo.h"
|
|
const zend_function_entry *php_imagickpixeliterator_class_methods = class_ImagickPixelIterator_methods;
|
|
|
|
#include "ImagickPixel_arginfo.h"
|
|
const zend_function_entry *php_imagickpixel_class_methods = class_ImagickPixel_methods;
|
|
|
|
#include "Imagick_arginfo.h"
|
|
const zend_function_entry *php_imagick_class_methods = class_Imagick_methods;
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
#include "ImagickKernel_arginfo.h"
|
|
const zend_function_entry *php_imagickkernel_class_methods = class_ImagickKernel_methods;
|
|
#endif
|
|
|
|
static void php_imagick_object_free_storage(IM_ZEND_OBJECT *object TSRMLS_DC)
|
|
{
|
|
php_imagick_object *intern = php_imagick_fetch_object(object);
|
|
|
|
if (!intern) {
|
|
return;
|
|
}
|
|
|
|
if (intern->progress_monitor_name) {
|
|
//TODO - is this meant to be free by us?
|
|
efree(intern->progress_monitor_name);
|
|
}
|
|
|
|
if (intern->magick_wand != NULL) {
|
|
intern->magick_wand = DestroyMagickWand(intern->magick_wand);
|
|
}
|
|
|
|
zend_object_std_dtor(&intern->zo TSRMLS_CC);
|
|
#if PHP_VERSION_ID < 70000
|
|
efree(intern);
|
|
#endif
|
|
}
|
|
|
|
|
|
static void php_imagickdraw_object_free_storage(IM_ZEND_OBJECT *object TSRMLS_DC)
|
|
{
|
|
php_imagickdraw_object *intern = php_imagickdraw_fetch_object(object);
|
|
|
|
if (!intern) {
|
|
return;
|
|
}
|
|
|
|
if (intern->drawing_wand != NULL) {
|
|
intern->drawing_wand = DestroyDrawingWand(intern->drawing_wand);
|
|
}
|
|
|
|
zend_object_std_dtor(&intern->zo TSRMLS_CC);
|
|
|
|
#if PHP_VERSION_ID < 70000
|
|
efree(intern);
|
|
#endif
|
|
}
|
|
|
|
static void php_imagickpixeliterator_object_free_storage(IM_ZEND_OBJECT *object TSRMLS_DC)
|
|
{
|
|
php_imagickpixeliterator_object *intern = php_imagickpixeliterator_fetch_object(object);
|
|
|
|
if (!intern) {
|
|
return;
|
|
}
|
|
|
|
if (intern->pixel_iterator != NULL) {
|
|
intern->pixel_iterator = DestroyPixelIterator(intern->pixel_iterator);
|
|
}
|
|
|
|
zend_object_std_dtor(&intern->zo TSRMLS_CC);
|
|
#if PHP_VERSION_ID < 70000
|
|
efree(intern);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
static void php_imagickpixel_object_free_storage(IM_ZEND_OBJECT *object TSRMLS_DC)
|
|
{
|
|
php_imagickpixel_object *intern = php_imagickpixel_fetch_object(object);
|
|
|
|
if (!intern) {
|
|
return;
|
|
}
|
|
if (!intern->initialized_via_iterator && intern->pixel_wand)
|
|
intern->pixel_wand = DestroyPixelWand(intern->pixel_wand);
|
|
|
|
zend_object_std_dtor(&intern->zo TSRMLS_CC);
|
|
#if PHP_VERSION_ID < 70000
|
|
efree(intern);
|
|
#endif
|
|
}
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
static void php_imagickkernel_object_free_storage(IM_ZEND_OBJECT *object TSRMLS_DC)
|
|
{
|
|
php_imagickkernel_object *intern = php_imagickkernel_fetch_object(object);
|
|
|
|
if (!intern) {
|
|
return;
|
|
}
|
|
|
|
if (intern->kernel_info != NULL) {
|
|
// This segfaults in PHP 5.6
|
|
//intern->kernel_info = DestroyKernelInfo(intern->kernel_info);
|
|
intern->kernel_info = NULL;
|
|
}
|
|
|
|
zend_object_std_dtor(&intern->zo TSRMLS_CC);
|
|
#if PHP_VERSION_ID < 70000
|
|
efree(intern);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
#if PHP_VERSION_ID < 50399
|
|
# define object_properties_init(zo, class_type) { \
|
|
zval *tmp; \
|
|
zend_hash_copy((*zo).properties, \
|
|
&class_type->default_properties, \
|
|
(copy_ctor_func_t) zval_add_ref, \
|
|
(void *) &tmp, \
|
|
sizeof(zval *)); \
|
|
}
|
|
#endif
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_object_new_ex(zend_class_entry *class_type, php_imagick_object **ptr, zend_bool init_wand TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_object_new_ex(zend_class_entry *class_type, php_imagick_object **ptr, zend_bool init_wand TSRMLS_DC)
|
|
#endif
|
|
|
|
{
|
|
php_imagick_object *intern;
|
|
|
|
/* Allocate memory for it */
|
|
#if PHP_VERSION_ID >= 70000
|
|
intern = ecalloc(1,
|
|
sizeof(php_imagick_object) +
|
|
zend_object_properties_size(class_type));
|
|
#else
|
|
zend_object_value retval;
|
|
|
|
intern = (php_imagick_object *) emalloc(sizeof(php_imagick_object));
|
|
memset(&intern->zo, 0, sizeof(zend_object));
|
|
#endif
|
|
|
|
#if defined(ZTS) && defined(PHP_WIN32)
|
|
/* If its our thread then we already have the lock so no need to lock again */
|
|
if (imagick_thread_id != tsrm_thread_id()) {
|
|
tsrm_mutex_lock(imagick_mutex);
|
|
imagick_thread_id = tsrm_thread_id();
|
|
}
|
|
#endif
|
|
|
|
if (ptr) {
|
|
*ptr = intern;
|
|
}
|
|
|
|
/* Set the magickwand */
|
|
if (init_wand) {
|
|
intern->magick_wand = NewMagickWand();
|
|
|
|
if (!intern->magick_wand) {
|
|
zend_error(E_ERROR, "Failed to create Imagick object, could not set magick_wand");
|
|
}
|
|
} else {
|
|
intern->magick_wand = NULL;
|
|
}
|
|
intern->next_out_of_bound = 0;
|
|
intern->progress_monitor_name = NULL;
|
|
|
|
zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
|
|
object_properties_init(&intern->zo, class_type);
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
#if PHP_VERSION_ID < 80300
|
|
intern->zo.handlers = &imagick_object_handlers;
|
|
#endif
|
|
return &intern->zo;
|
|
#else
|
|
retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_imagick_object_free_storage, NULL TSRMLS_CC);
|
|
retval.handlers = (zend_object_handlers *) &imagick_object_handlers;
|
|
return retval;
|
|
#endif
|
|
}
|
|
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#endif
|
|
{
|
|
return php_imagick_object_new_ex(class_type, NULL, 1 TSRMLS_CC);
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickdraw_object_new_ex(zend_class_entry *class_type, php_imagickdraw_object **ptr, zend_bool init_wand TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickdraw_object_new_ex(zend_class_entry *class_type, php_imagickdraw_object **ptr, zend_bool init_wand TSRMLS_DC)
|
|
#endif
|
|
{
|
|
php_imagickdraw_object *intern;
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
/* Allocate memory for it */
|
|
intern = ecalloc(1,
|
|
sizeof(php_imagickdraw_object) +
|
|
zend_object_properties_size(class_type));
|
|
|
|
zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
|
|
object_properties_init(&intern->zo, class_type);
|
|
#if PHP_VERSION_ID < 80300
|
|
intern->zo.handlers = &imagickdraw_object_handlers;
|
|
#endif
|
|
#else
|
|
zend_object_value retval;
|
|
intern = (php_imagickdraw_object *) emalloc(sizeof(php_imagickdraw_object));
|
|
memset(&intern->zo, 0, sizeof(zend_object));
|
|
#endif
|
|
|
|
if (ptr) {
|
|
*ptr = intern;
|
|
}
|
|
|
|
/* Set the DrawingWand */
|
|
if (init_wand) {
|
|
intern->drawing_wand = NewDrawingWand();
|
|
|
|
if (!intern->drawing_wand) {
|
|
zend_error(E_ERROR, "Failed to create ImagickDraw object");
|
|
}
|
|
} else {
|
|
intern->drawing_wand = NULL;
|
|
}
|
|
#if PHP_VERSION_ID >= 70000
|
|
intern->zo.handlers = &imagickdraw_object_handlers;
|
|
|
|
return &intern->zo;
|
|
#else
|
|
/* 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_imagickdraw_object_free_storage, NULL TSRMLS_CC);
|
|
retval.handlers = (zend_object_handlers *) &imagickdraw_object_handlers;
|
|
|
|
return retval;
|
|
#endif
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickdraw_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickdraw_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#endif
|
|
{
|
|
return php_imagickdraw_object_new_ex(class_type, NULL, 1 TSRMLS_CC);
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickpixeliterator_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickpixeliterator_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#endif
|
|
{
|
|
php_imagickpixeliterator_object *intern;
|
|
|
|
/* Allocate memory for it */
|
|
#if PHP_VERSION_ID >= 70000
|
|
intern = ecalloc(1,
|
|
sizeof(php_imagickpixeliterator_object) +
|
|
zend_object_properties_size(class_type));
|
|
#else
|
|
zend_object_value retval;
|
|
intern = (php_imagickpixeliterator_object *) emalloc(sizeof(php_imagickpixeliterator_object));
|
|
memset(&intern->zo, 0, sizeof(zend_object));
|
|
#endif
|
|
|
|
/* We cant initialize yet */
|
|
intern->pixel_iterator = NULL;
|
|
intern->initialized = 0;
|
|
|
|
#if MagickLibVersion <= 0x628
|
|
intern->rows = 0;
|
|
intern->iterator_position = 0;
|
|
#endif
|
|
|
|
zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
|
|
object_properties_init(&intern->zo, class_type);
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
#if PHP_VERSION_ID < 80300
|
|
intern->zo.handlers = &imagickpixeliterator_object_handlers;
|
|
#endif
|
|
return &intern->zo;
|
|
#else
|
|
retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_imagickpixeliterator_object_free_storage, NULL TSRMLS_CC);
|
|
retval.handlers = (zend_object_handlers *) &imagickpixeliterator_object_handlers;
|
|
|
|
return retval;
|
|
#endif
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickpixel_object_new_ex(zend_class_entry *class_type, php_imagickpixel_object **ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickpixel_object_new_ex(zend_class_entry *class_type, php_imagickpixel_object **ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
php_imagickpixel_object *intern;
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
/* Allocate memory for it */
|
|
intern = ecalloc(1,
|
|
sizeof(php_imagickpixel_object) +
|
|
zend_object_properties_size(class_type));
|
|
#else
|
|
zend_object_value retval;
|
|
intern = (php_imagickpixel_object *) emalloc(sizeof(php_imagickpixel_object));
|
|
memset(&intern->zo, 0, sizeof(zend_object));
|
|
#endif
|
|
|
|
if (ptr) {
|
|
*ptr = intern;
|
|
}
|
|
|
|
/* Set the pixeliterator */
|
|
intern->pixel_wand = NULL;
|
|
intern->initialized_via_iterator = 0;
|
|
zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
|
|
object_properties_init(&intern->zo, class_type);
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
#if PHP_VERSION_ID < 80300
|
|
intern->zo.handlers = &imagickpixel_object_handlers;
|
|
#endif
|
|
return &intern->zo;
|
|
#else
|
|
retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_imagickpixel_object_free_storage, NULL TSRMLS_CC);
|
|
retval.handlers = (zend_object_handlers *) &imagickpixel_object_handlers;
|
|
|
|
return retval;
|
|
#endif
|
|
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickpixel_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickpixel_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#endif
|
|
{
|
|
return php_imagickpixel_object_new_ex(class_type, NULL TSRMLS_CC);
|
|
}
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickkernel_object_new_ex(zend_class_entry *class_type, php_imagickkernel_object **ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickkernel_object_new_ex(zend_class_entry *class_type, php_imagickkernel_object **ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
|
|
php_imagickkernel_object *intern;
|
|
|
|
/* Allocate memory for it */
|
|
#if PHP_VERSION_ID >= 70000
|
|
intern = ecalloc(1,
|
|
sizeof(php_imagickkernel_object) +
|
|
zend_object_properties_size(class_type));
|
|
#else
|
|
zend_object_value retval;
|
|
intern = (php_imagickkernel_object *) emalloc(sizeof(php_imagickkernel_object));
|
|
memset(&intern->zo, 0, sizeof(zend_object));
|
|
#endif
|
|
|
|
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);
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
#if PHP_VERSION_ID < 80300
|
|
intern->zo.handlers = &imagickkernel_object_handlers;
|
|
#endif
|
|
return &intern->zo;
|
|
#else
|
|
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;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#undef object_properties_init
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagickkernel_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagickkernel_object_new(zend_class_entry *class_type TSRMLS_DC)
|
|
#endif
|
|
{
|
|
return php_imagickkernel_object_new_ex(class_type, NULL TSRMLS_CC);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
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.skip_version_check", "0", PHP_INI_ALL, OnUpdateBool, skip_version_check, zend_imagick_globals, imagick_globals)
|
|
STD_PHP_INI_ENTRY("imagick.progress_monitor", "0", PHP_INI_SYSTEM, OnUpdateBool, progress_monitor, zend_imagick_globals, imagick_globals)
|
|
|
|
STD_PHP_INI_ENTRY("imagick.set_single_thread", "1", PHP_INI_SYSTEM, OnUpdateBool, set_single_thread, zend_imagick_globals, imagick_globals)
|
|
STD_PHP_INI_ENTRY("imagick.shutdown_sleep_count", "10", PHP_INI_ALL, OnUpdateLong, shutdown_sleep_count, zend_imagick_globals, imagick_globals)
|
|
STD_PHP_INI_ENTRY("imagick.allow_zero_dimension_images", "0", PHP_INI_ALL, OnUpdateBool, allow_zero_dimension_images, zend_imagick_globals, imagick_globals)
|
|
PHP_INI_END()
|
|
|
|
static void php_imagick_init_globals(zend_imagick_globals *imagick_globals)
|
|
{
|
|
imagick_globals->locale_fix = 0;
|
|
imagick_globals->progress_monitor = 0;
|
|
imagick_globals->skip_version_check = 0;
|
|
imagick_globals->set_single_thread = 1;
|
|
imagick_globals->allow_zero_dimension_images = 0;
|
|
// 10 is magick number, that seems to be enough.
|
|
imagick_globals->shutdown_sleep_count = 10;
|
|
}
|
|
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static int php_imagick_count_elements(zend_object *object, im_long *count) /* {{{ */
|
|
{
|
|
php_imagick_object *intern= php_imagick_fetch_object(object);
|
|
#else
|
|
static int php_imagick_count_elements(zval *object, im_long *count TSRMLS_DC) /* {{{ */
|
|
{
|
|
php_imagick_object *intern= Z_IMAGICK_P(object);
|
|
#endif
|
|
|
|
if (intern->magick_wand) {
|
|
*count = MagickGetNumberImages(intern->magick_wand);
|
|
return SUCCESS;
|
|
}
|
|
return FAILURE;
|
|
}
|
|
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static zval *php_imagick_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv)
|
|
{
|
|
int ret;
|
|
php_imagick_object *intern;
|
|
zval *retval = NULL;
|
|
const zend_object_handlers *std_hnd;
|
|
|
|
|
|
std_hnd = zend_get_std_object_handlers();
|
|
|
|
ret = std_hnd->has_property(object, member, type, cache_slot TSRMLS_CC);
|
|
|
|
if (ret) {
|
|
//TODO - this would allow better immutability
|
|
//ZVAL_COPY_VALUE(retval, std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC));
|
|
retval = std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC);
|
|
}
|
|
else {
|
|
|
|
intern = php_imagick_fetch_object(object);
|
|
/* Do we have any images? */
|
|
if (MagickGetNumberImages(intern->magick_wand)) {
|
|
|
|
//TODO - this seems redundant
|
|
/* Is this overloaded? */
|
|
if (!strcmp(ZSTR_VAL(member), "width") ||
|
|
!strcmp(ZSTR_VAL(member), "height") ||
|
|
!strcmp(ZSTR_VAL(member), "format")) {
|
|
|
|
if (!strcmp(ZSTR_VAL(member), "width")) {
|
|
retval = rv;
|
|
ZVAL_LONG(retval, MagickGetImageWidth(intern->magick_wand));
|
|
} else if (!strcmp(ZSTR_VAL(member), "height")) {
|
|
retval = rv;
|
|
ZVAL_LONG(retval, MagickGetImageHeight(intern->magick_wand));
|
|
} else if (!strcmp(ZSTR_VAL(member), "format")) {
|
|
char *format = MagickGetImageFormat(intern->magick_wand);
|
|
|
|
if (format) {
|
|
retval = rv;
|
|
ZVAL_STRING(retval, format);
|
|
zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
|
IMAGICK_FREE_MAGICK_MEMORY(format);
|
|
} else {
|
|
retval = rv;
|
|
ZVAL_STRING(retval, "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!retval) {
|
|
//TODO - why is the error silent - it would be a small BC break
|
|
//to enable the warning. I think it would be the correct thing to do though.
|
|
//zend_error(E_NOTICE,"Undefined property: \Imagick::$%s", Z_STRVAL_P(member));
|
|
retval = &EG(uninitialized_zval);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
#else // PHP_VERSION_ID >= 80000
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
static zval *php_imagick_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv TSRMLS_DC)
|
|
{
|
|
int ret;
|
|
php_imagick_object *intern;
|
|
zval *retval = NULL;
|
|
zval tmp_member;
|
|
const zend_object_handlers *std_hnd;
|
|
|
|
ZVAL_DEREF(member);
|
|
if (Z_TYPE_P(member) != IS_STRING) {
|
|
tmp_member = *member;
|
|
zval_copy_ctor(&tmp_member);
|
|
convert_to_string(&tmp_member);
|
|
member = &tmp_member;
|
|
}
|
|
|
|
std_hnd = zend_get_std_object_handlers();
|
|
|
|
ret = std_hnd->has_property(object, member, type, cache_slot TSRMLS_CC);
|
|
|
|
if (ret) {
|
|
//TODO - this would allow better immutability
|
|
//ZVAL_COPY_VALUE(retval, std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC));
|
|
retval = std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC);
|
|
}
|
|
else {
|
|
|
|
intern = Z_IMAGICK_P(object);
|
|
/* Do we have any images? */
|
|
if (MagickGetNumberImages(intern->magick_wand)) {
|
|
|
|
//TODO - this seems redundant
|
|
/* Is this overloaded? */
|
|
if (!strcmp(Z_STRVAL_P(member), "width") ||
|
|
!strcmp(Z_STRVAL_P(member), "height") ||
|
|
!strcmp(Z_STRVAL_P(member), "format")) {
|
|
|
|
if (!strcmp(Z_STRVAL_P(member), "width")) {
|
|
retval = rv;
|
|
ZVAL_LONG(retval, MagickGetImageWidth(intern->magick_wand));
|
|
} else if (!strcmp(Z_STRVAL_P(member), "height")) {
|
|
retval = rv;
|
|
ZVAL_LONG(retval, MagickGetImageHeight(intern->magick_wand));
|
|
} else if (!strcmp(Z_STRVAL_P(member), "format")) {
|
|
char *format = MagickGetImageFormat(intern->magick_wand);
|
|
|
|
if (format) {
|
|
retval = rv;
|
|
ZVAL_STRING(retval, format);
|
|
zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
|
IMAGICK_FREE_MAGICK_MEMORY(format);
|
|
} else {
|
|
retval = rv;
|
|
ZVAL_STRING(retval, "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!retval) {
|
|
//TODO - why is the error silent - it would be a small BC break
|
|
//to enable the warning. I think it would be the correct thing to do though.
|
|
//zend_error(E_NOTICE,"Undefined property: \Imagick::$%s", Z_STRVAL_P(member));
|
|
retval = &EG(uninitialized_zval);
|
|
}
|
|
|
|
if (member == &tmp_member) {
|
|
zval_dtor(member);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
#else
|
|
|
|
#if PHP_VERSION_ID < 50399
|
|
static zval *php_imagick_read_property(zval *object, zval *member, int type TSRMLS_DC)
|
|
#else
|
|
static zval *php_imagick_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
|
|
#endif
|
|
{
|
|
int ret;
|
|
php_imagick_object *intern;
|
|
zval *retval = NULL, tmp_member;
|
|
zend_object_handlers *std_hnd;
|
|
|
|
if (Z_TYPE_P(member) != IS_STRING) {
|
|
tmp_member = *member;
|
|
zval_copy_ctor(&tmp_member);
|
|
convert_to_string(&tmp_member);
|
|
member = &tmp_member;
|
|
}
|
|
|
|
std_hnd = zend_get_std_object_handlers();
|
|
#if PHP_VERSION_ID < 50399
|
|
ret = std_hnd->has_property(object, member, 2 TSRMLS_CC);
|
|
#else
|
|
ret = std_hnd->has_property(object, member, 2, key TSRMLS_CC);
|
|
#endif
|
|
|
|
if (ret) {
|
|
std_hnd = zend_get_std_object_handlers();
|
|
#if PHP_VERSION_ID < 50399
|
|
retval = std_hnd->read_property(object, member, type TSRMLS_CC);
|
|
#else
|
|
retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
|
|
#endif
|
|
} else {
|
|
intern = (php_imagick_object *) zend_object_store_get_object(object TSRMLS_CC);
|
|
/* Do we have any images? */
|
|
if (MagickGetNumberImages(intern->magick_wand)) {
|
|
/* Is this overloaded? */
|
|
if (!strcmp(Z_STRVAL_P(member), "width") ||
|
|
!strcmp(Z_STRVAL_P(member), "height") ||
|
|
!strcmp(Z_STRVAL_P(member), "format")) {
|
|
|
|
MAKE_STD_ZVAL(retval);
|
|
#ifdef Z_SET_REFCOUNT_P
|
|
Z_SET_REFCOUNT_P(retval, 0);
|
|
#else
|
|
retval->refcount = 0;
|
|
#endif
|
|
if (!strcmp(Z_STRVAL_P(member), "width")) {
|
|
ZVAL_LONG(retval, MagickGetImageWidth(intern->magick_wand));
|
|
} else if (!strcmp(Z_STRVAL_P(member), "height")) {
|
|
ZVAL_LONG(retval, MagickGetImageHeight(intern->magick_wand));
|
|
} else if (!strcmp(Z_STRVAL_P(member), "format")) {
|
|
char *format = MagickGetImageFormat(intern->magick_wand);
|
|
|
|
if (format) {
|
|
ZVAL_STRING(retval, format, 1);
|
|
zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
|
IMAGICK_FREE_MAGICK_MEMORY(format);
|
|
} else {
|
|
ZVAL_STRING(retval, "", 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (member == &tmp_member) {
|
|
zval_dtor(member);
|
|
}
|
|
|
|
if (!retval) {
|
|
retval = EG(uninitialized_zval_ptr);
|
|
}
|
|
return retval;
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static zend_object * php_imagick_clone_imagick_object(zend_object *this_ptr)
|
|
#elif PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_clone_imagick_object(zval *this_ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_clone_imagick_object(zval *this_ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
MagickWand *wand_copy = NULL;
|
|
php_imagick_object *new_obj = NULL;
|
|
#if PHP_VERSION_ID >= 80000
|
|
php_imagick_object *old_obj = php_imagick_fetch_object(this_ptr);
|
|
zend_object * new_zo = php_imagick_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#elif PHP_VERSION_ID >= 70000
|
|
php_imagick_object *old_obj = Z_IMAGICK_P(this_ptr);
|
|
zend_object * new_zo = php_imagick_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#else
|
|
php_imagick_object *old_obj = (php_imagick_object *) zend_object_store_get_object(this_ptr TSRMLS_CC);
|
|
zend_object_value new_zo = php_imagick_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, new_zo, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
|
|
#endif
|
|
|
|
wand_copy = CloneMagickWand(old_obj->magick_wand);
|
|
if (!wand_copy) {
|
|
zend_error(E_ERROR, "Failed to clone Imagick object");
|
|
} else {
|
|
php_imagick_replace_magickwand(new_obj, wand_copy);
|
|
new_obj->next_out_of_bound = old_obj->next_out_of_bound;
|
|
|
|
if (old_obj->progress_monitor_name) {
|
|
new_obj->progress_monitor_name = estrdup(old_obj->progress_monitor_name);
|
|
}
|
|
}
|
|
return new_zo;
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static zend_object * php_imagick_clone_imagickdraw_object(zend_object *this_ptr)
|
|
#elif PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_clone_imagickdraw_object(zval *this_ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_clone_imagickdraw_object(zval *this_ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
DrawingWand *wand_copy = NULL;
|
|
php_imagickdraw_object *new_obj = NULL;
|
|
#if PHP_VERSION_ID >= 80000
|
|
php_imagickdraw_object *old_obj = php_imagickdraw_fetch_object(this_ptr);
|
|
zend_object * new_zo = php_imagickdraw_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#elif PHP_VERSION_ID >= 70000
|
|
php_imagickdraw_object *old_obj = Z_IMAGICKDRAW_P(this_ptr);
|
|
zend_object * new_zo = php_imagickdraw_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#else
|
|
php_imagickdraw_object *old_obj = (php_imagickdraw_object *) zend_object_store_get_object(this_ptr TSRMLS_CC);
|
|
zend_object_value new_zo = php_imagickdraw_object_new_ex(old_obj->zo.ce, &new_obj, 0 TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, new_zo, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
|
|
#endif
|
|
|
|
wand_copy = CloneDrawingWand(old_obj->drawing_wand);
|
|
|
|
if (!wand_copy) {
|
|
zend_error(E_ERROR, "Failed to clone ImagickDraw object");
|
|
} else {
|
|
php_imagick_replace_drawingwand(new_obj, wand_copy);
|
|
}
|
|
return new_zo;
|
|
}
|
|
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static zend_object * php_imagick_clone_imagickpixel_object(zend_object *this_ptr)
|
|
#elif PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_clone_imagickpixel_object(zval *this_ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_clone_imagickpixel_object(zval *this_ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
PixelWand *wand_copy = NULL;
|
|
php_imagickpixel_object *new_obj = NULL;
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
zend_object *new_zo;
|
|
php_imagickpixel_object *old_obj = php_imagickpixel_fetch_object(this_ptr);
|
|
new_zo = php_imagickpixel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#elif PHP_VERSION_ID >= 70000
|
|
zend_object *new_zo;
|
|
php_imagickpixel_object *old_obj = Z_IMAGICKPIXEL_P(this_ptr);
|
|
new_zo = php_imagickpixel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#else
|
|
php_imagickpixel_object *old_obj = (php_imagickpixel_object *) zend_object_store_get_object(this_ptr TSRMLS_CC);
|
|
zend_object_value new_zo = php_imagickpixel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, new_zo, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
|
|
#endif
|
|
|
|
wand_copy = php_imagick_clone_pixelwand (old_obj->pixel_wand);
|
|
if (!wand_copy) {
|
|
zend_error(E_ERROR, "Failed to clone ImagickPixel object");
|
|
} else {
|
|
php_imagick_replace_pixelwand(new_obj, wand_copy);
|
|
new_obj->initialized_via_iterator = 0;
|
|
}
|
|
return new_zo;
|
|
}
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
static zend_object * php_imagick_clone_imagickkernel_object(zend_object *this_ptr TSRMLS_DC)
|
|
#elif PHP_VERSION_ID >= 70000
|
|
static zend_object * php_imagick_clone_imagickkernel_object(zval *this_ptr TSRMLS_DC)
|
|
#else
|
|
static zend_object_value php_imagick_clone_imagickkernel_object(zval *this_ptr TSRMLS_DC)
|
|
#endif
|
|
{
|
|
KernelInfo *kernel_info_copy = NULL;
|
|
php_imagickkernel_object *new_obj = NULL;
|
|
|
|
#if PHP_VERSION_ID >= 80000
|
|
zend_object *new_zo;
|
|
php_imagickkernel_object *old_obj = php_imagickkernel_fetch_object(this_ptr);
|
|
new_zo = php_imagickkernel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#elif PHP_VERSION_ID >= 70000
|
|
zend_object *new_zo;
|
|
php_imagickkernel_object *old_obj = Z_IMAGICKKERNEL_P(this_ptr);
|
|
new_zo = php_imagickkernel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, &old_obj->zo TSRMLS_CC);
|
|
#else
|
|
zend_object_value new_zo;
|
|
php_imagickkernel_object *old_obj = (php_imagickkernel_object *) zend_object_store_get_object(this_ptr TSRMLS_CC);
|
|
new_zo = php_imagickkernel_object_new_ex(old_obj->zo.ce, &new_obj TSRMLS_CC);
|
|
zend_objects_clone_members(&new_obj->zo, new_zo, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
|
|
#endif
|
|
|
|
if (old_obj->kernel_info != NULL) {
|
|
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_zo;
|
|
}
|
|
#endif
|
|
|
|
|
|
static void checkImagickVersion()
|
|
{
|
|
//This gets the version that Imagick was compiled against.
|
|
size_t imagickVersion = MagickLibVersion;
|
|
|
|
//This gets the version of ImageMagick that has been loaded
|
|
size_t imageMagickLibraryVersion;
|
|
|
|
GetMagickVersion(&imageMagickLibraryVersion);
|
|
|
|
if (imagickVersion == imageMagickLibraryVersion) {
|
|
return;
|
|
}
|
|
|
|
zend_error(
|
|
E_WARNING,
|
|
"Version warning: Imagick was compiled against ImageMagick version %lu but version %lu is loaded. Imagick will run but may behave surprisingly",
|
|
(unsigned long)imagickVersion,
|
|
(unsigned long)imageMagickLibraryVersion
|
|
);
|
|
}
|
|
|
|
PHP_MINIT_FUNCTION(imagick)
|
|
{
|
|
zend_class_entry ce;
|
|
|
|
/* Initialize globals */
|
|
ZEND_INIT_MODULE_GLOBALS(imagick, php_imagick_init_globals, NULL);
|
|
|
|
|
|
// This suppresses an 'unused parameter' warning.
|
|
(void)type;
|
|
|
|
/*
|
|
Allocate some memory
|
|
*/
|
|
memcpy(&imagick_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
|
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));
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
memcpy(&imagickkernel_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
|
#endif
|
|
|
|
/* Set custom allocators */
|
|
MagickWandGenesis();
|
|
|
|
/*
|
|
Initialize exceptions (Imagick exception)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICK_EXCEPTION_SC_NAME, NULL);
|
|
#if PHP_VERSION_ID >= 70000
|
|
php_imagick_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
|
#else
|
|
php_imagick_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
|
#endif
|
|
|
|
/*
|
|
Initialize exceptions (ImagickDraw exception)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKDRAW_EXCEPTION_SC_NAME, NULL);
|
|
#if PHP_VERSION_ID >= 70000
|
|
php_imagickdraw_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
|
#else
|
|
php_imagickdraw_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
|
#endif
|
|
|
|
/*
|
|
Initialize exceptions (ImagickPixelIterator exception)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKPIXELITERATOR_EXCEPTION_SC_NAME, NULL);
|
|
#if PHP_VERSION_ID >= 70000
|
|
php_imagickpixeliterator_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
|
#else
|
|
php_imagickpixeliterator_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
|
#endif
|
|
|
|
/*
|
|
Initialize exceptions (ImagickPixel exception)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKPIXEL_EXCEPTION_SC_NAME, NULL);
|
|
#if PHP_VERSION_ID >= 70000
|
|
php_imagickpixel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
|
#else
|
|
php_imagickpixel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
|
#endif
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
/*
|
|
Initialize exceptions (ImagickKernel exception)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKKERNEL_EXCEPTION_SC_NAME, NULL);
|
|
#if PHP_VERSION_ID >= 70000
|
|
php_imagickkernel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
|
#else
|
|
php_imagickkernel_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*
|
|
Initialize the class (Imagick)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICK_SC_NAME, php_imagick_class_methods);
|
|
#if PHP_VERSION_ID < 80300
|
|
ce.create_object = php_imagick_object_new;
|
|
#endif
|
|
imagick_object_handlers.clone_obj = php_imagick_clone_imagick_object;
|
|
imagick_object_handlers.read_property = php_imagick_read_property;
|
|
imagick_object_handlers.count_elements = php_imagick_count_elements;
|
|
#if PHP_VERSION_ID >= 70000
|
|
imagick_object_handlers.offset = XtOffsetOf(php_imagick_object, zo);
|
|
imagick_object_handlers.free_obj = php_imagick_object_free_storage;
|
|
#endif
|
|
|
|
php_imagick_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
|
|
#if PHP_VERSION_ID >= 80300
|
|
php_imagick_sc_entry->create_object = php_imagick_object_new;
|
|
php_imagick_sc_entry->default_object_handlers = &imagick_object_handlers;
|
|
#endif
|
|
zend_class_implements(php_imagick_sc_entry TSRMLS_CC, 2, zend_ce_iterator, im_ce_countable);
|
|
|
|
/*
|
|
Initialize the class (ImagickDraw)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKDRAW_SC_NAME, php_imagickdraw_class_methods);
|
|
#if PHP_VERSION_ID < 80300
|
|
ce.create_object = php_imagickdraw_object_new;
|
|
#endif
|
|
imagickdraw_object_handlers.clone_obj = php_imagick_clone_imagickdraw_object;
|
|
#if PHP_VERSION_ID >= 70000
|
|
imagickdraw_object_handlers.offset = XtOffsetOf(php_imagickdraw_object, zo);
|
|
imagickdraw_object_handlers.free_obj = php_imagickdraw_object_free_storage;
|
|
#endif
|
|
php_imagickdraw_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
|
|
#if PHP_VERSION_ID >= 80300
|
|
php_imagickdraw_sc_entry->create_object = php_imagickdraw_object_new;
|
|
php_imagickdraw_sc_entry->default_object_handlers = &imagickdraw_object_handlers;
|
|
#endif
|
|
|
|
/*
|
|
Initialize the class (ImagickPixelIterator)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKPIXELITERATOR_SC_NAME, php_imagickpixeliterator_class_methods);
|
|
#if PHP_VERSION_ID < 80300
|
|
ce.create_object = php_imagickpixeliterator_object_new;
|
|
#endif
|
|
imagickpixeliterator_object_handlers.clone_obj = NULL;
|
|
#if PHP_VERSION_ID >= 70000
|
|
imagickpixeliterator_object_handlers.offset = XtOffsetOf(php_imagickpixeliterator_object, zo);
|
|
imagickpixeliterator_object_handlers.free_obj = php_imagickpixeliterator_object_free_storage;
|
|
#endif
|
|
php_imagickpixeliterator_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
|
|
#if PHP_VERSION_ID >= 80300
|
|
php_imagickpixeliterator_sc_entry->create_object = php_imagickpixeliterator_object_new;
|
|
php_imagickpixeliterator_sc_entry->default_object_handlers = &imagickpixeliterator_object_handlers;
|
|
#endif
|
|
zend_class_implements(php_imagickpixeliterator_sc_entry TSRMLS_CC, 1, zend_ce_iterator);
|
|
|
|
/*
|
|
Initialize the class (ImagickPixel)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKPIXEL_SC_NAME, php_imagickpixel_class_methods);
|
|
#if PHP_VERSION_ID < 80300
|
|
ce.create_object = php_imagickpixel_object_new;
|
|
#endif
|
|
imagickpixel_object_handlers.clone_obj = php_imagick_clone_imagickpixel_object;
|
|
#if PHP_VERSION_ID >= 70000
|
|
imagickpixel_object_handlers.offset = XtOffsetOf(php_imagickpixel_object, zo);
|
|
imagickpixel_object_handlers.free_obj = php_imagickpixel_object_free_storage;
|
|
#endif
|
|
|
|
php_imagickpixel_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
|
|
#if PHP_VERSION_ID >= 80300
|
|
php_imagickpixel_sc_entry->create_object = php_imagickpixel_object_new;
|
|
php_imagickpixel_sc_entry->default_object_handlers = &imagickpixel_object_handlers;
|
|
#endif
|
|
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
/*
|
|
Initialize the class (ImagickKernel)
|
|
*/
|
|
INIT_CLASS_ENTRY(ce, PHP_IMAGICKKERNEL_SC_NAME, php_imagickkernel_class_methods);
|
|
#if PHP_VERSION_ID < 80300
|
|
ce.create_object = php_imagickkernel_object_new;
|
|
#endif
|
|
// Disabled until can be compiled under wall correctly
|
|
imagickkernel_object_handlers.get_debug_info = php_imagickkernel_get_debug_info;
|
|
imagickkernel_object_handlers.clone_obj = php_imagick_clone_imagickkernel_object;
|
|
#if PHP_VERSION_ID >= 70000
|
|
imagickkernel_object_handlers.offset = XtOffsetOf(php_imagickkernel_object, zo);
|
|
imagickkernel_object_handlers.free_obj = php_imagickkernel_object_free_storage;
|
|
#endif
|
|
|
|
php_imagickkernel_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
|
|
#if PHP_VERSION_ID >= 80300
|
|
php_imagickkernel_sc_entry->create_object = php_imagickkernel_object_new;
|
|
php_imagickkernel_sc_entry->default_object_handlers = &imagickkernel_object_handlers;
|
|
#endif
|
|
#endif
|
|
|
|
php_imagick_initialize_constants (TSRMLS_C);
|
|
|
|
#if defined(ZTS) && defined(PHP_WIN32)
|
|
imagick_mutex = tsrm_mutex_alloc();
|
|
#endif
|
|
|
|
REGISTER_INI_ENTRIES();
|
|
|
|
if (!IMAGICK_G(skip_version_check)) {
|
|
checkImagickVersion();
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
PHP_MINFO_FUNCTION(imagick)
|
|
{
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
smart_string formats = {0};
|
|
#else
|
|
smart_str formats = {0};
|
|
#endif
|
|
|
|
char **supported_formats, *buffer;
|
|
unsigned long i;
|
|
size_t num_formats;
|
|
size_t version_number;
|
|
|
|
num_formats = 0;
|
|
|
|
supported_formats = MagickQueryFormats("*", &num_formats);
|
|
spprintf(&buffer, 0, "%ld", (long)num_formats);
|
|
|
|
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);
|
|
#ifdef IMAGICK_WITH_KERNEL
|
|
php_info_print_table_row(2, "imagick classes", "Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel");
|
|
#else
|
|
php_info_print_table_row(2, "imagick classes", "Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator");
|
|
#endif
|
|
#ifdef MagickVersion
|
|
php_info_print_table_row(2, "Imagick compiled with ImageMagick version", MagickVersion);
|
|
#endif
|
|
php_info_print_table_row(2, "Imagick using ImageMagick library version", MagickGetVersion(&version_number));
|
|
php_info_print_table_row(2, "ImageMagick copyright", MagickGetCopyright());
|
|
php_info_print_table_row(2, "ImageMagick release date", MagickGetReleaseDate());
|
|
php_info_print_table_row(2, "ImageMagick number of supported formats: ", buffer);
|
|
|
|
efree (buffer);
|
|
|
|
if (supported_formats) {
|
|
for (i = 0; i < num_formats; i++) {
|
|
#if PHP_VERSION_ID >= 70000
|
|
if (i != 0) {
|
|
smart_string_appends(&formats, ", ");
|
|
}
|
|
smart_string_appends(&formats, supported_formats[i]);
|
|
#else
|
|
smart_str_appends(&formats, supported_formats[i]);
|
|
if (i != (num_formats - 1)) {
|
|
smart_str_appends(&formats, ", ");
|
|
}
|
|
#endif
|
|
IMAGICK_FREE_MAGICK_MEMORY(supported_formats[i]);
|
|
}
|
|
|
|
#if PHP_VERSION_ID >= 70000
|
|
smart_string_0(&formats);
|
|
php_info_print_table_row(2, "ImageMagick supported formats", formats.c);
|
|
smart_string_free(&formats);
|
|
#else
|
|
smart_str_0(&formats);
|
|
php_info_print_table_row(2, "ImageMagick supported formats", formats.c);
|
|
smart_str_free(&formats);
|
|
#endif
|
|
IMAGICK_FREE_MAGICK_MEMORY(supported_formats);
|
|
}
|
|
|
|
php_info_print_table_end();
|
|
DISPLAY_INI_ENTRIES();
|
|
}
|
|
|
|
|
|
PHP_MSHUTDOWN_FUNCTION(imagick)
|
|
{
|
|
#if !HAVE_OMP_PAUSE_RESOURCE_ALL
|
|
int i;
|
|
#endif
|
|
|
|
// This suppresses an 'unused parameter' warning.
|
|
(void)type;
|
|
|
|
MagickWandTerminus();
|
|
|
|
#if HAVE_OMP_PAUSE_RESOURCE_ALL
|
|
omp_pause_resource_all(omp_pause_hard);
|
|
#else
|
|
// Sleep for a bit to hopefully allow OpenMP to
|
|
// shut down the threads it created, and avoid a segfault
|
|
// This hack won't be needed once everyone is compiling ImageMagick
|
|
// against a version of OpenMP that has omp_pause_resource_all()
|
|
for (i = 0; i < 100 && i < IMAGICK_G(shutdown_sleep_count); i += 1) {
|
|
usleep(1000);
|
|
}
|
|
#endif
|
|
|
|
#if defined(ZTS) && defined(PHP_WIN32)
|
|
tsrm_mutex_free(imagick_mutex);
|
|
#endif
|
|
UNREGISTER_INI_ENTRIES();
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_RINIT_FUNCTION(imagick)
|
|
{
|
|
// This suppresses an 'unused parameter' warning.
|
|
(void)type;
|
|
(void)module_number;
|
|
|
|
IMAGICK_G(progress_callback) = NULL;
|
|
|
|
if (IMAGICK_G(set_single_thread)) {
|
|
MagickSetResourceLimit(ThreadResource, 1);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_RSHUTDOWN_FUNCTION(imagick)
|
|
{
|
|
php_imagick_callback* progress_callback = IMAGICK_G(progress_callback);
|
|
// This suppresses an 'unused parameter' warning.
|
|
(void)type;
|
|
(void)module_number;
|
|
|
|
if (progress_callback) {
|
|
php_imagick_cleanup_progress_callback(progress_callback TSRMLS_CC);
|
|
efree(progress_callback);
|
|
IMAGICK_G(progress_callback) = NULL;
|
|
}
|
|
|
|
#if defined(ZTS) && defined(PHP_WIN32)
|
|
/* We have the lock so lets release it */
|
|
if (imagick_thread_id == tsrm_thread_id()) {
|
|
imagick_thread_id = (THREAD_T)NULL;
|
|
tsrm_mutex_unlock(imagick_mutex);
|
|
}
|
|
#endif
|
|
return SUCCESS;
|
|
}
|
|
|
|
#if ZEND_MODULE_API_NO >= 20050922
|
|
static const zend_module_dep imagick_deps[] = {
|
|
ZEND_MOD_CONFLICTS("gmagick")
|
|
ZEND_MOD_REQUIRED("standard")
|
|
ZEND_MOD_REQUIRED("spl")
|
|
ZEND_MOD_END
|
|
};
|
|
#endif
|
|
|
|
zend_module_entry imagick_module_entry =
|
|
{
|
|
#if ZEND_MODULE_API_NO >= 20050922
|
|
STANDARD_MODULE_HEADER_EX, NULL,
|
|
imagick_deps,
|
|
#else
|
|
STANDARD_MODULE_HEADER,
|
|
#endif
|
|
PHP_IMAGICK_EXTNAME,
|
|
php_imagick_functions, /* Functions */
|
|
PHP_MINIT(imagick), /* MINIT */
|
|
PHP_MSHUTDOWN(imagick), /* MSHUTDOWN */
|
|
PHP_RINIT(imagick), /* RINIT */
|
|
PHP_RSHUTDOWN(imagick),
|
|
PHP_MINFO(imagick), /* MINFO */
|
|
PHP_IMAGICK_VERSION,
|
|
STANDARD_MODULE_PROPERTIES
|
|
};
|
|
|
|
#ifdef COMPILE_DL_IMAGICK
|
|
ZEND_GET_MODULE(imagick)
|
|
#endif
|