Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 44 additions & 57 deletions qrcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,55 @@ STATIC mp_obj_t qrcode_encode(mp_obj_t text_obj) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(text_obj, &bufinfo, MP_BUFFER_READ);

enum qrcodegen_Ecc errCorLvl = qrcodegen_Ecc_LOW; // Error correction level
enum qrcodegen_Ecc ecl = qrcodegen_Ecc_LOW; // Error correction level
bool boostEcl = true;

uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
memcpy(tempBuffer, bufinfo.buf, bufinfo.len);
bool ok = false;
const char *text = bufinfo.buf;
size_t textLen = strlen(text);
bool is_bytes = false;
for (int i = 0; i < bufinfo.len; i++) {
if (tempBuffer[i] == 0) { // \x00 will cut the byte array
is_bytes = true;
}
if (textLen != bufinfo.len) {
is_bytes = true;
}
if (is_bytes) {
ok = qrcodegen_encodeBinary(tempBuffer, bufinfo.len, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
struct qrcodegen_Segment seg;
bool ok = true;
if (textLen == 0) {
ok = qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, boostEcl, tempBuffer, qrcode);
} else {
ok = qrcodegen_encodeText(bufinfo.buf, tempBuffer, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (!is_bytes) {
size_t bufLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX);
if (qrcodegen_isNumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen) {
ok = false;
} else {
seg = qrcodegen_makeNumeric(text, tempBuffer);
}
} else if (qrcodegen_isAlphanumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen) {
ok = false;
} else {
seg = qrcodegen_makeAlphanumeric(text, tempBuffer);
}
} else {
is_bytes = true;
}
}
if (is_bytes) {
ok = qrcodegen_encodeBinary(
tempBuffer,
bufinfo.len,
qrcode,
ecl,
qrcodegen_VERSION_MIN,
qrcodegen_VERSION_MAX,
qrcodegen_Mask_AUTO,
boostEcl
);
} else if (ok) {
ok = qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, boostEcl, tempBuffer, qrcode);
}
}
if (!ok) {
mp_raise_ValueError("Failed to encode");
Expand All @@ -36,62 +67,18 @@ STATIC mp_obj_t qrcode_encode(mp_obj_t text_obj) {
size_t bufsize = (size * size + 7) / 8;
vstr_t vstr;
vstr_init_len(&vstr, bufsize);
for (size_t i = 0; i < bufsize - 1; ++i) {
vstr.buf[i] = qrcode[(i + 1)];
}
// Skip QR metadata byte at index 0
memcpy(vstr.buf, &qrcode[1], bufsize - 1);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(qrcode_encode_obj, qrcode_encode);


STATIC mp_obj_t qrcode_encode_to_string(mp_obj_t text_obj){
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(text_obj, &bufinfo, MP_BUFFER_READ);

enum qrcodegen_Ecc errCorLvl = qrcodegen_Ecc_LOW; // Error correction level

uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
memcpy(tempBuffer, bufinfo.buf, bufinfo.len);
bool ok = false;
bool is_bytes = false;
for(int i = 0; i < bufinfo.len; i++){
if(tempBuffer[i] == 0){ // \x00 will cut the byte array
is_bytes = true;
}
}
if(is_bytes){
ok = qrcodegen_encodeBinary(tempBuffer, bufinfo.len, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
}else{
ok = qrcodegen_encodeText(bufinfo.buf, tempBuffer, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
}
if(!ok){
mp_raise_ValueError("Failed to encode");
}
int size = qrcodegen_getSize(qrcode);
size_t bufsize = (size+1)*size;
vstr_t vstr;
vstr_init_len(&vstr, bufsize);
memset((byte*)vstr.buf, '0', bufsize);
for(int y=0; y<size; y++){
for(int x=0; x<size; x++){
if(qrcodegen_getModule(qrcode, x, y)){
vstr.buf[y*(size+1)+x]='1';
}
}
vstr.buf[y*(size+1)+size]='\n';
}
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(qrcode_encode_to_string_obj, qrcode_encode_to_string);
/****************************** MODULE ******************************/

STATIC const mp_rom_map_elem_t qrcode_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_qrcode) },
{ MP_ROM_QSTR(MP_QSTR_encode), MP_ROM_PTR(&qrcode_encode_obj) },
{ MP_ROM_QSTR(MP_QSTR_encode_to_string), MP_ROM_PTR(&qrcode_encode_to_string_obj) },
};
STATIC MP_DEFINE_CONST_DICT(qrcode_module_globals, qrcode_module_globals_table);

Expand Down
64 changes: 32 additions & 32 deletions qrcodegen/qrcodegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,41 +126,41 @@ static const int PENALTY_N4 = 10;
/*---- High-level QR Code encoding functions ----*/

// Public function - see documentation comment in header file.
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {
// bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
// enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) {

size_t textLen = strlen(text);
if (textLen == 0)
return qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
size_t bufLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);
// size_t textLen = strlen(text);
// if (textLen == 0)
// return qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
// size_t bufLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion);

struct qrcodegen_Segment seg;
if (qrcodegen_isNumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen)
goto fail;
seg = qrcodegen_makeNumeric(text, tempBuffer);
} else if (qrcodegen_isAlphanumeric(text)) {
if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen)
goto fail;
seg = qrcodegen_makeAlphanumeric(text, tempBuffer);
} else {
if (textLen > bufLen)
goto fail;
for (size_t i = 0; i < textLen; i++)
tempBuffer[i] = (uint8_t)text[i];
seg.mode = qrcodegen_Mode_BYTE;
seg.bitLength = calcSegmentBitLength(seg.mode, textLen);
if (seg.bitLength == -1)
goto fail;
seg.numChars = (int)textLen;
seg.data = tempBuffer;
}
return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);
// struct qrcodegen_Segment seg;
// if (qrcodegen_isNumeric(text)) {
// if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen)
// goto fail;
// seg = qrcodegen_makeNumeric(text, tempBuffer);
// } else if (qrcodegen_isAlphanumeric(text)) {
// if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen)
// goto fail;
// seg = qrcodegen_makeAlphanumeric(text, tempBuffer);
// } else {
// if (textLen > bufLen)
// goto fail;
// for (size_t i = 0; i < textLen; i++)
// tempBuffer[i] = (uint8_t)text[i];
// seg.mode = qrcodegen_Mode_BYTE;
// seg.bitLength = calcSegmentBitLength(seg.mode, textLen);
// if (seg.bitLength == -1)
// goto fail;
// seg.numChars = (int)textLen;
// seg.data = tempBuffer;
// }
// return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode);

fail:
qrcode[0] = 0; // Set size to invalid value for safety
return false;
}
// fail:
// qrcode[0] = 0; // Set size to invalid value for safety
// return false;
// }


// Public function - see documentation comment in header file.
Expand Down
4 changes: 2 additions & 2 deletions qrcodegen/qrcodegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ struct qrcodegen_Segment {
* - Please consult the QR Code specification for information on
* data capacities per version, ECC level, and text encoding mode.
*/
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
// bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
// enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);


/*
Expand Down