1 //------------------------------------------------------------------------
2 //  Copyright 2008-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
3 //
4 //  This file is part of the ZBar Bar Code Reader.
5 //
6 //  The ZBar Bar Code Reader is free software; you can redistribute it
7 //  and/or modify it under the terms of the GNU Lesser Public License as
8 //  published by the Free Software Foundation; either version 2.1 of
9 //  the License, or (at your option) any later version.
10 //
11 //  The ZBar Bar Code Reader is distributed in the hope that it will be
12 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU Lesser Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser Public License
17 //  along with the ZBar Bar Code Reader; if not, write to the Free
18 //  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 //  Boston, MA  02110-1301  USA
20 //
21 //  http://sourceforge.net/projects/zbar
22 //------------------------------------------------------------------------
23 #include "EXTERN.h"
24 #include "perl.h"
25 #include "XSUB.h"
26 
27 #include "ppport.h"
28 
29 #include <zbar.h>
30 
31 typedef zbar_symbol_t *Barcode__ZBar__Symbol;
32 typedef zbar_image_t *Barcode__ZBar__Image;
33 typedef zbar_processor_t *Barcode__ZBar__Processor;
34 typedef zbar_video_t *Barcode__ZBar__Video;
35 typedef zbar_window_t *Barcode__ZBar__Window;
36 typedef zbar_image_scanner_t *Barcode__ZBar__ImageScanner;
37 typedef zbar_decoder_t *Barcode__ZBar__Decoder;
38 typedef zbar_scanner_t *Barcode__ZBar__Scanner;
39 typedef void *Barcode__ZBar__Error;
40 
41 typedef unsigned long fourcc_t;
42 typedef int timeout_t;
43 typedef int config_error;
44 
45 typedef struct handler_wrapper_s {
46     SV *instance;
47     SV *handler;
48     SV *closure;
49 } handler_wrapper_t;
50 
51 
52 static AV *LOOKUP_zbar_color_t = NULL;
53 static AV *LOOKUP_zbar_symbol_type_t = NULL;
54 static AV *LOOKUP_zbar_error_t = NULL;
55 static AV *LOOKUP_zbar_config_t = NULL;
56 static AV *LOOKUP_zbar_modifier_t = NULL;
57 static AV *LOOKUP_zbar_orientation_t = NULL;
58 
59 #define CONSTANT(typ, prefix, sym, name)                \
60     do {                                                \
61         SV *c = newSViv(ZBAR_ ## prefix ## sym);        \
62         sv_setpv(c, name);                              \
63         SvIOK_on(c);                                    \
64         newCONSTSUB(stash, #sym, c);                    \
65         av_store(LOOKUP_zbar_ ## typ ## _t,             \
66                  ZBAR_ ## prefix ## sym,                \
67                  SvREFCNT_inc(c));                      \
68     } while(0)
69 
70 #define LOOKUP_ENUM(typ, val) \
71     lookup_enum(LOOKUP_zbar_ ## typ ## _t, val)
72 
lookup_enum(AV * lookup,int val)73 static inline SV *lookup_enum (AV *lookup, int val)
74 {
75     SV **tmp = av_fetch(lookup, val, 0);
76     return((tmp) ? *tmp : sv_newmortal());
77 }
78 
check_error(int rc,void * obj)79 static inline void check_error (int rc, void *obj)
80 {
81     if(rc < 0) {
82         sv_setref_pv(get_sv("@", TRUE), "Barcode::ZBar::Error", obj);
83         croak(NULL);
84     }
85 }
86 
87 #define PUSH_SYMS(x)                                                    \
88     do {                                                                \
89         const zbar_symbol_t *sym = (const zbar_symbol_t*)(x);           \
90         for(; sym; sym = zbar_symbol_next(sym)) {                       \
91             zbar_symbol_t *s = (zbar_symbol_t*)sym;                     \
92             zbar_symbol_ref(s, 1);                                      \
93             XPUSHs(sv_setref_pv(sv_newmortal(), "Barcode::ZBar::Symbol", \
94                                 (void*)sym));                           \
95         }                                                               \
96     } while(0);
97 
98 #define PUSH_ENUM_MASK(typ, TYP, val)                         \
99     do {                                                      \
100         unsigned mask = (val);                                \
101         int i;                                                \
102         for(i = 0; i < ZBAR_ ## TYP ## _NUM; i++, mask >>= 1) \
103             if(mask & 1)                                      \
104                 XPUSHs(LOOKUP_ENUM(typ, i));                  \
105     } while(0);
106 
image_cleanup_handler(zbar_image_t * image)107 static void image_cleanup_handler (zbar_image_t *image)
108 {
109     SV *data = zbar_image_get_userdata(image);
110     if(!data)
111         /* FIXME this is internal error */
112         return;
113 
114     /* release reference to cleanup data */
115     SvREFCNT_dec(data);
116 }
117 
set_handler(handler_wrapper_t ** wrapp,SV * instance,SV * handler,SV * closure)118 static inline int set_handler (handler_wrapper_t **wrapp,
119                                SV *instance,
120                                SV *handler,
121                                SV *closure)
122 {
123     handler_wrapper_t *wrap = *wrapp;
124     if(!handler || !SvOK(handler)) {
125         if(wrap) {
126             if(wrap->instance) SvREFCNT_dec(wrap->instance);
127             if(wrap->handler) SvREFCNT_dec(wrap->handler);
128             if(wrap->closure) SvREFCNT_dec(wrap->closure);
129             wrap->instance = wrap->handler = wrap->closure = NULL;
130         }
131         return(0);
132     }
133 
134     if(!wrap) {
135         Newxz(wrap, 1, handler_wrapper_t);
136         wrap->instance = newSVsv(instance);
137         wrap->closure = newSV(0);
138         *wrapp = wrap;
139     }
140 
141     if(wrap->handler)
142         SvSetSV(wrap->handler, handler);
143     else
144         wrap->handler = newSVsv(handler);
145 
146     if(!closure || !SvOK(closure))
147         SvSetSV(wrap->closure, &PL_sv_undef);
148     else
149         SvSetSV(wrap->closure, closure);
150     return(1);
151 }
152 
activate_handler(handler_wrapper_t * wrap,SV * param)153 static inline void activate_handler (handler_wrapper_t *wrap,
154                                      SV *param)
155 {
156     dSP;
157     if(!wrap)
158         /* FIXME this is internal error */
159         return;
160 
161     ENTER;
162     SAVETMPS;
163 
164     PUSHMARK(SP);
165     EXTEND(SP, 3);
166     PUSHs(sv_mortalcopy(wrap->instance));
167     if(param)
168         PUSHs(param);
169     PUSHs(sv_mortalcopy(wrap->closure));
170     PUTBACK;
171 
172     call_sv(wrap->handler, G_DISCARD);
173 
174     FREETMPS;
175     LEAVE;
176 }
177 
processor_handler(zbar_image_t * image,const void * userdata)178 static void processor_handler (zbar_image_t *image,
179                                const void *userdata)
180 {
181     SV *img;
182     zbar_image_ref(image, 1);
183     img = sv_setref_pv(newSV(0), "Barcode::ZBar::Image", image);
184     activate_handler((void*)userdata, img);
185     SvREFCNT_dec(img);
186 }
187 
decoder_handler(zbar_decoder_t * decoder)188 static void decoder_handler (zbar_decoder_t *decoder)
189 {
190     activate_handler(zbar_decoder_get_userdata(decoder), NULL);
191 }
192 
193 
194 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar		PREFIX = zbar_
195 
196 PROTOTYPES: ENABLE
197 
198 BOOT:
199     {
200         HV *stash = gv_stashpv("Barcode::ZBar", TRUE);
201 
202         LOOKUP_zbar_color_t = newAV();
203         CONSTANT(color, , SPACE, "SPACE");
204         CONSTANT(color, , BAR, "BAR");
205     }
206 
207 SV *
208 zbar_version()
209     PREINIT:
210 	unsigned major;
211         unsigned minor;
212     CODE:
213         zbar_version(&major, &minor, NULL);
214         RETVAL = newSVpvf("%u.%u", major, minor);
215     OUTPUT:
216         RETVAL
217 
218 void
219 zbar_increase_verbosity()
220 
221 void
222 zbar_set_verbosity(verbosity)
223 	int	verbosity
224 
225 SV *
226 parse_config(config_string)
227         const char *	config_string
228     PREINIT:
229         zbar_symbol_type_t sym;
230         zbar_config_t cfg;
231         int val;
232     PPCODE:
233         if(zbar_parse_config(config_string, &sym, &cfg, &val))
234             croak("invalid configuration setting: %s", config_string);
235         EXTEND(SP, 3);
236         PUSHs(LOOKUP_ENUM(symbol_type, sym));
237         PUSHs(LOOKUP_ENUM(config, cfg));
238         mPUSHi(val);
239 
240 
241 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Error	PREFIX = zbar_
242 
243 BOOT:
244     {
245         HV *stash = gv_stashpv("Barcode::ZBar::Error", TRUE);
246 
247         LOOKUP_zbar_error_t = newAV();
248         CONSTANT(error, ERR_, NOMEM, "out of memory");
249         CONSTANT(error, ERR_, INTERNAL, "internal library error");
250         CONSTANT(error, ERR_, UNSUPPORTED, "unsupported request");
251         CONSTANT(error, ERR_, INVALID, "invalid request");
252         CONSTANT(error, ERR_, SYSTEM, "system error");
253         CONSTANT(error, ERR_, LOCKING, "locking error");
254         CONSTANT(error, ERR_, BUSY, "all resources busy");
255         CONSTANT(error, ERR_, XDISPLAY, "X11 display error");
256         CONSTANT(error, ERR_, XPROTO, "X11 protocol error");
257         CONSTANT(error, ERR_, CLOSED, "output window is closed");
258         CONSTANT(error, ERR_, WINAPI, "windows system error");
259     }
260 
261 zbar_error_t
262 get_error_code(err)
263 	Barcode::ZBar::Error	err
264     CODE:
265 	RETVAL = _zbar_get_error_code(err);
266     OUTPUT:
267 	RETVAL
268 
269 const char *
270 error_string(err)
271 	Barcode::ZBar::Error	err
272     CODE:
273 	RETVAL = _zbar_error_string(err, 1);
274     OUTPUT:
275 	RETVAL
276 
277 
278 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Config	PREFIX = zbar_config_
279 
280 BOOT:
281     {
282         HV *stash = gv_stashpv("Barcode::ZBar::Config", TRUE);
283 
284         LOOKUP_zbar_config_t = newAV();
285         CONSTANT(config, CFG_, ENABLE, "enable");
286         CONSTANT(config, CFG_, ADD_CHECK, "add-check");
287         CONSTANT(config, CFG_, EMIT_CHECK, "emit-check");
288         CONSTANT(config, CFG_, ASCII, "ascii");
289         CONSTANT(config, CFG_, MIN_LEN, "min-length");
290         CONSTANT(config, CFG_, MAX_LEN, "max-length");
291         CONSTANT(config, CFG_, UNCERTAINTY, "uncertainty");
292         CONSTANT(config, CFG_, POSITION, "position");
293         CONSTANT(config, CFG_, X_DENSITY, "x-density");
294         CONSTANT(config, CFG_, Y_DENSITY, "y-density");
295     }
296 
297 MODULE = Barcode::ZBar  PACKAGE = Barcode::ZBar::Modifier  PREFIX = zbar_mod_
298 
299 BOOT:
300     {
301         HV *stash = gv_stashpv("Barcode::ZBar::Modifier", TRUE);
302 
303         LOOKUP_zbar_modifier_t = newAV();
304         CONSTANT(modifier, MOD_, GS1, "GS1");
305         CONSTANT(modifier, MOD_, AIM, "AIM");
306     }
307 
308 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Orient	PREFIX = zbar_orientation_
309 
310 BOOT:
311     {
312         HV *stash = gv_stashpv("Barcode::ZBar::Orient", TRUE);
313 
314         LOOKUP_zbar_orientation_t = newAV();
315         CONSTANT(orientation, ORIENT_, UNKNOWN, "UNKNOWN");
316         CONSTANT(orientation, ORIENT_, UP, "UP");
317         CONSTANT(orientation, ORIENT_, RIGHT, "RIGHT");
318         CONSTANT(orientation, ORIENT_, DOWN, "DOWN");
319         CONSTANT(orientation, ORIENT_, LEFT, "LEFT");
320     }
321 
322 
323 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Symbol	PREFIX = zbar_symbol_
324 
325 BOOT:
326     {
327         HV *stash = gv_stashpv("Barcode::ZBar::Symbol", TRUE);
328 
329         LOOKUP_zbar_symbol_type_t = newAV();
330         CONSTANT(symbol_type, , NONE, "None");
331         CONSTANT(symbol_type, , PARTIAL, "Partial");
332         CONSTANT(symbol_type, , EAN8, zbar_get_symbol_name(ZBAR_EAN8));
333         CONSTANT(symbol_type, , UPCE, zbar_get_symbol_name(ZBAR_UPCE));
334         CONSTANT(symbol_type, , ISBN10, zbar_get_symbol_name(ZBAR_ISBN10));
335         CONSTANT(symbol_type, , UPCA, zbar_get_symbol_name(ZBAR_UPCA));
336         CONSTANT(symbol_type, , EAN13, zbar_get_symbol_name(ZBAR_EAN13));
337         CONSTANT(symbol_type, , ISBN13, zbar_get_symbol_name(ZBAR_ISBN13));
338         CONSTANT(symbol_type, , DATABAR, zbar_get_symbol_name(ZBAR_DATABAR));
339         CONSTANT(symbol_type, , DATABAR_EXP,
340                  zbar_get_symbol_name(ZBAR_DATABAR_EXP));
341         CONSTANT(symbol_type, , I25, zbar_get_symbol_name(ZBAR_I25));
342         CONSTANT(symbol_type, , CODABAR, zbar_get_symbol_name(ZBAR_CODABAR));
343         CONSTANT(symbol_type, , CODE39, zbar_get_symbol_name(ZBAR_CODE39));
344         CONSTANT(symbol_type, , PDF417, zbar_get_symbol_name(ZBAR_PDF417));
345         CONSTANT(symbol_type, , QRCODE, zbar_get_symbol_name(ZBAR_QRCODE));
346         CONSTANT(symbol_type, , CODE93, zbar_get_symbol_name(ZBAR_CODE93));
347         CONSTANT(symbol_type, , CODE128, zbar_get_symbol_name(ZBAR_CODE128));
348     }
349 
350 void
351 DESTROY(symbol)
352         Barcode::ZBar::Symbol symbol
353     CODE:
354         zbar_symbol_ref(symbol, -1);
355 
356 zbar_symbol_type_t
357 zbar_symbol_get_type(symbol)
358 	Barcode::ZBar::Symbol symbol
359 
360 SV *
361 zbar_symbol_get_configs(symbol)
362 	Barcode::ZBar::Symbol	symbol
363     PPCODE:
364         PUSH_ENUM_MASK(config, CFG, zbar_symbol_get_configs(symbol));
365 
366 SV *
367 zbar_symbol_get_modifiers(symbol)
368 	Barcode::ZBar::Symbol	symbol
369     PPCODE:
370         PUSH_ENUM_MASK(modifier, MOD, zbar_symbol_get_modifiers(symbol));
371 
372 SV *
373 zbar_symbol_get_data(symbol)
374 	Barcode::ZBar::Symbol symbol
375     CODE:
376 	RETVAL = newSVpvn(zbar_symbol_get_data(symbol),
377                           zbar_symbol_get_data_length(symbol));
378     OUTPUT:
379         RETVAL
380 
381 int
382 zbar_symbol_get_count(symbol)
383 	Barcode::ZBar::Symbol symbol
384 
385 int
386 zbar_symbol_get_quality(symbol)
387 	Barcode::ZBar::Symbol symbol
388 
389 SV *
390 zbar_symbol_get_loc(symbol)
391 	Barcode::ZBar::Symbol symbol
392     PREINIT:
393         unsigned i, size;
394     PPCODE:
395         size = zbar_symbol_get_loc_size(symbol);
396         EXTEND(SP, size);
397         for(i = 0; i < size; i++) {
398             AV *pt = (AV*)sv_2mortal((SV*)newAV());
399             PUSHs(newRV((SV*)pt));
400             av_push(pt, newSVuv(zbar_symbol_get_loc_x(symbol, i)));
401             av_push(pt, newSVuv(zbar_symbol_get_loc_y(symbol, i)));
402         }
403 
404 zbar_orientation_t
405 zbar_symbol_get_orientation(symbol)
406 	Barcode::ZBar::Symbol symbol
407 
408 SV *
409 get_components(symbol)
410         Barcode::ZBar::Symbol	symbol
411     PPCODE:
412         PUSH_SYMS(zbar_symbol_first_component(symbol));
413 
414 
415 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Image	PREFIX = zbar_image_
416 
417 Barcode::ZBar::Image
418 new(package)
419         char *	package
420     CODE:
421         RETVAL = zbar_image_create();
422     OUTPUT:
423         RETVAL
424 
425 void
426 DESTROY(image)
427         Barcode::ZBar::Image	image
428     CODE:
429         zbar_image_destroy(image);
430 
431 Barcode::ZBar::Image
432 zbar_image_convert(image, format)
433         Barcode::ZBar::Image	image
434 	fourcc_t	format
435 
436 Barcode::ZBar::Image
437 zbar_image_convert_resize(image, format, width, height)
438         Barcode::ZBar::Image	image
439 	fourcc_t	format
440 	unsigned width
441 	unsigned height
442 
443 fourcc_t
444 zbar_image_get_format(image)
445         Barcode::ZBar::Image	image
446 
447 unsigned
448 zbar_image_get_sequence(image)
449         Barcode::ZBar::Image	image
450 
451 void
452 get_size(image)
453         Barcode::ZBar::Image	image
454     PPCODE:
455         EXTEND(SP, 2);
456         mPUSHu(zbar_image_get_width(image));
457         mPUSHu(zbar_image_get_height(image));
458 
459 void
460 get_crop(image)
461         Barcode::ZBar::Image	image
462     PREINIT:
463         unsigned x, y, w, h;
464     PPCODE:
465         zbar_image_get_crop(image, &x, &y, &w, &h);
466         EXTEND(SP, 4);
467         mPUSHu(x);
468         mPUSHu(y);
469         mPUSHu(w);
470         mPUSHu(h);
471 
472 SV *
473 zbar_image_get_data(image)
474         Barcode::ZBar::Image	image
475     CODE:
476 	RETVAL = newSVpvn(zbar_image_get_data(image),
477                           zbar_image_get_data_length(image));
478     OUTPUT:
479         RETVAL
480 
481 SV *
482 get_symbols(image)
483         Barcode::ZBar::Image	image
484     PPCODE:
485         PUSH_SYMS(zbar_image_first_symbol(image));
486 
487 void
488 zbar_image_set_format(image, format)
489         Barcode::ZBar::Image	image
490 	fourcc_t	format
491 
492 void
493 zbar_image_set_sequence(image, seq_num)
494         Barcode::ZBar::Image	image
495 	unsigned	seq_num
496 
497 void
498 zbar_image_set_size(image, width, height)
499         Barcode::ZBar::Image	image
500         int	width + if(width < 0) width = 0;
501         int	height + if(height < 0) height = 0;
502 
503 void
504 zbar_image_set_crop(image, x, y, width, height)
505         Barcode::ZBar::Image	image
506         int	x + if(x < 0) { width += x; x = 0; }
507         int	y + if(y < 0) { height += y; y = 0; }
508         int	width
509         int	height
510 
511 void
512 zbar_image_set_data(image, data)
513         Barcode::ZBar::Image	image
514 	SV *	data
515     PREINIT:
516         SV *old;
517     CODE:
518 	if(!data || !SvOK(data)) {
519             zbar_image_set_data(image, NULL, 0, NULL);
520             zbar_image_set_userdata(image, NULL);
521         }
522         else if(SvPOK(data)) {
523             /* FIXME is this copy of data or new ref to same data?
524              * not sure this is correct:
525              * need to retain a reference to image data,
526              * but do not really want to copy it...maybe an RV?
527              */
528             SV *copy = newSVsv(data);
529             STRLEN len;
530             void *raw = SvPV(copy, len);
531             zbar_image_set_data(image, raw, len, image_cleanup_handler);
532             zbar_image_set_userdata(image, copy);
533         }
534         else
535             croak("image data must be binary string");
536 
537 
538 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Processor	PREFIX = zbar_processor_
539 
540 Barcode::ZBar::Processor
541 new(package, threaded=0)
542         char *	package
543         bool	threaded
544     CODE:
545         RETVAL = zbar_processor_create(threaded);
546     OUTPUT:
547         RETVAL
548 
549 void
550 DESTROY(processor)
551         Barcode::ZBar::Processor	processor
552     CODE:
553         zbar_processor_destroy(processor);
554 
555 void
556 zbar_processor_init(processor, video_device="", enable_display=1)
557         Barcode::ZBar::Processor	processor
558         const char *	video_device
559 	bool	enable_display
560     CODE:
561         check_error(zbar_processor_init(processor, video_device, enable_display),
562                     processor);
563 
564 void
565 zbar_processor_request_size(processor, width, height)
566         Barcode::ZBar::Processor	processor
567 	unsigned	width
568 	unsigned	height
569     CODE:
570 	check_error(zbar_processor_request_size(processor, width, height),
571                     processor);
572 
573 void
574 zbar_processor_force_format(processor, input_format=0, output_format=0)
575         Barcode::ZBar::Processor	processor
576 	fourcc_t	input_format
577 	fourcc_t	output_format
578     CODE:
579 	check_error(zbar_processor_force_format(processor, input_format, output_format),
580                     processor);
581 
582 void
583 zbar_processor_set_config(processor, symbology, config, value=1)
584         Barcode::ZBar::Processor	processor
585 	zbar_symbol_type_t	symbology
586 	zbar_config_t	config
587 	int	value
588 
589 config_error
590 zbar_processor_parse_config(processor, config_string)
591         Barcode::ZBar::Processor	processor
592         const char *config_string
593 
594 bool
595 zbar_processor_is_visible(processor)
596         Barcode::ZBar::Processor	processor
597     CODE:
598 	check_error((RETVAL = zbar_processor_is_visible(processor)),
599                     processor);
600     OUTPUT:
601 	RETVAL
602 
603 void
604 zbar_processor_set_visible(processor, visible=1)
605         Barcode::ZBar::Processor	processor
606 	bool	visible
607     CODE:
608 	check_error(zbar_processor_set_visible(processor, visible),
609                     processor);
610 
611 void
612 zbar_processor_set_active(processor, active=1)
613         Barcode::ZBar::Processor	processor
614 	bool	active
615     CODE:
616 	check_error(zbar_processor_set_active(processor, active),
617                     processor);
618 
619 SV *
620 get_results(processor)
621         Barcode::ZBar::Processor	processor
622     PREINIT:
623         const zbar_symbol_set_t	*syms;
624     PPCODE:
625         syms = zbar_processor_get_results(processor);
626         PUSH_SYMS(zbar_symbol_set_first_symbol(syms));
627         zbar_symbol_set_ref(syms, -1);
628 
629 int
630 zbar_processor_user_wait(processor, timeout=-1)
631         Barcode::ZBar::Processor	processor
632 	timeout_t	timeout
633     CODE:
634 	check_error((RETVAL = zbar_processor_user_wait(processor, timeout)),
635                     processor);
636     OUTPUT:
637 	RETVAL
638 
639 int
640 process_one(processor, timeout=-1)
641         Barcode::ZBar::Processor	processor
642 	timeout_t	timeout
643     CODE:
644 	check_error((RETVAL = zbar_process_one(processor, timeout)),
645                     processor);
646     OUTPUT:
647 	RETVAL
648 
649 int
650 process_image(processor, image)
651         Barcode::ZBar::Processor	processor
652         Barcode::ZBar::Image	image
653     CODE:
654 	check_error((RETVAL = zbar_process_image(processor, image)),
655                     processor);
656     OUTPUT:
657 	RETVAL
658 
659 void
660 zbar_processor_set_data_handler(processor, handler = 0, closure = 0)
661         Barcode::ZBar::Processor	processor
662 	SV *	handler
663 	SV *	closure
664     PREINIT:
665         handler_wrapper_t *wrap;
666         zbar_image_data_handler_t *callback = NULL;
667     CODE:
668         wrap = zbar_processor_get_userdata(processor);
669         if(set_handler(&wrap, ST(0), handler, closure))
670             callback = processor_handler;
671         zbar_processor_set_data_handler(processor, callback, wrap);
672 
673 
674 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::ImageScanner	PREFIX = zbar_image_scanner_
675 
676 Barcode::ZBar::ImageScanner
677 new(package)
678         char *	package
679     CODE:
680         RETVAL = zbar_image_scanner_create();
681     OUTPUT:
682         RETVAL
683 
684 void
685 DESTROY(scanner)
686         Barcode::ZBar::ImageScanner	scanner
687     CODE:
688         zbar_image_scanner_destroy(scanner);
689 
690 void
691 zbar_image_scanner_set_config(scanner, symbology, config, value=1)
692         Barcode::ZBar::ImageScanner	scanner
693 	zbar_symbol_type_t	symbology
694 	zbar_config_t	config
695 	int	value
696 
697 config_error
698 zbar_image_scanner_parse_config(scanner, config_string)
699         Barcode::ZBar::ImageScanner	scanner
700         const char *config_string
701 
702 void
703 zbar_image_scanner_enable_cache(scanner, enable)
704         Barcode::ZBar::ImageScanner	scanner
705 	int	enable
706 
707 void
708 zbar_image_scanner_recycle_image(scanner, image)
709         Barcode::ZBar::ImageScanner	scanner
710         Barcode::ZBar::Image	image
711 
712 SV *
713 get_results(scanner)
714         Barcode::ZBar::ImageScanner	scanner
715     PREINIT:
716         const zbar_symbol_set_t	*syms;
717     PPCODE:
718         syms = zbar_image_scanner_get_results(scanner);
719         PUSH_SYMS(zbar_symbol_set_first_symbol(syms));
720 
721 int
722 scan_image(scanner, image)
723         Barcode::ZBar::ImageScanner	scanner
724         Barcode::ZBar::Image	image
725     CODE:
726 	RETVAL = zbar_scan_image(scanner, image);
727     OUTPUT:
728 	RETVAL
729 
730 
731 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Decoder	PREFIX = zbar_decoder_
732 
733 Barcode::ZBar::Decoder
734 new(package)
735         char *	package
736     CODE:
737         RETVAL = zbar_decoder_create();
738     OUTPUT:
739         RETVAL
740 
741 void
742 DESTROY(decoder)
743         Barcode::ZBar::Decoder	decoder
744     CODE:
745         /* FIXME cleanup handler wrapper */
746         zbar_decoder_destroy(decoder);
747 
748 void
749 zbar_decoder_set_config(decoder, symbology, config, value=1)
750         Barcode::ZBar::Decoder	decoder
751 	zbar_symbol_type_t	symbology
752 	zbar_config_t	config
753 	int	value
754 
755 config_error
756 zbar_decoder_parse_config(decoder, config_string)
757         Barcode::ZBar::Decoder decoder
758         const char *config_string
759 
760 void
761 zbar_decoder_reset(decoder)
762         Barcode::ZBar::Decoder	decoder
763 
764 void
765 zbar_decoder_new_scan(decoder)
766 	Barcode::ZBar::Decoder	decoder
767 
768 zbar_symbol_type_t
769 decode_width(decoder, width)
770 	Barcode::ZBar::Decoder	decoder
771 	unsigned	width
772     CODE:
773 	RETVAL = zbar_decode_width(decoder, width);
774     OUTPUT:
775 	RETVAL
776 
777 zbar_color_t
778 zbar_decoder_get_color(decoder)
779 	Barcode::ZBar::Decoder	decoder
780 
781 SV *
782 zbar_decoder_get_data(decoder)
783 	Barcode::ZBar::Decoder	decoder
784     CODE:
785 	RETVAL = newSVpvn(zbar_decoder_get_data(decoder),
786                           zbar_decoder_get_data_length(decoder));
787     OUTPUT:
788         RETVAL
789 
790 zbar_symbol_type_t
791 zbar_decoder_get_type(decoder)
792 	Barcode::ZBar::Decoder	decoder
793 
794 SV *
795 zbar_decoder_get_configs(decoder, symbology)
796 	Barcode::ZBar::Decoder	decoder
797         zbar_symbol_type_t	symbology
798     PPCODE:
799         if(symbology == ZBAR_NONE)
800             symbology = zbar_decoder_get_type(decoder);
801         PUSH_ENUM_MASK(config, CFG, zbar_decoder_get_configs(decoder, symbology));
802 
803 SV *
804 zbar_decoder_get_modifiers(decoder)
805 	Barcode::ZBar::Decoder	decoder
806     PPCODE:
807         PUSH_ENUM_MASK(modifier, MOD, zbar_decoder_get_modifiers(decoder));
808 
809 int
810 zbar_decoder_get_direction(decoder)
811 	Barcode::ZBar::Decoder	decoder
812 
813 void
814 zbar_decoder_set_handler(decoder, handler = 0, closure = 0)
815 	Barcode::ZBar::Decoder	decoder
816 	SV *	handler
817 	SV *	closure
818     PREINIT:
819         handler_wrapper_t *wrap;
820     CODE:
821         wrap = zbar_decoder_get_userdata(decoder);
822         zbar_decoder_set_handler(decoder, NULL);
823         if(set_handler(&wrap, ST(0), handler, closure)) {
824             zbar_decoder_set_userdata(decoder, wrap);
825             zbar_decoder_set_handler(decoder, decoder_handler);
826         }
827 
828 
829 MODULE = Barcode::ZBar	PACKAGE = Barcode::ZBar::Scanner	PREFIX = zbar_scanner_
830 
831 Barcode::ZBar::Scanner
832 new(package, decoder = 0)
833         char *	package
834         Barcode::ZBar::Decoder	decoder
835     CODE:
836         RETVAL = zbar_scanner_create(decoder);
837     OUTPUT:
838         RETVAL
839 
840 void
841 DESTROY(scanner)
842         Barcode::ZBar::Scanner	scanner
843     CODE:
844         zbar_scanner_destroy(scanner);
845 
846 zbar_symbol_type_t
847 zbar_scanner_reset(scanner)
848 	Barcode::ZBar::Scanner	scanner
849 
850 zbar_symbol_type_t
851 zbar_scanner_new_scan(scanner)
852 	Barcode::ZBar::Scanner	scanner
853 
854 zbar_color_t
855 zbar_scanner_get_color(scanner)
856 	Barcode::ZBar::Scanner	scanner
857 
858 unsigned
859 zbar_scanner_get_width(scanner)
860 	Barcode::ZBar::Scanner	scanner
861 
862 zbar_symbol_type_t
863 scan_y(scanner, y)
864 	Barcode::ZBar::Scanner	scanner
865 	int	y
866     CODE:
867 	RETVAL = zbar_scan_y(scanner, y);
868     OUTPUT:
869 	RETVAL
870