[ ] PHP 7 C++ |
ext_skel
. . , ./ext
PHP ext_skel
:./ext_skel --extname=phpcv
tests
config.m4
, php_phpcv.h
phpcv.c
. phpcv.c
phpcv.cpp
.phpize
.acinclude.m4
aclocal.m4
php, . , dnl , .
PHP_ARG_ENABLE(phpcv, whether to enable phpcv support,
[ --enable-phpcv Enable phpcv support])
if test "$PHP_PHPCV" != "no"; then
PHP_REQUIRE_CXX()
SEARCH_PATH="/usr/local /usr /opt/local"
SEARCH_FOR="/include/opencv2/opencv.hpp"
if test -r $PHP_PHPCV/$SEARCH_FOR; then
CV_DIR=$PHP_PHPCV
else
AC_MSG_CHECKING([for opencv in default path])
for i in $SEARCH_PATH ; do
if test -r $i/$SEARCH_FOR; then
CV_DIR=$i
AC_MSG_RESULT(found in $i)
break
fi
done
fi
if test -z "$CV_DIR"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Please reinstall the OpenCV distribution])
fi
AC_CHECK_HEADER([$CV_DIR/include/opencv2/objdetect/objdetect.hpp], [], AC_MSG_ERROR('opencv2/objdetect/objdetect.hpp' header not found))
AC_CHECK_HEADER([$CV_DIR/include/opencv2/highgui/highgui.hpp], [], AC_MSG_ERROR('opencv2/highgui/highgui.hpp' header not found))
PHP_ADD_LIBRARY_WITH_PATH(opencv_objdetect, $CV_DIR/lib, PHPCV_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(opencv_highgui, $CV_DIR/lib, PHPCV_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(opencv_imgproc, $CV_DIR/lib, PHPCV_SHARED_LIBADD)
PHP_SUBST(PHPCV_SHARED_LIBADD)
PHP_NEW_EXTENSION(phpcv, phpcv.cpp, $ext_shared,, -std=c++0x -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
fi
#ifndef PHP_PHPCV_H
#define PHP_PHPCV_H
#define PHP_PHPCV_EXTNAME "phpcv"
#define PHP_PHPCV_VERSION "0.2.0"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
extern "C" {
#include "php.h"
#include "ext/standard/info.h"
}
#ifdef ZTS
#include "TSRM.h"
#endif
extern zend_module_entry phpcv_module_entry;
#define phpext_phpcv_ptr &phpcv_module_entry
#if defined(ZTS) && defined(COMPILE_DL_PHPCV)
ZEND_TSRMLS_CACHE_EXTERN();
#endif
#endif /* PHP_PHPCV_H */
extern "C" { ... }
/**
* @see cv::CascadeClassifier::detectMultiScale()
* @param string $imgPath
* @param string $cascadePath
* @param double $scaleFactor
* @param int $minNeighbors
*
* @return array
*/
function cv_detect_multiscale($imgPath, $cascadePath, $scaleFactor, $minNeighbors) {
}
#include "php_phpcv.h"
#include objdetect/objdetect.hpp>
#include highgui/highgui.hpp>
#include imgproc/imgproc.hpp>
PHP_MINFO_FUNCTION(phpcv) {
php_info_print_table_start();
php_info_print_table_header(2, "phpcv support", "enabled");
php_info_print_table_end();
}
PHP_FUNCTION(cv_detect_multiscale) {
char *imgPath = NULL, *cascadePath = NULL;
long imgPathLen, cascadePathLen, minNeighbors;
double scaleFactor, minWidth, minHeight;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssdl", &imgPath, &imgPathLen, &cascadePath, &cascadePathLen, &scaleFactor, &minNeighbors) == FAILURE) {
RETURN_FALSE;
}
// Read Image
cv::Mat image;
image = cv::imread(imgPath, CV_LOAD_IMAGE_GRAYSCALE);
if (image.empty()) {
RETURN_FALSE;
}
equalizeHist(image, image);
//min size for detected object, discarding objects smaller than this
minWidth = image.size().width / 10;
minHeight = image.size().height / 10;
// Load Face cascade (.xml file)
cv::CascadeClassifier faceCascade;
if (!faceCascade.load(cascadePath)) {
RETURN_FALSE;
}
// Detect faces
std::vector faces;
faceCascade.detectMultiScale(image, faces, scaleFactor, minNeighbors, 0, cv::Size(minWidth, minHeight));
array_init(return_value);
// Build array to return
for ( int i = 0; i < faces.size(); i++ ) {
// Now we have: faces[i].x faces[i].y faces[i].width faces[i].height
zval face;
array_init(&face);
add_assoc_long(&face, "x", faces[i].x);
add_assoc_long(&face, "y", faces[i].y);
add_assoc_long(&face, "w", faces[i].width);
add_assoc_long(&face, "h", faces[i].height);
add_next_index_zval(return_value, &face);
}
}
const zend_function_entry phpcv_functions[] = {
PHP_FE(cv_detect_multiscale, NULL)
PHP_FE_END
};
zend_module_entry phpcv_module_entry = {
STANDARD_MODULE_HEADER,
PHP_PHPCV_EXTNAME,
phpcv_functions,
NULL,
NULL,
NULL,
NULL,
PHP_MINFO(phpcv),
PHP_PHPCV_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_PHPCV
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(phpcv)
#endif
zend_parse_parameters
++. opencv .NULL
, shutdown , .tests
--TEST--
Test face detection
--SKIPIF--
--FILE--
--EXPECT--
face detection works
phpize && ./configure && make
make test
PHP_ARG_ENABLE(intl-dtpg, whether to enable intl-dtpg support,
[ --enable-intl-dtpg Enable intl-dtpg support])
if test "$PHP_INTL_DTPG" != "no"; then
PHP_SETUP_ICU(INTL_DTPG_SHARED_LIBADD)
PHP_SUBST(INTL_DTPG_SHARED_LIBADD)
PHP_REQUIRE_CXX()
PHP_NEW_EXTENSION(intl_dtpg, intl_dtpg.cpp, $ext_shared,,-std=c++0x $ICU_INCS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
fi
$ICU_INCS
ICU .#ifndef INTL_DTPG_H
#define INTL_DTPG_H
#include
#include
#include dtptngen.h>
extern "C" {
#include "php.h"
#include "ext/standard/info.h"
}
extern zend_module_entry intl_dtpg_module_entry;
#define phpext_intl_dtpg_ptr &intl_dtpg_module_entry
#define INTL_DTPG_VERSION "1.0.0"
#ifdef ZTS
#include "TSRM.h"
#endif
typedef struct {
DateTimePatternGenerator *dtpg;
UErrorCode status;
zend_object zo;
} IntlDateTimePatternGenerator_object;
static inline IntlDateTimePatternGenerator_object *php_intl_datetimepatterngenerator_fetch_object(zend_object *obj) {
return (IntlDateTimePatternGenerator_object *)((char*)(obj) - XtOffsetOf(IntlDateTimePatternGenerator_object, zo));
}
#if defined(ZTS) && defined(COMPILE_DL_INTL_DTPG)
ZEND_TSRMLS_CACHE_EXTERN()
#endif
#endif /* INTL_DTPG_H */
IntlDateTimePatternGenerator_object
. DateTimePatternGenerator
ICU, zend_object
, PHP . C++ . API PHP zend_object
, , zend_object
.inline
IntlDateTimePatternGenerator_object
zend_object
. zend_object
zend_object
. , . intl.class IntlDateTimePatternGenerator
{
/**
* @param string $locale
*/
public function __construct(string $locale) {}
/**
* Return the best pattern matching the input skeleton.
* It is guaranteed to have all of the fields in the skeleton.
*
* @param string $skeleton The skeleton is a pattern containing only the variable fields.
* For example, "MMMdd" and "mmhh" are skeletons.
* @return string The best pattern found from the given skeleton.
*/
public function findBestPattern(string $skeleton) {}
}
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "intl_dtpg.h"
#include ustdio.h>
#include smpdtfmt.h>
zend_class_entry *IntlDateTimePatternGenerator_ce;
zend_object_handlers IntlDateTimePatternGenerator_object_handlers;
/* {{{ IntlDateTimePatternGenerator_objects_dtor */
static void IntlDateTimePatternGenerator_object_dtor(zend_object *object)
{
zend_objects_destroy_object(object);
}
/* }}} */
/* {{{ IntlDateTimePatternGenerator_objects_free */
void IntlDateTimePatternGenerator_object_free(zend_object *object)
{
IntlDateTimePatternGenerator_object *dtpgo = php_intl_datetimepatterngenerator_fetch_object(object);
zend_object_std_dtor(&dtpgo->zo);
dtpgo->status = U_ZERO_ERROR;
if (dtpgo->dtpg) {
delete dtpgo->dtpg;
dtpgo->dtpg = nullptr;
}
}
/* }}} */
/* {{{ IntlDateTimePatternGenerator_object_create */
zend_object *IntlDateTimePatternGenerator_object_create(zend_class_entry *ce)
{
IntlDateTimePatternGenerator_object* intern;
intern = (IntlDateTimePatternGenerator_object*)ecalloc(1,
sizeof(IntlDateTimePatternGenerator_object) + zend_object_properties_size(ce));
zend_object_std_init(&intern->zo, ce);
object_properties_init(&intern->zo, ce);
intern->dtpg = nullptr;
intern->status = U_ZERO_ERROR;
intern->zo.handlers = &IntlDateTimePatternGenerator_object_handlers;
return &intern->zo;
}
/* }}} */
/* {{{ proto void IntlDateTimePatternGenerator::__construct(string $locale)
* IntlDateTimePatternGenerator object constructor.
*/
PHP_METHOD(IntlDateTimePatternGenerator, __construct)
{
zend_string *locale;
zval *object;
IntlDateTimePatternGenerator_object* dtpg = nullptr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &locale) == FAILURE) {
return;
}
object = getThis();
dtpg = php_intl_datetimepatterngenerator_fetch_object(Z_OBJ_P(object));
dtpg->status = U_ZERO_ERROR;
dtpg->dtpg = DateTimePatternGenerator::createInstance(Locale(ZSTR_VAL(locale)), dtpg->status);
}
/* }}} */
/* {{{ proto string IntlDateTimePatternGenerator::findBestPattern(string $skeleton)
* Return the best pattern matching the input skeleton.
*/
PHP_METHOD(IntlDateTimePatternGenerator, findBestPattern)
{
zend_string *skeleton;
zval *object;
IntlDateTimePatternGenerator_object* dtpg = nullptr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &skeleton) == FAILURE) {
return;
}
object = getThis();
dtpg = php_intl_datetimepatterngenerator_fetch_object(Z_OBJ_P(object));
UnicodeString pattern = dtpg->dtpg->getBestPattern(UnicodeString(ZSTR_VAL(skeleton)), dtpg->status);
std::string s;
pattern.toUTF8String(s);
RETURN_STRING(s.c_str());
}
/* }}} */
ZEND_BEGIN_ARG_INFO_EX(arginfo_findBestPattern, 0, 0, 1)
ZEND_ARG_INFO(0, skeleton)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 1)
ZEND_ARG_INFO(0, locale)
ZEND_END_ARG_INFO()
const zend_function_entry IntlDateTimePatternGenerator_functions[] = {
PHP_ME(IntlDateTimePatternGenerator, __construct, arginfo___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(IntlDateTimePatternGenerator, findBestPattern, arginfo_findBestPattern, ZEND_ACC_PUBLIC)
PHP_FE_END
};
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(intl_dtpg)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "IntlDateTimePatternGenerator", IntlDateTimePatternGenerator_functions);
ce.create_object = IntlDateTimePatternGenerator_object_create;
IntlDateTimePatternGenerator_ce = zend_register_internal_class(&ce);
memcpy(&IntlDateTimePatternGenerator_object_handlers, zend_get_std_object_handlers(),
sizeof IntlDateTimePatternGenerator_object_handlers);
IntlDateTimePatternGenerator_object_handlers.offset =
XtOffsetOf(IntlDateTimePatternGenerator_object, zo);
IntlDateTimePatternGenerator_object_handlers.clone_obj = NULL; //no clone support
IntlDateTimePatternGenerator_object_handlers.dtor_obj = IntlDateTimePatternGenerator_object_dtor;
IntlDateTimePatternGenerator_object_handlers.free_obj = IntlDateTimePatternGenerator_object_free;
if(!IntlDateTimePatternGenerator_ce) {
zend_error(E_ERROR, "Failed to register IntlDateTimePatternGenerator class");
return FAILURE;
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(intl_dtpg)
{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(intl_dtpg)
{
php_info_print_table_start();
php_info_print_table_header(2, "intl_dtpg support", "enabled");
php_info_print_table_header(2, "intl_dtpg version", INTL_DTPG_VERSION);
php_info_print_table_end();
}
/* }}} */
/* {{{ intl_dtpg_functions[]
*/
const zend_function_entry intl_dtpg_functions[] = {
PHP_FE_END
};
/* }}} */
/* {{{ intl_dtpg_module_entry
*/
zend_module_entry intl_dtpg_module_entry = {
STANDARD_MODULE_HEADER,
"intl_dtpg",
intl_dtpg_functions,
PHP_MINIT(intl_dtpg),
PHP_MSHUTDOWN(intl_dtpg),
NULL,
NULL,
PHP_MINFO(intl_dtpg),
INTL_DTPG_VERSION,
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_INTL_DTPG
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(intl_dtpg)
#endif
zend_object
, ++ .DateTimePatternGenerator
.zend_string
, zend_parse_parameters S. PHP 7. s C-style , .zend_API.h
, .SUCCESS
, , zend_module_entry, NULL
.NULL
request, shutdown .--TEST--
Check for intl_dtpg presence
--SKIPIF--
--FILE--
--EXPECT--
d MMMM;MMMM d
phpize && ./configure && make
make test
extension=modules/intl_dtpg.so