ZBar - Attempting to read PDF417 codes - c

I am attempting to make a PDF417 barcode reader for the web using Web Assembly (there's a few out there but the only reliable one is licenced). The idea is simple, just build a binary file with C code that can be called via JavaScript.
I followed this guide which got me almost there! I had to add --enable-codes=pdf417 as a parameter to configure to enable PDF417 symbols and disable all the others I'm not interested in.
The code actually works amazingly well for any other type of symbol (see demo) but if I compile ZBar to accept PDF417, it detects it but throws a warning:
WARNING: zbar/decoder/pdf417.c:73: pdf417_decode8: Assertion "clst >= 0 && clst < 9" failed.
dir=0 sig=5a44 k=9 buf[0000]=
WARNING: zbar/decoder/pdf417.c:89: pdf417_decode8: Assertion "g[0] >= 0 && g[1] >= 0 && g[2] >= 0" failed.
dir=1 sig=ca03 k=6 g0=ffffffff g1=e71 g2=585 buf[0000]=
Those assertions are on lines 71 and 86 of ZBar.
You can see all the code I'm using in the guide I mentioned earlier (the only difference is that I enabled PDF417 before compiling) ¿Any ideas?

The default behaviour of zbar is to attempt to decode all symbol types.
if(sym == ZBAR_NONE) {
static const zbar_symbol_type_t all[] = {
ZBAR_EAN13, ZBAR_EAN2, ZBAR_EAN5, ZBAR_EAN8,
ZBAR_UPCA, ZBAR_UPCE, ZBAR_ISBN10, ZBAR_ISBN13,
ZBAR_I25, ZBAR_DATABAR, ZBAR_DATABAR_EXP, ZBAR_CODABAR,
ZBAR_CODE39, ZBAR_CODE93, ZBAR_CODE128, ZBAR_QRCODE,
ZBAR_PDF417, 0
};
const zbar_symbol_type_t *symp;
for(symp = all; *symp; symp++)
zbar_decoder_set_config(dcode, *symp, cfg, val);
return(0);
}
Does your images contain PDF417 barcodes? If not, you could instruct zbar to decode just the symbol types of that are of interest to you, so the PF417 decoder will not be run. You do this using the symbols argument e.g., if your images contain just QR codes,
// disable all
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 0);
// enable qr
scanner.set_config(ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);
in pyzbar
from pyzbar.pyzbar import ZBarSymbol
decode(Image.open('pyzbar/tests/qrcode.png'), symbols=[ZBarSymbol.QRCODE])

For anyone trying to use ZBar for reading PDF417, PDF417 decoding is incomplete. It will not work. Your best open source bet is ZXing.

Related

How to do automatic OpenGL error checking using GLEW?

