1
/**********************************************************************
2
* $Id: php_mapscript.c 9765 2010-01-28 15:32:10Z aboudreault $
5
* Purpose: PHP/MapScript extension for MapServer. External interface
7
* Author: Daniel Morissette, DM Solutions Group (dmorissette@dmsolutions.ca)
8
* Alan Boudreault, Mapgears
10
**********************************************************************
11
* Copyright (c) 2000-2010, Daniel Morissette, DM Solutions Group Inc.
13
* Permission is hereby granted, free of charge, to any person obtaining a
14
* copy of this software and associated documentation files (the "Software"),
15
* to deal in the Software without restriction, including without limitation
16
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
17
* and/or sell copies of the Software, and to permit persons to whom the
18
* Software is furnished to do so, subject to the following conditions:
20
* The above copyright notice and this permission notice shall be included in
21
* all copies of this Software or works derived from this Software.
23
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
* DEALINGS IN THE SOFTWARE.
30
**********************************************************************/
32
#include "php_mapscript.h"
33
#include "ext/standard/head.h"
34
#include "main/php_output.h"
36
zend_class_entry *mapscript_ce_image;
38
ZEND_BEGIN_ARG_INFO_EX(image___get_args, 0, 0, 1)
39
ZEND_ARG_INFO(0, property)
42
ZEND_BEGIN_ARG_INFO_EX(image___set_args, 0, 0, 2)
43
ZEND_ARG_INFO(0, property)
44
ZEND_ARG_INFO(0, value)
47
ZEND_BEGIN_ARG_INFO_EX(image_pasteImage_args, 0, 0, 2)
48
ZEND_ARG_INFO(0, srcImg)
49
ZEND_ARG_INFO(0, transparentColorHex)
50
ZEND_ARG_INFO(0, dstX)
51
ZEND_ARG_INFO(0, dstY)
52
ZEND_ARG_INFO(0, angle)
55
ZEND_BEGIN_ARG_INFO_EX(image_saveImage_args, 0, 0, 2)
56
ZEND_ARG_INFO(0, filename)
57
ZEND_ARG_OBJ_INFO(0, map, mapObj, 0)
61
/* {{{ proto image __construct()
62
imageObj CANNOT be instanciated, this will throw an exception on use */
63
PHP_METHOD(imageObj, __construct)
65
mapscript_throw_exception("imageObj cannot be constructed" TSRMLS_CC);
69
PHP_METHOD(imageObj, __get)
73
zval *zobj = getThis();
74
php_image_object *php_image;
76
PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
77
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
78
&property, &property_len) == FAILURE) {
79
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
82
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
84
php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
86
IF_GET_LONG("width", php_image->image->width)
87
else IF_GET_LONG("height", php_image->image->height)
88
else IF_GET_LONG("resolution", php_image->image->resolution)
89
else IF_GET_LONG("resolutionfactor", php_image->image->resolutionfactor)
90
else IF_GET_STRING("imagepath", php_image->image->imagepath)
91
else IF_GET_STRING("imageurl", php_image->image->imageurl)
92
else IF_GET_STRING("imagetype", php_image->image->format->name)
95
mapscript_throw_exception("Property '%s' does not exist in this object." TSRMLS_CC, property);
99
PHP_METHOD(imageObj, __set)
104
zval *zobj = getThis();
105
php_image_object *php_image;
107
PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
108
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz",
109
&property, &property_len, &value) == FAILURE) {
110
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
113
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
115
php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
117
IF_SET_STRING("imagepath", php_image->image->imagepath, value)
118
else IF_SET_STRING("imageurl", php_image->image->imageurl, value)
119
else IF_SET_STRING("imagetype", php_image->image->format->name, value)
120
else if ( (STRING_EQUAL("width", property)) ||
121
(STRING_EQUAL("resolution", property)) ||
122
(STRING_EQUAL("resolutionfactor", property)) ||
123
(STRING_EQUAL("height", property)) )
125
mapscript_throw_exception("Property '%s' is read-only and cannot be set." TSRMLS_CC, property);
129
mapscript_throw_exception("Property '%s' does not exist in this object." TSRMLS_CC, property);
133
/* {{{ proto int saveWebImage()
134
Writes image to temp directory. Returns image URL. */
135
PHP_METHOD(imageObj, saveWebImage)
137
zval *zobj = getThis();
138
php_image_object *php_image;
139
char *imageFile = NULL;
140
char *imageFilename = NULL;
141
char path[MS_MAXPATHLEN];
142
char *imageUrlFull = NULL;
144
PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
145
if (zend_parse_parameters_none() == FAILURE) {
146
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
149
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
151
php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
153
imageFilename = msTmpFilename(php_image->image->format->extension);
154
imageFile = msBuildPath(path, php_image->image->imagepath, imageFilename);
156
if (msSaveImage(NULL, php_image->image, imageFile) != MS_SUCCESS)
158
mapscript_throw_mapserver_exception("Failed writing image to %s" TSRMLS_CC, imageFile);
162
imageUrlFull = msBuildPath(path, php_image->image->imageurl, imageFilename);
163
msFree(imageFilename);
165
RETURN_STRING(imageUrlFull, 1);
169
/* {{{ proto void pasteImage(imageObj Src, int transparentColor [[,int dstx, int dsty], int angle])
170
Pastes another imageObj on top of this imageObj. transparentColor is
171
the color (0xrrggbb) from srcImg that should be considered transparent.
172
Pass transparentColor=-1 if you don't want any transparent color.
173
If optional dstx,dsty are provided then they define the position where the
174
image should be copied (dstx,dsty = top-left corner position).
175
The optional angle is a value between 0 and 360 degrees to rotate the
176
source image counterclockwise. Note that if a rotation is requested then
177
the dstx and dsty coordinates specify the CENTER of the destination area.
178
NOTE : this function only works for 8 bits GD images.
180
PHP_METHOD(imageObj, pasteImage)
182
long transparent=-1, dstx=0, dsty=0, angle=0;
183
int angleSet=MS_FALSE;
185
zval *zobj = getThis();
186
php_image_object *php_image, *php_imageSrc;
187
/*int oldTransparentColor, newTransparentColor=-1, r, g, b;*/
188
rendererVTableObj *renderer = NULL;
191
PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
192
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|lll",
193
&zimage, mapscript_ce_image, &transparent,
194
&dstx, &dsty, &angle) == FAILURE) {
195
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
198
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
200
if (ZEND_NUM_ARGS() == 3) {
201
mapscript_report_php_error(E_WARNING, "dstX parameter given but not dstY" TSRMLS_CC);
206
php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
207
php_imageSrc = (php_image_object *) zend_object_store_get_object(zimage TSRMLS_CC);
209
if (!MS_RENDERER_PLUGIN(php_imageSrc->image->format) ||
210
!MS_RENDERER_PLUGIN(php_image->image->format))
212
mapscript_throw_exception("PasteImage function should only be used with renderer plugin drivers." TSRMLS_CC);
216
#ifdef undef //USE_AGG
217
if( MS_RENDERER_AGG(php_imageSrc->image->format))
218
msAlphaAGG2GD(php_imageSrc->image);
219
if( MS_RENDERER_AGG(php_image->image->format))
220
msAlphaAGG2GD(php_image->image);
224
renderer = MS_IMAGE_RENDERER(php_image->image);
225
memset(&rb,0,sizeof(rasterBufferObj));
227
renderer->getRasterBufferHandle(php_imageSrc->image, &rb);
228
renderer->mergeRasterBuffer(php_image->image, &rb, 1.0, 0, 0, dstx, dsty, rb.width, rb.height);
230
/* Look for r,g,b in color table and make it transparent.
231
* will return -1 if there is no exact match which will result in
232
* no transparent color in the call to gdImageColorTransparent().
234
/* if (transparent != -1)
236
r = (transparent / 0x010000) & 0xff;
237
g = (transparent / 0x0100) & 0xff;
238
b = transparent & 0xff;
239
newTransparentColor = gdImageColorExact(php_imageSrc->image->img.gd, r, g, b);
242
oldTransparentColor = gdImageGetTransparent(php_imageSrc->image->img.gd);
243
gdImageColorTransparent(php_imageSrc->image->img.gd, newTransparentColor);
246
gdImageCopy(php_image->image->img.gd, php_imageSrc->image->img.gd, dstx, dsty,
247
0, 0, php_imageSrc->image->img.gd->sx, php_imageSrc->image->img.gd->sy);
249
gdImageCopyRotated(php_image->image->img.gd, php_imageSrc->image->img.gd, dstx, dsty,
250
0, 0, php_imageSrc->image->img.gd->sx, php_imageSrc->image->img.gd->sy,
253
gdImageColorTransparent(php_imageSrc->image->img.gd, oldTransparentColor);*/
255
RETURN_LONG(MS_SUCCESS);
260
/* {{{ proto int saveImage(string filename, mapObj map)
261
Writes image object to specifed filename. If filename is empty then
262
write to stdout. Returns MS_FAILURE on error. Second aregument oMap is not
263
manadatory. It is usful when saving to other formats like GTIFF to get
264
georeference infos.*/
266
PHP_METHOD(imageObj, saveImage)
268
zval *zobj = getThis();
270
char *filename = NULL;
271
long filename_len = 0;
272
php_image_object *php_image;
273
php_map_object *php_map;
274
int status = MS_SUCCESS;
275
/* stdout specific vars */
279
PHP_MAPSCRIPT_ERROR_HANDLING(TRUE);
280
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO",
281
&filename, &filename_len,
282
&zmap, mapscript_ce_map) == FAILURE) {
283
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
286
PHP_MAPSCRIPT_RESTORE_ERRORS(TRUE);
288
php_image = (php_image_object *) zend_object_store_get_object(zobj TSRMLS_CC);
290
php_map = (php_map_object *) zend_object_store_get_object(zmap TSRMLS_CC);
294
if ((status = msSaveImage((zmap ? php_map->map:NULL), php_image->image, filename) != MS_SUCCESS))
296
mapscript_throw_mapserver_exception("Failed writing image to %s" TSRMLS_CC, filename);
303
/* no filename - read stdout */
305
/* if there is no output buffer active, set the header */
306
if (OG(ob_nesting_level)<=0)
308
php_header(TSRMLS_C);
312
if (MS_RENDERER_PLUGIN(php_image->image->format))
314
iptr = (void *)msSaveImageBuffer(php_image->image, &size, php_image->image->format);
316
else if (php_image->image->format->name && (strcasecmp(php_image->image->format->name, "imagemap")==0))
318
iptr = php_image->image->img.imagemap;
319
size = strlen(php_image->image->img.imagemap);
323
mapscript_throw_mapserver_exception("Failed writing image to stdout" TSRMLS_CC);
328
php_write(iptr, size TSRMLS_CC);
330
/* status = size; why should we return the size ?? */
338
zend_function_entry image_functions[] = {
339
PHP_ME(imageObj, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
340
PHP_ME(imageObj, __get, image___get_args, ZEND_ACC_PUBLIC)
341
PHP_ME(imageObj, __set, image___set_args, ZEND_ACC_PUBLIC)
342
PHP_MALIAS(imageObj, set, __set, NULL, ZEND_ACC_PUBLIC)
343
PHP_ME(imageObj, saveWebImage, NULL, ZEND_ACC_PUBLIC)
344
PHP_ME(imageObj, pasteImage, image_pasteImage_args, ZEND_ACC_PUBLIC)
345
PHP_ME(imageObj, saveImage, image_saveImage_args, ZEND_ACC_PUBLIC)
350
void mapscript_create_image(imageObj *image, zval *return_value TSRMLS_DC)
352
php_image_object * php_image;
353
object_init_ex(return_value, mapscript_ce_image);
354
php_image = (php_image_object *)zend_object_store_get_object(return_value TSRMLS_CC);
355
php_image->image = image;
358
static void mapscript_image_object_destroy(void *object TSRMLS_DC)
360
php_image_object *php_image = (php_image_object *)object;
362
MAPSCRIPT_FREE_OBJECT(php_image);
364
msFreeImage(php_image->image);
369
static zend_object_value mapscript_image_object_new(zend_class_entry *ce TSRMLS_DC)
371
zend_object_value retval;
372
php_image_object *php_image;
374
MAPSCRIPT_ALLOC_OBJECT(php_image, php_image_object);
376
retval = mapscript_object_new(&php_image->std, ce,
377
&mapscript_image_object_destroy TSRMLS_CC);
382
PHP_MINIT_FUNCTION(image)
386
MAPSCRIPT_REGISTER_CLASS("imageObj",
389
mapscript_image_object_new);
391
mapscript_ce_image->ce_flags |= ZEND_ACC_FINAL_CLASS;