]> git.sur5r.net Git - glabels/blob - glabels2/qrencode-3.1.0/tests/view_qrcode.c
ed86183c68a30d172566f96673c405eccf32d3e0
[glabels] / glabels2 / qrencode-3.1.0 / tests / view_qrcode.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <SDL.h>
5 #include <getopt.h>
6 #include <errno.h>
7 #include "../config.h"
8 #include "../qrspec.h"
9 #include "../qrinput.h"
10 #include "../split.h"
11 #include "../qrencode_inner.h"
12
13 static SDL_Surface *screen = NULL;
14 static int casesensitive = 1;
15 static int eightbit = 0;
16 static int version = 1;
17 static int size = 4;
18 static int margin = 4;
19 static int structured = 0;
20 static QRecLevel level = QR_ECLEVEL_L;
21 static QRencodeMode hint = QR_MODE_8;
22
23 static char **textv;
24 static int textc;
25
26 static const struct option options[] = {
27         {"help"         , no_argument      , NULL, 'h'},
28         {"level"        , required_argument, NULL, 'l'},
29         {"size"         , required_argument, NULL, 's'},
30         {"symversion"   , required_argument, NULL, 'v'},
31         {"margin"       , required_argument, NULL, 'm'},
32         {"structured"   , no_argument      , NULL, 'S'},
33         {"kanji"        , no_argument      , NULL, 'k'},
34         {"casesensitive", no_argument      , NULL, 'c'},
35         {"ignorecase"   , no_argument      , NULL, 'i'},
36         {"8bit"         , no_argument      , NULL, '8'},
37         {"version"      , no_argument      , NULL, 'V'},
38         {NULL, 0, NULL, 0}
39 };
40
41 static char *optstring = "ho:l:s:v:m:Skci8V";
42
43 static char levelChar[4] = {'L', 'M', 'Q', 'H'};
44 static void usage(int help, int longopt)
45 {
46         fprintf(stderr,
47 "view_qrcode version %s\n"
48 "Copyright (C) 2008, 2009 Kentaro Fukuchi\n", VERSION);
49         if(help) {
50                 if(longopt) {
51                         fprintf(stderr,
52 "Usage: view_qrcode [OPTION]... [STRING]\n"
53 "Encode input data in a QR Code and display.\n\n"
54 "  -h, --help   display the help message. -h displays only the help of short\n"
55 "               options.\n\n"
56 "  -s NUMBER, --size=NUMBER\n"
57 "               specify the size of dot (pixel). (default=3)\n\n"
58 "  -l {LMQH}, --level={LMQH}\n"
59 "               specify error collectin level from L (lowest) to H (highest).\n"
60 "               (default=L)\n\n"
61 "  -v NUMBER, --symversion=NUMBER\n"
62 "               specify the version of the symbol. (default=auto)\n\n"
63 "  -m NUMBER, --margin=NUMBER\n"
64 "               specify the width of margin. (default=4)\n\n"
65 "  -S, --structured\n"
66 "               make structured symbols. Version must be specified.\n\n"
67 "  -k, --kanji  assume that the input text contains kanji (shift-jis).\n\n"
68 "  -c, --casesensitive\n"
69 "               encode lower-case alphabet characters in 8-bit mode. (default)\n\n"
70 "  -i, --ignorecase\n"
71 "               ignore case distinctions and use only upper-case characters.\n\n"
72 "  -8, -8bit    encode entire data in 8-bit mode. -k, -c and -i will be ignored.\n\n"
73 "  -V, --version\n"
74 "               display the version number and copyrights of the qrencode.\n\n"
75 "  [STRING]     input data. If it is not specified, data will be taken from\n"
76 "               standard input.\n"
77                         );
78                 } else {
79                         fprintf(stderr,
80 "Usage: view_qrcode [OPTION]... [STRING]\n"
81 "Encode input data in a QR Code and display.\n\n"
82 "  -h           display this message.\n"
83 "  --help       display the usage of long options.\n"
84 "  -s NUMBER    specify the size of dot (pixel). (default=3)\n"
85 "  -l {LMQH}    specify error collectin level from L (lowest) to H (highest).\n"
86 "               (default=L)\n"
87 "  -v NUMBER    specify the version of the symbol. (default=auto)\n"
88 "  -m NUMBER    specify the width of margin. (default=4)\n"
89 "  -S           make structured symbols. Version must be specified.\n"
90 "  -k           assume that the input text contains kanji (shift-jis).\n"
91 "  -c           encode lower-case alphabet characters in 8-bit mode. (default)\n"
92 "  -i           ignore case distinctions and use only upper-case characters.\n"
93 "  -8           encode entire data in 8-bit mode. -k, -c and -i will be ignored.\n"
94 "  -V           display the version number and copyrights of the qrencode.\n"
95 "  [STRING]     input data. If it is not specified, data will be taken from\n"
96 "               standard input.\n"
97                         );
98                 }
99         }
100 }
101
102 #define MAX_DATA_SIZE (7090 * 16) /* from the specification */
103 static char *readStdin(void)
104 {
105         char *buffer;
106         int ret;
107
108         buffer = (char *)malloc(MAX_DATA_SIZE);
109         ret = fread(buffer, 1, MAX_DATA_SIZE, stdin);
110         if(ret == 0) {
111                 fprintf(stderr, "No input data.\n");
112                 exit(1);
113         }
114         if(!feof(stdin)) {
115                 fprintf(stderr, "Input data is too large.\n");
116                 exit(1);
117         }
118
119         buffer[ret] = '\0';
120
121         return buffer;
122 }
123
124 static void draw_QRcode(QRcode *qrcode, int ox, int oy)
125 {
126         int x, y, width;
127         unsigned char *p;
128         SDL_Rect rect;
129
130         ox += margin * size;
131         oy += margin * size;
132         width = qrcode->width;
133         p = qrcode->data;
134         for(y=0; y<width; y++) {
135                 for(x=0; x<width; x++) {
136                         rect.x = ox + x * size;
137                         rect.y = oy + y * size;
138                         rect.w = size;
139                         rect.h = size;
140                         SDL_FillRect(screen, &rect, (*p&1)?0:0xffffff);
141                         p++;
142                 }
143         }
144 }
145
146 void draw_singleQRcode(QRinput *stream, int mask)
147 {
148         QRcode *qrcode;
149         int width;
150
151         QRinput_setVersion(stream, version);
152         QRinput_setErrorCorrectionLevel(stream, level);
153         qrcode = QRcode_encodeMask(stream, mask);
154         if(qrcode == NULL) return;
155
156         version = qrcode->version;
157         width = (qrcode->width + margin * 2) * size;
158
159         screen = SDL_SetVideoMode(width, width, 32, 0);
160         SDL_FillRect(screen, NULL, 0xffffff);
161         draw_QRcode(qrcode, 0, 0);
162         SDL_Flip(screen);
163         QRcode_free(qrcode);
164 }
165
166 void draw_structuredQRcode(QRinput_Struct *s)
167 {
168         int i, w, h, n, x, y;
169         int swidth;
170         QRcode_List *qrcodes, *p;
171
172         qrcodes = QRcode_encodeInputStructured(s);
173         if(qrcodes == NULL) return;
174
175         swidth = (qrcodes->code->width + margin * 2) * size;
176         n = QRcode_List_size(qrcodes);
177         w = (n < 4)?n:4;
178         h = (n - 1) / 4 + 1;
179
180         screen = SDL_SetVideoMode(swidth * w, swidth * h, 32, 0);
181         SDL_FillRect(screen, NULL, 0xffffff);
182
183         p = qrcodes;
184         for(i=0; i<n; i++) {
185                 x = (i % 4) * swidth;
186                 y = (i / 4) * swidth;
187                 draw_QRcode(p->code, x, y);
188                 p = p->next;
189         }
190         SDL_Flip(screen);
191         QRcode_List_free(qrcodes);
192 }
193
194 void draw_structuredQRcodeFromText(int argc, char **argv)
195 {
196         QRinput_Struct *s;
197         QRinput *input;
198         int i, ret;
199
200         s = QRinput_Struct_new();
201         if(s == NULL) {
202                 fprintf(stderr, "Failed to allocate memory.\n");
203                 exit(1);
204         }
205         for(i=0; i<argc; i++) {
206                 input = QRinput_new2(version, level);
207                 if(input == NULL) {
208                         fprintf(stderr, "Failed to allocate memory.\n");
209                         exit(1);
210                 }
211                 if(eightbit) {
212                         ret = QRinput_append(input, QR_MODE_8, strlen(argv[i]), (unsigned char *)argv[i]);
213                 } else {
214                         ret = Split_splitStringToQRinput(argv[i], input, hint, casesensitive);
215                 }
216                 if(ret < 0) {
217                         perror("Encoding the input string");
218                         exit(1);
219                 }
220                 ret = QRinput_Struct_appendInput(s, input);
221                 if(ret < 0) {
222                         perror("Encoding the input string");
223                         exit(1);
224                 }
225         }
226         ret = QRinput_Struct_insertStructuredAppendHeaders(s);
227         if(ret < 0) {
228                 fprintf(stderr, "Too many inputs.\n");
229         }
230
231         draw_structuredQRcode(s);
232         QRinput_Struct_free(s);
233 }
234
235 void draw_structuredQRcodeFromQRinput(QRinput *stream)
236 {
237         QRinput_Struct *s;
238
239         QRinput_setVersion(stream, version);
240         QRinput_setErrorCorrectionLevel(stream, level);
241         s = QRinput_splitQRinputToStruct(stream);
242         if(s != NULL) {
243                 draw_structuredQRcode(s);
244                 QRinput_Struct_free(s);
245         } else {
246                 fprintf(stderr, "Input data is too large for this setting.\n");
247         }
248 }
249
250 void view(int mode, QRinput *input)
251 {
252         int flag = 1;
253         int mask = -1;
254         SDL_Event event;
255         int loop;
256
257         while(flag) {
258                 if(mode) {
259                         draw_structuredQRcodeFromText(textc, textv);
260                 } else {
261                         if(structured) {
262                                 draw_structuredQRcodeFromQRinput(input);
263                         } else {
264                                 draw_singleQRcode(input, mask);
265                         }
266                 }
267                 if(mode || structured) {
268                         printf("Version %d, Level %c.\n", version, levelChar[level]);
269                 } else {
270                         printf("Version %d, Level %c, Mask %d.\n", version, levelChar[level], mask);
271                 }
272                 loop = 1;
273                 while(loop) {
274                         usleep(10000);
275                         while(SDL_PollEvent(&event)) {
276                                 if(event.type == SDL_KEYDOWN) {
277                                         switch(event.key.keysym.sym) {
278                                         case SDLK_RIGHT:
279                                                 version++;
280                                                 if(version > QRSPEC_VERSION_MAX)
281                                                         version = QRSPEC_VERSION_MAX;
282                                                 loop = 0;
283                                                 break;
284                                         case SDLK_LEFT:
285                                                 version--;
286                                                 if(version < 1)
287                                                         version = 1;
288                                                 loop = 0;
289                                                 break;
290                                         case SDLK_UP:
291                                                 size++;
292                                                 loop = 0;
293                                                 break;
294                                         case SDLK_DOWN:
295                                                 size--;
296                                                 if(size < 1) size = 1;
297                                                 loop = 0;
298                                                 break;
299                                         case SDLK_0:
300                                         case SDLK_1:
301                                         case SDLK_2:
302                                         case SDLK_3:
303                                         case SDLK_4:
304                                         case SDLK_5:
305                                         case SDLK_6:
306                                         case SDLK_7:
307                                                 if(!mode && !structured) {
308                                                         mask = (event.key.keysym.sym - SDLK_0);
309                                                         loop = 0;
310                                                 }
311                                                 break;
312                                         case SDLK_8:
313                                                 if(!mode && !structured) {
314                                                         mask = -1;
315                                                         loop = 0;
316                                                 }
317                                                 break;
318                                         case SDLK_l:
319                                                 level = QR_ECLEVEL_L;
320                                                 loop = 0;
321                                                 break;
322                                         case SDLK_m:
323                                                 level = QR_ECLEVEL_M;
324                                                 loop = 0;
325                                                 break;
326                                         case SDLK_h:
327                                                 level = QR_ECLEVEL_H;
328                                                 loop = 0;
329                                                 break;
330                                         case SDLK_q:
331                                                 level = QR_ECLEVEL_Q;
332                                                 loop = 0;
333                                                 break;
334                                         case SDLK_ESCAPE:
335                                                 loop = 0;
336                                                 flag = 0;
337                                                 break;
338                                         default:
339                                                 break;
340                                         }
341                                 }
342                                 if(event.type == SDL_QUIT) {
343                                         loop = 0;
344                                         flag = 0;
345                                 }
346                         }
347                 }
348         }
349 }
350
351 void view_simple(const char *str)
352 {
353         QRinput *input;
354         int ret;
355
356         input = QRinput_new2(version, level);
357         if(input == NULL) {
358                 fprintf(stderr, "Memory allocation error.\n");
359                 exit(1);
360         }
361         if(eightbit) {
362                 ret = QRinput_append(input, QR_MODE_8, strlen(str), (unsigned char *)str);
363         } else {
364                 ret = Split_splitStringToQRinput(str, input, hint, casesensitive);
365         }
366         if(ret < 0) {
367                 perror("Encoding the input string");
368                 exit(1);
369         }
370
371         view(0, input);
372
373         QRinput_free(input);
374 }
375
376 void view_multiText(char **argv, int argc)
377 {
378         textc = argc;
379         textv = argv;
380
381         view(1, NULL);
382 }
383
384 int main(int argc, char **argv)
385 {
386         int opt, lindex = -1;
387         char *intext = NULL;
388
389         while((opt = getopt_long(argc, argv, optstring, options, &lindex)) != -1) {
390                 switch(opt) {
391                         case 'h':
392                                 if(lindex == 0) {
393                                         usage(1, 1);
394                                 } else {
395                                         usage(1, 0);
396                                 }
397                                 exit(0);
398                                 break;
399                         case 's':
400                                 size = atoi(optarg);
401                                 if(size <= 0) {
402                                         fprintf(stderr, "Invalid size: %d\n", size);
403                                         exit(1);
404                                 }
405                                 break;
406                         case 'v':
407                                 version = atoi(optarg);
408                                 if(version < 0) {
409                                         fprintf(stderr, "Invalid version: %d\n", version);
410                                         exit(1);
411                                 }
412                                 break;
413                         case 'l':
414                                 switch(*optarg) {
415                                         case 'l':
416                                         case 'L':
417                                                 level = QR_ECLEVEL_L;
418                                                 break;
419                                         case 'm':
420                                         case 'M':
421                                                 level = QR_ECLEVEL_M;
422                                                 break;
423                                         case 'q':
424                                         case 'Q':
425                                                 level = QR_ECLEVEL_Q;
426                                                 break;
427                                         case 'h':
428                                         case 'H':
429                                                 level = QR_ECLEVEL_H;
430                                                 break;
431                                         default:
432                                                 fprintf(stderr, "Invalid level: %s\n", optarg);
433                                                 exit(1);
434                                                 break;
435                                 }
436                                 break;
437                         case 'm':
438                                 margin = atoi(optarg);
439                                 if(margin < 0) {
440                                         fprintf(stderr, "Invalid margin: %d\n", margin);
441                                         exit(1);
442                                 }
443                                 break;
444                         case 'S':
445                                 structured = 1;
446                         case 'k':
447                                 hint = QR_MODE_KANJI;
448                                 break;
449                         case 'c':
450                                 casesensitive = 1;
451                                 break;
452                         case 'i':
453                                 casesensitive = 0;
454                                 break;
455                         case '8':
456                                 eightbit = 1;
457                                 break;
458                         case 'V':
459                                 usage(0, 0);
460                                 exit(0);
461                                 break;
462                         default:
463                                 fprintf(stderr, "Try `view_qrcode --help' for more information.\n");
464                                 exit(1);
465                                 break;
466                 }
467         }
468         if(argc == 1) {
469                 usage(1, 0);
470                 exit(0);
471         }
472
473         if(optind < argc) {
474                 intext = argv[optind];
475         }
476         if(intext == NULL) {
477                 intext = readStdin();
478         }
479
480         if(SDL_Init(SDL_INIT_VIDEO) < 0) {
481                 fprintf(stderr, "Failed initializing SDL: %s\n", SDL_GetError());
482                 return -1;
483         }
484         if(structured && version < 1) {
485                 fprintf(stderr, "Version number must be greater than 0 to encode structured symbols.\n");
486                 exit(1);
487         }
488         if(structured && (argc - optind > 1)) {
489                 view_multiText(argv + optind, argc - optind);
490         } else {
491                 view_simple(intext);
492         }
493
494         SDL_Quit();
495
496         return 0;
497 }