zbar_image_t *zbar_image_create () { zbar_image_t *img = (zbar_image_t *)calloc(1, sizeof(zbar_image_t)); _zbar_refcnt_init(); _zbar_image_refcnt(img, 1); img->srcidx = -1; return(img); }
int zbar_window_draw (zbar_window_t *w, zbar_image_t *img) { if(window_lock(w)) return(-1); if(!w->draw_image) img = NULL; if(img) { _zbar_image_refcnt(img, 1); if(img->width != w->src_width || img->height != w->src_height) w->dst_width = 0; } if(w->image) _zbar_image_refcnt(w->image, -1); w->image = img; return(window_unlock(w)); }
zbar_image_t *zbar_video_next_image (zbar_video_t *vdo) { unsigned frame; zbar_image_t *img; if(video_lock(vdo)) return(NULL); if(!vdo->active) { video_unlock(vdo); return(NULL); } frame = vdo->frame++; img = vdo->dq(vdo); if(img) { img->seq = frame; if(vdo->num_images < 2) { /* return a *copy* of the video image and immediately recycle * the driver's buffer to avoid deadlocking the resources */ zbar_image_t *tmp = img; video_lock(vdo); img = vdo->shadow_image; vdo->shadow_image = (img) ? img->next : NULL; video_unlock(vdo); if(!img) { img = zbar_image_create(); assert(img); img->refcnt = 0; img->src = vdo; /* recycle the shadow images */ img->format = vdo->format; zbar_image_set_size(img, vdo->width, vdo->height); img->datalen = vdo->datalen; img->data = malloc(vdo->datalen); } img->cleanup = _zbar_video_recycle_shadow; img->seq = frame; memcpy((void*)img->data, tmp->data, img->datalen); _zbar_video_recycle_image(tmp); } else img->cleanup = _zbar_video_recycle_image; _zbar_image_refcnt(img, 1); } return(img); }
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); }
void zbar_image_ref (zbar_image_t *img, int refs) { _zbar_image_refcnt(img, refs); }
void zbar_image_destroy (zbar_image_t *img) { _zbar_image_refcnt(img, -1); }