浏览代码

二维码ok

guohui 1 年之前
父节点
当前提交
7a5e1e8b73
共有 5 个文件被更改,包括 139 次插入 和 25 次删除
  1. 6 1
      pro/CMakeLists.txt
  2. 118 11
      pro/qrcode/qrc.c
  3. 2 2
      pro/qrcode/qrc.h
  4. 9 9
      pro/qrcode/qrcode.c
  5. 4 2
      pro/qrcode/rpng.h

+ 6 - 1
pro/CMakeLists.txt

@@ -35,6 +35,8 @@ include_directories (${PROJECT_SOURCE_DIR}/modbus/inc)
 include_directories (${PROJECT_SOURCE_DIR}/snmp/include)
 include_directories (${PROJECT_SOURCE_DIR}/upgrade)
 include_directories (${PROJECT_SOURCE_DIR}/config)
+include_directories (${PROJECT_SOURCE_DIR}/qrcode)
+include_directories (${PROJECT_SOURCE_DIR}/src)
 
 
 link_directories(${PROJECT_SOURCE_DIR}/appweb/lib)
@@ -62,6 +64,9 @@ set(PDU_SRC_LIST
 	${PROJECT_SOURCE_DIR}/ini/dictionary.c
 	${PROJECT_SOURCE_DIR}/ini/iniparser.c
 
+        ${PROJECT_SOURCE_DIR}/qrcode/qrcode.c
+        ${PROJECT_SOURCE_DIR}/qrcode/qrc.c
+
 	${PROJECT_SOURCE_DIR}/mongoose/mongoose.c
 	${PROJECT_SOURCE_DIR}/src/websocket_handle.c
 
@@ -275,4 +280,4 @@ set(PDU_SRC_LIST
 	COMMAND mkdir -p ${DST_DIR}/${CHIP}/root/mnt/UDISK/app
 	COMMAND cp -upf  ${SRC_DIR}/smartPDU ${DST_DIR}/${CHIP}/root/mnt/UDISK/app)
 
-endif()
+endif()

+ 118 - 11
pro/qrcode/qrc.c

@@ -1,6 +1,8 @@
-#include "elog.h"
 #include "qrcode.h"
 #include "rpng.h"
+#include "file.h"
+#include "elog.h"
+
 
 #if 1
     #define LOGD  log_d
@@ -12,20 +14,125 @@
 
 
 
-
-
-int qrc_make(char *txt, )
+static const uint8_t base64_enc_map[64] =
 {
-    QRCode qrcode;
-    uint8_t qrcodeBytes[qrcode_getBufferSize()];
-
-    qrcode_initText(&qrcode, qrcodeBytes, 3, ECC_LOW, txt;
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', '+', '/'
+};
+static int base64_len(int n)
+{
+    return ((n / 3) + (n % 3 ? 1 : 0)) * 4 + 1;
+}
+static int base64_encode(uint8_t *src, size_t slen, uint8_t *dst, size_t dlen)
+{
+    size_t i, n;
+    int C1, C2, C3;
+    uint8_t *p;
+ 
+    if( slen == 0 ) {
+        return -1;
+    }
+ 
+    n = (slen / 3 + ( slen % 3 != 0 )) * 4;
+    if( ( dlen < n + 1 ) || ( NULL == dst ) ) {
+        return -1;
+    }
+ 
+    n = ( slen / 3 ) * 3;
+    for( i = 0, p = dst; i < n; i += 3 ) {
+        C1 = *src++;
+        C2 = *src++;
+        C3 = *src++;
+ 
+        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
+        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
+        *p++ = base64_enc_map[C3 & 0x3F];
+    }
+ 
+    if( i < slen ) {
+        C1 = *src++;
+        C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
+ 
+        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+ 
+        if( ( i + 1 ) < slen )
+             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+        else *p++ = '=';
+ 
+        *p++ = '=';
+    }
+    *p = 0;
+ 
+    return (p - dst);
+}
+//////////////////////////////////////////////////////////////
+#define ARGB(a,r,g,b) (((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
+char* qrc_txt_to_png(char *txt)
+{
+    QRCode qrc;
+    int x,y;
+    char *p64buf=NULL;
+    uint8_t blackPixel=0x00,whitePixel=0xFF;
     
-    for (uint8 y = 0; y < qrcode.size; y++) {
-    for (uint8 x = 0; x < qrcode.size; x++) {
-        if (qrcode_getModule(&qrcode, x, y) {
+    int ver=6,ecc=ECC_QUARTILE;
+    uint16_t bufsz=qrcode_getBufferSize(ver);
+    uint8_t *pQRC=(uint8_t*)malloc(bufsz);
+    uint32_t *pRGB=(uint32_t*)malloc(qrc.size*qrc.size);
+    
+    if(!pQRC || !pRGB) {
+        if(pQRC) free(pQRC);
+        if(pRGB) free(pRGB);
+        return NULL;
+    }
+    qrcode_initText(&qrc, pQRC, ver, ecc, txt);
+    
+    for (y=0; y<qrc.size; y++) {    // row
+        for (x=0; x<qrc.size; x++) {// module pixel (height)
+            if (qrcode_getModule(&qrc, x, y)) {
+                pRGB[y*qrc.size+x] = ARGB(255,0,0,0);
+            }
+            else {
+                pRGB[y*qrc.size+x] = ARGB(200,255,255,255);
+            }
+        }
+    }
+
+    int pngSize;
+    char *pPNG = rpng_save_image_to_memory((const char*)pRGB, qrc.size, qrc.size, 4, 8, &pngSize);
+    if(pPNG) {
+        //file_save("/tmp/xxx.png", pPNG, pngSize);
+
+        int b64len = base64_len(pngSize)+8;
+        p64buf = (char*)malloc(b64len);
+        if(p64buf) {
+            
+            extern char *rpng_save_image_to_memory(const char *data, int width, int height, int color_channels, int bit_depth, int *output_size);
+            int d64len = base64_encode((uint8_t*)pPNG, pngSize, (uint8_t*)p64buf, b64len);
             
         }
+        RPNG_FREE(pPNG);
+    }
+    free(pRGB);
+    free(pQRC);
     
+    return p64buf;
 }
 
+
+int qrc_free(void *p)
+{
+    if(!p) {
+        return -1;
+    }
+    free(p);
+    return 0;
+}
+
+

+ 2 - 2
pro/qrcode/qrc.h

@@ -1,8 +1,8 @@
 #ifndef __QRC_Hx__
 #define __QRC_Hx__
 
-
-int qrc_make(void);
+char* qrc_txt_to_png(char *txt);
+int qrc_free(void *p);
 
 #endif
 

+ 9 - 9
pro/qrcode/qrcode.c

@@ -38,7 +38,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#pragma mark - Error Correction Lookup tables
+//#pragma mark - Error Correction Lookup tables
 
 #if LOCK_VERSION == 0
 
@@ -101,7 +101,7 @@ static int abs(int value) {
 */
 
 
-#pragma mark - Mode testing and conversion
+//#pragma mark - Mode testing and conversion
 
 static int8_t getAlphanumeric(char c) {
     
@@ -140,7 +140,7 @@ static bool isNumeric(const char *text, uint16_t length) {
 }
 
 
-#pragma mark - Counting
+////#pragma mark - Counting
 
 // We store the following tightly packed (less 8) in modeInfo
 //               <=9  <=26  <= 40
@@ -167,7 +167,7 @@ static char getModeBits(uint8_t version, uint8_t mode) {
 }
 
 
-#pragma mark - BitBucket
+//#pragma mark - BitBucket
 
 typedef struct BitBucket {
     uint32_t bitOffsetOrWidth;
@@ -251,7 +251,7 @@ static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) {
 }
 
 
-#pragma mark - Drawing Patterns
+//#pragma mark - Drawing Patterns
 
 // XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
 // properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
@@ -474,7 +474,7 @@ static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *
 
 
 
-#pragma mark - Penalty Calculation
+//#pragma mark - Penalty Calculation
 
 #define PENALTY_N1      3
 #define PENALTY_N2      3
@@ -574,7 +574,7 @@ static uint32_t getPenaltyScore(BitBucket *modules) {
 }
 
 
-#pragma mark - Reed-Solomon Generator
+//#pragma mark - Reed-Solomon Generator
 
 static uint8_t rs_multiply(uint8_t x, uint8_t y) {
     // Russian peasant multiplication
@@ -628,7 +628,7 @@ static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8
 
 
 
-#pragma mark - QrCode
+//#pragma mark - QrCode
 
 static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) {
     int8_t mode = MODE_BYTE;
@@ -769,7 +769,7 @@ static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data
 static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0);
 
 
-#pragma mark - Public QRCode functions
+//#pragma mark - Public QRCode functions
 
 uint16_t qrcode_getBufferSize(uint8_t version) {
     return bb_getGridSizeBytes(4 * version + 17);

+ 4 - 2
pro/qrcode/rpng.h

@@ -321,7 +321,7 @@ RPNGAPI char *rpng_chunk_split_image_data_from_memory(char *buffer, int split_si
 *   RPNG IMPLEMENTATION
 *
 ************************************************************************************/
-
+#define RPNG_IMPLEMENTATION
 #if defined(RPNG_IMPLEMENTATION)
 
 #if !defined(RPNG_NO_STDIO)
@@ -492,6 +492,7 @@ static int save_file_from_buffer(const char *filename, void *data, int bytesToWr
 static bool file_exists(const char *filename);
 
 // sdelf and sinfl implementations placed at the end of file
+#define SINFL_NO_SIMD
 #define SDEFL_IMPLEMENTATION
 #define SINFL_IMPLEMENTATION
 
@@ -2336,6 +2337,7 @@ static bool file_exists(const char *filename)
     return result;
 }
 
+#define RPNG_DEFLATE_IMPLEMENTATION
 #if defined(RPNG_DEFLATE_IMPLEMENTATION)
 
 //=========================================================================
@@ -2986,7 +2988,7 @@ sdefl_bound(int len) {
   #include <arm_neon.h>
   #define sinfl_char16 uint8x16_t
   #define sinfl_char16_ld(p) vld1q_u8((const unsigned char*)(p))
-  #define sinfl_char16_str(d,v) vst1q_u8((unsigned char*)(d), v)
+  #define sinfl_char16_str(d,v) vst1q_u8((uint8_t*)(d), v)
   #define sinfl_char16_char(c) vdupq_n_u8(c)
 #else
   #define SINFL_NO_SIMD