Merge branch 'task/change_qrcode' into 'master'

qrcode: Replacing the qrcode component with the one from IDF.

See merge request app-frameworks/esp-rainmaker!261
This commit is contained in:
Piyush Shah
2021-09-30 09:56:19 +00:00
5 changed files with 167 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
idf_component_register(SRCS ./src/qrcodegen.c ./src/qrcode.c
idf_component_register(SRCS ./src/qrcodegen.c ./src/esp_qrcode_main.c ./src/esp_qrcode_wrapper.c
INCLUDE_DIRS include
REQUIRES
PRIV_REQUIRES )

View File

@@ -0,0 +1,5 @@
# QR Code generator component
This directory contains a QR code generator component written in C. This component is based on [QR-Code-generator](https://github.com/nayuki/QR-Code-generator).
To learn more about how to use this component, please check API Documentation from header file [qrcode.h](./include/qrcode.h).

View File

@@ -26,6 +26,8 @@ extern "C" {
* @attention 1. Can successfully encode a UTF-8 string of up to 2953 bytes or an alphanumeric
* string of up to 4296 characters or any digit string of up to 7089 characters
*
* @note This API is kept for backward compatibility
*
* @param text string to encode into a QR Code.
*
* @return
@@ -35,6 +37,86 @@ extern "C" {
*/
esp_err_t qrcode_display(const char *text);
/**
* @brief QR Code handle used by the display function
*/
typedef const uint8_t * esp_qrcode_handle_t;
/**
* @brief QR Code configuration options
*/
typedef struct {
void (*display_func)(esp_qrcode_handle_t qrcode); /**< Function called for displaying the QR Code after encoding is complete */
int max_qrcode_version; /**< Max QR Code Version to be used. Range: 2 - 40 */
int qrcode_ecc_level; /**< Error Correction Level for QR Code */
} esp_qrcode_config_t;
/**
* @brief Error Correction Level in a QR Code Symbol
*/
enum {
ESP_QRCODE_ECC_LOW, /**< QR Code Error Tolerance of 7% */
ESP_QRCODE_ECC_MED, /**< QR Code Error Tolerance of 15% */
ESP_QRCODE_ECC_QUART, /**< QR Code Error Tolerance of 25% */
ESP_QRCODE_ECC_HIGH /**< QR Code Error Tolerance of 30% */
};
/**
* @brief Encodes the given string into a QR Code and calls the display function
*
* @attention 1. Can successfully encode a UTF-8 string of up to 2953 bytes or an alphanumeric
* string of up to 4296 characters or any digit string of up to 7089 characters
*
* @param cfg Configuration used for QR Code encoding.
* @param text String to encode into a QR Code.
*
* @return
* - ESP_OK: succeed
* - ESP_FAIL: Failed to encode string into a QR Code
* - ESP_ERR_NO_MEM: Failed to allocate buffer for given max_qrcode_version
*/
esp_err_t esp_qrcode_generate(esp_qrcode_config_t *cfg, const char *text);
/**
* @brief Displays QR Code on the console
*
* @param qrcode QR Code handle used by the display function.
*/
void esp_qrcode_print_console(esp_qrcode_handle_t qrcode);
/**
* @brief Returns the side length of the given QR Code
*
* @param qrcode QR Code handle used by the display function.
*
* @return
* - val[21, 177]: Side length of QR Code
*/
int esp_qrcode_get_size(esp_qrcode_handle_t qrcode);
/**
* @brief Returns the Pixel value for the given coordinates
* False indicates White and True indicates Black
*
* @attention 1. Coordinates for top left corner are (x=0, y=0)
* @attention 2. For out of bound coordinates false (White) is returned
*
* @param qrcode QR Code handle used by the display function.
* @param x X-Coordinate of QR Code module
* @param y Y-Coordinate of QR Code module
*
* @return
* - true: (x, y) Pixel is Black
* - false: (x, y) Pixel is White
*/
bool esp_qrcode_get_module(esp_qrcode_handle_t qrcode, int x, int y);
#define ESP_QRCODE_CONFIG_DEFAULT() (esp_qrcode_config_t) { \
.display_func = esp_qrcode_print_console, \
.max_qrcode_version = 10, \
.qrcode_ecc_level = ESP_QRCODE_ECC_LOW, \
}
#ifdef __cplusplus
}
#endif

View File

@@ -1,4 +1,4 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,10 +14,12 @@
#include <stdio.h>
#include <esp_err.h>
#include "esp_log.h"
#include "qrcodegen.h"
#include "qrcode.h"
#define MAX_QRCODE_VERSION 5
static const char *TAG = "qrcode";
static const char *lt[] = {
/* 0 */ " ",
@@ -38,13 +40,8 @@ static const char *lt[] = {
/* 15 */ "\u2588\u2588",
};
void print_qr_char(unsigned char n)
void esp_qrcode_print_console(esp_qrcode_handle_t qrcode)
{
printf("%s", lt[n]);
}
extern void print_qr_char(unsigned char);
static void printQr(const uint8_t qrcode[]) {
int size = qrcodegen_getSize(qrcode);
int border = 2;
unsigned char num = 0;
@@ -64,38 +61,69 @@ static void printQr(const uint8_t qrcode[]) {
if ((x < size + border) && (y < size + border) && qrcodegen_getModule(qrcode, x+1, y+1)) {
num |= 1 << 3;
}
print_qr_char(num);
printf("%s", lt[num]);
}
printf("\n");
}
printf("\n");
}
esp_err_t qrcode_display(const char *text)
esp_err_t esp_qrcode_generate(esp_qrcode_config_t *cfg, const char *text)
{
enum qrcodegen_Ecc errCorLvl = qrcodegen_Ecc_LOW;
uint8_t *qrcode, *tempBuffer;
enum qrcodegen_Ecc ecc_lvl;
uint8_t *qrcode, *tempbuf;
esp_err_t err = ESP_FAIL;
qrcode = calloc(1, qrcodegen_BUFFER_LEN_FOR_VERSION(MAX_QRCODE_VERSION));
if (!qrcode)
qrcode = calloc(1, qrcodegen_BUFFER_LEN_FOR_VERSION(cfg->max_qrcode_version));
if (!qrcode) {
return ESP_ERR_NO_MEM;
}
tempBuffer = calloc(1, qrcodegen_BUFFER_LEN_FOR_VERSION(MAX_QRCODE_VERSION));
if (!tempBuffer) {
tempbuf = calloc(1, qrcodegen_BUFFER_LEN_FOR_VERSION(cfg->max_qrcode_version));
if (!tempbuf) {
free(qrcode);
return ESP_ERR_NO_MEM;
}
// Make and print the QR Code symbol
bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode, errCorLvl,
qrcodegen_VERSION_MIN, MAX_QRCODE_VERSION, qrcodegen_Mask_AUTO, true);
if (ok) {
printQr(qrcode);
switch(cfg->qrcode_ecc_level) {
case ESP_QRCODE_ECC_LOW:
ecc_lvl = qrcodegen_Ecc_LOW;
break;
case ESP_QRCODE_ECC_MED:
ecc_lvl = qrcodegen_Ecc_MEDIUM;
break;
case ESP_QRCODE_ECC_QUART:
ecc_lvl = qrcodegen_Ecc_QUARTILE;
break;
case ESP_QRCODE_ECC_HIGH:
ecc_lvl = qrcodegen_Ecc_HIGH;
break;
default:
ecc_lvl = qrcodegen_Ecc_LOW;
break;
}
ESP_LOGD(TAG, "Encoding below text with ECC LVL %d & QR Code Version %d",
ecc_lvl, cfg->max_qrcode_version);
ESP_LOGD(TAG, "%s", text);
// Make and print the QR Code symbol
bool ok = qrcodegen_encodeText(text, tempbuf, qrcode, ecc_lvl,
qrcodegen_VERSION_MIN, cfg->max_qrcode_version,
qrcodegen_Mask_AUTO, true);
if (ok && cfg->display_func) {
cfg->display_func((esp_qrcode_handle_t)qrcode);
err = ESP_OK;
}
free(qrcode);
free(tempBuffer);
free(tempbuf);
return err;
}
esp_err_t qrcode_display(const char *text)
{
#define MAX_QRCODE_VERSION 5
esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT();
cfg.max_qrcode_version = MAX_QRCODE_VERSION;
return esp_qrcode_generate(&cfg, text);
}

View File

@@ -0,0 +1,29 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <esp_err.h>
#include "qrcodegen.h"
#include "qrcode.h"
int esp_qrcode_get_size(esp_qrcode_handle_t qrcode)
{
return qrcodegen_getSize(qrcode);
}
bool esp_qrcode_get_module(esp_qrcode_handle_t qrcode, int x, int y)
{
return qrcodegen_getModule(qrcode, x, y);
}