当前位置: 首页 > 工具软件 > ZBar > 使用案例 >

ZBar源码分析:zbar_symbol(5)

哈涵容
2023-12-01

2021SC@SDUSC

symbol.c中关键函数

zbar_symbol_xml方法将XML符号元素表示形式打印到用户结果缓冲区。symbol是要打印的符号,buffer是inout结果指针,它将被重新分配,buflen是结果缓冲区的输入输出长度。函数返回缓冲区指针。

char *zbar_symbol_xml (const zbar_symbol_t *sym,
                       char **buf,
                       unsigned *len)
{
    unsigned int datalen, maxlen;
    int i, n = 0;

    const char *type = zbar_get_symbol_name(sym->type);
    const char *orient = zbar_get_orientation_name(sym->orient);

    /* check for binary data */
    unsigned char *data = (unsigned char*)sym->data;
    char binary = ((data[0] == 0xff && data[1] == 0xfe) ||
                   (data[0] == 0xfe && data[1] == 0xff) ||
                   !strncmp(sym->data, "<?xml", 5));
    for(i = 0; !binary && i < sym->datalen; i++) {
        unsigned char c = sym->data[i];
        binary = ((c < 0x20 && ((~0x00002600 >> c) & 1)) ||
                  (c >= 0x7f && c < 0xa0) ||
                  (c == ']' && i + 2 < sym->datalen &&
                   sym->data[i + 1] == ']' &&
                   sym->data[i + 2] == '>'));
    }

    datalen = strlen(sym->data);
    if(binary)
        datalen = (sym->datalen + 2) / 3 * 4 + sym->datalen / 57 + 3;

    maxlen = (MAX_STATIC + strlen(type) + strlen(orient) +
              datalen + MAX_INT_DIGITS + 1);
    unsigned int mods = sym->modifiers;
    if(mods)
        maxlen += MAX_MOD;
    unsigned int cfgs = sym->configs & ~(1 << ZBAR_CFG_ENABLE);
    if(cfgs)
        maxlen += MAX_CFG;
    if(binary)
        maxlen += MAX_INT_DIGITS;

    if(!*buf || (*len < maxlen)) {
        if(*buf)
            free(*buf);
        *buf = malloc(maxlen);
        /* FIXME check OOM */
        *len = maxlen;
    }

    TMPL_FMT("<symbol type='%s' quality='%d' orientation='%s'",
             type, sym->quality, orient);

    if(mods) {
        int j;
        TMPL_COPY(" modifiers='");
        for(j = 0; mods && j < ZBAR_MOD_NUM; j++, mods >>= 1)
            if(mods & 1)
                TMPL_FMT("%s ", zbar_get_modifier_name(j));
        /* cleanup trailing space */
        n--;
        TMPL_COPY("'");
    }

    if(cfgs) {
        int j;
        TMPL_COPY(" configs='");
        for(j = 0; cfgs && j < ZBAR_CFG_NUM; j++, cfgs >>= 1)
            if(cfgs & 1)
                TMPL_FMT("%s ", zbar_get_config_name(j));
        /* cleanup trailing space */
        n--;
        TMPL_COPY("'");
    }

    if(sym->cache_count)
        TMPL_FMT(" count='%d'", sym->cache_count);

    TMPL_COPY("><data");
    if(binary)
        TMPL_FMT(" format='base64' length='%d'", sym->datalen);
    TMPL_COPY("><![CDATA[");

    if(!binary) {
        memcpy(*buf + n, sym->data, sym->datalen + 1);
        n += sym->datalen;
    }
    else {
        TMPL_COPY("\n");
        n += base64_encode(*buf + n, sym->data, sym->datalen);
    }
    assert(n <= maxlen);

    TMPL_COPY("]]></data></symbol>");

    *len = n;
    return(*buf);
}

zbar_symbol_set_ref方法引用计数操作。存储新引用时增加引用计数。不再使用引用时减少引用计数。一旦引用被释放,就不再引用对象。

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

zbar_symbol_set_get_size方法检索设置大小。返回集合中的符号数。

int zbar_symbol_set_get_size (const zbar_symbol_set_t *syms)
{
    return(syms->nsyms);
}

zbar_symbol_set_first_symbol方法设置迭代器。返回集合中的第一个解码符号结果,若集合为空,则返回NULL。

const zbar_symbol_t*
zbar_symbol_set_first_symbol (const zbar_symbol_set_t *syms)
{
    zbar_symbol_t *sym = syms->tail;
    if(sym)
        return(sym->next);
    return(syms->head);
}

zbar_symbol_set_first_unfiltered方法为原始结果迭代器。在过滤之前返回集合中的第一个解码符号结果,如果集合为空,则返回NULL。

const zbar_symbol_t*
zbar_symbol_set_first_unfiltered (const zbar_symbol_set_t *syms)
{
    return(syms->head);
}

 类似资料: