Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:nandcd:15.5
zbar
nand_grading_support.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nand_grading_support.patch of Package zbar
diff --git a/include/zbar.h b/include/zbar.h index 66281c1..cb68b48 100644 --- a/include/zbar.h +++ b/include/zbar.h @@ -364,6 +364,23 @@ extern zbar_error_t _zbar_get_error_code(const void *object); /*@}*/ +typedef struct decodeErrorsInfo_struct { + int errors[81]; + int maxCorrectableErrors[81]; + int checkedBlocks; + int totalBlocks; + int readError; +} decodeErrorsInfo; +typedef struct codeStructureInfo_struct { + // int numElems[81][2]; + int (*numElems)[2]; + // int blocks[81][2][153][8][2]; + int (*blocks)[2][153][8][2]; + int numBlocks; + int codeSize; + int valid; +} codeStructureInfo; + struct zbar_symbol_s; typedef struct zbar_symbol_s zbar_symbol_t; @@ -1567,6 +1584,10 @@ extern unsigned zbar_scanner_get_edge(const zbar_scanner_t *scn, /** retrieve last scanned color. */ extern zbar_color_t zbar_scanner_get_color(const zbar_scanner_t *scanner); +extern float zbar_uec(const zbar_symbol_t* sym); +extern codeStructureInfo* zbar_structure(const zbar_symbol_t* sym); +extern int zbar_size(const zbar_symbol_t* sym); + /*@}*/ #ifdef __cplusplus diff --git a/include/zbar/Symbol.h b/include/zbar/Symbol.h index f3a5668..c011c86 100644 --- a/include/zbar/Symbol.h +++ b/include/zbar/Symbol.h @@ -35,6 +35,8 @@ #include <stdlib.h> #include <string> +#include <vector> + namespace zbar { class SymbolIterator; @@ -398,6 +400,45 @@ public: return (zbar_symbol_xml(_sym, (char **)&_xmlbuf, (unsigned *)&_xmllen)); } + float uec() const + { + return zbar_uec(_sym); + } + std::vector< std::vector< std::vector< std::vector< std::vector<int> > > > > structure() const + { + std::vector< std::vector< std::vector< std::vector< std::vector<int> > > > > ret; + if (_type != ZBAR_QRCODE) { + return ret; + } + codeStructureInfo* res = zbar_structure(_sym); + if (!res->valid) { + return ret; + } + for (int block = 0; block < res->numBlocks; ++block) { + std::vector< std::vector< std::vector< std::vector<int> > > > t4; + for (int type = 0; type < 2; ++type) { + std::vector< std::vector< std::vector<int> > > t3; + for (int sym = 0; sym < res->numElems[block][type]; ++sym) { + std::vector< std::vector<int> > t2; + for (int bit = 0; bit < 8; ++bit) { + std::vector<int> t1; + t1.push_back(res->blocks[block][type][sym][bit][0]); + t1.push_back(res->blocks[block][type][sym][bit][1]); + t2.push_back( std::move(t1) ); + } + t3.push_back( std::move(t2) ); + } + t4.push_back( std::move(t3) ); + } + ret.push_back( std::move(t4) ); + } + return ret; + } + int size() const + { + return zbar_size(_sym); + } + protected: /// (re)initialize Symbol from C symbol object. void init(const zbar_symbol_t *sym = NULL) diff --git a/zbar/img_scanner.c b/zbar/img_scanner.c index 3e235d1..71fcfc5 100644 --- a/zbar/img_scanner.c +++ b/zbar/img_scanner.c @@ -169,6 +169,11 @@ void _zbar_image_scanner_recycle_syms(zbar_image_scanner_t *iscn, free(sym->data); sym->data = NULL; sym->data_alloc = 0; + + sym->str.valid = 0; + if (sym->str.numElems) {free(sym->str.numElems); sym->str.numElems = NULL;} + if (sym->str.blocks) {free(sym->str.blocks); sym->str.blocks = NULL;} + i = 0; } bucket = &iscn->recycle[i]; @@ -253,6 +258,12 @@ inline zbar_symbol_t *_zbar_image_scanner_alloc_sym(zbar_image_scanner_t *iscn, sym->orient = ZBAR_ORIENT_UNKNOWN; sym->cache_count = 0; sym->time = iscn->time; + + sym->uec.readError = 1; + sym->str.valid = 0; + sym->str.numElems = malloc(sizeof(*sym->str.numElems) * 81); + sym->str.blocks = malloc(sizeof(*sym->str.blocks) * 81); + assert(!sym->syms); if (datalen > 0) { diff --git a/zbar/qrcode/qrdec.c b/zbar/qrcode/qrdec.c index 905336a..27f2398 100644 --- a/zbar/qrcode/qrdec.c +++ b/zbar/qrcode/qrdec.c @@ -3289,7 +3289,8 @@ static void qr_sampling_grid_sample(const qr_sampling_grid *_grid, static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, int _nshort_data, int _nshort_blocks, const unsigned *_data_bits, - const unsigned *_fp_mask, int _dim) + const unsigned *_fp_mask, int _dim, + codeStructureInfo *_info) { unsigned bits; int biti; @@ -3298,6 +3299,23 @@ static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, int blockj; int i; int j; + + int numTotalDataSyms; + int currInsSyms; + int storage[9][2]; + _info->codeSize = _dim; + _info->numBlocks = _nblocks; + if (_info->numElems) {free(_info->numElems);} + _info->numElems = malloc(sizeof(*_info->numElems) * _nblocks); + if (_info->blocks) {free(_info->blocks);} + _info->blocks = malloc(sizeof(*_info->blocks) * _nblocks); + for (int ij = 0; ij < _nblocks; ++ij) { + _info->numElems[ij][0] = 0; + _info->numElems[ij][1] = 0; + } + numTotalDataSyms = _nshort_blocks * _nshort_data + (_nblocks - _nshort_blocks) * (_nshort_data + 1); + currInsSyms = 0; + stride = _dim + QR_INT_BITS - 1 >> QR_INT_LOGBITS; /*If _all_ the blocks are short, don't skip anything (see below).*/ if (_nshort_blocks >= _nblocks) @@ -3323,16 +3341,36 @@ static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, /*Pull a bit from the right column.*/ if (!(fp_mask1 >> nbits & 1)) { bits = bits << 1 | data1 >> nbits & 1; + + storage[biti][0] = j; + storage[biti][1] = nbits + QR_INT_BITS * i; + biti++; } /*Pull a bit from the left column.*/ if (!(fp_mask2 >> nbits & 1)) { bits = bits << 1 | data2 >> nbits & 1; + + storage[biti][0] = j - 1; + storage[biti][1] = nbits + QR_INT_BITS * i; + biti++; } /*If we finished a byte, drop it in a block.*/ if (biti >= 8) { + biti -= 8; + + for (int bi = 0; bi < 8; ++bi) { + _info->blocks[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ][ _info->numElems[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ] ][bi][0] = storage[bi][0]; + _info->blocks[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ][ _info->numElems[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ] ][bi][1] = storage[bi][1]; + } + if (biti > 0) { + storage[0][0] = storage[8][0]; + storage[0][1] = storage[8][1]; + } + (++currInsSyms > numTotalDataSyms) ? (_info->numElems[blocki][1]++) : (_info->numElems[blocki][0]++); + *_blocks[blocki++]++ = (unsigned char)(bits >> biti); /*For whatever reason, the long blocks are at the _end_ of the list, instead of the beginning. @@ -3356,15 +3394,25 @@ static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, /*Scan down a pair of columns.*/ l = j * stride; for (i = 0; i < stride; i++) { + + int maxnbits; + data1 = _data_bits[l + i]; fp_mask1 = _fp_mask[l + i]; data2 = _data_bits[l + i - stride]; fp_mask2 = _fp_mask[l + i - stride]; nbits = QR_MINI(_dim - (i << QR_INT_LOGBITS), QR_INT_BITS); + + maxnbits = nbits - 1; + while (nbits-- > 0) { /*Pull a bit from the right column.*/ if (!(fp_mask1 & 1)) { bits = bits << 1 | data1 & 1; + + storage[biti][0] = j; + storage[biti][1] = (maxnbits - nbits) + QR_INT_BITS * i; + biti++; } data1 >>= 1; @@ -3372,13 +3420,29 @@ static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, /*Pull a bit from the left column.*/ if (!(fp_mask2 & 1)) { bits = bits << 1 | data2 & 1; + + storage[biti][0] = j - 1; + storage[biti][1] = (maxnbits - nbits) + QR_INT_BITS * i; + biti++; } data2 >>= 1; fp_mask2 >>= 1; /*If we finished a byte, drop it in a block.*/ if (biti >= 8) { + biti -= 8; + + for (int bi = 0; bi < 8; ++bi) { + _info->blocks[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ][ _info->numElems[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ] ][bi][0] = storage[bi][0]; + _info->blocks[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ][ _info->numElems[blocki][ ((currInsSyms >= numTotalDataSyms) ? 1 : 0) ] ][bi][1] = storage[bi][1]; + } + if (biti > 0) { + storage[0][0] = storage[8][0]; + storage[0][1] = storage[8][1]; + } + (++currInsSyms > numTotalDataSyms) ? (_info->numElems[blocki][1]++) : (_info->numElems[blocki][0]++); + *_blocks[blocki++]++ = (unsigned char)(bits >> biti); /*See comments on the "up" loop for the reason behind this mess.*/ if (blocki >= _nblocks) @@ -3387,6 +3451,9 @@ static void qr_samples_unpack(unsigned char **_blocks, int _nblocks, } } } + + _info->valid = 1; + } /*Bit reading code blatantly stolen^W^Wadapted from libogg/libtheora (because @@ -3745,6 +3812,10 @@ static void qr_code_data_clear(qr_code_data *_qrdata) } } free(_qrdata->entries); + + if (_qrdata->str.numElems) {free(_qrdata->str.numElems); _qrdata->str.numElems = NULL;} + if (_qrdata->str.blocks) {free(_qrdata->str.blocks); _qrdata->str.blocks = NULL;} + } void qr_code_data_list_init(qr_code_data_list *_qrlist) @@ -3909,7 +3980,7 @@ static int qr_code_decode(qr_code_data *_qrdata, const rs_gf256 *_gf, for (i = 1; i < nblocks; i++) blocks[i] = blocks[i - 1] + block_sz + (i > nshort_blocks); qr_samples_unpack(blocks, nblocks, block_sz - npar, nshort_blocks, - data_bits, grid.fpmask, dim); + data_bits, grid.fpmask, dim, &_qrdata->str); qr_sampling_grid_clear(&grid); free(blocks); free(data_bits); @@ -3917,6 +3988,10 @@ static int qr_code_decode(qr_code_data *_qrdata, const rs_gf256 *_gf, ndata = 0; ncodewords = 0; ret = 0; + + _qrdata->uec.checkedBlocks = 0; + _qrdata->uec.totalBlocks = nblocks; + for (i = 0; i < nblocks; i++) { int block_szi; int ndatai; @@ -3925,6 +4000,19 @@ static int qr_code_decode(qr_code_data *_qrdata, const rs_gf256 *_gf, NULL, 0); zprintf(1, "Number of errors corrected: %i%s\n", ret, ret < 0 ? " (data irrecoverable)" : ""); + + _qrdata->uec.errors[i] = ret; + if (_version == 1) { + _qrdata->uec.maxCorrectableErrors[i] = (ecc_level + 1) << 1; + } + else if (_version == 2 && ecc_level == 0) { + _qrdata->uec.maxCorrectableErrors[i] = (npar - 1) >> 1; + } + else { + _qrdata->uec.maxCorrectableErrors[i] = npar >> 1; + } + _qrdata->uec.checkedBlocks += 1; + /*For version 1 symbols and version 2-L and 3-L symbols, we aren't allowed to use all the parity bytes for correction. They are instead used to improve detection. @@ -3951,9 +4039,19 @@ static int qr_code_decode(qr_code_data *_qrdata, const rs_gf256 *_gf, API support for that; a mode ignoring ECC errors might also be useful.*/ if (ret < 0) qr_code_data_clear(_qrdata); + + else + _qrdata->uec.readError = 0; + _qrdata->version = _version; _qrdata->ecc_level = ecc_level; } + + else { + if (_qrdata->str.numElems) {free(_qrdata->str.numElems); _qrdata->str.numElems = NULL;} + if (_qrdata->str.blocks) {free(_qrdata->str.blocks); _qrdata->str.blocks = NULL;} + } + free(block_data); return ret; } @@ -4247,6 +4345,12 @@ void qr_reader_match_centers(qr_reader *_reader, qr_code_data_list *_qrlist, if (!mark[k]) { qr_finder_center *c[3]; qr_code_data qrdata; + + qrdata.uec.readError = 1; + qrdata.str.valid = 0; + qrdata.str.numElems = NULL; + qrdata.str.blocks = NULL; + int version; c[0] = _centers + i; c[1] = _centers + j; diff --git a/zbar/qrcode/qrdec.h b/zbar/qrcode/qrdec.h index 40cb204..5192199 100644 --- a/zbar/qrcode/qrdec.h +++ b/zbar/qrcode/qrdec.h @@ -140,6 +140,10 @@ struct qr_code_data { Points appear in the order up-left, up-right, down-left, down-right, relative to the orientation of the QR code.*/ qr_point bbox[4]; + + decodeErrorsInfo uec; + codeStructureInfo str; + }; struct qr_code_data_list { diff --git a/zbar/qrcode/qrdectxt.c b/zbar/qrcode/qrdectxt.c index 71c59cb..b53a98c 100644 --- a/zbar/qrcode/qrdectxt.c +++ b/zbar/qrcode/qrdectxt.c @@ -500,9 +500,20 @@ int qr_code_data_list_extract_text(const qr_code_data_list *_qrlist, (char *)realloc(sa_text, sa_ntext * sizeof(*sa_text)); } - if (sa_size == 1) + if (sa_size == 1) { sa_sym = syms; - else { + if (!qrdata[i].uec.readError) { + sa_sym->uec = qrdata[i].uec; + } + if (qrdata[i].str.valid) { + sa_sym->str.valid = qrdata[i].str.valid; + sa_sym->str.codeSize = qrdata[i].str.codeSize; + sa_sym->str.numBlocks = qrdata[i].str.numBlocks; + memcpy(sa_sym->str.numElems, qrdata[i].str.numElems, sizeof(*qrdata[i].str.numElems) * qrdata[i].str.numBlocks); + memcpy(sa_sym->str.blocks, qrdata[i].str.blocks, sizeof(*qrdata[i].str.blocks) * qrdata[i].str.numBlocks); + } + + } else { /* cheap out w/axis aligned bbox for now */ int xmin = img->width, xmax = -2; int ymin = img->height, ymax = -2; diff --git a/zbar/symbol.c b/zbar/symbol.c index fe2a4f8..20a9866 100644 --- a/zbar/symbol.c +++ b/zbar/symbol.c @@ -223,6 +223,10 @@ void _zbar_symbol_free(zbar_symbol_t *sym) free(sym->pts); if (sym->data_alloc && sym->data) free(sym->data); + + if (sym->str.numElems) {free(sym->str.numElems); sym->str.numElems = NULL;} + if (sym->str.blocks) {free(sym->str.blocks); sym->str.blocks = NULL;} + free(sym); } @@ -511,3 +515,40 @@ zbar_symbol_set_first_unfiltered(const zbar_symbol_set_t *syms) { return (syms->head); } + +float +zbar_uec(const zbar_symbol_t* sym) +{ + if (sym->type != ZBAR_QRCODE) { + return -1; + } + if (!sym->uec.readError && sym->uec.checkedBlocks == sym->uec.totalBlocks) { + float minUEC = 1.0; + for (int i = 0; i < sym->uec.checkedBlocks; ++i) { + float blockUEC; + if (sym->uec.errors[i] > sym->uec.maxCorrectableErrors[i]) { + minUEC = 0.0; + break; + } + blockUEC = 1.0 - (float)sym->uec.errors[i] / sym->uec.maxCorrectableErrors[i]; + if (blockUEC < minUEC) minUEC = blockUEC; + } + return minUEC; + } + else { + return 0.0; + } +} +codeStructureInfo* +zbar_structure(const zbar_symbol_t* sym) +{ + return &sym->str; +} +int +zbar_size(const zbar_symbol_t* sym) +{ + if (sym->type != ZBAR_QRCODE || !sym->str.valid) { + return -1; + } + return sym->str.codeSize; +} diff --git a/zbar/symbol.h b/zbar/symbol.h index 5ea97a3..cfc78c4 100644 --- a/zbar/symbol.h +++ b/zbar/symbol.h @@ -59,6 +59,10 @@ struct zbar_symbol_s { unsigned long time; /* relative symbol capture time */ int cache_count; /* cache state */ int quality; /* relative symbol reliability metric */ + + decodeErrorsInfo uec; + codeStructureInfo str; + }; extern int _zbar_get_symbol_hash(zbar_symbol_type_t);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor