ZBar源码分析(四)

2021SC@SDUSC

目录

一、proc_enter、proc_leave函数分析

二、_zbar_process_image函数分析


一、proc_enter、proc_leave函数分析

static inline int proc_enter (zbar_processor_t *proc)
{
    _zbar_mutex_lock(&proc->mutex);
    return(_zbar_processor_lock(proc));
}

static inline int proc_leave (zbar_processor_t *proc)
{
    int rc = _zbar_processor_unlock(proc, 0);
    _zbar_mutex_unlock(&proc->mutex);
    return(rc);
}

proc_enter、proc_leave函数分别负责临界资源的上锁与解锁

二、_zbar_process_image函数分析

该函数为图像处理函数,调用前提是API已经上锁

int _zbar_process_image (zbar_processor_t *proc,
                         zbar_image_t *img)

zbar_image_t具体属性如下:

struct zbar_image_s {
    uint32_t format;            /* fourcc图像格式代码 */
    unsigned width, height;     /* 图像大小 */
    const void *data;           /* 图像样本数据 */
    unsigned long datalen;      /* 数据的已分配/映射大小 */
    unsigned crop_x, crop_y;    /* 裁剪矩形 */
    unsigned crop_w, crop_h;
    void *userdata;             /* 与图像关联的用户指定数据 */

    /* 清理处理器 */
    zbar_image_cleanup_handler_t *cleanup;
    refcnt_t refcnt;            /* 参考计数 */
    zbar_video_t *src;          /* 发起者 */
    int srcidx;                 /* 发起者使用的索引 */
    zbar_image_t *next;         /* 内部图像列表 */

    unsigned seq;               /* 页面/帧序列号 */
    zbar_symbol_set_t *syms;    /* 解码结果集 */
};

 

uint32_t force_fmt = proc->force_output;

记录强制格式转换

if(img) 
    {
        if(proc->dumping) {
            zbar_image_write(proc->window->image, "zbar");
            proc->dumping = 0;
        }

进行debug映像转储

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));

检索与此图像关联的序列编号,获得相关信息,并冲洗流中的信息

zbar_image_t *tmp = zbar_image_convert(img, fourcc('Y','8','0','0'));

图像格式转换为Y800

if(!tmp)
            goto error;
error:
    return(err_capture(proc, SEV_ERROR, ZBAR_ERR_UNSUPPORTED,
                       __func__, "unknown image format"));

如果格式转换失败,返回错误信息

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;

从图像扫描仪和中删除任何先前解码的结果

nsyms:如果成功解码图像中的符号,则返回>0;如果未找到符号,则为0;如果发生错误,则为-1

交换解码结果

析构tmp

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

检索上次扫描图像的解码结果,增加引用计数

if(nsyms) {
            _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);
        }
    }

处理强制格式转换

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);

如果启用,则显示到窗口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值