2021SC@SDUSC
目录
一、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);
如果启用,则显示到窗口