Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file taler-merchant-httpd_qr.c
18 : * @brief logic to create QR codes in HTML
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include <gnunet/gnunet_util_lib.h>
23 : #include <qrencode.h>
24 : #include <taler-merchant-httpd_qr.h>
25 :
26 : /**
27 : * Create the HTML for a QR code for a URI.
28 : *
29 : * @param uri input string to encode
30 : * @return NULL on error, encoded URI otherwise
31 : */
32 : char *
33 0 : TMH_create_qrcode (const char *uri)
34 : {
35 : QRinput *qri;
36 : QRcode *qrc;
37 0 : struct GNUNET_Buffer buf = { 0 };
38 :
39 0 : qri = QRinput_new2 (0,
40 : QR_ECLEVEL_M);
41 0 : if (NULL == qri)
42 : {
43 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
44 : "QRinput_new2");
45 0 : return NULL;
46 : }
47 : /* first try encoding as uppercase-only alpha-numerical
48 : QR code (much smaller encoding); if that fails, also
49 : try using binary encoding */
50 0 : if ( (0 !=
51 0 : QRinput_append (qri,
52 : QR_MODE_AN,
53 0 : strlen (uri),
54 0 : (unsigned char *) uri)) &&
55 : (0 !=
56 0 : QRinput_append (qri,
57 : QR_MODE_8,
58 0 : strlen (uri),
59 : (unsigned char *) uri)) )
60 : {
61 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
62 : "QRinput_append");
63 0 : QRinput_free (qri);
64 0 : return NULL;
65 : }
66 0 : qrc = QRcode_encodeInput (qri);
67 0 : if (NULL == qrc)
68 : {
69 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
70 : "QRcode_encodeInput");
71 0 : QRinput_free (qri);
72 0 : return NULL;
73 : }
74 0 : QRinput_free (qri);
75 0 : GNUNET_buffer_write_fstr (&buf,
76 : "<svg width='100mm' height='100mm' viewBox='0 0 %u %u' "
77 : "version='1.1' xmlns='http://www.w3.org/2000/svg' "
78 : "style='shape-rendering: crispedges;'>\n",
79 : qrc->width,
80 : qrc->width);
81 0 : for (unsigned int y = 0; y<(unsigned int) qrc->width; y++)
82 : {
83 0 : for (unsigned int x = 0; x<(unsigned int) qrc->width; x++)
84 : {
85 0 : unsigned int off = x + y * (unsigned int) qrc->width;
86 0 : if (0 == (qrc->data[off] & 1))
87 0 : continue;
88 0 : GNUNET_buffer_write_fstr (&buf,
89 : " <rect x=%u y=%u width=1 height=1 />\n",
90 : x,
91 : y);
92 : }
93 : }
94 0 : GNUNET_buffer_write_str (&buf,
95 : "</svg>");
96 0 : QRcode_free (qrc);
97 0 : return GNUNET_buffer_reap_str (&buf);
98 : }
|