├── .travis.yml
├── README.md
├── config.m4
├── doc
└── en
│ └── reference
│ └── zbarcode
│ ├── .cvsignore
│ ├── book.xml
│ ├── configure.xml
│ ├── constants.xml
│ ├── examples.xml
│ ├── reference.xml
│ ├── setup.xml
│ ├── versions.xml
│ ├── zbarcode.xml
│ ├── zbarcodeexception.xml
│ ├── zbarcodeimage.xml
│ ├── zbarcodeimage
│ ├── clear.xml
│ ├── construct.xml
│ ├── count.xml
│ └── read.xml
│ ├── zbarcodescanner.xml
│ └── zbarcodescanner
│ ├── scan.xml
│ └── setconfig.xml
├── imagemagick.m4
├── php_zbarcode.h
├── tests
├── 001-construct.phpt
├── 002-read-barcode.phpt
├── 003-setconfig.phpt
├── 004-paged-reading.phpt
├── 005-count.phpt
├── 006-imagick.phpt
├── 007-test-gd.phpt
├── ean13.jpg
└── skipif.inc.php
└── zbarcode.c
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 7.4
4 | - 7.3
5 | - 7.2
6 | - 7.1
7 | - 7.0
8 |
9 |
10 |
11 | before_install:
12 | - sudo apt-get update
13 | - sudo apt-get install libzbar0 libzbar-dev imagemagick libmagickwand-6.q16-dev
14 | - sudo ln -s /usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/MagickWand-config /usr/bin
15 | script:
16 | - export NO_INTERACTION=1
17 | - export REPORT_EXIT_STATUS=1
18 | - phpize
19 | - ./configure
20 | - make
21 | - make test
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Simple extension to read barcodes from images
2 |
3 | [](https://travis-ci.org/mkoppanen/php-zbarcode)
4 |
5 | ## Upgrade at 2018-12-05
6 |
7 | Support PHP7, And fix some bug that may cause crash.
8 |
9 | ## Basic usage:
10 |
11 | scan($image);
20 |
21 | /* Loop through possible barcodes */
22 | if (!empty($barcode)) {
23 | foreach ($barcode as $code) {
24 | printf("Found type %s barcode with data %s\n", $code['type'], $code['data']);
25 | }
26 | }
27 | ?>
28 |
29 | The EAN13 image in the tests/ directory is from
30 | http://en.wikipedia.org/wiki/File:Ean-13-5901234123457.png
31 |
32 | ## Dependencies:
33 |
34 | ZBar
35 | http://zbar.sourceforge.net/
36 |
37 | ImageMagick
38 | http://www.imagemagick.org/
39 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | PHP_ARG_WITH(zbarcode, whether to enable the zbarcode extension,
2 | [ --with-zbarcode[=DIR] Enables the zbarcode extension.], no)
3 |
4 | PHP_ARG_WITH(zbarcode-imagemagick-dir, path to ImageMagick library,
5 | [ --with-zbarcode-imagemagick-dir[=DIR] path to ImageMagick library.], no)
6 |
7 | PHP_ARG_ENABLE(zbarcode-imagick, whether to enable zbarcode Imagick support,
8 | [ --enable-zbarcode-imagick whether to enable zbarcode Imagick support], no, no)
9 |
10 | PHP_ARG_ENABLE(zbarcode-gd, whether to enable zbarcode GD Imagick support,
11 | [ --enable-zbarcode-gd whether to enable zbarcode GD support], no, no)
12 |
13 | if test $PHP_ZBARCODE != "no"; then
14 |
15 | #
16 | # ImageMagick macros
17 | #
18 | m4_include([imagemagick.m4])
19 | IM_FIND_IMAGEMAGICK(6002004, $PHP_ZBARCODE_IMAGEMAGICK_DIR)
20 |
21 | AC_MSG_CHECKING(zbar installation)
22 | if test "x$PHP_ZBARCODE" = "xyes"; then
23 | if test "x${PKG_CONFIG_PATH}" = "x"; then
24 | #
25 | # "By default, pkg-config looks in the directory prefix/lib/pkgconfig for these files"
26 | #
27 | # Add a bit more search paths for common installation locations. Can be overridden by setting
28 | # PKG_CONFIG_PATH env variable or passing --with-zbarcode=PATH
29 | #
30 | export PKG_CONFIG_PATH="/usr/local/${PHP_LIBDIR}/pkgconfig:/usr/${PHP_LIBDIR}/pkgconfig:/opt/${PHP_LIBDIR}/pkgconfig:/opt/local/${PHP_LIBDIR}/pkgconfig"
31 | fi
32 | else
33 | export PKG_CONFIG_PATH="${PHP_ZBARCODE}/${PHP_LIBDIR}/pkgconfig"
34 | fi
35 |
36 | if $PKG_CONFIG --exists zbar; then
37 | PHP_ZBAR_VERSION=`$PKG_CONFIG zbar --modversion`
38 | PHP_ZBAR_PREFIX=`$PKG_CONFIG zbar --variable=prefix`
39 |
40 | AC_MSG_RESULT([found version $PHP_ZMQ_VERSION, under $PHP_ZBAR_PREFIX])
41 | PHP_ZBAR_LIBS=`$PKG_CONFIG zbar --libs`
42 | PHP_ZBAR_INCS=`$PKG_CONFIG zbar --cflags`
43 |
44 | PHP_EVAL_LIBLINE($PHP_ZBAR_LIBS, ZBARCODE_SHARED_LIBADD)
45 | PHP_EVAL_INCLINE($PHP_ZBAR_INCS)
46 | else
47 | AC_MSG_ERROR(Unable to find zbar installation)
48 | fi
49 |
50 |
51 | PHP_CHECK_LIBRARY(zbar, zbar_symbol_get_quality, [
52 | AC_DEFINE(HAVE_ZBAR_SYMBOL_GET_QUALITY,1,[ ])
53 | ],[],[
54 | -L$PHP_ZBAR_PREFIX/$PHP_LIBDIR
55 | ])
56 |
57 | #
58 | # Imagick support
59 | #
60 | if test $PHP_ZBARCODE_IMAGICK != "no"; then
61 | AC_MSG_CHECKING(php_imagick_shared.h header file)
62 |
63 | if test -z "$PHP_CONFIG"; then
64 | AC_MSG_ERROR([php-config not found])
65 | fi
66 |
67 | PHP_IMAGICK_HEADER="`$PHP_CONFIG --include-dir`/ext/imagick/php_imagick_shared.h"
68 |
69 | if test -r $PHP_IMAGICK_HEADER; then
70 | AC_MSG_RESULT(found.)
71 | AC_DEFINE(HAVE_ZBARCODE_IMAGICK,1,[ ])
72 |
73 | PHP_ADD_EXTENSION_DEP(zbarcode, imagick)
74 | else
75 | AC_MSG_ERROR(not found. Run with --disable-zbarcode-imagick to disable this feature)
76 | fi
77 | fi
78 |
79 | #
80 | # GD support
81 | #
82 | if test $PHP_ZBARCODE_GD != "no"; then
83 |
84 | AC_MSG_CHECKING(ext/gd/php_gd.h header file)
85 |
86 | if test -z "$PHP_CONFIG"; then
87 | AC_MSG_ERROR([php-config not found])
88 | fi
89 |
90 | PHP_GD_CHECK_HEADER="`$PHP_CONFIG --include-dir`/ext/gd/php_gd.h"
91 |
92 | if test -r $PHP_GD_CHECK_HEADER; then
93 | AC_MSG_RESULT(found.)
94 | else
95 | AC_MSG_ERROR(not found. Run with --disable-zbarcode-gd to disable this feature)
96 | fi
97 |
98 | PHP_ADD_EXTENSION_DEP(zbarcode, gd)
99 | AC_DEFINE(HAVE_ZBARCODE_GD,1,[ ])
100 | fi
101 |
102 | PHP_EVAL_LIBLINE($IM_IMAGEMAGICK_LIBS, ZBARCODE_SHARED_LIBADD)
103 | PHP_EVAL_INCLINE($IM_IMAGEMAGICK_CFLAGS)
104 |
105 | AC_DEFINE(HAVE_ZBARCODE,1,[ ])
106 | PHP_SUBST(ZBARCODE_SHARED_LIBADD)
107 | PHP_NEW_EXTENSION(zbarcode, zbarcode.c, $ext_shared,,$IM_IMAGEMAGICK_CFLAGS)
108 | fi
109 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/.cvsignore:
--------------------------------------------------------------------------------
1 | entities.*.xml
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/book.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Zbarcode
6 | Zbarcode
7 |
8 |
9 | &reftitle.intro;
10 |
11 | zbarcode can be used to scan barcodes from images. ImageMagick is used to handle image reading and conversion
12 | and ZBar library is used to scan barcodes from images.
13 |
14 |
15 |
16 | &reference.zbarcode.setup;
17 | &reference.zbarcode.constants;
18 | &reference.zbarcode.examples;
19 | &reference.zbarcode.reference;
20 |
21 |
22 |
23 |
43 |
44 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/configure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.install;
6 |
7 |
8 | Use when compiling PHP. The DIR is an
9 | optional parameter to ZBar library installation.
10 |
11 |
12 |
13 | Use
14 | to specify location of the ImageMagick library.
15 |
16 |
17 |
18 |
19 |
20 |
40 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/constants.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.constants;
6 | &no.constants;
7 |
8 |
9 |
29 |
30 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/examples.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.examples;
6 |
7 | Example of basic usage of the library
8 |
9 |
10 | Zbarcode Example
11 |
12 | scan($image);
22 |
23 | /* Loop through possible barcodes */
24 | if (!empty($barcode)) {
25 | foreach ($barcode as $code) {
26 | printf("Found type %s barcode with data %s\n", $code['type'], $code['data']);
27 | }
28 | }
29 | ?>
30 | ]]>
31 |
32 | &example.outputs.similar;
33 |
34 |
37 |
38 |
39 |
40 |
41 |
61 |
62 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/reference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Zbarcode &Functions;
6 |
7 | &reference.zbarcode.entities.functions;
8 |
9 |
10 |
11 |
31 |
32 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/setup.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.setup;
6 |
7 |
8 | &reftitle.required;
9 |
10 |
11 | This extension requires ZBar library version 0.8+ and ImageMagick 6.2.4+.
12 |
13 |
14 |
15 |
16 |
17 | &reftitle.install;
18 | &no.install;
19 |
20 |
21 |
22 |
23 |
24 |
25 |
45 |
46 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/versions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
46 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcode.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The ZBarCode class
7 | ZBarCode
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | ZBarCode class contains all constants provided by this extension.
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | ZBarCode
26 |
27 |
28 |
29 |
30 | ZBarCode
31 |
32 |
33 |
34 | Constants
35 |
36 | const
37 | boolean
38 | zbarcode::HAVE_IMAGICK
39 | false
40 |
41 |
42 | const
43 | boolean
44 | zbarcode::HAVE_GD
45 | false
46 |
47 |
48 | const
49 | integer
50 | zbarcode::CFG_ENABLE
51 | 0
52 |
53 |
54 | const
55 | integer
56 | zbarcode::CFG_ADD_CHECK
57 | 1
58 |
59 |
60 | const
61 | integer
62 | zbarcode::CFG_EMIT_CHECK
63 | 2
64 |
65 |
66 | const
67 | integer
68 | zbarcode::CFG_ASCII
69 | 3
70 |
71 |
72 | const
73 | integer
74 | zbarcode::CFG_NUM
75 | 4
76 |
77 |
78 | const
79 | integer
80 | zbarcode::CFG_MIN_LEN
81 | 32
82 |
83 |
84 | const
85 | integer
86 | zbarcode::CFG_MAX_LEN
87 | 33
88 |
89 |
90 | const
91 | integer
92 | zbarcode::CFG_X_DENSITY
93 | 256
94 |
95 |
96 | const
97 | integer
98 | zbarcode::CFG_Y_DENSITY
99 | 257
100 |
101 |
102 | const
103 | integer
104 | zbarcode::SYM_ALL
105 | 0
106 |
107 |
108 | const
109 | integer
110 | zbarcode::SYM_NONE
111 | 0
112 |
113 |
114 | const
115 | integer
116 | zbarcode::SYM_PARTIAL
117 | 1
118 |
119 |
120 | const
121 | integer
122 | zbarcode::SYM_EAN8
123 | 8
124 |
125 |
126 | const
127 | integer
128 | zbarcode::SYM_UPCE
129 | 9
130 |
131 |
132 | const
133 | integer
134 | zbarcode::SYM_ISBN10
135 | 10
136 |
137 |
138 | const
139 | integer
140 | zbarcode::SYM_UPCA
141 | 12
142 |
143 |
144 | const
145 | integer
146 | zbarcode::SYM_EAN13
147 | 13
148 |
149 |
150 | const
151 | integer
152 | zbarcode::SYM_ISBN13
153 | 14
154 |
155 |
156 | const
157 | integer
158 | zbarcode::SYM_I25
159 | 25
160 |
161 |
162 | const
163 | integer
164 | zbarcode::SYM_CODE39
165 | 39
166 |
167 |
168 | const
169 | integer
170 | zbarcode::SYM_PDF417
171 | 57
172 |
173 |
174 | const
175 | integer
176 | zbarcode::SYM_CODE128
177 | 128
178 |
179 |
180 | const
181 | integer
182 | zbarcode::SYM_SYMBOL
183 | 255
184 |
185 |
186 | const
187 | integer
188 | zbarcode::SYM_ADDON2
189 | 512
190 |
191 |
192 | const
193 | integer
194 | zbarcode::SYM_ADDON5
195 | 1280
196 |
197 |
198 | const
199 | integer
200 | zbarcode::SYM_ADDON
201 | 1792
202 |
203 |
204 | const
205 | integer
206 | zbarcode::OPT_RESOLUTION
207 | 1
208 |
209 |
210 | const
211 | integer
212 | zbarcode::OPT_ENHANCE
213 | 2
214 |
215 |
216 | const
217 | integer
218 | zbarcode::OPT_SHARPEN
219 | 4
220 |
221 |
222 | Methods
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | &reftitle.constants;
232 |
233 | zbarcode Node Types
234 |
235 |
236 |
237 | zbarcode::HAVE_IMAGICK
238 |
239 | &true; if Imagick support is enabled
240 |
241 |
242 |
243 |
244 | zbarcode::HAVE_GD
245 |
246 | &true; if GD support is enabled
247 |
248 |
249 |
250 |
251 | zbarcode::CFG_ENABLE
252 |
253 | Enable configuration item
254 |
255 |
256 |
257 |
258 | zbarcode::CFG_ADD_CHECK
259 |
260 | Enable check digit when optional
261 |
262 |
263 |
264 |
265 | zbarcode::CFG_EMIT_CHECK
266 |
267 | Return check digit when present
268 |
269 |
270 |
271 |
272 | zbarcode::CFG_ASCII
273 |
274 | Enable full ASCII character set
275 |
276 |
277 |
278 |
279 | zbarcode::CFG_NUM
280 |
281 | Number of boolean decoder configs
282 |
283 |
284 |
285 |
286 | zbarcode::CFG_MIN_LEN
287 |
288 | Minimum data length for valid decode
289 |
290 |
291 |
292 |
293 | zbarcode::CFG_MAX_LEN
294 |
295 | Maximum data length for valid decode
296 |
297 |
298 |
299 |
300 | zbarcode::CFG_X_DENSITY
301 |
302 | Image scanner vertical scan density
303 |
304 |
305 |
306 |
307 | zbarcode::CFG_Y_DENSITY
308 |
309 | Image scanner horizontal scan density
310 |
311 |
312 |
313 |
314 | zbarcode::SYM_ALL
315 |
316 | All symbols
317 |
318 |
319 |
320 |
321 | zbarcode::SYM_NONE
322 |
323 | No symbol specified. Same as SYM_ALL
324 |
325 |
326 |
327 |
328 | zbarcode::SYM_PARTIAL
329 |
330 | Intermediate status
331 |
332 |
333 |
334 |
335 | zbarcode::SYM_EAN8
336 |
337 | EAN8 symbol
338 |
339 |
340 |
341 |
342 | zbarcode::SYM_UPCE
343 |
344 | UPCE symbol
345 |
346 |
347 |
348 |
349 | zbarcode::SYM_ISBN10
350 |
351 | ISBN10 symbol
352 |
353 |
354 |
355 |
356 | zbarcode::SYM_UPCA
357 |
358 | UPCA symbol
359 |
360 |
361 |
362 |
363 | zbarcode::SYM_EAN13
364 |
365 | EAN13 symbol
366 |
367 |
368 |
369 |
370 | zbarcode::SYM_ISBN13
371 |
372 | ISBN13 symbol
373 |
374 |
375 |
376 |
377 | zbarcode::SYM_I25
378 |
379 | I25 symbol
380 |
381 |
382 |
383 |
384 | zbarcode::SYM_CODE39
385 |
386 | CODE39 symbol
387 |
388 |
389 |
390 |
391 | zbarcode::SYM_PDF417
392 |
393 | PDF417 symbol
394 |
395 |
396 |
397 |
398 | zbarcode::SYM_CODE128
399 |
400 | CODE128 symbol
401 |
402 |
403 |
404 |
405 | zbarcode::SYM_SYMBOL
406 |
407 | Mask for base symbol type
408 |
409 |
410 |
411 |
412 | zbarcode::SYM_ADDON2
413 |
414 | 2-digit add-on flag
415 |
416 |
417 |
418 |
419 | zbarcode::SYM_ADDON5
420 |
421 | 5-digit add-on flag
422 |
423 |
424 |
425 |
426 | zbarcode::SYM_ADDON
427 |
428 | Add-on flag mask
429 |
430 |
431 |
432 |
433 | zbarcode::OPT_RESOLUTION
434 |
435 | Improve the resolution during reading
436 |
437 |
438 |
439 |
440 | zbarcode::OPT_ENHANCE
441 |
442 | Reduce image noise
443 |
444 |
445 |
446 |
447 | zbarcode::OPT_SHARPEN
448 |
449 | Sharpen the image
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 | &reference.zbarcode.entities.zbarcode;
462 |
463 |
464 |
465 |
485 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeexception.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The zbarcodeexception class
7 | zbarcodeexception
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | The class used in exceptions.
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | zbarcodeexception
26 |
27 |
28 |
29 |
30 | zbarcodeexception
31 |
32 |
33 |
34 | extends
35 | Exception
36 |
37 |
38 |
39 | Properties
40 |
41 |
42 | Methods
43 |
44 |
45 | Inherited methods
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | &reftitle.properties;
57 |
58 |
59 | message
60 |
61 | Exception message
62 |
63 |
64 |
65 | code
66 |
67 | Exception code
68 |
69 |
70 |
71 | file
72 |
73 | Filename
74 |
75 |
76 |
77 | line
78 |
79 | Line
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | &reference.zbarcode.entities.zbarcodeexception;
90 |
91 |
92 |
93 |
113 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeimage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The ZBarCodeImage class
7 | ZBarCodeImage
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | This class represents image from which to read the barcode. Each object contains
16 | single image which can be passed to the scanner.
17 |
18 |
19 |
20 |
21 |
22 | &reftitle.classsynopsis;
23 |
24 |
25 |
26 | ZBarCodeImage
27 |
28 |
29 |
30 |
31 | ZBarCodeImage
32 |
33 |
34 |
35 |
36 | Methods
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | &reference.zbarcode.entities.zbarcodeimage;
46 |
47 |
48 |
49 |
69 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeimage/clear.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeImage::clear
7 | Clear the pages
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public ZBarCodeImageZBarCodeImage::clear
14 |
15 |
16 |
17 | Removes all pages from the ZBarCodeImage object.
18 |
19 |
20 |
21 |
22 | &reftitle.returnvalues;
23 |
24 | Returns the current object on success and throws ZBarCodeException on failure.
25 |
26 |
27 |
28 |
29 | &reftitle.seealso;
30 |
31 |
32 | ZBarCodeScanner::scan
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeimage/construct.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeImage::__construct
7 | Construct a new image object
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | ZBarCodeImage::__construct
14 | stringfilename
15 | integerenhance
16 |
17 |
18 | The constructor for the ZBarCodeImage class.
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 |
27 | filename
28 |
29 |
30 | Optional filename. If filename is not empty the image is read
31 |
32 |
33 |
34 |
35 | enhance
36 |
37 |
38 | Bitmask of ZBarCode::OPT_* constants.
39 | Usually specifying ZBarCode::OPT_RESOLUTION improves results with PDFs.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | &reftitle.returnvalues;
49 |
50 | If filename is set and reading of the image fails throws ZBarCodeException.
51 |
52 |
53 |
54 |
55 | &reftitle.examples;
56 |
57 |
58 | ZBarCodeImage::__construct example
59 |
60 |
66 | ]]>
67 |
68 |
69 |
70 |
71 |
72 |
73 | &reftitle.seealso;
74 |
75 |
76 | ZBarCodeScanner::scan
77 |
78 |
79 |
80 |
81 |
82 |
83 |
103 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeimage/count.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeImage::count
7 | Count the pages
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public integerZBarCodeImage::count
14 |
15 |
16 |
17 | Counts the number of pages in the object
18 |
19 |
20 |
21 |
22 | &reftitle.returnvalues;
23 |
24 | Returns an integer representing the number of pages in the object.
25 |
26 |
27 |
28 |
29 | &reftitle.examples;
30 |
31 |
32 | ZBarCodeImage::count example
33 |
34 | read("page1.jpg");
38 |
39 | echo "Pages: " . $image->count() . "\n";
40 | $image->read("page1.jpg");
41 |
42 | echo "Pages: " . $image->count() . "\n";
43 |
44 | /* Scan the second page */
45 | $scanner = new ZBarCodeScanner();
46 | $barcodes = $scanner->scan($image, 2);
47 | ?>
48 | ]]>
49 |
50 | &example.outputs.similar;
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | &reftitle.seealso;
63 |
64 |
65 | ZBarCodeImage::read
66 |
67 |
68 |
69 |
70 |
71 |
72 |
92 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodeimage/read.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeImage::read
7 | Read an image
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public ZBarCodeImageZBarCodeImage::read
14 | stringfilename
15 | intenhance
16 |
17 |
18 | Read an image into the ZBarCodeImage object. The object can hold multiple images
19 | at the same time. This is convenient with for example multi-page PDF files.
20 |
21 |
22 |
23 |
24 | &reftitle.parameters;
25 |
26 |
27 |
28 | filename
29 |
30 |
31 | Filename of an image to read.
32 |
33 |
34 |
35 |
36 | enhance
37 |
38 |
39 | Bitmask of ZBarCode::OPT_* constants.
40 | Usually specifying ZBarCode::OPT_RESOLUTION improves results with PDFs.
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | &reftitle.returnvalues;
50 |
51 | Returns the current object on success and throws ZBarCodeException on failure.
52 |
53 |
54 |
55 |
56 | &reftitle.examples;
57 |
58 |
59 | ZBarCodeImage::read example
60 |
61 | read("test1.jpg")
68 | ->read("test2.jpg")
69 | ->read("test3.jpg");
70 |
71 | /* Create scanner */
72 | $scanner = new ZBarCodeScanner();
73 |
74 | /* Read the second page, test2.jpg */
75 | var_dump($scanner->scan($pages, 2));
76 | ?>
77 | ]]>
78 |
79 | &example.outputs.similar;
80 |
81 |
84 | array(2) {
85 | ["data"]=>
86 | string(13) "5901234123457"
87 | ["type"]=>
88 | string(6) "EAN-13"
89 | }
90 | }
91 | ]]>
92 |
93 |
94 |
95 |
96 |
97 |
98 | &reftitle.seealso;
99 |
100 |
101 | ZBarCodeScanner::scan
102 |
103 |
104 |
105 |
106 |
107 |
108 |
128 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodescanner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The ZBarCodeScanner class
7 | ZBarCodeScanner
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 | The barcode scanner class. This class reads barcodes from ZBarCodeImage objects.
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | ZBarCodeScanner
26 |
27 |
28 |
29 |
30 | ZBarCodeScanner
31 |
32 |
33 |
34 |
35 | Methods
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | &reference.zbarcode.entities.zbarcodescanner;
45 |
46 |
47 |
48 |
68 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodescanner/scan.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeScanner::scan
7 | Scan image object
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public arrayZBarCodeScanner::scan
14 | mixedimage
15 | integerpage_num
16 | booleanextended_info
17 |
18 |
19 | Scans image object for barcodes and returns an array representing barcodes
20 | found on the page.
21 |
22 |
23 |
24 |
25 |
26 | &reftitle.parameters;
27 |
28 |
29 |
30 | image
31 |
32 |
33 | Image object to scan for barcodes. This parameter can be one of the following: ZBarCodeImage object,
34 | Imagick object or GD resource. Imagick and GD support has to be enabled separately during installation.
35 | Imagick support requires Imagick 2.3.1 or newer.
36 |
37 |
38 |
39 |
40 | page_num
41 |
42 |
43 | The page to scan. Pass 0 for all pages. (Default: 1)
44 |
45 |
46 |
47 |
48 | extended_info
49 |
50 |
51 | If &true; location polygon of each barcode is returned within the array. (Default: &false;)
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | &reftitle.returnvalues;
61 |
62 | Returns an array describing the barcodes or an empty array if no barcodes were found. On successfull execution the
63 | array will contain elements 'data' and 'type'. If extended_info is &true; the array will
64 | contain 'location' element which is an an array of coordinates for the bounding polygon of the barcode.
65 | 'quality' element is available with ZBar 0.9 and higher.
66 |
67 |
68 |
69 |
70 | &reftitle.examples;
71 |
72 |
73 | ZBarCodeScanner::scan single page reading
74 |
75 | read("ean13.jpg");
79 |
80 | $scanner = new ZBarcodeScanner();
81 | var_dump($scanner->scan($image));
82 | ?>
83 | ]]>
84 |
85 | &example.outputs.similar;
86 |
87 |
90 | array(2) {
91 | ["data"]=>
92 | string(13) "5901234123457"
93 | ["type"]=>
94 | string(6) "EAN-13"
95 | }
96 | }
97 | ]]>
98 |
99 |
100 |
101 |
102 |
103 | ZBarCodeScanner::scan multi-page reading
104 |
105 | read("invoice.pdf");
109 |
110 | $scanner = new ZBarcodeScanner();
111 | var_dump($scanner->scan($image, 0));
112 | ?>
113 | ]]>
114 |
115 | &example.outputs.similar;
116 |
117 |
120 | array(1) {
121 | [0]=>
122 | array(2) {
123 | ["data"]=>
124 | string(13) "5901234123457"
125 | ["type"]=>
126 | string(6) "EAN-13"
127 | }
128 | [1]=>
129 | array(2) {
130 | ["data"]=>
131 | string(13) "5901234123457"
132 | ["type"]=>
133 | string(6) "EAN-13"
134 | }
135 | }
136 | [2]=>
137 | array(1) {
138 | [0]=>
139 | array(2) {
140 | ["data"]=>
141 | string(13) "5901234123457"
142 | ["type"]=>
143 | string(6) "EAN-13"
144 | }
145 | }
146 | }
147 | ]]>
148 |
149 |
150 |
151 |
152 |
153 |
154 |
174 |
--------------------------------------------------------------------------------
/doc/en/reference/zbarcode/zbarcodescanner/setconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZBarCodeScanner::setConfig
7 | Set config value
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public ZBarCodeScannerZBarCodeScanner::setConfig
14 | integername
15 | integervalue
16 | integersymbology
17 |
18 |
19 | Sets a configuration value for specific symbology or all of them.
20 |
21 |
22 |
23 |
24 | &reftitle.parameters;
25 |
26 |
27 |
28 | name
29 |
30 |
31 | One of the ZBarCode::CFG_* constants
32 |
33 |
34 |
35 |
36 | value
37 |
38 |
39 | The value of the configuration item
40 |
41 |
42 |
43 |
44 | symbology
45 |
46 |
47 | One of the ZBarCode::SYM_* barcode type constants
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | &reftitle.returnvalues;
57 |
58 | Returns the current object on success and throws ZBarCodeException on failure.
59 |
60 |
61 |
62 |
63 | &reftitle.examples;
64 |
65 |
66 | ZBarCodeScanner::setConfig example
67 |
68 | setConfig(ZBarcode::CFG_MIN_LEN, 1);
73 | } catch (Exception $e) {
74 | echo "Failed to set config";
75 | }
76 | ?>
77 | ]]>
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
105 |
--------------------------------------------------------------------------------
/imagemagick.m4:
--------------------------------------------------------------------------------
1 | #########################################################
2 | # Locate ImageMagick configuration program
3 | # ImageMagick has the config program:
4 | # bin/Wand-config
5 | # bin/MagickWand-config
6 | #
7 | # Sets
8 | # IM_WAND_BINARY
9 | # IM_IMAGEMAGICK_PREFIX
10 | # IM_IMAGEMAGICK_VERSION
11 | # IM_IMAGEMAGICK_VERSION_MASK
12 | #
13 |
14 | #########################################################
15 |
16 | AC_DEFUN([IM_FIND_IMAGEMAGICK],[
17 |
18 | AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
19 | if test "x$PKG_CONFIG" = "xno"; then
20 | AC_MSG_RESULT([pkg-config not found])
21 | AC_MSG_ERROR([Please reinstall the pkg-config distribution])
22 | fi
23 |
24 | if test -z "$AWK"; then
25 | AC_MSG_ERROR([awk not found])
26 | fi
27 |
28 | AC_MSG_CHECKING(ImageMagick MagickWand API configuration program)
29 |
30 | if test "$2" != "yes"; then
31 | for i in "$2" /usr/local /usr /opt /opt/local;
32 | do
33 | if test -r "${i}/bin/MagickWand-config"; then
34 | IM_WAND_BINARY="${i}/bin/MagickWand-config"
35 | IM_IMAGEMAGICK_PREFIX=$i
36 | break
37 | fi
38 |
39 | if test -r "${i}/bin/Wand-config"; then
40 | IM_WAND_BINARY="${i}/bin/Wand-config"
41 | IM_IMAGEMAGICK_PREFIX=$i
42 | break
43 | fi
44 | done
45 | else
46 | for i in /usr/local /usr /opt /opt/local;
47 | do
48 | if test -r "${i}/bin/MagickWand-config"; then
49 | IM_WAND_BINARY="${i}/bin/MagickWand-config"
50 | IM_IMAGEMAGICK_PREFIX=$i
51 | break
52 | fi
53 |
54 | if test -r "${i}/bin/Wand-config"; then
55 | IM_WAND_BINARY="${i}/bin/Wand-config"
56 | IM_IMAGEMAGICK_PREFIX=$i
57 | break
58 | fi
59 | done
60 | fi
61 |
62 | if test "x" = "x$IM_WAND_BINARY"; then
63 | AC_MSG_ERROR(not found. Please provide a path to MagickWand-config or Wand-config program.)
64 | fi
65 | AC_MSG_RESULT([found in $IM_WAND_BINARY])
66 |
67 | # This is used later for cflags and libs
68 | export PKG_CONFIG_PATH="${IM_IMAGEMAGICK_PREFIX}/${PHP_LIBDIR}/pkgconfig"
69 |
70 | # Check version
71 | #
72 | IM_IMAGEMAGICK_VERSION=`$IM_WAND_BINARY --version`
73 | IM_IMAGEMAGICK_VERSION_MASK=`echo $IM_IMAGEMAGICK_VERSION | $AWK 'BEGIN { FS = "."; } { printf "%d", ($[1] * 1000 + $[2]) * 1000 + $[3];}'`
74 |
75 | AC_MSG_CHECKING(if ImageMagick version is at least $1)
76 | if test "$IM_IMAGEMAGICK_VERSION_MASK" -ge $1; then
77 | AC_MSG_RESULT(found version $IM_IMAGEMAGICK_VERSION)
78 | else
79 | AC_MSG_ERROR(no. You need at least Imagemagick version $1 to use this extension.)
80 | fi
81 |
82 | # Potential locations for the header
83 | # include/wand/magick-wand.h
84 | # include/ImageMagick/wand/MagickWand.h
85 | # include/ImageMagick-6/wand/MagickWand.h
86 | # include/ImageMagick-7/MagickWand/MagickWand.h
87 |
88 | AC_MSG_CHECKING(for MagickWand.h or magick-wand.h header)
89 |
90 | IM_PREFIX=`$IM_WAND_BINARY --prefix`
91 | IM_MAJOR_VERSION=`echo $IM_IMAGEMAGICK_VERSION | $AWK 'BEGIN { FS = "."; } {print $[1]}'`
92 |
93 | # Try the header formats from newest to oldest
94 | if test -r "${IM_PREFIX}/include/ImageMagick-${IM_MAJOR_VERSION}/MagickWand/MagickWand.h"; then
95 |
96 | IM_INCLUDE_FORMAT="MagickWand/MagickWand.h"
97 | IM_HEADER_STYLE="SEVEN"
98 | AC_DEFINE([IM_MAGICKWAND_HEADER_STYLE_SEVEN], [1], [ImageMagick 7.x style header])
99 |
100 | AC_MSG_RESULT([${IM_PREFIX}/include/ImageMagick-${IM_MAJOR_VERSION}/MagickWand/MagickWand.h])
101 |
102 | elif test -r "${IM_PREFIX}/include/ImageMagick-${IM_MAJOR_VERSION}/wand/MagickWand.h"; then
103 |
104 | IM_INCLUDE_FORMAT="wand/MagickWand.h"
105 | IM_HEADER_STYLE="SIX"
106 | AC_DEFINE([IM_MAGICKWAND_HEADER_STYLE_SIX], [1], [ImageMagick 6.x style header])
107 |
108 | AC_MSG_RESULT([${IM_PREFIX}/include/ImageMagick-${IM_MAJOR_VERSION}/wand/MagickWand.h])
109 |
110 | elif test -r "${IM_PREFIX}/include/ImageMagick/wand/MagickWand.h"; then
111 |
112 | IM_INCLUDE_FORMAT="wand/MagickWand.h"
113 | IM_HEADER_STYLE="SIX"
114 | AC_DEFINE([IM_MAGICKWAND_HEADER_STYLE_SIX], [1], [ImageMagick 6.x style header])
115 |
116 | AC_MSG_RESULT([${IM_PREFIX}/include/ImageMagick/wand/MagickWand.h])
117 |
118 | elif test -r "${IM_PREFIX}/include/ImageMagick/wand/magick-wand.h"; then
119 |
120 | IM_INCLUDE_FORMAT="wand/magick-wand.h"
121 | IM_HEADER_STYLE="OLD"
122 | AC_DEFINE([IM_MAGICKWAND_HEADER_STYLE_OLD], [1], [ImageMagick old style header])
123 |
124 | AC_MSG_RESULT([${IM_PREFIX}/include/wand/magick-wand.h])
125 |
126 | else
127 | AC_MSG_ERROR([Unable to find MagickWand.h or magick-wand.h header])
128 | fi
129 |
130 | #
131 | # The cflags and libs
132 | #
133 | IM_IMAGEMAGICK_LIBS=`$IM_WAND_BINARY --libs`
134 | IM_IMAGEMAGICK_CFLAGS=`$IM_WAND_BINARY --cflags`
135 |
136 | export IM_IMAGEMAGICK_PREFIX
137 | export IM_WAND_BINARY
138 | export IM_IMAGEMAGICK_VERSION
139 | export IM_IMAGEMAGICK_VERSION_MASK
140 | export IM_INCLUDE_FORMAT
141 | export IM_HEADER_STYLE
142 |
143 | export IM_IMAGEMAGICK_LIBS
144 | export IM_IMAGEMAGICK_CFLAGS
145 | ])
146 |
147 |
--------------------------------------------------------------------------------
/php_zbarcode.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 / zbarcode |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 2009 Mikko Koppanen |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Mikko Kopppanen |
16 | +----------------------------------------------------------------------+
17 | */
18 | #ifndef _PHP_ZBARCODE_H_
19 | # define _PHP_ZBARCODE_H_
20 |
21 | #define PHP_ZBARCODE_EXTNAME "zbarcode"
22 | #define PHP_ZBARCODE_EXTVER "0.0.2-dev"
23 |
24 | #ifdef HAVE_CONFIG_H
25 | # include "config.h"
26 | #endif
27 |
28 | #ifdef ZTS
29 | # include "TSRM.h"
30 | #endif
31 |
32 | /* Include magic wand header */
33 | #if defined (IM_MAGICKWAND_HEADER_STYLE_SEVEN)
34 | # include
35 | #elif defined (IM_MAGICKWAND_HEADER_STYLE_OLD)
36 | # include
37 | #else
38 | # include
39 | #endif
40 |
41 | #include "php.h"
42 | #include "Zend/zend_exceptions.h"
43 |
44 | #include
45 |
46 | /* {{{ typedef struct _php_zbarcode_object
47 | */
48 | typedef struct _php_zbarcode_object {
49 | zend_object zo;
50 | } php_zbarcode_object;
51 | /* }}} */
52 |
53 | /* {{{ typedef struct _php_zbarcode_scanner_object
54 | */
55 | typedef struct _php_zbarcode_scanner_object {
56 | zbar_image_scanner_t *scanner;
57 | zend_object zo;
58 | } php_zbarcode_scanner_object;
59 | /* }}} */
60 |
61 | /* {{{ typedef struct _php_zbarcode_image_object
62 | */
63 | typedef struct _php_zbarcode_image_object {
64 | MagickWand *magick_wand;
65 | zend_object zo;
66 | } php_zbarcode_image_object;
67 | /* }}} */
68 |
69 | #endif
70 |
--------------------------------------------------------------------------------
/tests/001-construct.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test construction
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
14 | --EXPECT--
15 | OK
16 | OK
--------------------------------------------------------------------------------
/tests/002-read-barcode.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test reading image and scanning barcode
3 | --SKIPIF--
4 |
7 | --FILE--
8 | read(dirname(__FILE__) . "/ean13.jpg"));
11 |
12 | echo "-----------------------------\n";
13 |
14 | $scanner = new ZBarcodeScanner();
15 | var_dump($scanner->scan($image));
16 |
17 | $info = $scanner->scan($image, 0, true);
18 | echo gettype($info[1][0]['location']) . "\n";
19 |
20 | /* Try to scan empty object */
21 | $image->clear();
22 | try {
23 | var_dump($scanner->scan($image));
24 | } catch (ZBarCodeException $e) {
25 | echo "Got exception";
26 | }
27 | ?>
28 | --EXPECTF--
29 | object(zbarcodeimage)#%d (0) {
30 | }
31 | -----------------------------
32 | array(1) {
33 | [0]=>
34 | array(3) {
35 | ["data"]=>
36 | string(13) "5901234123457"
37 | ["type"]=>
38 | string(6) "EAN-13"
39 | ["quality"]=>
40 | int(539)
41 | }
42 | }
43 | array
44 | Got exception
--------------------------------------------------------------------------------
/tests/003-setconfig.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test setting config
3 | --SKIPIF--
4 |
7 | --FILE--
8 | setConfig(ZBarcode::CFG_MIN_LEN, 1));
11 | var_dump($scanner->setConfig(ZBarcode::CFG_MIN_LEN, 10, ZBarcode::SYM_ALL));
12 |
13 | var_dump($scanner->setConfig(ZBarcode::CFG_MAX_LEN, 50));
14 | var_dump($scanner->setConfig(ZBarcode::CFG_MAX_LEN, 15, ZBarcode::SYM_ALL));
15 |
16 | ?>
17 | --EXPECT--
18 | object(zbarcodescanner)#1 (0) {
19 | }
20 | object(zbarcodescanner)#1 (0) {
21 | }
22 | object(zbarcodescanner)#1 (0) {
23 | }
24 | object(zbarcodescanner)#1 (0) {
25 | }
--------------------------------------------------------------------------------
/tests/004-paged-reading.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test multipage reading and single page reading
3 | --SKIPIF--
4 |
7 | --FILE--
8 | read(dirname(__FILE__) . "/ean13.jpg")
11 | ->read(dirname(__FILE__) . "/ean13.jpg")
12 | ->read(dirname(__FILE__) . "/ean13.jpg")
13 | ->read(dirname(__FILE__) . "/ean13.jpg");
14 |
15 | $scanner = new ZBarcodeScanner();
16 | var_dump($scanner->scan($image, 0));
17 |
18 | echo "-----------------------------\n";
19 |
20 | var_dump($scanner->scan($image, 4));
21 |
22 | echo "-----------------------------\n";
23 |
24 | $image->clear();
25 | $image->read(dirname(__FILE__) . "/ean13.jpg");
26 | var_dump($scanner->scan($image));
27 |
28 | ?>
29 | --EXPECT--
30 | array(4) {
31 | [1]=>
32 | array(1) {
33 | [0]=>
34 | array(3) {
35 | ["data"]=>
36 | string(13) "5901234123457"
37 | ["type"]=>
38 | string(6) "EAN-13"
39 | ["quality"]=>
40 | int(539)
41 | }
42 | }
43 | [2]=>
44 | array(1) {
45 | [0]=>
46 | array(3) {
47 | ["data"]=>
48 | string(13) "5901234123457"
49 | ["type"]=>
50 | string(6) "EAN-13"
51 | ["quality"]=>
52 | int(540)
53 | }
54 | }
55 | [3]=>
56 | array(1) {
57 | [0]=>
58 | array(3) {
59 | ["data"]=>
60 | string(13) "5901234123457"
61 | ["type"]=>
62 | string(6) "EAN-13"
63 | ["quality"]=>
64 | int(540)
65 | }
66 | }
67 | [4]=>
68 | array(1) {
69 | [0]=>
70 | array(3) {
71 | ["data"]=>
72 | string(13) "5901234123457"
73 | ["type"]=>
74 | string(6) "EAN-13"
75 | ["quality"]=>
76 | int(540)
77 | }
78 | }
79 | }
80 | -----------------------------
81 | array(1) {
82 | [0]=>
83 | array(3) {
84 | ["data"]=>
85 | string(13) "5901234123457"
86 | ["type"]=>
87 | string(6) "EAN-13"
88 | ["quality"]=>
89 | int(540)
90 | }
91 | }
92 | -----------------------------
93 | array(1) {
94 | [0]=>
95 | array(3) {
96 | ["data"]=>
97 | string(13) "5901234123457"
98 | ["type"]=>
99 | string(6) "EAN-13"
100 | ["quality"]=>
101 | int(540)
102 | }
103 | }
--------------------------------------------------------------------------------
/tests/005-count.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test count
3 | --SKIPIF--
4 |
7 | --FILE--
8 | read(dirname(__FILE__) . "/ean13.jpg")
11 | ->read(dirname(__FILE__) . "/ean13.jpg")
12 | ->read(dirname(__FILE__) . "/ean13.jpg")
13 | ->read(dirname(__FILE__) . "/ean13.jpg");
14 |
15 | echo "Count: " . $image->count() . "\n";
16 | $image->clear();
17 | echo "Count: " . $image->count() . "\n";
18 | sleep(1);
19 |
20 | ?>
21 | --EXPECT--
22 | Count: 4
23 | Count: 0
--------------------------------------------------------------------------------
/tests/006-imagick.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Check whether imagick integration works
3 | --SKIPIF--
4 |
16 | --FILE--
17 | scan($image), $scanner->scan($image)));
23 |
24 | ?>
25 | --EXPECT--
26 | array(0) {
27 | }
--------------------------------------------------------------------------------
/tests/007-test-gd.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test GD support
3 | --SKIPIF--
4 |
15 | --FILE--
16 | scan($image));
21 | ?>
22 | --EXPECT--
23 | array(1) {
24 | [1]=>
25 | array(1) {
26 | [0]=>
27 | array(2) {
28 | ["data"]=>
29 | string(13) "5901234123457"
30 | ["type"]=>
31 | string(6) "EAN-13"
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/tests/ean13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mkoppanen/php-zbarcode/1c613bf112e9f62427698ea89b3feee5201a1816/tests/ean13.jpg
--------------------------------------------------------------------------------
/tests/skipif.inc.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/zbarcode.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 5 / zbarcode |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 2009 Mikko Koppanen |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Mikko Kopppanen |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #include "php_zbarcode.h"
20 | #include "ext/standard/info.h"
21 |
22 | /* Handlers */
23 | static zend_object_handlers php_zbarcode_object_handlers;
24 | static zend_object_handlers php_zbarcode_scanner_object_handlers;
25 | static zend_object_handlers php_zbarcode_image_object_handlers;
26 |
27 | /* Class entries */
28 | zend_class_entry *php_zbarcode_sc_entry;
29 | zend_class_entry *php_zbarcode_image_sc_entry;
30 | zend_class_entry *php_zbarcode_scanner_sc_entry;
31 | zend_class_entry *php_zbarcode_exception_class_entry;
32 |
33 | /* Imagick support */
34 | #ifdef HAVE_ZBARCODE_IMAGICK
35 | # include "ext/imagick/php_imagick_shared.h"
36 | #endif
37 |
38 | /* GD support */
39 | #if HAVE_ZBARCODE_GD
40 | # include "ext/gd/php_gd.h"
41 | # if HAVE_GD_BUNDLED
42 | # include "ext/gd/libgd/gd.h"
43 | # else
44 | # include "gd.h"
45 | # endif
46 | #endif
47 |
48 | #define PHP_ZBARCODE_RESOLUTION 1
49 | #define PHP_ZBARCODE_ENHANCE 2
50 | #define PHP_ZBARCODE_SHARPEN 4
51 |
52 | static inline php_zbarcode_object *php_zbarcode_fetch_object(zend_object *obj) {
53 | return (php_zbarcode_object *)((char *)obj - XtOffsetOf(php_zbarcode_object, zo));
54 | }
55 | #define Z_ZBARCODE_OBJ_P(zv) php_zbarcode_fetch_object(Z_OBJ_P(zv));
56 |
57 | static inline php_zbarcode_image_object *php_zbarcode_image_fetch_object(zend_object *obj) {
58 | return (php_zbarcode_image_object *)((char *)obj - XtOffsetOf(php_zbarcode_image_object, zo));
59 | }
60 | #define Z_ZBARCODE_IMAGE_OBJ_P(zv) php_zbarcode_image_fetch_object(Z_OBJ_P(zv));
61 |
62 | static inline php_zbarcode_scanner_object *php_zbarcode_scanner_fetch_object(zend_object *obj) {
63 | return (php_zbarcode_scanner_object *)((char *)obj - XtOffsetOf(php_zbarcode_scanner_object, zo));
64 | }
65 | #define Z_ZBARCODE_SCANNER_OBJ_P(zv) php_zbarcode_scanner_fetch_object(Z_OBJ_P(zv));
66 |
67 | static
68 | void s_throw_image_exception (MagickWand *magick_wand, const char *message TSRMLS_DC)
69 | {
70 | ExceptionType severity;
71 | char *magick_msg;
72 |
73 | magick_msg = MagickGetException (magick_wand, &severity);
74 | MagickClearException (magick_wand);
75 |
76 | if (magick_msg && strlen (magick_msg) > 0) {
77 | zend_throw_exception(php_zbarcode_exception_class_entry, magick_msg, 1 TSRMLS_CC);
78 | magick_msg = MagickRelinquishMemory(magick_msg);
79 | return;
80 | }
81 |
82 | if (magick_msg) {
83 | MagickRelinquishMemory(magick_msg);
84 | }
85 |
86 | zend_throw_exception(php_zbarcode_exception_class_entry, message, 1 TSRMLS_CC);
87 | }
88 |
89 | #define PHP_ZBARCODE_CHAIN_METHOD RETURN_ZVAL(getThis(), 1, 0);
90 |
91 | static
92 | zend_bool s_php_zbarcode_read(MagickWand *wand, char *filename, long enhance)
93 | {
94 | if (enhance & PHP_ZBARCODE_RESOLUTION) {
95 | MagickSetResolution(wand, 200, 200);
96 | }
97 |
98 | if (MagickReadImage(wand, filename) == MagickFalse) {
99 | ClearMagickWand(wand);
100 | return 0;
101 | }
102 |
103 | if (enhance & PHP_ZBARCODE_ENHANCE) {
104 | MagickEnhanceImage(wand);
105 | }
106 |
107 | if (enhance & PHP_ZBARCODE_SHARPEN) {
108 | MagickSharpenImage(wand, 0, 0.5);
109 | }
110 |
111 | return 1;
112 | }
113 |
114 | /* {{{ zBarcodeImage zBarcodeImage::__construct([string filename, int enhance])
115 | Construct a new zBarcodeImage object
116 | */
117 | PHP_METHOD(zbarcodeimage, __construct)
118 | {
119 | php_zbarcode_image_object *intern;
120 | zend_string *filename = NULL;
121 | long enhance = 0;
122 | char resolved_path[MAXPATHLEN];
123 |
124 | ZEND_PARSE_PARAMETERS_START(0, 2)
125 | Z_PARAM_OPTIONAL
126 | Z_PARAM_STR(filename)
127 | Z_PARAM_LONG(enhance)
128 | ZEND_PARSE_PARAMETERS_END();
129 |
130 | if (filename == NULL || !filename->len) {
131 | return;
132 | }
133 |
134 | if (!tsrm_realpath(filename->val, resolved_path TSRMLS_CC)) {
135 | zend_throw_exception(php_zbarcode_exception_class_entry, "The file does not exist or cannot be read", 1 TSRMLS_CC);
136 | return;
137 | }
138 |
139 | if (php_check_open_basedir(resolved_path TSRMLS_CC)) {
140 | return;
141 | }
142 |
143 | intern = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(getThis());
144 |
145 | if (!s_php_zbarcode_read(intern->magick_wand, resolved_path, enhance)) {
146 | s_throw_image_exception (intern->magick_wand, "Unable to read the image" TSRMLS_CC);
147 | return;
148 | }
149 | return;
150 | }
151 | /* }}} */
152 |
153 | /* {{{ zBarcodeImage zBarcodeImage::read(string filename[, int enhance])
154 | Read an image
155 | */
156 | PHP_METHOD(zbarcodeimage, read)
157 | {
158 | php_zbarcode_image_object *intern;
159 | zend_string *filename = NULL;
160 | long enhance = 0;
161 | char resolved_path[MAXPATHLEN];
162 |
163 | ZEND_PARSE_PARAMETERS_START(1, 2)
164 | Z_PARAM_STR(filename)
165 | Z_PARAM_OPTIONAL
166 | Z_PARAM_LONG(enhance)
167 | ZEND_PARSE_PARAMETERS_END();
168 |
169 | if (!tsrm_realpath(filename->val, resolved_path TSRMLS_CC)) {
170 | zend_throw_exception(php_zbarcode_exception_class_entry, "The file does not exist or cannot be read", 1 TSRMLS_CC);
171 | return;
172 | }
173 |
174 | if (php_check_open_basedir(resolved_path TSRMLS_CC)) {
175 | return;
176 | }
177 |
178 | intern = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(getThis());
179 |
180 | if (!s_php_zbarcode_read(intern->magick_wand, resolved_path, enhance)) {
181 | s_throw_image_exception (intern->magick_wand, "Unable to read the image" TSRMLS_CC);
182 | return;
183 | }
184 | PHP_ZBARCODE_CHAIN_METHOD;
185 | }
186 | /* }}} */
187 |
188 | /* {{{ zBarcodeImage zBarcodeImage:clear()
189 | Remove existing pages
190 | */
191 | PHP_METHOD(zbarcodeimage, clear)
192 | {
193 | php_zbarcode_image_object *intern;
194 |
195 | if (zend_parse_parameters_none() == FAILURE) {
196 | return;
197 | }
198 |
199 | intern = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(getThis());
200 | ClearMagickWand(intern->magick_wand);
201 |
202 | PHP_ZBARCODE_CHAIN_METHOD;
203 | }
204 | /* }}} */
205 |
206 | /* {{{ integer zBarcodeImage:count()
207 | Count pages
208 | */
209 | PHP_METHOD(zbarcodeimage, count)
210 | {
211 | php_zbarcode_image_object *intern;
212 |
213 | if (zend_parse_parameters_none() == FAILURE) {
214 | return;
215 | }
216 |
217 | intern = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(getThis());
218 | RETURN_LONG(MagickGetNumberImages(intern->magick_wand));
219 | }
220 | /* }}} */
221 |
222 | static
223 | zbar_image_t *s_php_zbarcode_image_create(unsigned long width, unsigned long height, unsigned char *image_data)
224 | {
225 | zbar_image_t *image = zbar_image_create();
226 |
227 | if (!image) {
228 | return NULL;
229 | }
230 |
231 | zbar_image_set_format(image, *(int*)"Y800");
232 | zbar_image_set_size(image, width, height);
233 | zbar_image_set_data(image, (void *)image_data, width * height, zbar_image_free_data);
234 | return image;
235 | }
236 |
237 | static
238 | zbar_image_t *s_php_zbarcode_get_page(MagickWand *wand)
239 | {
240 | unsigned long width, height;
241 | unsigned char *image_data;
242 | size_t image_size;
243 |
244 | if (MagickSetImageDepth(wand, 8) == MagickFalse) {
245 | return NULL;
246 | }
247 |
248 | if (MagickSetImageFormat(wand, "GRAY") == MagickFalse) {
249 | return NULL;
250 | }
251 |
252 | width = MagickGetImageWidth(wand);
253 | height = MagickGetImageHeight(wand);
254 |
255 | image_data = calloc(width * height, sizeof (char));
256 |
257 | if (!MagickExportImagePixels(wand, 0, 0, width, height, "I", CharPixel, image_data)) {
258 | return NULL;
259 | }
260 | return s_php_zbarcode_image_create(width, height, image_data);
261 | }
262 |
263 | static
264 | zval *s_php_zbarcode_scan_page(zbar_image_scanner_t *scanner, zbar_image_t *image, zend_bool extended, zval *return_array TSRMLS_DC)
265 | {
266 | int n;
267 | const zbar_symbol_t *symbol;
268 |
269 | array_init(return_array);
270 |
271 | /* scan the image for barcodes */
272 | n = zbar_scan_image(scanner, image);
273 |
274 | /* extract results */
275 | symbol = zbar_image_first_symbol(image);
276 |
277 | /* Loop through all all symbols */
278 | for(; symbol; symbol = zbar_symbol_next(symbol)) {
279 | zval symbol_array, loc_array;
280 | zbar_symbol_type_t symbol_type;
281 | const char *data;
282 | unsigned int loc_size;
283 |
284 | /* Initialize array element */
285 | array_init(&symbol_array);
286 |
287 | /* Get symbol type and data in it */
288 | symbol_type = zbar_symbol_get_type(symbol);
289 | data = zbar_symbol_get_data(symbol);
290 |
291 | add_assoc_string(&symbol_array, "data", (char *)data);
292 | add_assoc_string(&symbol_array, "type", (char *)zbar_get_symbol_name(symbol_type));
293 | #ifdef HAVE_ZBAR_SYMBOL_GET_QUALITY
294 | add_assoc_long(&symbol_array, "quality", zbar_symbol_get_quality(symbol));
295 | #endif
296 | if (extended) {
297 | unsigned int i;
298 |
299 | array_init(&loc_array);
300 | loc_size = zbar_symbol_get_loc_size(symbol);
301 |
302 | for (i = 0; i < loc_size; i++) {
303 | zval coords;
304 | array_init(&coords);
305 |
306 | add_assoc_long(&coords, "x", zbar_symbol_get_loc_x(symbol, i));
307 | add_assoc_long(&coords, "y", zbar_symbol_get_loc_y(symbol, i));
308 |
309 | add_next_index_zval(&loc_array, &coords);
310 | }
311 | add_assoc_zval(&symbol_array, "location", &loc_array);
312 | }
313 | add_next_index_zval(return_array, &symbol_array);
314 | }
315 | return return_array;
316 | }
317 |
318 | /* {{{ array zBarCodeScanner::scan(mixed image[, int page_num, bool extended])
319 | Scan an image
320 | */
321 | PHP_METHOD(zbarcodescanner, scan)
322 | {
323 | zval *image;
324 | MagickWand *magick_wand;
325 |
326 | zbar_image_t *page;
327 | php_zbarcode_scanner_object *intern;
328 |
329 | zval *object;
330 | int i = 1;
331 | zend_bool extended = 0;
332 | long page_num = 1, image_count;
333 | zend_bool free_ptr = 0;
334 |
335 | ZEND_PARSE_PARAMETERS_START(1, 3)
336 | Z_PARAM_ZVAL(image)
337 | Z_PARAM_OPTIONAL
338 | Z_PARAM_LONG(page_num)
339 | Z_PARAM_BOOL(extended)
340 | ZEND_PARSE_PARAMETERS_END();
341 |
342 | #ifdef HAVE_ZBARCODE_GD
343 | if (Z_TYPE_P(image) != IS_OBJECT && Z_TYPE_P(image) != IS_RESOURCE) {
344 | zend_throw_exception(php_zbarcode_exception_class_entry, "The first parameter must be a valid object or a GD resource", 1 TSRMLS_CC);
345 | return;
346 | }
347 | #else
348 | if (Z_TYPE_P(image) != IS_OBJECT) {
349 | zend_throw_exception(php_zbarcode_exception_class_entry, "The first parameter must be a valid object", 1 TSRMLS_CC);
350 | return;
351 | }
352 | #endif
353 |
354 | intern = (php_zbarcode_scanner_object *)Z_ZBARCODE_SCANNER_OBJ_P(getThis());
355 |
356 | if (Z_TYPE_P(image) == IS_OBJECT && instanceof_function_ex(Z_OBJCE_P(image), php_zbarcode_image_sc_entry, 0 TSRMLS_CC)) {
357 | php_zbarcode_image_object *intern_image;
358 |
359 | intern_image = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(image);
360 | magick_wand = intern_image->magick_wand;
361 | }
362 | #ifdef HAVE_ZBARCODE_IMAGICK
363 | else if (Z_TYPE_P(image) == IS_OBJECT && instanceof_function_ex(Z_OBJCE_P(image), php_imagick_get_class_entry(), 0 TSRMLS_CC)) {
364 | php_zbarcode_image_object *intern_image;
365 | intern_image = (php_zbarcode_image_object *)Z_ZBARCODE_IMAGE_OBJ_P(image);
366 | magick_wand = intern_image->magick_wand;
367 | }
368 | #endif
369 | #ifdef HAVE_ZBARCODE_GD
370 | /* Handle GD resource */
371 | else if (Z_TYPE_P(image) == IS_RESOURCE) {
372 | gdImagePtr gd_image = NULL;
373 | MagickWand *wand;
374 | unsigned long image_w, image_h;
375 | PixelWand *color;
376 | MagickBooleanType status;
377 | unsigned char *pixels;
378 | int x, y, pixel_pos = 0;
379 | zend_bool has_pixels = 0;
380 |
381 | ZEND_FETCH_RESOURCE(gd_image, gdImagePtr, &image, -1, "Image", phpi_get_le_gd());
382 |
383 | if (!gd_image) {
384 | zend_throw_exception(php_zbarcode_exception_class_entry, "The given resource is not a valid GD image", 1 TSRMLS_CC);
385 | return;
386 | }
387 |
388 | image_w = gdImageSX(gd_image);
389 | image_h = gdImageSY(gd_image);
390 |
391 | pixels = emalloc((3 * image_w) * image_h);
392 |
393 | for (y = 0; y < image_h; y++) {
394 | for (x = 0; x < image_w; x++) {
395 | int pixel = 0;
396 | if (gdImageTrueColor(gd_image)) {
397 | if (gd_image->tpixels && gdImageBoundsSafe(gd_image, x, y)) {
398 | pixel = gdImageTrueColorPixel(gd_image, x, y);
399 | pixels[pixel_pos++] = (pixel >> 16) & 0xFF;
400 | pixels[pixel_pos++] = (pixel >> 8) & 0xFF;
401 | pixels[pixel_pos++] = pixel & 0xFF;
402 | has_pixels = 1;
403 | }
404 | } else {
405 | if (gd_image->pixels && gdImageBoundsSafe(gd_image, x, y)) {
406 | pixel = gd_image->pixels[y][x];
407 | pixels[pixel_pos++] = gd_image->red[pixel];
408 | pixels[pixel_pos++] = gd_image->green[pixel];
409 | pixels[pixel_pos++] = gd_image->blue[pixel];
410 | has_pixels = 1;
411 | }
412 | }
413 | }
414 | }
415 |
416 | if (!has_pixels) {
417 | efree(pixels);
418 | zend_throw_exception(php_zbarcode_exception_class_entry, "Unable to get pixels from GD resource", 1 TSRMLS_CC);
419 | return;
420 | }
421 |
422 | wand = NewMagickWand();
423 | if (!wand) {
424 | efree(pixels);
425 | zend_throw_exception(php_zbarcode_exception_class_entry, "Failed to allocate MagickWand structure", 1 TSRMLS_CC);
426 | return;
427 | }
428 |
429 | color = NewPixelWand();
430 | if (!color) {
431 | efree(pixels);
432 | DestroyMagickWand(wand);
433 | zend_throw_exception(php_zbarcode_exception_class_entry, "Failed to allocate PixelWand structure", 1 TSRMLS_CC);
434 | return;
435 | }
436 |
437 | if (MagickNewImage(wand, image_w, image_h, color) == MagickFalse) {
438 | efree(pixels);
439 | DestroyMagickWand(wand);
440 | DestroyPixelWand(color);
441 | return;
442 | }
443 | DestroyPixelWand(color);
444 |
445 | status = MagickSetImagePixels(wand, 0, 0, image_w, image_h, "RGB", CharPixel, pixels);
446 | efree(pixels);
447 |
448 | if (status == MagickFalse) {
449 | DestroyMagickWand(wand);
450 | return;
451 | }
452 |
453 | magick_wand = wand;
454 | page_num = 0;
455 | free_ptr = 1;
456 | }
457 | #endif
458 | else {
459 | zend_throw_exception(php_zbarcode_exception_class_entry, "Invalid parameter type", 1 TSRMLS_CC);
460 | return;
461 | }
462 |
463 | image_count = MagickGetNumberImages(magick_wand);
464 |
465 | if (image_count == 0) {
466 | zend_throw_exception(php_zbarcode_exception_class_entry, "The image object does not contain images", 1 TSRMLS_CC);
467 | return;
468 | }
469 |
470 | if (page_num > 0) {
471 | if (image_count < page_num) {
472 | if (free_ptr) {
473 | DestroyMagickWand(magick_wand);
474 | }
475 | zend_throw_exception_ex(php_zbarcode_exception_class_entry, 1 TSRMLS_CC, "Invalid page specified. The object contains %ld page(s)", image_count);
476 | return;
477 | }
478 |
479 | if (MagickSetIteratorIndex(magick_wand, page_num - 1) == MagickFalse) {
480 | if (free_ptr) {
481 | DestroyMagickWand(magick_wand);
482 | }
483 | zend_throw_exception(php_zbarcode_exception_class_entry, "Failed to set the page number", 1 TSRMLS_CC);
484 | return;
485 | }
486 | /* Read page */
487 | page = s_php_zbarcode_get_page(magick_wand);
488 |
489 | if (!page) {
490 | if (free_ptr) {
491 | DestroyMagickWand(magick_wand);
492 | }
493 | zend_throw_exception(php_zbarcode_exception_class_entry, "Failed to get the page", 1 TSRMLS_CC);
494 | return;
495 | }
496 |
497 | /* Scan the page for barcodes */
498 | s_php_zbarcode_scan_page(intern->scanner, page, extended, return_value TSRMLS_CC);
499 | } else {
500 | array_init(return_value);
501 |
502 | MagickResetIterator(magick_wand);
503 | while (MagickNextImage(magick_wand) != MagickFalse) {
504 | zval page_array;
505 |
506 | /* Read the current page */
507 | page = s_php_zbarcode_get_page(magick_wand);
508 |
509 | /* Reading current page failed */
510 | if (!page) {
511 | i++;
512 | continue;
513 | }
514 | /* Scan the page for barcodes */
515 |
516 | s_php_zbarcode_scan_page(intern->scanner, page, extended, &page_array TSRMLS_CC);
517 | add_index_zval(return_value, i++, &page_array);
518 | }
519 | }
520 |
521 | if (free_ptr) {
522 | DestroyMagickWand(magick_wand);
523 | }
524 |
525 | return;
526 | }
527 | /* }}} */
528 |
529 | /* {{{ zBarCodeScanner zBarCodeScanner::setConfig(int name, int value[, int symbology])
530 | Set config option
531 | */
532 | PHP_METHOD(zbarcodescanner, setconfig)
533 | {
534 | php_zbarcode_scanner_object *intern;
535 | long symbology = 0, name, value;
536 |
537 | ZEND_PARSE_PARAMETERS_START(2, 3)
538 | Z_PARAM_LONG(name)
539 | Z_PARAM_LONG(value)
540 | Z_PARAM_OPTIONAL
541 | Z_PARAM_LONG(symbology)
542 | ZEND_PARSE_PARAMETERS_END();
543 |
544 | intern = (php_zbarcode_scanner_object *)Z_ZBARCODE_SCANNER_OBJ_P(getThis());
545 |
546 | if (zbar_image_scanner_set_config(intern->scanner, symbology, name, value) != 0) {
547 | zend_throw_exception(php_zbarcode_exception_class_entry, "Config does not apply to specified symbology, or value out of range", 1 TSRMLS_CC);
548 | return;
549 | }
550 | PHP_ZBARCODE_CHAIN_METHOD;
551 | }
552 | /* }}} */
553 |
554 | static zend_function_entry php_zbarcode_class_methods[] =
555 | {
556 | { NULL, NULL, NULL }
557 | };
558 |
559 | ZEND_BEGIN_ARG_INFO_EX(zbarcode_image_construct_args, 0, 0, 0)
560 | ZEND_ARG_INFO(0, filename)
561 | ZEND_ARG_INFO(0, enhance)
562 | ZEND_END_ARG_INFO()
563 |
564 | ZEND_BEGIN_ARG_INFO_EX(zbarcode_image_read_args, 0, 0, 1)
565 | ZEND_ARG_INFO(0, filename)
566 | ZEND_ARG_INFO(0, enhance)
567 | ZEND_END_ARG_INFO()
568 |
569 | ZEND_BEGIN_ARG_INFO_EX(zbarcode_image_no_args, 0, 0, 0)
570 | ZEND_END_ARG_INFO()
571 |
572 | static zend_function_entry php_zbarcode_image_class_methods[] =
573 | {
574 | PHP_ME(zbarcodeimage, __construct, zbarcode_image_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
575 | PHP_ME(zbarcodeimage, read, zbarcode_image_read_args, ZEND_ACC_PUBLIC)
576 | PHP_ME(zbarcodeimage, clear, zbarcode_image_no_args, ZEND_ACC_PUBLIC)
577 | PHP_ME(zbarcodeimage, count, zbarcode_image_no_args, ZEND_ACC_PUBLIC)
578 | { NULL, NULL, NULL }
579 | };
580 |
581 | ZEND_BEGIN_ARG_INFO_EX(zbarcode_scanner_scan_args, 0, 0, 1)
582 | ZEND_ARG_INFO(0, image)
583 | ZEND_ARG_INFO(0, page_num)
584 | ZEND_ARG_INFO(0, extended)
585 | ZEND_END_ARG_INFO()
586 |
587 | ZEND_BEGIN_ARG_INFO_EX(zbarcode_scanner_setconfig_args, 0, 0, 2)
588 | ZEND_ARG_INFO(0, name)
589 | ZEND_ARG_INFO(0, value)
590 | ZEND_ARG_INFO(0, symbology)
591 | ZEND_END_ARG_INFO()
592 |
593 | static zend_function_entry php_zbarcode_scanner_class_methods[] =
594 | {
595 | PHP_ME(zbarcodescanner, scan, zbarcode_scanner_scan_args, ZEND_ACC_PUBLIC)
596 | PHP_ME(zbarcodescanner, setconfig, zbarcode_scanner_setconfig_args, ZEND_ACC_PUBLIC)
597 | { NULL, NULL, NULL }
598 | };
599 |
600 | /* {{{ static void php_zbarcode_object_free_storage(zend_object *object)
601 | */
602 | static void php_zbarcode_object_free_storage(zend_object *object)
603 | {
604 | php_zbarcode_object *intern = php_zbarcode_fetch_object(object);
605 |
606 | if (!intern) {
607 | return;
608 | }
609 | if (&intern->zo) {
610 | zend_object_std_dtor(&intern->zo);
611 | }
612 | }
613 | /* }}} */
614 |
615 | /* {{{ static void php_zbarcode_scanner_object_free_storage(zend_object *object)
616 | */
617 | static void php_zbarcode_scanner_object_free_storage(zend_object *object)
618 | {
619 | php_zbarcode_scanner_object *intern = php_zbarcode_scanner_fetch_object(object);
620 |
621 | if (!intern) {
622 | return;
623 | }
624 |
625 | if (intern->scanner) {
626 | zbar_image_scanner_destroy(intern->scanner);
627 | intern->scanner = NULL;
628 | }
629 | zend_object_std_dtor(&intern->zo);
630 | }
631 | /* }}} */
632 |
633 | /* {{{ static void php_zbarcode_image_object_free_storage(zend_object *object)
634 | */
635 | static void php_zbarcode_image_object_free_storage(zend_object *object)
636 | {
637 | php_zbarcode_image_object *intern = php_zbarcode_image_fetch_object(object);
638 |
639 | if (!intern) {
640 | return;
641 | }
642 |
643 | if (intern->magick_wand) {
644 | DestroyMagickWand(intern->magick_wand);
645 | intern->magick_wand = NULL;
646 | }
647 |
648 | zend_object_std_dtor(&intern->zo);
649 | }
650 | /* }}} */
651 |
652 | /* PHP 5.4 */
653 | #if PHP_VERSION_ID < 50399
654 | # define object_properties_init(zo, class_type) { \
655 | zval *tmp; \
656 | zend_hash_copy((*zo).properties, \
657 | &class_type->default_properties, \
658 | (copy_ctor_func_t) zval_add_ref, \
659 | (void *) &tmp, \
660 | sizeof(zval *)); \
661 | }
662 | #endif
663 |
664 | /* {{{ static zend_object *php_zbarcode_object_new(zend_class_entry *ce)
665 | */
666 | static zend_object *php_zbarcode_object_new(zend_class_entry *ce)
667 | {
668 | php_zbarcode_object *intern = ecalloc(1, sizeof(php_zbarcode_object) + zend_object_properties_size(ce));
669 |
670 | zend_object_std_init(&intern->zo, ce);
671 | object_properties_init(&intern->zo, ce);
672 |
673 | intern->zo.handlers = &php_zbarcode_object_handlers;
674 | return &intern->zo;
675 | }
676 | /* }}} */
677 |
678 | /* {{{ static zend_object *php_zbarcode_scanner_object_new(zend_class_entry *ce)
679 | */
680 | static zend_object *php_zbarcode_scanner_object_new(zend_class_entry *ce)
681 | {
682 | php_zbarcode_scanner_object *intern = ecalloc(1, sizeof(php_zbarcode_scanner_object) + zend_object_properties_size(ce));
683 |
684 | zend_object_std_init(&intern->zo, ce);
685 | object_properties_init(&intern->zo, ce);
686 |
687 | /* Initialize reader */
688 | intern->scanner = zbar_image_scanner_create();
689 |
690 | intern->zo.handlers = &php_zbarcode_scanner_object_handlers;
691 | return &intern->zo;
692 | }
693 | /* }}} */
694 |
695 | /* {{{ static zend_object *php_zbarcode_image_object_new(zend_class_entry *ce)
696 | */
697 | static zend_object *php_zbarcode_image_object_new(zend_class_entry *ce)
698 | {
699 | php_zbarcode_image_object *intern = ecalloc(1, sizeof(php_zbarcode_image_object) + zend_object_properties_size(ce));
700 |
701 | zend_object_std_init(&intern->zo, ce);
702 | object_properties_init(&intern->zo, ce);
703 |
704 | /* Initialize reader */
705 | intern->magick_wand = NewMagickWand();
706 |
707 | intern->zo.handlers = &php_zbarcode_image_object_handlers;
708 | return &intern->zo;
709 | }
710 | /* }}} */
711 |
712 | /* {{{ PHP_MINIT_FUNCTION(zbarcode)
713 | */
714 | PHP_MINIT_FUNCTION(zbarcode)
715 | {
716 | zend_class_entry ce;
717 | memcpy(&php_zbarcode_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
718 | memcpy(&php_zbarcode_scanner_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
719 | memcpy(&php_zbarcode_image_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
720 |
721 | MagickWandGenesis();
722 |
723 | /*
724 | Initialize exceptions (zbarcode exception)
725 | */
726 | INIT_CLASS_ENTRY(ce, "zbarcodeexception", NULL);
727 | php_zbarcode_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C));
728 | php_zbarcode_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
729 |
730 | /*
731 | Initialize the class (zbarcode). This class is just a container for constants
732 | */
733 | INIT_CLASS_ENTRY(ce, "zbarcode", php_zbarcode_class_methods);
734 | ce.create_object = php_zbarcode_object_new;
735 | php_zbarcode_object_handlers.clone_obj = NULL;
736 | php_zbarcode_object_handlers.free_obj = php_zbarcode_object_free_storage;
737 | php_zbarcode_object_handlers.offset = XtOffsetOf(php_zbarcode_object, zo);
738 | php_zbarcode_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
739 |
740 | /*
741 | Initialize the class (zbarcode image)
742 | */
743 | INIT_CLASS_ENTRY(ce, "zbarcodeimage", php_zbarcode_image_class_methods);
744 | ce.create_object = php_zbarcode_image_object_new;
745 | php_zbarcode_image_object_handlers.clone_obj = NULL;
746 | php_zbarcode_image_object_handlers.free_obj = php_zbarcode_image_object_free_storage;
747 | php_zbarcode_image_object_handlers.offset = XtOffsetOf(php_zbarcode_image_object, zo);
748 | php_zbarcode_image_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
749 |
750 | /*
751 | Initialize the class (zbarcode scanner)
752 | */
753 | INIT_CLASS_ENTRY(ce, "zbarcodescanner", php_zbarcode_scanner_class_methods);
754 | ce.create_object = php_zbarcode_scanner_object_new;
755 | php_zbarcode_scanner_object_handlers.clone_obj = NULL;
756 | php_zbarcode_scanner_object_handlers.free_obj = php_zbarcode_scanner_object_free_storage;
757 | php_zbarcode_scanner_object_handlers.offset = XtOffsetOf(php_zbarcode_scanner_object, zo);
758 | php_zbarcode_scanner_sc_entry = zend_register_internal_class(&ce TSRMLS_CC);
759 |
760 | /* Do we have imagick support */
761 | #ifdef HAVE_ZBARCODE_IMAGICK
762 | zend_declare_class_constant_bool(php_zbarcode_sc_entry, "HAVE_IMAGICK", sizeof("HAVE_IMAGICK")-1, 1 TSRMLS_CC);
763 | #else
764 | zend_declare_class_constant_bool(php_zbarcode_sc_entry, "HAVE_IMAGICK", sizeof("HAVE_IMAGICK")-1, 0 TSRMLS_CC);
765 | #endif
766 |
767 | /* Do we have GD support */
768 | #ifdef HAVE_ZBARCODE_GD
769 | zend_declare_class_constant_bool(php_zbarcode_sc_entry, "HAVE_GD", sizeof("HAVE_GD")-1, 1 TSRMLS_CC);
770 | #else
771 | zend_declare_class_constant_bool(php_zbarcode_sc_entry, "HAVE_GD", sizeof("HAVE_GD")-1, 0 TSRMLS_CC);
772 | #endif
773 |
774 | #define PHP_ZBARCODE_REGISTER_CONST_LONG(const_name, value) \
775 | zend_declare_class_constant_long(php_zbarcode_sc_entry, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
776 |
777 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_ENABLE", ZBAR_CFG_ENABLE); /**< enable symbology/feature */
778 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_ADD_CHECK", ZBAR_CFG_ADD_CHECK); /**< enable check digit when optional */
779 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_EMIT_CHECK", ZBAR_CFG_EMIT_CHECK); /**< return check digit when present */
780 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_ASCII", ZBAR_CFG_ASCII); /**< enable full ASCII character set */
781 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_NUM", ZBAR_CFG_NUM); /**< number of boolean decoder configs */
782 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_MIN_LEN", ZBAR_CFG_MIN_LEN); /**< minimum data length for valid decode */
783 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_MAX_LEN", ZBAR_CFG_MAX_LEN); /**< maximum data length for valid decode */
784 | #ifdef HAVE_ZBAR_SYMBOL_GET_QUALITY
785 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_POSITION", ZBAR_CFG_POSITION); /**< enable scanner to collect position data */
786 | #endif
787 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_X_DENSITY", ZBAR_CFG_X_DENSITY); /**< image scanner vertical scan density */
788 | PHP_ZBARCODE_REGISTER_CONST_LONG("CFG_Y_DENSITY", ZBAR_CFG_Y_DENSITY); /**< image scanner horizontal scan density */
789 |
790 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ALL", 0); /**< all symbologies */
791 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_NONE", ZBAR_NONE); /**< no symbol decoded */
792 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_PARTIAL", ZBAR_PARTIAL); /**< intermediate status */
793 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_EAN8", ZBAR_EAN8); /**< EAN-8 */
794 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_UPCE", ZBAR_UPCE); /**< UPC-E */
795 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ISBN10", ZBAR_ISBN10); /**< ISBN-10 (from EAN-13).*/
796 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_UPCA", ZBAR_UPCA); /**< UPC-A */
797 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_EAN13", ZBAR_EAN13); /**< EAN-13 */
798 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ISBN13", ZBAR_ISBN13); /**< ISBN-13 (from EAN-13). */
799 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_I25", ZBAR_I25); /**< Interleaved 2 of 5. */
800 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_CODE39", ZBAR_CODE39); /**< Code 39. */
801 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_PDF417", ZBAR_PDF417); /**< PDF417. */
802 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_CODE128", ZBAR_CODE128); /**< Code 128 */
803 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_SYMBOL", ZBAR_SYMBOL); /**< mask for base symbol type */
804 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ADDON2", ZBAR_ADDON2); /**< 2-digit add-on flag */
805 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ADDON5", ZBAR_ADDON5); /**< 5-digit add-on flag */
806 | PHP_ZBARCODE_REGISTER_CONST_LONG("SYM_ADDON", ZBAR_ADDON); /**< add-on flag mask */
807 | PHP_ZBARCODE_REGISTER_CONST_LONG("OPT_RESOLUTION", PHP_ZBARCODE_RESOLUTION); /**< Set higher resolution */
808 | PHP_ZBARCODE_REGISTER_CONST_LONG("OPT_ENHANCE", PHP_ZBARCODE_ENHANCE); /**< Reduce noise */
809 | PHP_ZBARCODE_REGISTER_CONST_LONG("OPT_SHARPEN", PHP_ZBARCODE_SHARPEN); /**< Sharpen */
810 |
811 | #undef PHP_ZBARCODE_REGISTER_CONST_LONG
812 |
813 | return SUCCESS;
814 | }
815 | /* }}} */
816 |
817 | /* {{{ PHP_MSHUTDOWN_FUNCTION(zbarcode)
818 | */
819 | PHP_MSHUTDOWN_FUNCTION(zbarcode)
820 | {
821 | MagickWandTerminus();
822 | return SUCCESS;
823 | }
824 | /* }}} */
825 |
826 | /* {{{ PHP_MINFO_FUNCTION(zbarcode)
827 | */
828 | PHP_MINFO_FUNCTION(zbarcode)
829 | {
830 | unsigned int major = 0, minor = 0, patch = 0;
831 | char *zbar_ver = NULL;
832 | unsigned long magick_version;
833 |
834 | zbar_version(&major, &minor, &patch);
835 | spprintf(&zbar_ver, 24, "%d.%d.%d", major, minor,patch);
836 |
837 | php_info_print_table_start();
838 | php_info_print_table_row(2, "zbarcode module", "enabled");
839 | php_info_print_table_row(2, "zbarcode module version", PHP_ZBARCODE_EXTVER);
840 | php_info_print_table_row(2, "ZBar library version", zbar_ver);
841 | php_info_print_table_row(2, "ImageMagick version", MagickGetVersion(&magick_version));
842 |
843 | #ifdef HAVE_ZBARCODE_IMAGICK
844 | php_info_print_table_row(2, "Imagick support", "enabled");
845 | #else
846 | php_info_print_table_row(2, "Imagick support", "disabled");
847 | #endif
848 |
849 | #ifdef HAVE_ZBARCODE_GD
850 | php_info_print_table_row(2, "GD support", "enabled");
851 | #else
852 | php_info_print_table_row(2, "GD support", "disabled");
853 | #endif
854 |
855 | php_info_print_table_end();
856 | efree(zbar_ver);
857 | }
858 | /* }}} */
859 |
860 | static zend_function_entry php_zbarcode_functions[] =
861 | {
862 | { NULL, NULL, NULL }
863 | };
864 |
865 | zend_module_entry zbarcode_module_entry =
866 | {
867 | #if ZEND_MODULE_API_NO >= 20010901
868 | STANDARD_MODULE_HEADER,
869 | #endif
870 | PHP_ZBARCODE_EXTNAME,
871 | php_zbarcode_functions, /* Functions */
872 | PHP_MINIT(zbarcode), /* MINIT */
873 | PHP_MSHUTDOWN(zbarcode), /* MSHUTDOWN */
874 | NULL, /* RINIT */
875 | NULL, /* RSHUTDOWN */
876 | PHP_MINFO(zbarcode), /* MINFO */
877 | #if ZEND_MODULE_API_NO >= 20010901
878 | PHP_ZBARCODE_EXTVER,
879 | #endif
880 | STANDARD_MODULE_PROPERTIES
881 | };
882 |
883 | #ifdef COMPILE_DL_ZBARCODE
884 | ZEND_GET_MODULE(zbarcode)
885 | #endif
--------------------------------------------------------------------------------