void zbar_image_scanner_destroy (zbar_image_scanner_t *iscn) { dump_stats(iscn); if(iscn->syms) { if(iscn->syms->refcnt) zbar_symbol_set_ref(iscn->syms, -1); else _zbar_symbol_set_free(iscn->syms); iscn->syms = NULL; } if(iscn->scn) zbar_scanner_destroy(iscn->scn); iscn->scn = NULL; if(iscn->dcode) zbar_decoder_destroy(iscn->dcode); iscn->dcode = NULL; int i; for(i = 0; i < RECYCLE_BUCKETS; i++) { zbar_symbol_t *sym, *next; for(sym = iscn->recycle[i].head; sym; sym = next) { next = sym->next; _zbar_symbol_free(sym); } } #ifdef ENABLE_QRCODE if(iscn->qr) { _zbar_qr_destroy(iscn->qr); iscn->qr = NULL; } #endif free(iscn); }
inline void zbar_image_scanner_recycle_image (zbar_image_scanner_t *iscn, zbar_image_t *img) { zbar_symbol_set_t *syms = iscn->syms; if(syms && syms->refcnt) { if(recycle_syms(iscn, syms)) { STAT(iscn_syms_inuse); iscn->syms = NULL; } else STAT(iscn_syms_recycle); } syms = img->syms; img->syms = NULL; if(syms && recycle_syms(iscn, syms)) { STAT(img_syms_inuse); syms = iscn->syms; } else if(syms) { STAT(img_syms_recycle); /* select one set to resurrect, destroy the other */ if(iscn->syms) { _zbar_symbol_set_free(syms); syms = iscn->syms; } else iscn->syms = syms; } }
void zbar_symbol_set_ref (const zbar_symbol_set_t *syms, int delta) { zbar_symbol_set_t *ncsyms = (zbar_symbol_set_t*)syms; if(!_zbar_refcnt(&ncsyms->refcnt, delta) && delta <= 0) _zbar_symbol_set_free(ncsyms); }
void _zbar_image_scanner_recycle_syms (zbar_image_scanner_t *iscn, zbar_symbol_t *sym) { zbar_symbol_t *next = NULL; for(; sym; sym = next) { next = sym->next; if(sym->refcnt && _zbar_refcnt(&sym->refcnt, -1)) { /* unlink referenced symbol */ /* FIXME handle outstanding component refs (currently unsupported) */ assert(sym->data_alloc); sym->next = NULL; } else { int i; recycle_bucket_t *bucket; /* recycle unreferenced symbol */ if(!sym->data_alloc) { sym->data = NULL; sym->datalen = 0; } if(sym->syms) { if(_zbar_refcnt(&sym->syms->refcnt, -1)) assert(0); _zbar_image_scanner_recycle_syms(iscn, sym->syms->head); sym->syms->head = NULL; _zbar_symbol_set_free(sym->syms); sym->syms = NULL; } for(i = 0; i < RECYCLE_BUCKETS; i++) if(sym->data_alloc < 1 << (i * 2)) break; if(i == RECYCLE_BUCKETS) { assert(sym->data); free(sym->data); sym->data = NULL; sym->data_alloc = 0; i = 0; } bucket = &iscn->recycle[i]; /* FIXME cap bucket fill */ bucket->nsyms++; sym->next = bucket->head; bucket->head = sym; } } }