I was recently trying to implement automatic error checking after each OpenGL function call. I considered wrapping each OpenGL function in a caller like this:
CheckForErrors(glCreateBuffers(1, &VBO));
But I saw that GLEW already uses its own function wrapper:
#define GLEW_GET_FUN(x) x
So I decided to edit it instead of writting my own function wrapper:
#ifndef GLEW_GET_FUN
#ifdef DEBUG
#define GLEW_GET_FUN(x) while (glGetError() != GL_NO_ERROR);\
x; {\
GLenum error = glGetError();\
if (error != GL_NO_ERROR) {\
printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", #x, __FILE__, __LINE__);\
do printf(" %d", error); while (error = glGetError());\
printf("\n");\
__debugbreak();\
}
#else
#define GLEW_GET_FUN(x) x
#endif
#endif
Unfortunately, this doesn't compile. For example this function call:
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
Gets changed to this by the preprocessor:
GLuint vertexShaderID = while (glGetError() != GL_NO_ERROR); __glewCreateShader; { GLenum error = glGetError(); if (error != 0) { printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", "__glewCreateShader", "main.cpp", 51); do printf(" %d", error); while (error = glGetError()); printf("\n"); __debugbreak(); }(GL_VERTEX_SHADER);
There are 2 problems here:
The statement starts with a while loop, so it cannot return the value.
The parentheses with function parameters are placed after the whole thing and not right after the function call.
I don't know how to overcome those problems and I will appreciate help.
Notes
I am aware of the glDebugMessageCallback() function, but it is only availble in OpenGL 4.3+ which is a rather new and partially insupported yet version.
I cannot remove the while loop at the beginning, because I have to clear all errors before calling the function (unless there is a diffrent way to do this).
I am trying to do something like this, but without using a separate function wrapper.
I don't know how to overcome those problems
You can't. What you want to do is simply not viable in the way you want to do it. You cannot turn an expression (which is what a function call is) into a statement (or rather, a series of statements) and have that work everywhere. It will only work in circumstances where the expression is used as a statement.
If you are unwilling to just regularly insert error checking code into your application, and are unable to use the modern debug messaging API, then the standard solution is to use an external tool to find and report errors. RenderDoc can detect OpenGL errors, for example. It allows you to log every OpenGL call and can report errors anytime they occur.
As Nicol Bolas said, it is impossible to do it the way I originally wanted, but I will describe why this is the case and what can be done instead.
The Problem
GLEW wraps only the name of the function with GLEW_GET_FUN(), so function parameters will always be placed after the end of the define as they are not included in it:
//In code:
glGenBuffers(1, &VBO);
//After preprocessing:
{stuff generated by GLEW_GET_FUN}(1, &VBO);
Preprocessing isn't very inteligent so it will just put the function parameters at the end.
Other Solutions
As described in the question, one could use glDebugMessageCallback() if availble.
Wrap each function with a custom wrapper. Not automatic at all, but if someone is interested here is a great tutorial on how to make one.

When I was using a dll comiled by msvc_2015 in qt's program,my program works ok,but debuging shows segemts error

firstly, I have to say the dll was translated by MatLab's m file, which was compiled by c compiler using msvc_2015.
The dll was C shared library, which was said that has a common interface.
I don‘t think it's MatLab's error,because my program works.
The qt was compiled by MinGW_64_4.9.3 on my own computer,so i think qt's configuration is OK.
I can’t figure out why my program works OK, but debugging error, once I was using the fooInitialize(), there were a lot of segments error when debugging
QLibrary lib("foo.dll");
QMessageBox msg;
if(lib.load())
{
QMessageBox::information(NULL,"OK","DLL load is OK!");
Fun mlfFoo=(Fun)lib.resolve("mlfFoo"); //
Fun2 init=(Fun2)lib.resolve("fooInitialize");//
Fun2 termi=(Fun3)lib.resolve("fooTerminate");//
if (mlfFoo) //
{
QMessageBox::information(NULL,"OK","Link to Function is OK!");
init(); //
double numbrOut,*out;
double data[]={1};
mxArray* array_in,*array_out ;
array_in = mxCreateDoubleMatrix(1, 1, mxREAL);//
memcpy(mxGetPr(array_in),data , sizeof(double));
array_out=NULL;
mlfFoo(1, &array_out,array_in);
out=mxGetPr(array_out);
numbrOut=out[0];
mxDestroyArray(array_in); array_in=0;
mxDestroyArray(array_out); array_out = 0;
out=0;
if(numbrOut==10) QMessageBox::information(NULL,"NO","perfect!!!!");
termi();
}
else
QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");
}
else
QMessageBox::information(NULL,"NO","DLL is not loaded!");`
I got this few minutes ago
"while parsing target library list: not well-formed (invalid token)"
"SuspendThread (tid=0x788) failed. (winerr 2)"
the dll's header file was made by matlab using msvc , I compared it to the samples in the matlab's document , it is the similar

Adding tags to header with rpmlib

I am trying to create a new header and insert some tags with the RPM Header API using the headerPut* functions, but in this simple example my attempted insertions fail with the exception of headerPutString and I am at a loss as to why:
Header s = NULL;
unsigned char md5[16] = {0};
uint32_t size = 42;
s = headerNew();
if (headerPutString(s, RPMSIGTAG_SHA1, "foo") != 1)
fprintf(stderr, "headerPutString error\n");
if (headerPutUint32(s, RPMSIGTAG_SIZE, &size, 1) != 1)
fprintf(stderr, "headerPutUint32 error\n");
if (headerPutBin(s, RPMSIGTAG_MD5, md5, 16) != 1)
fprintf(stderr, "headerPutBin error\n");
Running this outputs:
headerPutUint32 error
headerPutBin error
and when I then call headerWrite and examine the resulting file contents with the hexdump tool, I can see that the header only contains the string-type tag.
Why can't I insert the other two?
Well, after some gdb debugging and looking through the RPM source files, I see where the problem is.
In the signature, RPMSIGTAG_SIZE (1000) is of type INT32 and RPMSIGTAG_MD5 (1004) is of type BIN. The problem is that these symbolic values also correspond to RPM header tags, where the type differs: RPMTAG_NAME is 1000 and is a STRING, RPMTAG_SUMMARY is 1004 and is an I18NSTRING. The RPM source files have no way to distinguish between the two and assume they are header tags, not signature tags.
Fortunately, the API also contains the headerPut function. This is actually what gets called by the type-specific functions after the sanity checks (including type checking), headerPut itself doesn't attempt any tag-type match, it just goes ahead and tries to add/append it, and is therefore a good solution for these situations.

nrf51 timer driver code bugs

I'm currently trying to make an application using the nrf51 development kit & I'm trying to use the timer driver, when I induled the C & H files of the driver I got some error :
static const nrf_drv_timer_config_t m_default_config[] = {// here it told me there is error #1
#if (TIMER0_ENABLED == 1)
NRF_DRV_TIMER_DEFAULT_CONFIG(0),
#endif
#if (TIMER1_ENABLED == 1)
NRF_DRV_TIMER_DEFAULT_CONFIG(1),
#endif
#if (TIMER2_ENABLED == 1)
NRF_DRV_TIMER_DEFAULT_CONFIG(2)
#endif
};
// here it told me there is error #2
ret_code_t nrf_drv_timer_init(nrf_drv_timer_t const * const p_instance,
nrf_drv_timer_config_t const * p_config,
nrf_timer_event_handler_t timer_event_handler)
{
ASSERT((p_instance->instance_id) < TIMER_INSTANCE_NUMBER);
ASSERT(TIMER_IS_BIT_WIDTH_VALID(p_instance->instance_id, p_config->bit_width));
if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED)
{
return NRF_ERROR_INVALID_STATE; // timer already initialized
}
if (p_config == NULL)
{
p_config = &m_default_config[p_instance->instance_id];
}
#ifdef SOFTDEVICE_PRESENT
if (p_instance->p_reg == NRF_TIMER0)
{
return NRF_ERROR_INVALID_PARAM;
}
#endif
nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority);
mp_contexts[p_instance->instance_id] = p_config->p_context;
if (timer_event_handler != NULL)
{
m_timer_event_handlers[p_instance->instance_id] = timer_event_handler;
}
else
{
return NRF_ERROR_INVALID_PARAM;
}
nrf_timer_mode_set(p_instance->p_reg, p_config->mode);
nrf_timer_bit_width_set(p_instance->p_reg, p_config->bit_width);
nrf_timer_frequency_set(p_instance->p_reg, p_config->frequency);
m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED;
return NRF_SUCCESS;
}
the error #1 says that "an empty initializer is invalid for an array with unspecified bound"
the error #2 says that it expected an expression
I till now didn't use any of these functions in the main.c code, I'm just added the header files that will be used further.
Error 1: Apparently neither of TIMERx_ENABLED is 1, so the array will be empty. As it is const, there is no chance to initialize it later. That would also result in an array of zero elements, which is not allowed. Easiest might be to have an #else clause with a single null entry. However, I suspect you have to configure the stuff for your system first. Read the documentation.
Error 2: might be a follow up error, or one of the custom types are not defined - hard to say without more info, or the location the error is reported is simply not that of the actual error, or ... . Best is to fix the first error, then try again for error 2.
If you are using examples from nordic then the defines are either in nrf_drv_config.h or in the sdk_config.h for new versions of the nordic sdk.
You have to enable the timers by changing the TIMER_ENABLED define to 1. Then do the same for the timers you want to use.
You could make these defines yourself as other people have suggested.

C_Login fails in PKCS11 in C

Simple issue, but i don't know how to unlock USB Token(epass2003) ,I have try to read PKCS 11 but have no idea how to implement C_Login function for execution in c ,when i am using command line tool (Linux)to do that token is working perfectly fine but with c its not working I have used user type as CKU_USER, Can anyone have knowledge about this, please help
you have to check the return values from the PKCS functions to see if there has been any errors. Try this way and see what happen. If the return code from C_login() is CKR_PIN_LOCKED, then it is clear that you should unlock your card.
CK_RV ret;
ret = C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
if (ret != CKR_OK){
error_message(ret);
return;
}
readPIN("Intro PIN: ", pin, 4);
ret = (f_C_Login)(hSession,CKU_USER, (unsigned char *) pin,strlen(pin));
if (ret != CKR_OK){
closeSessions(slot);
error_message(ret);
return;
}
A token can get locked due to a certain number of failed login (for TrustKey it is 10). There are provider specific utilities to unlock tokens. You could check Feitian site. There is some pointer to this kind of problem in Gooze forum (though not exactly). Your problem looks quite like a token lock problem.

Resources