Пример #1
0
const zbar_symbol_set_t*
zbar_processor_get_results (const zbar_processor_t *proc)
{
    zbar_processor_t *ncproc = (zbar_processor_t*)proc;
    proc_enter(ncproc);
    const zbar_symbol_set_t *syms = proc->syms;
    if(syms)
        zbar_symbol_set_ref(syms, 1);
    proc_leave(ncproc);
    return(syms);
}
Пример #2
0
JNIEXPORT jlong JNICALL
Java_net_sourceforge_zbar_Image_getSymbols (JNIEnv *env,
                                            jobject obj,
                                            jlong peer)
{
    const zbar_symbol_set_t *zsyms = zbar_image_get_symbols(PEER_CAST(peer));
    if(zsyms) {
        zbar_symbol_set_ref(zsyms, 1);
        stats.SymbolSet_create++;
    }
    return((intptr_t)zsyms);
}
Пример #3
0
void _zbar_symbol_free (zbar_symbol_t *sym)
{
    if(sym->syms) {
        zbar_symbol_set_ref(sym->syms, -1);
        sym->syms = NULL;
    }
    if(sym->pts)
        free(sym->pts);
    if(sym->data_alloc && sym->data)
        free(sym->data);
    free(sym);
}
Пример #4
0
zbarSymbolSet*
zbarSymbolSet_FromSymbolSet(const zbar_symbol_set_t *zsyms)
{
    zbarSymbolSet *self = PyObject_New(zbarSymbolSet, &zbarSymbolSet_Type);
    if(!self)
        return(NULL);
    if(zsyms) {
        zbar_symbol_set_t *ncsyms = (zbar_symbol_set_t*)zsyms;
        zbar_symbol_set_ref(ncsyms, 1);
    }
    self->zsyms = zsyms;
    return(self);
}
Пример #5
0
int zbar_scan_image (zbar_image_scanner_t *iscn,
					 zbar_image_t *img)
{
	/* timestamp image
	 * FIXME prefer video timestamp
	 */
#if _POSIX_TIMERS > 0
	struct timespec abstime;
	clock_gettime(CLOCK_REALTIME, &abstime);
	iscn->time = (abstime.tv_sec * 1000) + ((abstime.tv_nsec / 500000) + 1) / 2;
#else
	struct timeval abstime;
	gettimeofday(&abstime, NULL);
	iscn->time = (abstime.tv_sec * 1000) + ((abstime.tv_usec / 500) + 1) / 2;
#endif

#ifdef ENABLE_QRCODE
	_zbar_qr_reset(iscn->qr);
#endif

	/* get grayscale image, convert if necessary */
	if(img->format != fourcc('Y','8','0','0') &&
	   img->format != fourcc('G','R','E','Y')){
		printf("ERROR: zbar unsupported format: %x ", img->format);
		return(-1);
	}
	iscn->img = img;

	/* recycle previous scanner and image results */
	zbar_image_scanner_recycle_image(iscn, img);
	zbar_symbol_set_t *syms = iscn->syms;
	if(!syms) {
		syms = iscn->syms = _zbar_symbol_set_create();
		STAT(syms_new);
		zbar_symbol_set_ref(syms, 1);
	}
	else
		zbar_symbol_set_ref(syms, 2);
	img->syms = syms;

	unsigned w = img->width;
	unsigned h = img->height;
	const uint8_t *data = img->data;

	zbar_image_write_png(img, "debug.png");
	svg_open("debug.svg", 0, 0, w, h);
	svg_image("debug.png", w, h);

	zbar_scanner_t *scn = iscn->scn;

	int density = CFG(iscn, ZBAR_CFG_Y_DENSITY);
	if(density > 0) {
		svg_group_start("scanner", 0, 1, 1, 0, 0);
		const uint8_t *p = data;
		int x = 0, y = 0;
		iscn->dy = 0;

		int border = (((h - 1) % density) + 1) / 2;
		if(border > h / 2)
			border = h / 2;
		movedelta(0, border);
		iscn->v = y;

		zbar_scanner_new_scan(scn);

		while(y < h) {
			zprintf(128, "img_x+: %04d,%04d @%p\n", x, y, p);
			svg_path_start("vedge", 1. / 32, 0, y + 0.5);
			iscn->dx = iscn->du = 1;
			iscn->umin = 0;
			while(x < w) {
				uint8_t d = *p;
				movedelta(1, 0);
				zbar_scan_y(scn, d);
			}
			ASSERT_POS;
			quiet_border(iscn);
			svg_path_end();

			movedelta(-1, density);
			iscn->v = y;
			if(y >= h)
				break;

			zprintf(128, "img_x-: %04d,%04d @%p\n", x, y, p);
			svg_path_start("vedge", -1. / 32, w, y + 0.5);
			iscn->dx = iscn->du = -1;
			iscn->umin = w;
			while(x >= 0) {
				uint8_t d = *p;
				movedelta(-1, 0);
				zbar_scan_y(scn, d);
			}
			ASSERT_POS;
			quiet_border(iscn);
			svg_path_end();

			movedelta(1, density);
			iscn->v = y;
		}
		svg_group_end();
	}
	iscn->dx = 0;

	density = CFG(iscn, ZBAR_CFG_X_DENSITY);
	if(density > 0) {
		svg_group_start("scanner", 90, 1, -1, 0, 0);
		const uint8_t *p = data;
		int x = 0, y = 0;

		int border = (((w - 1) % density) + 1) / 2;
		if(border > w / 2)
			border = w / 2;
		movedelta(border, 0);
		iscn->v = x;

		while(x < w) {
			zprintf(128, "img_y+: %04d,%04d @%p\n", x, y, p);
			svg_path_start("vedge", 1. / 32, 0, x + 0.5);
			iscn->dy = iscn->du = 1;
			iscn->umin = 0;
			while(y < h) {
				uint8_t d = *p;
				movedelta(0, 1);
				zbar_scan_y(scn, d);
			}
			ASSERT_POS;
			quiet_border(iscn);
			svg_path_end();

			movedelta(density, -1);
			iscn->v = x;
			if(x >= w)
				break;

			zprintf(128, "img_y-: %04d,%04d @%p\n", x, y, p);
			svg_path_start("vedge", -1. / 32, h, x + 0.5);
			iscn->dy = iscn->du = -1;
			iscn->umin = h;
			while(y >= 0) {
				uint8_t d = *p;
				movedelta(0, -1);
				zbar_scan_y(scn, d);
			}
			ASSERT_POS;
			quiet_border(iscn);
			svg_path_end();

			movedelta(density, 1);
			iscn->v = x;
		}
		svg_group_end();
	}
	iscn->dy = 0;
	iscn->img = NULL;

#ifdef ENABLE_QRCODE
	_zbar_qr_decode(iscn->qr, iscn, img);
#endif

	/* FIXME tmp hack to filter bad EAN results */
	if(syms->nsyms && !iscn->enable_cache &&
	   (density == 1 || CFG(iscn, ZBAR_CFG_Y_DENSITY) == 1)) {
		zbar_symbol_t **symp = &syms->head, *sym;
		while((sym = *symp)) {
			if(sym->type < ZBAR_I25 && sym->type > ZBAR_PARTIAL &&
			   sym->quality < 3) {
				/* recycle */
				*symp = sym->next;
				syms->nsyms--;
				sym->next = NULL;
				_zbar_image_scanner_recycle_syms(iscn, sym);
			}
			else
				symp = &sym->next;
		}
	}

	if(syms->nsyms && iscn->handler)
		iscn->handler(img, iscn->userdata);

	svg_close();
	return(syms->nsyms);
}
Пример #6
0
inline int zbar_window_redraw (zbar_window_t *w)
{
    if(window_lock(w))
        return(-1);
    if(!w->display || _zbar_window_begin(w)) {
        (void)window_unlock(w);
        return(-1);
    }

    int rc = 0;
    zbar_image_t *img = w->image;
    if(w->init && w->draw_image && img) {
        int format_change = (w->src_format != img->format &&
                             w->format != img->format);
        if(format_change) {
            _zbar_best_format(img->format, &w->format, w->formats);
            if(!w->format)
                rc = err_capture_int(w, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__,
                                     "no conversion from %x to supported formats",
                                     img->format);
            w->src_format = img->format;
        }

        if(!rc && (format_change || !w->scaled_size.x || !w->dst_width)) {
            zprintf(24, "init: src=%.4s(%08lx) %dx%d dst=%.4s(%08lx) %dx%d\n",
                    (char*)&w->src_format, w->src_format,
                    w->src_width, w->src_height,
                    (char*)&w->format, w->format,
                    w->dst_width, w->dst_height);
            if(!w->dst_width) {
                w->src_width = img->width;
                w->src_height = img->height;
            }

            point_t size = { w->width, w->height };
            if(size.x > w->max_width)
                size.x = w->max_width;
            if(size.y > w->max_height)
                size.y = w->max_height;

            if(size.x * w->src_height < size.y * w->src_width) {
                w->scale_num = size.x;
                w->scale_den = w->src_width;
            }
            else {
                w->scale_num = size.y;
                w->scale_den = w->src_height;
            }

            rc = w->init(w, img, format_change);

            if(!rc) {
                size.x = w->src_width;
                size.y = w->src_height;
                w->scaled_size = size = window_scale_pt(w, size);
                w->scaled_offset.x = ((int)w->width - size.x) / 2;
                w->scaled_offset.y = ((int)w->height - size.y) / 2;
                zprintf(24, "scale: src=%dx%d win=%dx%d by %d/%d => %dx%d @%d,%d\n",
                        w->src_width, w->src_height, w->width, w->height,
                        w->scale_num, w->scale_den,
                        size.x, size.y, w->scaled_offset.x, w->scaled_offset.y);
            }
            else {
                /* unable to display this image */
                _zbar_image_refcnt(img, -1);
                w->image = img = NULL;
            }
        }

        if(!rc &&
                (img->format != w->format ||
                 img->width != w->dst_width ||
                 img->height != w->dst_height)) {
            /* save *converted* image for redraw */
            zprintf(48, "convert: %.4s(%08lx) %dx%d => %.4s(%08lx) %dx%d\n",
                    (char*)&img->format, img->format, img->width, img->height,
                    (char*)&w->format, w->format, w->dst_width, w->dst_height);
            w->image = zbar_image_convert_resize(img, w->format,
                                                 w->dst_width, w->dst_height);
            w->image->syms = img->syms;
            if(img->syms)
                zbar_symbol_set_ref(img->syms, 1);
            zbar_image_destroy(img);
            img = w->image;
        }

        if(!rc) {
            rc = w->draw_image(w, img);

            point_t org = w->scaled_offset;
            if(org.x > 0) {
                point_t p = { 0, org.y };
                point_t s = { org.x, w->scaled_size.y };
                _zbar_window_fill_rect(w, 0, p, s);
                s.x = w->width - w->scaled_size.x - s.x;
                if(s.x > 0) {
                    p.x = w->width - s.x;
                    _zbar_window_fill_rect(w, 0, p, s);
                }
            }
            if(org.y > 0) {
                point_t p = { 0, 0 };
                point_t s = { w->width, org.y };
                _zbar_window_fill_rect(w, 0, p, s);
                s.y = w->height - w->scaled_size.y - s.y;
                if(s.y > 0) {
                    p.y = w->height - s.y;
                    _zbar_window_fill_rect(w, 0, p, s);
                }
            }
        }
        if(!rc)
            rc = window_draw_overlay(w);
    }
    else
        rc = 1;

    if(rc)
        rc = _zbar_window_draw_logo(w);

    _zbar_window_end(w);
    (void)window_unlock(w);
    return(rc);
}
Пример #7
0
int zbar_scan_image (zbar_image_scanner_t *iscn,
                     zbar_image_t *img)
{
    zbar_symbol_set_t *syms;
    const uint8_t *data;
    zbar_scanner_t *scn = iscn->scn;
    unsigned w, h, cx1, cy1;
    int density;

    /* timestamp image
     * FIXME prefer video timestamp
     */
    iscn->time = _zbar_timer_now();

#ifdef ENABLE_QRCODE
    _zbar_qr_reset(iscn->qr);
#endif

    /* image must be in grayscale format */
    if(img->format != fourcc('Y','8','0','0') &&
       img->format != fourcc('G','R','E','Y'))
        return(-1);
    iscn->img = img;

    /* recycle previous scanner and image results */
    zbar_image_scanner_recycle_image(iscn, img);
    syms = iscn->syms;
    if(!syms) {
        syms = iscn->syms = _zbar_symbol_set_create();
        STAT(syms_new);
        zbar_symbol_set_ref(syms, 1);
    }
    else
        zbar_symbol_set_ref(syms, 2);
    img->syms = syms;

    w = img->width;
    h = img->height;
    cx1 = img->crop_x + img->crop_w;
    assert(cx1 <= w);
    cy1 = img->crop_y + img->crop_h;
    assert(cy1 <= h);
    data = img->data;

    zbar_image_write_png(img, "debug.png");
    svg_open("debug.svg", 0, 0, w, h);
    svg_image("debug.png", w, h);

    zbar_scanner_new_scan(scn);

    density = CFG(iscn, ZBAR_CFG_Y_DENSITY);
    if(density > 0) {
        const uint8_t *p = data;
        int x = 0, y = 0;

        int border = (((img->crop_h - 1) % density) + 1) / 2;
        if(border > img->crop_h / 2)
            border = img->crop_h / 2;
        border += img->crop_y;
        assert(border <= h);
        svg_group_start("scanner", 0, 1, 1, 0, 0);
        iscn->dy = 0;

        movedelta(img->crop_x, border);
        iscn->v = y;

        while(y < cy1) {
            int cx0 = img->crop_x;;
            zprintf(128, "img_x+: %04d,%04d @%p\n", x, y, p);
            svg_path_start("vedge", 1. / 32, 0, y + 0.5);
            iscn->dx = iscn->du = 1;
            iscn->umin = cx0;
            while(x < cx1) {
                uint8_t d = *p;
                movedelta(1, 0);
                zbar_scan_y(scn, d);
            }
            ASSERT_POS;
            quiet_border(iscn);
            svg_path_end();

            movedelta(-1, density);
            iscn->v = y;
            if(y >= cy1)
                break;

            zprintf(128, "img_x-: %04d,%04d @%p\n", x, y, p);
            svg_path_start("vedge", -1. / 32, w, y + 0.5);
            iscn->dx = iscn->du = -1;
            iscn->umin = cx1;
            while(x >= cx0) {
                uint8_t d = *p;
                movedelta(-1, 0);
                zbar_scan_y(scn, d);
            }
            ASSERT_POS;
            quiet_border(iscn);
            svg_path_end();

            movedelta(1, density);
            iscn->v = y;
        }
        svg_group_end();
    }
    iscn->dx = 0;

    density = CFG(iscn, ZBAR_CFG_X_DENSITY);
    if(density > 0) {
        const uint8_t *p = data;
        int x = 0, y = 0;

        int border = (((img->crop_w - 1) % density) + 1) / 2;
        if(border > img->crop_w / 2)
            border = img->crop_w / 2;
        border += img->crop_x;
        assert(border <= w);
        svg_group_start("scanner", 90, 1, -1, 0, 0);
        movedelta(border, img->crop_y);
        iscn->v = x;

        while(x < cx1) {
            int cy0 = img->crop_y;
            zprintf(128, "img_y+: %04d,%04d @%p\n", x, y, p);
            svg_path_start("vedge", 1. / 32, 0, x + 0.5);
            iscn->dy = iscn->du = 1;
            iscn->umin = cy0;
            while(y < cy1) {
                uint8_t d = *p;
                movedelta(0, 1);
                zbar_scan_y(scn, d);
            }
            ASSERT_POS;
            quiet_border(iscn);
            svg_path_end();

            movedelta(density, -1);
            iscn->v = x;
            if(x >= cx1)
                break;

            zprintf(128, "img_y-: %04d,%04d @%p\n", x, y, p);
            svg_path_start("vedge", -1. / 32, h, x + 0.5);
            iscn->dy = iscn->du = -1;
            iscn->umin = cy1;
            while(y >= cy0) {
                uint8_t d = *p;
                movedelta(0, -1);
                zbar_scan_y(scn, d);
            }
            ASSERT_POS;
            quiet_border(iscn);
            svg_path_end();

            movedelta(density, 1);
            iscn->v = x;
        }
        svg_group_end();
    }
    iscn->dy = 0;
    iscn->img = NULL;

#ifdef ENABLE_QRCODE
    _zbar_qr_decode(iscn->qr, iscn, img);
#endif

    /* FIXME tmp hack to filter bad EAN results */
    /* FIXME tmp hack to merge simple case EAN add-ons */
    char filter = (!iscn->enable_cache &&
                   (density == 1 || CFG(iscn, ZBAR_CFG_Y_DENSITY) == 1));
    int nean = 0, naddon = 0;
    if(syms->nsyms) {
        zbar_symbol_t **symp;
        for(symp = &syms->head; *symp; ) {
            zbar_symbol_t *sym = *symp;
            if(sym->cache_count <= 0 &&
               ((sym->type < ZBAR_COMPOSITE && sym->type > ZBAR_PARTIAL) ||
                sym->type == ZBAR_DATABAR ||
                sym->type == ZBAR_DATABAR_EXP ||
                sym->type == ZBAR_CODABAR))
            {
	        if((sym->type == ZBAR_CODABAR || filter) && sym->quality < 4) {
                    if(iscn->enable_cache) {
                        /* revert cache update */
                        zbar_symbol_t *entry = cache_lookup(iscn, sym);
                        if(entry)
                            entry->cache_count--;
                        else
                            assert(0);
                    }

                    /* recycle */
                    *symp = sym->next;
                    syms->nsyms--;
                    sym->next = NULL;
                    _zbar_image_scanner_recycle_syms(iscn, sym);
                    continue;
                }
                else if(sym->type < ZBAR_COMPOSITE &&
                        sym->type != ZBAR_ISBN10)
                {
                    if(sym->type > ZBAR_EAN5)
                        nean++;
                    else
                        naddon++;
                }
            }
            symp = &sym->next;
        }

        if(nean == 1 && naddon == 1 && iscn->ean_config) {
            /* create container symbol for composite result */
            zbar_symbol_t *ean = NULL, *addon = NULL;
            for(symp = &syms->head; *symp; ) {
                zbar_symbol_t *sym = *symp;
                if(sym->type < ZBAR_COMPOSITE && sym->type > ZBAR_PARTIAL) {
                    /* move to composite */
                    *symp = sym->next;
                    syms->nsyms--;
                    sym->next = NULL;
                    if(sym->type <= ZBAR_EAN5)
                        addon = sym;
                    else
                        ean = sym;
                }
                else
                    symp = &sym->next;
            }
            assert(ean);
            assert(addon);

            int datalen = ean->datalen + addon->datalen + 1;
            zbar_symbol_t *ean_sym =
                _zbar_image_scanner_alloc_sym(iscn, ZBAR_COMPOSITE, datalen);
            ean_sym->orient = ean->orient;
            ean_sym->syms = _zbar_symbol_set_create();
            memcpy(ean_sym->data, ean->data, ean->datalen);
            memcpy(ean_sym->data + ean->datalen,
                   addon->data, addon->datalen + 1);
            ean_sym->syms->head = ean;
            ean->next = addon;
            ean_sym->syms->nsyms = 2;
            _zbar_image_scanner_add_sym(iscn, ean_sym);
        }
    }

    if(syms->nsyms && iscn->handler)
        iscn->handler(img, iscn->userdata);

    svg_close();
    return(syms->nsyms);
}
Пример #8
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;
    int nsyms, rc;
    if(img) {
        zbar_image_t *tmp;
        uint32_t format = zbar_image_get_format(img);
        zprintf(16, "processing: %.4s(%08lx) %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...
         */
        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);
        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: %s (%d pts) (q=%d) (%s)\n",
                        zbar_get_symbol_name(type),
                        zbar_get_addon_name(type),
                        zbar_symbol_get_data(sym),
                        zbar_symbol_get_loc_size(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 */
    rc = 0;
    
    if(force_fmt && img)
        zbar_image_destroy(img);
    return(rc);

error:
    return(err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                       __func__, "unknown image format"));
}