QRGenerator.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // ---------------------------------------------------------------------------
  2. //
  3. // QRGenerator
  4. //
  5. // Create: 15/05/2013
  6. // Last update: 15/05/2013
  7. //
  8. // Author: TWOTM
  9. //
  10. //
  11. // Note:
  12. //
  13. // /o ULTRAMUNDUM FOUNDATION - all rights reserved
  14. // ---------------------------------------------------------------------------
  15. // -------------------------------------------------------
  16. // Includes
  17. // -------------------------------------------------------
  18. #include "stdafx.h"
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <conio.h>
  22. #include <ctype.h>
  23. #include <stdio.h>
  24. #include <stddef.h>
  25. #include <stdlib.h>
  26. #include <wchar.h>
  27. #include "qrencode.h"
  28. // -------------------------------------------------------
  29. // -------------------------------------------------------
  30. // DEFines
  31. // -------------------------------------------------------
  32. #define QRCODE_TEXT "http://www.ultramundum.org/index.htm"; // Text to encode into QRCode
  33. #define OUT_FILE "C:/test.bmp" // Output file name
  34. #define OUT_FILE_PIXEL_PRESCALER 8 // Prescaler (number of pixels in bmp file for each QRCode pixel, on each dimension)
  35. #define PIXEL_COLOR_R 0 // Color of bmp pixels
  36. #define PIXEL_COLOR_G 0
  37. #define PIXEL_COLOR_B 0xff
  38. // BMP defines
  39. typedef unsigned short WORD;
  40. typedef unsigned long DWORD;
  41. typedef signed long LONG;
  42. #define BI_RGB 0L
  43. #pragma pack(push, 2)
  44. typedef struct
  45. {
  46. WORD bfType;
  47. DWORD bfSize;
  48. WORD bfReserved1;
  49. WORD bfReserved2;
  50. DWORD bfOffBits;
  51. } BITMAPFILEHEADER;
  52. typedef struct
  53. {
  54. DWORD biSize;
  55. LONG biWidth;
  56. LONG biHeight;
  57. WORD biPlanes;
  58. WORD biBitCount;
  59. DWORD biCompression;
  60. DWORD biSizeImage;
  61. LONG biXPelsPerMeter;
  62. LONG biYPelsPerMeter;
  63. DWORD biClrUsed;
  64. DWORD biClrImportant;
  65. } BITMAPINFOHEADER;
  66. #pragma pack(pop)
  67. // -------------------------------------------------------
  68. // -------------------------------------------------------
  69. // Main
  70. // -------------------------------------------------------
  71. int _tmain(int argc, _TCHAR* argv[])
  72. {
  73. char* szSourceSring = QRCODE_TEXT;
  74. unsigned int unWidth, x, y, l, n, unWidthAdjusted, unDataBytes;
  75. unsigned char* pRGBData, *pSourceData, *pDestData;
  76. QRcode* pQRC;
  77. FILE* f;
  78. /*
  79. * Create a symbol from the string. The library automatically parses the input
  80. * string and encodes in a QR Code symbol.
  81. * @warning This function is THREAD UNSAFE when pthread is disabled.
  82. * @param string input string. It must be NUL terminated.
  83. * @param version version of the symbol. If 0, the library chooses the minimum
  84. * version for the given input data.
  85. * @param level error correction level.
  86. * @param hint tell the library how non-alphanumerical characters should be
  87. * encoded. If QR_MODE_KANJI is given, kanji characters will be
  88. * encoded as Shif-JIS characters. If QR_MODE_8 is given, all of
  89. * non-alphanumerical characters will be encoded as is. If you want
  90. * to embed UTF-8 string, choose this.
  91. * @param casesensitive case-sensitive(1) or not(0).
  92. * @return an instance of QRcode class. The version of the result QRcode may
  93. * be larger than the designated version. On error, NULL is returned,
  94. * and errno is set to indicate the error. See Exceptions for the
  95. * details.
  96. * @throw EINVAL invalid input object.
  97. * @throw ENOMEM unable to allocate memory for input objects.
  98. * @throw ERANGE input data is too large.
  99. */
  100. // Compute QRCode
  101. if (pQRC = QRcode_encodeString(szSourceSring, 0, QR_ECLEVEL_H, QR_MODE_8, 1))
  102. {
  103. unWidth = pQRC->width;
  104. unWidthAdjusted = unWidth * OUT_FILE_PIXEL_PRESCALER * 3;
  105. if (unWidthAdjusted % 4)
  106. unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
  107. unDataBytes = unWidthAdjusted * unWidth * OUT_FILE_PIXEL_PRESCALER;
  108. // Allocate pixels buffer
  109. if (!(pRGBData = (unsigned char*)malloc(unDataBytes)))
  110. {
  111. printf("Out of memory");
  112. exit(-1);
  113. }
  114. // Preset to white
  115. memset(pRGBData, 0xff, unDataBytes);
  116. // Prepare bmp headers
  117. BITMAPFILEHEADER kFileHeader;
  118. kFileHeader.bfType = 0x4d42; // "BM"
  119. kFileHeader.bfSize = sizeof(BITMAPFILEHEADER) +
  120. sizeof(BITMAPINFOHEADER) +
  121. unDataBytes;
  122. kFileHeader.bfReserved1 = 0;
  123. kFileHeader.bfReserved2 = 0;
  124. kFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
  125. sizeof(BITMAPINFOHEADER);
  126. BITMAPINFOHEADER kInfoHeader;
  127. kInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  128. kInfoHeader.biWidth = unWidth * OUT_FILE_PIXEL_PRESCALER;
  129. kInfoHeader.biHeight = -((int)unWidth * OUT_FILE_PIXEL_PRESCALER);
  130. kInfoHeader.biPlanes = 1;
  131. kInfoHeader.biBitCount = 24;
  132. kInfoHeader.biCompression = BI_RGB;
  133. kInfoHeader.biSizeImage = 0;
  134. kInfoHeader.biXPelsPerMeter = 0;
  135. kInfoHeader.biYPelsPerMeter = 0;
  136. kInfoHeader.biClrUsed = 0;
  137. kInfoHeader.biClrImportant = 0;
  138. // Convert QrCode bits to bmp pixels
  139. pSourceData = pQRC->data;
  140. for(y = 0; y < unWidth; y++)
  141. {
  142. pDestData = pRGBData + unWidthAdjusted * y * OUT_FILE_PIXEL_PRESCALER;
  143. for(x = 0; x < unWidth; x++)
  144. {
  145. if (*pSourceData & 1)
  146. {
  147. for(l = 0; l < OUT_FILE_PIXEL_PRESCALER; l++)
  148. {
  149. for(n = 0; n < OUT_FILE_PIXEL_PRESCALER; n++)
  150. {
  151. *(pDestData + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_B;
  152. *(pDestData + 1 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_G;
  153. *(pDestData + 2 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_R;
  154. }
  155. }
  156. }
  157. pDestData += 3 * OUT_FILE_PIXEL_PRESCALER;
  158. pSourceData++;
  159. }
  160. }
  161. // Output the bmp file
  162. if (!(fopen_s(&f, OUT_FILE, "wb")))
  163. {
  164. fwrite(&kFileHeader, sizeof(BITMAPFILEHEADER), 1, f);
  165. fwrite(&kInfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
  166. fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f);
  167. fclose(f);
  168. }
  169. else
  170. {
  171. printf("Unable to open file");
  172. exit(-1);
  173. }
  174. // Free data
  175. free(pRGBData);
  176. QRcode_free(pQRC);
  177. }
  178. else
  179. {
  180. printf("NULL returned");
  181. exit(-1);
  182. }
  183. return 0;
  184. }
  185. // -------------------------------------------------------