summaryrefslogtreecommitdiffstats
path: root/zbarcam/zbarcam.c
diff options
context:
space:
mode:
Diffstat (limited to 'zbarcam/zbarcam.c')
-rw-r--r--zbarcam/zbarcam.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/zbarcam/zbarcam.c b/zbarcam/zbarcam.c
new file mode 100644
index 0000000..040c030
--- /dev/null
+++ b/zbarcam/zbarcam.c
@@ -0,0 +1,375 @@
+/*------------------------------------------------------------------------
+ * Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ * This file is part of the ZBar Bar Code Reader.
+ *
+ * The ZBar Bar Code Reader is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The ZBar Bar Code Reader is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser Public License
+ * along with the ZBar Bar Code Reader; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#include <objbase.h>
+#endif
+#include <assert.h>
+
+#include <zbar.h>
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#define _(string) gettext(string)
+#else
+#define _(string) string
+#endif
+
+#define N_(string) string
+
+#define BELL "\a"
+
+static const char *note_usage = N_(
+ "usage: zbarcam [options] [/dev/video?]\n"
+ "\n"
+ "scan and decode bar codes from a video stream\n"
+ "\n"
+ "options:\n"
+ " -h, --help display this help text\n"
+ " --version display version information and exit\n"
+ " -q, --quiet disable beep when symbol is decoded\n"
+ " -v, --verbose increase debug output level\n"
+ " --verbose=N set specific debug output level\n"
+ " --xml use XML output format\n"
+ " --raw output decoded symbol data without converting charsets\n"
+ " -1, --oneshot exit after scanning one bar code\n"
+ " --nodisplay disable video display window\n"
+ " --prescale=<W>x<H>\n"
+ " request alternate video image size from driver\n"
+ " -S<CONFIG>[=<VALUE>], --set <CONFIG>[=<VALUE>]\n"
+ " set decoder/scanner <CONFIG> to <VALUE> (or 1)\n"
+ /* FIXME overlay level */
+ "\n");
+
+#ifdef HAVE_DBUS
+static const char *note_usage2 =
+ N_(" --nodbus disable dbus message\n");
+#endif
+
+static const char *xml_head =
+ "<barcodes xmlns='http://zbar.sourceforge.net/2008/barcode'>"
+ "<source device='%s'>\n";
+static const char *xml_foot = "</source></barcodes>\n";
+
+static zbar_processor_t *proc;
+static int quiet = 0, oneshot = 0;
+static enum
+{
+ DEFAULT,
+ RAW,
+ XML
+} format = DEFAULT;
+
+static char *xml_buf = NULL;
+static unsigned xml_len = 0;
+
+static int usage(int rc)
+{
+ FILE *out = (rc) ? stderr : stdout;
+ fprintf(out, "%s", _(note_usage));
+#ifdef HAVE_DBUS
+ fprintf(out, "%s", _(note_usage2));
+#endif
+ return (rc);
+}
+
+static inline int parse_config(const char *cfgstr, int i, int n, char *arg)
+{
+ if (i >= n || !*cfgstr) {
+ fprintf(stderr, "ERROR: need argument for option: %s\n", arg);
+ return (1);
+ }
+
+ if (zbar_processor_parse_config(proc, cfgstr)) {
+ fprintf(stderr, "ERROR: invalid configuration setting: %s\n", cfgstr);
+ return (1);
+ }
+ return (0);
+}
+
+static void data_handler(zbar_image_t *img, const void *userdata)
+{
+ int n = 0;
+ const zbar_symbol_t *sym = zbar_image_first_symbol(img);
+ assert(sym);
+ for (; sym; sym = zbar_symbol_next(sym)) {
+ zbar_symbol_type_t type;
+ if (zbar_symbol_get_count(sym))
+ continue;
+
+ type = zbar_symbol_get_type(sym);
+ if (type == ZBAR_PARTIAL)
+ continue;
+
+ if (!format) {
+ printf("%s:", zbar_get_symbol_name(type));
+ if (fwrite(zbar_symbol_get_data(sym),
+ zbar_symbol_get_data_length(sym), 1, stdout) != 1)
+ continue;
+ } else if (format == RAW) {
+ if (fwrite(zbar_symbol_get_data(sym),
+ zbar_symbol_get_data_length(sym), 1, stdout) != 1)
+ continue;
+ } else if (format == XML) {
+ if (!n)
+ printf("<index num='%u'>\n", zbar_image_get_sequence(img));
+ zbar_symbol_xml(sym, &xml_buf, &xml_len);
+ if (fwrite(xml_buf, xml_len, 1, stdout) != 1)
+ continue;
+ }
+ n++;
+
+ if (oneshot) {
+ if (format != RAW)
+ printf("\n");
+ break;
+ } else
+ printf("\n");
+ }
+
+ if (format == XML && n)
+ printf("</index>\n");
+ fflush(stdout);
+
+ if (!quiet && n)
+ fprintf(stderr, BELL);
+}
+
+int main(int argc, const char *argv[])
+{
+ const char *video_device;
+ int display;
+ unsigned long infmt, outfmt;
+ int i, active;
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+#ifdef DIRECTSHOW
+ HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (FAILED(res)) {
+ fprintf(stderr, "ERROR: failed to initialize COM library\n");
+ return (1);
+ }
+#endif
+
+ /* setup zbar library standalone processor,
+ * threads will be used if available
+ */
+ proc = zbar_processor_create(1);
+ if (!proc) {
+ fprintf(stderr, "ERROR: unable to allocate memory?\n");
+ return (1);
+ }
+ zbar_processor_set_data_handler(proc, data_handler, NULL);
+
+ video_device = "";
+#ifdef HAVE_DBUS
+ int dbus = 1;
+#endif
+ display = 1;
+ infmt = 0, outfmt = 0;
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] != '-')
+ video_device = argv[i];
+ else if (argv[i][1] != '-') {
+ int j;
+ for (j = 1; argv[i][j]; j++) {
+ if (argv[i][j] == 'S') {
+ if (!argv[i][++j]) {
+ i++;
+ j = 0;
+ }
+ if (parse_config(&argv[i][j], i, argc, "-S"))
+ return (usage(1));
+ break;
+ }
+ switch (argv[i][j]) {
+ case 'h':
+ return (usage(0));
+ case 'v':
+ zbar_increase_verbosity();
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case '1':
+ oneshot = 1;
+ break;
+ default:
+ fprintf(stderr, "ERROR: unknown bundled config: -%c\n\n",
+ argv[i][j]);
+ return (usage(1));
+ }
+ }
+ } else if (!argv[i][2]) {
+ if (i < argc - 1)
+ video_device = argv[argc - 1];
+ break;
+ } else if (!strcmp(argv[i], "--help"))
+ return (usage(0));
+ else if (!strcmp(argv[i], "--version"))
+ return (printf(PACKAGE_VERSION "\n") <= 0);
+ else if (!strcmp(argv[i], "--set")) {
+ i++;
+ if (parse_config(argv[i], i, argc, "--set"))
+ return (usage(1));
+ } else if (!strncmp(argv[i], "--set=", 6)) {
+ if (parse_config(&argv[i][6], i, argc, "--set="))
+ return (usage(1));
+ } else if (!strcmp(argv[i], "--quiet"))
+ quiet = 1;
+ else if (!strcmp(argv[i], "--oneshot"))
+ oneshot = 1;
+ else if (!strcmp(argv[i], "--xml"))
+ format = XML;
+ else if (!strcmp(argv[i], "--raw"))
+ format = RAW;
+ else if (!strcmp(argv[i], "--nodbus"))
+#ifdef HAVE_DBUS
+ dbus = 0;
+#else
+ ; /* silently ignore the option */
+#endif
+ else if (!strcmp(argv[i], "--nodisplay"))
+ display = 0;
+ else if (!strcmp(argv[i], "--verbose"))
+ zbar_increase_verbosity();
+ else if (!strncmp(argv[i], "--verbose=", 10))
+ zbar_set_verbosity(strtol(argv[i] + 10, NULL, 0));
+ else if (!strncmp(argv[i], "--prescale=", 11)) {
+ char *x = NULL;
+ long int w = strtol(argv[i] + 11, &x, 10);
+ long int h = 0;
+ if (x && *x == 'x')
+ h = strtol(x + 1, NULL, 10);
+ if (!w || !h || !x || *x != 'x') {
+ fprintf(stderr, "ERROR: invalid prescale: %s\n\n", argv[i]);
+ return (usage(1));
+ }
+ zbar_processor_request_size(proc, w, h);
+ } else if (!strncmp(argv[i], "--v4l=", 6)) {
+ long int v = strtol(argv[i] + 6, NULL, 0);
+ zbar_processor_request_interface(proc, v);
+ } else if (!strncmp(argv[i], "--iomode=", 9)) {
+ long int v = strtol(argv[i] + 9, NULL, 0);
+ zbar_processor_request_iomode(proc, v);
+ } else if (!strncmp(argv[i], "--infmt=", 8) && strlen(argv[i]) == 12)
+ infmt = (argv[i][8] | (argv[i][9] << 8) | (argv[i][10] << 16) |
+ (argv[i][11] << 24));
+ else if (!strncmp(argv[i], "--outfmt=", 9) && strlen(argv[i]) == 13)
+ outfmt = (argv[i][9] | (argv[i][10] << 8) | (argv[i][11] << 16) |
+ (argv[i][12] << 24));
+ else {
+ fprintf(stderr, "ERROR: unknown option argument: %s\n\n", argv[i]);
+ return (usage(1));
+ }
+ }
+
+ if (infmt || outfmt)
+ zbar_processor_force_format(proc, infmt, outfmt);
+
+#ifdef HAVE_DBUS
+ zbar_processor_request_dbus(proc, dbus);
+#endif
+
+ /* open video device, open window */
+ if (zbar_processor_init(proc, video_device, display) ||
+ /* show window */
+ (display && zbar_processor_set_visible(proc, 1)))
+ return (zbar_processor_error_spew(proc, 0));
+
+#ifdef _WIN32
+ if (format == XML || format == RAW) {
+ fflush(stdout);
+ if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
+ fprintf(stderr, "ERROR: failed to set stdout mode: %i\n", errno);
+ return (1);
+ }
+ }
+#endif
+
+ if (format == XML) {
+ printf(xml_head, video_device);
+ fflush(stdout);
+ }
+
+ /* start video */
+ active = 1;
+ if (zbar_processor_set_active(proc, active))
+ return (zbar_processor_error_spew(proc, 0));
+
+ if (oneshot) {
+ if (zbar_process_one(proc, -1) < 0)
+ if (zbar_processor_get_error_code(proc) != ZBAR_ERR_CLOSED)
+ return zbar_processor_error_spew(proc, 0);
+ } else {
+ /* let the callback handle data */
+ int rc;
+ while ((rc = zbar_processor_user_wait(proc, -1)) >= 0) {
+ if (rc == 'q' || rc == 'Q')
+ break;
+ // HACK: controls are known on V4L2 by ID, not by name. This is also
+ // not compatible with other platforms
+ if (rc == 'b' || rc == 'B') {
+ int value;
+ zbar_processor_get_control(proc, "Brightness", &value);
+ zbar_processor_set_control(proc, "Brightness", ++value);
+ }
+ if (rc == 'n' || rc == 'N') {
+ int value;
+ zbar_processor_get_control(proc, "Brightness", &value);
+ zbar_processor_set_control(proc, "Brightness", --value);
+ }
+ if (rc == ' ') {
+ active = !active;
+ if (zbar_processor_set_active(proc, active))
+ return (zbar_processor_error_spew(proc, 0));
+ }
+ }
+
+ /* report any errors that aren't "window closed" */
+ if (rc && rc != 'q' && rc != 'Q' &&
+ zbar_processor_get_error_code(proc) != ZBAR_ERR_CLOSED)
+ return (zbar_processor_error_spew(proc, 0));
+ }
+
+ /* free resources (leak check) */
+ zbar_processor_destroy(proc);
+
+ if (format == XML) {
+ printf("%s", xml_foot);
+ fflush(stdout);
+ }
+ return (0);
+}