示例#1
0
int zbar_processor_set_active (zbar_processor_t *proc,
                               int active)
{
    proc_enter(proc);

    int rc;
    if(!proc->video) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                         "video input not initialized");
        goto done;
    }
    _zbar_mutex_unlock(&proc->mutex);

    zbar_image_scanner_enable_cache(proc->scanner, active);

    rc = zbar_video_enable(proc->video, active);
    if(!rc) {
        _zbar_mutex_lock(&proc->mutex);
        proc->streaming = active;
        _zbar_mutex_unlock(&proc->mutex);
        rc = _zbar_processor_enable(proc);
    }
    else
        err_copy(proc, proc->video);

    if(!proc->streaming && proc->window) {
        if(zbar_window_draw(proc->window, NULL) && !rc)
            rc = err_copy(proc, proc->window);
        _zbar_processor_invalidate(proc);
    }

    _zbar_mutex_lock(&proc->mutex);
    if(proc->video_thread.started)
        _zbar_event_trigger(&proc->video_thread.notify);

 done:
    proc_leave(proc);
    return(rc);
}
示例#2
0
/* lock is already held */
static inline int process_image (zebra_processor_t *proc,
                                 zebra_image_t *img)
{
    if(img) {
        uint32_t format = zebra_image_get_format(img);
        zprintf(16, "processing: %.4s(%08" PRIx32 ") %dx%d @%p\n",
                (char*)&format, format,
                zebra_image_get_width(img), zebra_image_get_height(img),
                zebra_image_get_data(img));

        /* FIXME locking all other interfaces while processing is conservative
         * but easier for now and we don't expect this to take long...
         */
        int nsyms = zebra_scan_image(proc->scanner, img);
        if(nsyms < 0)
            return(err_capture(proc, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED,
                               __func__, "unknown image format"));

        if(_zebra_verbosity >= 8) {
            const zebra_symbol_t *sym = zebra_image_first_symbol(img);
            while(sym) {
                zebra_symbol_type_t type = zebra_symbol_get_type(sym);
                int count = zebra_symbol_get_count(sym);
                zprintf(8, "%s%s: %s (%s)\n",
                        zebra_get_symbol_name(type),
                        zebra_get_addon_name(type),
                        zebra_symbol_get_data(sym),
                        (count < 0) ? "uncertain" :
                        (count > 0) ? "duplicate" : "new");
                sym = zebra_symbol_next(sym);
            }
        }

        if(nsyms) {
            emit(proc, EVENT_OUTPUT);
            if(proc->handler)
                /* FIXME only call after filtering (unlocked...?) */
                proc->handler(img, proc->userdata);
        }

        if(proc->force_output) {
            img = zebra_image_convert(img, proc->force_output);
            if(!img)
                return(err_capture(proc, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED,
                                   __func__, "unknown image format"));
        }
    }

    /* display to window if enabled */
    if(proc->window &&
       (zebra_window_draw(proc->window, img) ||
        _zebra_window_invalidate(proc->window)))
        return(err_copy(proc, proc->window));
#if 0
    /* FIXME still don't understand why we need this */
    if(proc->window && _zebra_window_handle_events(proc, 0))
        return(-1);
#endif
    if(proc->force_output && img)
        zebra_image_destroy(img);
    return(0);
}
示例#3
0
int zebra_processor_init (zebra_processor_t *proc,
                          const char *dev,
                          int enable_display)
{
    if(proc_lock(proc) < 0)
        return(-1);
    proc_destroy_thread(proc->video_thread, &proc->video_started);
    proc_destroy_thread(proc->input_thread, &proc->input_started);
    proc->video_started = proc->input_started = 0;
    int rc = 0;
    if(proc->video) {
        if(dev)
            zebra_video_open(proc->video, NULL);
        else {
            zebra_video_destroy(proc->video);
            proc->video = NULL;
        }
    }
    if(proc->window) {
        zebra_window_destroy(proc->window);
        proc->window = NULL;
        _zebra_window_close(proc);
    }

    if(!dev && !enable_display)
        /* nothing to do */
        goto done;

    if(enable_display) {
        proc->window = zebra_window_create();
        if(!proc->window) {
            rc = err_copy(proc, proc->window);
            goto done;
        }
    }

    if(dev) {
        proc->video = zebra_video_create();
        if(!proc->video ||
           zebra_video_open(proc->video, dev)) {
            rc = err_copy(proc, proc->video);
            goto done;
        }
        if(zebra_video_get_fd(proc->video) < 0 && proc->threaded) {
#ifdef HAVE_LIBPTHREAD
            /* spawn blocking video thread */
            if((rc = pthread_create(&proc->video_thread, NULL,
                                    proc_video_thread, proc))) {
                rc = err_capture_num(proc, SEV_ERROR, ZEBRA_ERR_SYSTEM,
                                     __func__, "spawning video thread", rc);
                goto done;
            }
            proc->video_started = 1;
            zprintf(4, "spawned video thread\n");
#endif
        }
    }

#ifdef HAVE_LIBPTHREAD
    if(proc->threaded && (proc->window ||
                          (proc->video && !proc->video_started))) {
        /* spawn input monitor thread */
        if((rc = pthread_create(&proc->input_thread, NULL,
                                proc_input_thread, proc))) {
            rc = err_capture_num(proc, SEV_ERROR, ZEBRA_ERR_SYSTEM, __func__,
                                 "spawning input thread", rc);
            goto done;
        }
        proc->input_started = 1;
        zprintf(4, "spawned input thread\n");
    }
#endif

    if(proc->window) {
        /* arbitrary default */
        int width = 640, height = 480;
        if(proc->video) {
            width = zebra_video_get_width(proc->video);
            height = zebra_video_get_height(proc->video);
        }

        if(_zebra_window_open(proc, "zebra barcode reader", width, height)) {
            rc = -1;
            goto done;
        }
        else if(zebra_window_attach(proc->window, proc->display, proc->xwin)) {
            rc = err_copy(proc, proc->window);
            goto done;
        }
    }

    if(proc->video && proc->force_input) {
        if(zebra_video_init(proc->video, proc->force_input))
            rc = err_copy(proc, proc->video);
    }
    else if(proc->video)
        while(zebra_negotiate_format(proc->video, proc->window)) {
            if(proc->video && proc->window) {
                fprintf(stderr,
                        "WARNING: no compatible input to output format\n"
                        "...trying again with output disabled\n");
                zebra_window_destroy(proc->window);
                proc->window = NULL;
            }
            else {
                zprintf(1, "ERROR: no compatible %s format\n",
                        (proc->video) ? "video input" : "window output");
                rc = err_capture(proc, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED,
                                 __func__, "no compatible image format");
                goto done;
            }
        }

 done:
    proc_unlock(proc);
    return(rc);
}
示例#4
0
/* API lock is already held */
int _zbar_process_image (zbar_processor_t *proc,
                         zbar_image_t *img)
{
    uint32_t force_fmt = proc->force_output;
    if(img) {
        if(proc->dumping) {
            zbar_image_write(proc->window->image, "zbar");
            proc->dumping = 0;
        }

        uint32_t format = zbar_image_get_format(img);
        zprintf(16, "processing: %.4s(%08" PRIx32 ") %dx%d @%p\n",
                (char*)&format, format,
                zbar_image_get_width(img), zbar_image_get_height(img),
                zbar_image_get_data(img));

        /* FIXME locking all other interfaces while processing is conservative
         * but easier for now and we don't expect this to take long...
         */
        zbar_image_t *tmp = zbar_image_convert(img, fourcc('Y','8','0','0'));
        if(!tmp)
            goto error;

        if(proc->syms) {
            zbar_symbol_set_ref(proc->syms, -1);
            proc->syms = NULL;
        }
        zbar_image_scanner_recycle_image(proc->scanner, img);
        int nsyms = zbar_scan_image(proc->scanner, tmp);
        _zbar_image_swap_symbols(img, tmp);

        zbar_image_destroy(tmp);
        tmp = NULL;
        if(nsyms < 0)
            goto error;

        proc->syms = zbar_image_scanner_get_results(proc->scanner);
        if(proc->syms)
            zbar_symbol_set_ref(proc->syms, 1);

        if(_zbar_verbosity >= 8) {
            const zbar_symbol_t *sym = zbar_image_first_symbol(img);
            while(sym) {
                zbar_symbol_type_t type = zbar_symbol_get_type(sym);
                int count = zbar_symbol_get_count(sym);
                zprintf(8, "%s: %s (%d pts) (dir=%d) (q=%d) (%s)\n",
                        zbar_get_symbol_name(type),
                        zbar_symbol_get_data(sym),
                        zbar_symbol_get_loc_size(sym),
                        zbar_symbol_get_orientation(sym),
                        zbar_symbol_get_quality(sym),
                        (count < 0) ? "uncertain" :
                        (count > 0) ? "duplicate" : "new");
                sym = zbar_symbol_next(sym);
            }
        }

        if(nsyms) {
            /* FIXME only call after filtering */
            _zbar_mutex_lock(&proc->mutex);
            _zbar_processor_notify(proc, EVENT_OUTPUT);
            _zbar_mutex_unlock(&proc->mutex);
            if(proc->handler)
                proc->handler(img, proc->userdata);
        }

        if(force_fmt) {
            zbar_symbol_set_t *syms = img->syms;
            img = zbar_image_convert(img, force_fmt);
            if(!img)
                goto error;
            img->syms = syms;
            zbar_symbol_set_ref(syms, 1);
        }
    }

    /* display to window if enabled */
    int rc = 0;
    if(proc->window) {
        if((rc = zbar_window_draw(proc->window, img)))
            err_copy(proc, proc->window);
        _zbar_processor_invalidate(proc);
    }

    if(force_fmt && img)
        zbar_image_destroy(img);
    return(rc);

error:
    return(err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                       __func__, "unknown image format"));
}
示例#5
0
int zbar_processor_init (zbar_processor_t *proc,
                         const char *dev,
                         int enable_display)
{
    if(proc->video)
        zbar_processor_set_active(proc, 0);

    if(proc->window && !proc->input_thread.started)
        _zbar_processor_close(proc);

    _zbar_mutex_lock(&proc->mutex);
    _zbar_thread_stop(&proc->input_thread, &proc->mutex);
    _zbar_thread_stop(&proc->video_thread, &proc->mutex);

    _zbar_processor_lock(proc);
    _zbar_mutex_unlock(&proc->mutex);

    if(proc->window) {
        zbar_window_destroy(proc->window);
        proc->window = NULL;
    }

    int rc = 0;
    if(proc->video) {
        zbar_video_destroy(proc->video);
        proc->video = NULL;
    }

    if(!dev && !enable_display)
        /* nothing to do */
        goto done;

    if(enable_display) {
        proc->window = zbar_window_create();
        if(!proc->window) {
            rc = err_capture(proc, SEV_FATAL, ZBAR_ERR_NOMEM,
                             __func__, "allocating window resources");
            goto done;
        }
    }

    if(dev) {
        proc->video = zbar_video_create();
        if(!proc->video) {
            rc = err_capture(proc, SEV_FATAL, ZBAR_ERR_NOMEM,
                             __func__, "allocating video resources");
            goto done;
        }
        if(proc->req_width || proc->req_height)
            zbar_video_request_size(proc->video,
                                     proc->req_width, proc->req_height);
        if(proc->req_intf)
            zbar_video_request_interface(proc->video, proc->req_intf);
        if((proc->req_iomode &&
            zbar_video_request_iomode(proc->video, proc->req_iomode)) ||
           zbar_video_open(proc->video, dev)) {
            rc = err_copy(proc, proc->video);
            goto done;
        }
    }

    /* spawn blocking video thread */
    int video_threaded = (proc->threaded && proc->video &&
                          zbar_video_get_fd(proc->video) < 0);
    if(video_threaded &&
       _zbar_thread_start(&proc->video_thread, proc_video_thread, proc,
                          &proc->mutex)) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                         "spawning video thread");
        goto done;
    }

    /* spawn input monitor thread */
    int input_threaded = (proc->threaded &&
                          (proc->window ||
                           (proc->video && !video_threaded)));
    if(input_threaded &&
       _zbar_thread_start(&proc->input_thread, proc_input_thread, proc,
                          &proc->mutex)) {
        rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
                         "spawning input thread");
        goto done;
    }

    if(proc->window && !input_threaded &&
       (rc = proc_open(proc)))
        goto done;

    if(proc->video && proc->force_input) {
        if(zbar_video_init(proc->video, proc->force_input))
            rc = err_copy(proc, proc->video);
    }
    else if(proc->video) {
        int retry = -1;
        if(proc->window) {
            retry = zbar_negotiate_format(proc->video, proc->window);
            if(retry)
                fprintf(stderr,
                        "WARNING: no compatible input to output format\n"
                        "...trying again with output disabled\n");
        }
        if(retry)
            retry = zbar_negotiate_format(proc->video, NULL);

        if(retry) {
            zprintf(1, "ERROR: no compatible %s format\n",
                    (proc->video) ? "video input" : "window output");
            rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                             __func__, "no compatible image format");
        }
    }

 done:
    _zbar_mutex_lock(&proc->mutex);
    proc_leave(proc);
    return(rc);
}