/* 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); }
int zebra_scan_image (zebra_image_scanner_t *iscn, zebra_image_t *img) { recycle_syms(iscn, img); /* get grayscale image, convert if necessary */ /*img = zebra_image_convert(img, fourcc('Y','8','0','0'));*/ if(!img) return(-1); unsigned w = zebra_image_get_width(img); unsigned h = zebra_image_get_height(img); const uint8_t *data = zebra_image_get_data(img); const uint8_t *p = data; int x = 0, y = 0; #ifdef DEBUG_IMG_SCANNER movedelta(0, (h + 1) / 2); #else movedelta(0, 8); #endif if(zebra_scanner_new_scan(iscn->scn)) symbol_handler(iscn, x, y); /* FIXME add density config api */ /* FIXME less arbitrary lead-out default */ int quiet = w / 32; if(quiet < 8) quiet = 8; while(y < h) { zprintf(32, "img_x+: %03x,%03x @%p\n", x, y, p); while(x < w) { ASSERT_POS; if(zebra_scan_y(iscn->scn, *p)) symbol_handler(iscn, x, y); movedelta(1, 0); } quiet_border(iscn, quiet, x, y); movedelta(-1, 16); if(y >= h) break; zprintf(32, "img_x-: %03x,%03x @%p\n", x, y, p); while(x > 0) { ASSERT_POS; if(zebra_scan_y(iscn->scn, *p)) symbol_handler(iscn, x, y); movedelta(-1, 0); } quiet_border(iscn, quiet, x, y); movedelta(1, 16); #ifdef DEBUG_IMG_SCANNER break; #endif } #ifndef DEBUG_IMG_SCANNER x = y = 0; p = data; movedelta(8, 0); while(x < w) { zprintf(32, "img_y+: %03x,%03x @%p\n", x, y, p); while(y < h) { ASSERT_POS; if(zebra_scan_y(iscn->scn, *p)) symbol_handler(iscn, x, y); movedelta(0, 1); } quiet_border(iscn, quiet, x, y); movedelta(16, -1); if(x >= w) break; zprintf(32, "img_y-: %03x,%03x @%p\n", x, y, p); while(y >= 0) { ASSERT_POS; if(zebra_scan_y(iscn->scn, *p)) symbol_handler(iscn, x, y); movedelta(0, -1); } quiet_border(iscn, quiet, x, y); movedelta(16, 1); } #endif /* flush scanner pipe */ if(zebra_scanner_new_scan(iscn->scn)) symbol_handler(iscn, x, y); /* release reference */ zebra_image_destroy(img); return(iscn->img->nsyms); }