qrc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "qrcode.h"
  2. #include "rpng.h"
  3. #include "file.h"
  4. #include "elog.h"
  5. #define QRC_RESIZE
  6. #if 1
  7. #define LOGD log_d
  8. #define LOGE log_e
  9. #else
  10. #define LOGD printf
  11. #define LOGE printf
  12. #endif
  13. static const uint8_t base64_enc_map[64] =
  14. {
  15. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  16. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  17. 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  18. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  19. 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  20. 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  21. '8', '9', '+', '/'
  22. };
  23. static int base64_len(int n)
  24. {
  25. return ((n / 3) + (n % 3 ? 1 : 0)) * 4 + 1;
  26. }
  27. static int base64_encode(uint8_t *src, size_t slen, uint8_t *dst, size_t dlen)
  28. {
  29. size_t i, n;
  30. int C1, C2, C3;
  31. uint8_t *p;
  32. if( slen == 0 ) {
  33. return -1;
  34. }
  35. n = (slen / 3 + ( slen % 3 != 0 )) * 4;
  36. if( ( dlen < n + 1 ) || ( NULL == dst ) ) {
  37. return -1;
  38. }
  39. n = ( slen / 3 ) * 3;
  40. for( i = 0, p = dst; i < n; i += 3 ) {
  41. C1 = *src++;
  42. C2 = *src++;
  43. C3 = *src++;
  44. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  45. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  46. *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
  47. *p++ = base64_enc_map[C3 & 0x3F];
  48. }
  49. if( i < slen ) {
  50. C1 = *src++;
  51. C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
  52. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  53. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  54. if( ( i + 1 ) < slen )
  55. *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
  56. else *p++ = '=';
  57. *p++ = '=';
  58. }
  59. *p = 0;
  60. return (p - dst);
  61. }
  62. //////////////////////////////////////////////////////////////
  63. #if 1
  64. static inline int in_array(int x, int y, int w, int h)
  65. {
  66. if (x >= 0 && x < w && y >= 0 && y < h)
  67. return 1;
  68. else
  69. return 0;
  70. }
  71. static uint32_t* rgb_resize(uint32_t* in, int w, int h, int w2, int h2)
  72. {
  73. int i,j,x1, y1, x2, y2;
  74. double f11, f12, f21, f22;
  75. double a,b,c,d,e,f;
  76. double h_times = (double)h2 / (double)h,
  77. w_times = (double)w2 / (double)w;
  78. uint32_t *out=(uint32_t*)malloc(h2*w2*4);
  79. if(out) {
  80. for (i=0; i<h2; i++){
  81. for (j=0; j<w2; j++) {
  82. #if 0
  83. double x = j / w_times;
  84. double y = i / h_times;
  85. x1 = (int)(x - 1);
  86. x2 = (int)(x + 1);
  87. y1 = (int)(y - 1);
  88. y2 = (int)(y + 1);
  89. f11 = in_array(x1, y1, h, w) ? in[y1*w+x1] : 0;
  90. f12 = in_array(x1, y2, h, w) ? in[y2*w+x1] : 0;
  91. f21 = in_array(x2, y1, h, w) ? in[y1*w+x2] : 0;
  92. f22 = in_array(x2, y2, h, w) ? in[y2*w+x2] : 0;
  93. a = f11 * (x2 - x) * (y2 - y);
  94. b = f12 * (x2 - x) * (y - y1);
  95. c = f21 * (x - x1) * (y2 - y);
  96. d = f22 * (x - x1) * (y - y1);
  97. e = (x2 - x1) * (y2 - y1);
  98. f = (a +b + c + d) / e;
  99. out[i*w2+j] = (uint32_t)f;
  100. #else
  101. int x = j / w_times;
  102. int y = i / h_times;
  103. out[i*w2+j] = in[y*w+x];
  104. #endif
  105. }
  106. }
  107. }
  108. return out;
  109. }
  110. #else
  111. #endif
  112. #define RGBA(r,g,b,a) (((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
  113. int qrc_to_png(char *txt, char *path)
  114. {
  115. int r,x,y;
  116. QRCode qrc;
  117. int size,size2;
  118. int ver=8,ecc=ECC_QUARTILE;
  119. uint16_t bufsz=qrcode_getBufferSize(ver);
  120. uint8_t *pQRC=(uint8_t*)malloc(bufsz);
  121. r = qrcode_initText(&qrc, pQRC, ver, ecc, txt);
  122. if(!pQRC || r<0) {
  123. if(pQRC) free(pQRC);
  124. return -1;
  125. }
  126. size = qrc.size;
  127. uint32_t *pRGB=(uint32_t*)malloc(size*size*4);
  128. if(!pRGB) {
  129. free(pQRC);
  130. return -1;
  131. }
  132. for (y=0; y<size; y++) { // row
  133. for (x=0; x<size; x++) {// module pixel (height)
  134. if (qrcode_getModule(&qrc, x, y)) {
  135. pRGB[y*size+x] = RGBA(0,0,0,255);
  136. }
  137. else {
  138. pRGB[y*qrc.size+x] = RGBA(255,255,255,255);
  139. }
  140. }
  141. }
  142. #ifdef QRC_RESIZE
  143. size2 = size*6;
  144. uint32_t *pRGB2 = rgb_resize(pRGB, size, size, size2, size2);
  145. if(!pRGB2) {
  146. free(pQRC); free(pRGB);
  147. return -1;
  148. }
  149. free(pRGB);
  150. pRGB = pRGB2;
  151. size = size2;
  152. #endif
  153. int pngSize=0;
  154. char *pPNG = rpng_save_image_to_memory((const char*)pRGB, size, size, 4, 8, &pngSize);
  155. if(pPNG) {
  156. r = file_save(path, pPNG, pngSize);
  157. #if 0 //def QRC_BASE64
  158. char *p64buf=NULL;
  159. int b64len = base64_len(pngSize)+8;
  160. p64buf = (char*)malloc(b64len);
  161. if(p64buf) {
  162. int d64len = base64_encode((uint8_t*)pPNG, pngSize, (uint8_t*)p64buf, b64len);
  163. p64buf[d64len] = 0;
  164. }
  165. #endif
  166. RPNG_FREE(pPNG);
  167. }
  168. free(pRGB);
  169. free(pQRC);
  170. return 0;
  171. }
  172. int qrc_free(void *p)
  173. {
  174. if(!p) {
  175. return -1;
  176. }
  177. free(p);
  178. return 0;
  179. }