1 /*
2 * qrencode - QR Code encoder
3 *
4 * Input data chunk class
5 * Copyright (C) 2006-2011 Kentaro Fukuchi <kentaro@fukuchi.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include "qrencode.h"
31 #include "qrspec.h"
32 #include "mqrspec.h"
33 #include "bitstream.h"
34 #include "qrinput.h"
35
36 /******************************************************************************
37 * Utilities
38 *****************************************************************************/
QRinput_isSplittableMode(QRencodeMode mode)39 int QRinput_isSplittableMode(QRencodeMode mode)
40 {
41 return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI);
42 }
43
44 /******************************************************************************
45 * Entry of input data
46 *****************************************************************************/
47
QRinput_List_newEntry(QRencodeMode mode,int size,const unsigned char * data)48 static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data)
49 {
50 QRinput_List *entry;
51
52 if(QRinput_check(mode, size, data)) {
53 errno = EINVAL;
54 return NULL;
55 }
56
57 entry = (QRinput_List *)malloc(sizeof(QRinput_List));
58 if(entry == NULL) return NULL;
59
60 entry->mode = mode;
61 entry->size = size;
62 if(size > 0) {
63 entry->data = (unsigned char *)malloc(size);
64 if(entry->data == NULL) {
65 free(entry);
66 return NULL;
67 }
68 memcpy(entry->data, data, size);
69 }
70 entry->bstream = NULL;
71 entry->next = NULL;
72
73 return entry;
74 }
75
QRinput_List_freeEntry(QRinput_List * entry)76 static void QRinput_List_freeEntry(QRinput_List *entry)
77 {
78 if(entry != NULL) {
79 free(entry->data);
80 BitStream_free(entry->bstream);
81 free(entry);
82 }
83 }
84
QRinput_List_dup(QRinput_List * entry)85 static QRinput_List *QRinput_List_dup(QRinput_List *entry)
86 {
87 QRinput_List *n;
88
89 n = (QRinput_List *)malloc(sizeof(QRinput_List));
90 if(n == NULL) return NULL;
91
92 n->mode = entry->mode;
93 n->size = entry->size;
94 n->data = (unsigned char *)malloc(n->size);
95 if(n->data == NULL) {
96 free(n);
97 return NULL;
98 }
99 memcpy(n->data, entry->data, entry->size);
100 n->bstream = NULL;
101 n->next = NULL;
102
103 return n;
104 }
105
106 /******************************************************************************
107 * Input Data
108 *****************************************************************************/
109
QRinput_new(void)110 QRinput *QRinput_new(void)
111 {
112 return QRinput_new2(0, QR_ECLEVEL_L);
113 }
114
QRinput_new2(int version,QRecLevel level)115 QRinput *QRinput_new2(int version, QRecLevel level)
116 {
117 QRinput *input;
118
119 if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) {
120 errno = EINVAL;
121 return NULL;
122 }
123
124 input = (QRinput *)malloc(sizeof(QRinput));
125 if(input == NULL) return NULL;
126
127 input->head = NULL;
128 input->tail = NULL;
129 input->version = version;
130 input->level = level;
131 input->mqr = 0;
132 input->fnc1 = 0;
133
134 return input;
135 }
136
QRinput_newMQR(int version,QRecLevel level)137 QRinput *QRinput_newMQR(int version, QRecLevel level)
138 {
139 QRinput *input;
140
141 if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
142 if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;
143
144 input = QRinput_new2(version, level);
145 if(input == NULL) return NULL;
146
147 input->mqr = 1;
148
149 return input;
150
151 INVALID:
152 errno = EINVAL;
153 return NULL;
154 }
155
QRinput_getVersion(QRinput * input)156 int QRinput_getVersion(QRinput *input)
157 {
158 return input->version;
159 }
160
QRinput_setVersion(QRinput * input,int version)161 int QRinput_setVersion(QRinput *input, int version)
162 {
163 if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) {
164 errno = EINVAL;
165 return -1;
166 }
167
168 input->version = version;
169
170 return 0;
171 }
172
QRinput_getErrorCorrectionLevel(QRinput * input)173 QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input)
174 {
175 return input->level;
176 }
177
QRinput_setErrorCorrectionLevel(QRinput * input,QRecLevel level)178 int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level)
179 {
180 if(input->mqr || level > QR_ECLEVEL_H) {
181 errno = EINVAL;
182 return -1;
183 }
184
185 input->level = level;
186
187 return 0;
188 }
189
QRinput_setVersionAndErrorCorrectionLevel(QRinput * input,int version,QRecLevel level)190 int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level)
191 {
192 if(input->mqr) {
193 if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID;
194 if((MQRspec_getECCLength(version, level) == 0)) goto INVALID;
195 } else {
196 if(version < 0 || version > QRSPEC_VERSION_MAX) goto INVALID;
197 if(level > QR_ECLEVEL_H) goto INVALID;
198 }
199
200 input->version = version;
201 input->level = level;
202
203 return 0;
204
205 INVALID:
206 errno = EINVAL;
207 return -1;
208 }
209
QRinput_appendEntry(QRinput * input,QRinput_List * entry)210 static void QRinput_appendEntry(QRinput *input, QRinput_List *entry)
211 {
212 if(input->tail == NULL) {
213 input->head = entry;
214 input->tail = entry;
215 } else {
216 input->tail->next = entry;
217 input->tail = entry;
218 }
219 entry->next = NULL;
220 }
221
QRinput_append(QRinput * input,QRencodeMode mode,int size,const unsigned char * data)222 int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data)
223 {
224 QRinput_List *entry;
225
226 entry = QRinput_List_newEntry(mode, size, data);
227 if(entry == NULL) {
228 return -1;
229 }
230
231 QRinput_appendEntry(input, entry);
232
233 return 0;
234 }
235
236 /**
237 * Insert a structured-append header to the head of the input data.
238 * @param input input data.
239 * @param size number of structured symbols.
240 * @param index index number of the symbol. (1 <= index <= size)
241 * @param parity parity among input data. (NOTE: each symbol of a set of structured symbols has the same parity data)
242 * @retval 0 success.
243 * @retval -1 error occurred and errno is set to indeicate the error. See Execptions for the details.
244 * @throw EINVAL invalid parameter.
245 * @throw ENOMEM unable to allocate memory.
246 */
QRinput_insertStructuredAppendHeader(QRinput * input,int size,int index,unsigned char parity)247 __STATIC int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity)
248 {
249 QRinput_List *entry;
250 unsigned char buf[3];
251
252 if(size > MAX_STRUCTURED_SYMBOLS) {
253 errno = EINVAL;
254 return -1;
255 }
256 if(index <= 0 || index > MAX_STRUCTURED_SYMBOLS) {
257 errno = EINVAL;
258 return -1;
259 }
260
261 buf[0] = (unsigned char)size;
262 buf[1] = (unsigned char)index;
263 buf[2] = parity;
264 entry = QRinput_List_newEntry(QR_MODE_STRUCTURE, 3, buf);
265 if(entry == NULL) {
266 return -1;
267 }
268
269 entry->next = input->head;
270 input->head = entry;
271
272 return 0;
273 }
274
QRinput_appendECIheader(QRinput * input,unsigned int ecinum)275 int QRinput_appendECIheader(QRinput *input, unsigned int ecinum)
276 {
277 unsigned char data[4];
278
279 if(ecinum > 999999) {
280 errno = EINVAL;
281 return -1;
282 }
283
284 /* We manually create byte array of ecinum because
285 (unsigned char *)&ecinum may cause bus error on some architectures, */
286 data[0] = ecinum & 0xff;
287 data[1] = (ecinum >> 8) & 0xff;
288 data[2] = (ecinum >> 16) & 0xff;
289 data[3] = (ecinum >> 24) & 0xff;
290 return QRinput_append(input, QR_MODE_ECI, 4, data);
291 }
292
QRinput_free(QRinput * input)293 void QRinput_free(QRinput *input)
294 {
295 QRinput_List *list, *next;
296
297 if(input != NULL) {
298 list = input->head;
299 while(list != NULL) {
300 next = list->next;
301 QRinput_List_freeEntry(list);
302 list = next;
303 }
304 free(input);
305 }
306 }
307
QRinput_calcParity(QRinput * input)308 static unsigned char QRinput_calcParity(QRinput *input)
309 {
310 unsigned char parity = 0;
311 QRinput_List *list;
312 int i;
313
314 list = input->head;
315 while(list != NULL) {
316 if(list->mode != QR_MODE_STRUCTURE) {
317 for(i=list->size-1; i>=0; i--) {
318 parity ^= list->data[i];
319 }
320 }
321 list = list->next;
322 }
323
324 return parity;
325 }
326
QRinput_dup(QRinput * input)327 QRinput *QRinput_dup(QRinput *input)
328 {
329 QRinput *n;
330 QRinput_List *list, *e;
331
332 if(input->mqr) {
333 n = QRinput_newMQR(input->version, input->level);
334 } else {
335 n = QRinput_new2(input->version, input->level);
336 }
337 if(n == NULL) return NULL;
338
339 list = input->head;
340 while(list != NULL) {
341 e = QRinput_List_dup(list);
342 if(e == NULL) {
343 QRinput_free(n);
344 return NULL;
345 }
346 QRinput_appendEntry(n, e);
347 list = list->next;
348 }
349
350 return n;
351 }
352
353 /******************************************************************************
354 * Numeric data
355 *****************************************************************************/
356
357 /**
358 * Check the input data.
359 * @param size
360 * @param data
361 * @return result
362 */
QRinput_checkModeNum(int size,const char * data)363 static int QRinput_checkModeNum(int size, const char *data)
364 {
365 int i;
366
367 for(i=0; i<size; i++) {
368 if(data[i] < '0' || data[i] > '9')
369 return -1;
370 }
371
372 return 0;
373 }
374
375 /**
376 * Estimates the length of the encoded bit stream of numeric data.
377 * @param size
378 * @return number of bits
379 */
QRinput_estimateBitsModeNum(int size)380 int QRinput_estimateBitsModeNum(int size)
381 {
382 int w;
383 int bits;
384
385 w = size / 3;
386 bits = w * 10;
387 switch(size - w * 3) {
388 case 1:
389 bits += 4;
390 break;
391 case 2:
392 bits += 7;
393 break;
394 default:
395 break;
396 }
397
398 return bits;
399 }
400
401 /**
402 * Convert the number data to a bit stream.
403 * @param entry
404 * @param mqr
405 * @retval 0 success
406 * @retval -1 an error occurred and errno is set to indeicate the error.
407 * See Execptions for the details.
408 * @throw ENOMEM unable to allocate memory.
409 */
QRinput_encodeModeNum(QRinput_List * entry,int version,int mqr)410 static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr)
411 {
412 int words, i, ret;
413 unsigned int val;
414
415 entry->bstream = BitStream_new();
416 if(entry->bstream == NULL) return -1;
417
418 if(mqr) {
419 if(version > 1) {
420 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM);
421 if(ret < 0) goto ABORT;
422 }
423 ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
424 if(ret < 0) goto ABORT;
425 } else {
426 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM);
427 if(ret < 0) goto ABORT;
428
429 ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
430 if(ret < 0) goto ABORT;
431 }
432
433 words = entry->size / 3;
434 for(i=0; i<words; i++) {
435 val = (entry->data[i*3 ] - '0') * 100;
436 val += (entry->data[i*3+1] - '0') * 10;
437 val += (entry->data[i*3+2] - '0');
438
439 ret = BitStream_appendNum(entry->bstream, 10, val);
440 if(ret < 0) goto ABORT;
441 }
442
443 if(entry->size - words * 3 == 1) {
444 val = entry->data[words*3] - '0';
445 ret = BitStream_appendNum(entry->bstream, 4, val);
446 if(ret < 0) goto ABORT;
447 } else if(entry->size - words * 3 == 2) {
448 val = (entry->data[words*3 ] - '0') * 10;
449 val += (entry->data[words*3+1] - '0');
450 BitStream_appendNum(entry->bstream, 7, val);
451 if(ret < 0) goto ABORT;
452 }
453
454 return 0;
455 ABORT:
456 BitStream_free(entry->bstream);
457 entry->bstream = NULL;
458 return -1;
459 }
460
461 /******************************************************************************
462 * Alphabet-numeric data
463 *****************************************************************************/
464
465 const signed char QRinput_anTable[128] = {
466 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
467 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
468 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
469 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
470 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
471 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
472 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
473 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
474 };
475
476 /**
477 * Check the input data.
478 * @param size
479 * @param data
480 * @return result
481 */
QRinput_checkModeAn(int size,const char * data)482 static int QRinput_checkModeAn(int size, const char *data)
483 {
484 int i;
485
486 for(i=0; i<size; i++) {
487 if(QRinput_lookAnTable(data[i]) < 0)
488 return -1;
489 }
490
491 return 0;
492 }
493
494 /**
495 * Estimates the length of the encoded bit stream of alphabet-numeric data.
496 * @param size
497 * @return number of bits
498 */
QRinput_estimateBitsModeAn(int size)499 int QRinput_estimateBitsModeAn(int size)
500 {
501 int w;
502 int bits;
503
504 w = size / 2;
505 bits = w * 11;
506 if(size & 1) {
507 bits += 6;
508 }
509
510 return bits;
511 }
512
513 /**
514 * Convert the alphabet-numeric data to a bit stream.
515 * @param entry
516 * @param mqr
517 * @retval 0 success
518 * @retval -1 an error occurred and errno is set to indeicate the error.
519 * See Execptions for the details.
520 * @throw ENOMEM unable to allocate memory.
521 * @throw EINVAL invalid version.
522 */
QRinput_encodeModeAn(QRinput_List * entry,int version,int mqr)523 static int QRinput_encodeModeAn(QRinput_List *entry, int version, int mqr)
524 {
525 int words, i, ret;
526 unsigned int val;
527
528 entry->bstream = BitStream_new();
529 if(entry->bstream == NULL) return -1;
530
531 if(mqr) {
532 if(version < 2) {
533 errno = EINVAL;
534 goto ABORT;
535 }
536 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_AN);
537 if(ret < 0) goto ABORT;
538 ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_AN, version), entry->size);
539 if(ret < 0) goto ABORT;
540 } else {
541 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_AN);
542 if(ret < 0) goto ABORT;
543 ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_AN, version), entry->size);
544 if(ret < 0) goto ABORT;
545 }
546
547 words = entry->size / 2;
548 for(i=0; i<words; i++) {
549 val = (unsigned int)QRinput_lookAnTable(entry->data[i*2 ]) * 45;
550 val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]);
551
552 ret = BitStream_appendNum(entry->bstream, 11, val);
553 if(ret < 0) goto ABORT;
554 }
555
556 if(entry->size & 1) {
557 val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]);
558
559 ret = BitStream_appendNum(entry->bstream, 6, val);
560 if(ret < 0) goto ABORT;
561 }
562
563 return 0;
564 ABORT:
565 BitStream_free(entry->bstream);
566 entry->bstream = NULL;
567 return -1;
568 }
569
570 /******************************************************************************
571 * 8 bit data
572 *****************************************************************************/
573
574 /**
575 * Estimates the length of the encoded bit stream of 8 bit data.
576 * @param size
577 * @return number of bits
578 */
QRinput_estimateBitsMode8(int size)579 int QRinput_estimateBitsMode8(int size)
580 {
581 return size * 8;
582 }
583
584 /**
585 * Convert the 8bits data to a bit stream.
586 * @param entry
587 * @param mqr
588 * @retval 0 success
589 * @retval -1 an error occurred and errno is set to indeicate the error.
590 * See Execptions for the details.
591 * @throw ENOMEM unable to allocate memory.
592 */
QRinput_encodeMode8(QRinput_List * entry,int version,int mqr)593 static int QRinput_encodeMode8(QRinput_List *entry, int version, int mqr)
594 {
595 int ret;
596
597 entry->bstream = BitStream_new();
598 if(entry->bstream == NULL) return -1;
599
600 if(mqr) {
601 if(version < 3) {
602 errno = EINVAL;
603 goto ABORT;
604 }
605 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_8);
606 if(ret < 0) goto ABORT;
607 ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_8, version), entry->size);
608 if(ret < 0) goto ABORT;
609 } else {
610 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_8);
611 if(ret < 0) goto ABORT;
612 ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_8, version), entry->size);
613 if(ret < 0) goto ABORT;
614 }
615
616 ret = BitStream_appendBytes(entry->bstream, entry->size, entry->data);
617 if(ret < 0) goto ABORT;
618
619 return 0;
620 ABORT:
621 BitStream_free(entry->bstream);
622 entry->bstream = NULL;
623 return -1;
624 }
625
626
627 /******************************************************************************
628 * Kanji data
629 *****************************************************************************/
630
631 /**
632 * Estimates the length of the encoded bit stream of kanji data.
633 * @param size
634 * @return number of bits
635 */
QRinput_estimateBitsModeKanji(int size)636 int QRinput_estimateBitsModeKanji(int size)
637 {
638 return (size / 2) * 13;
639 }
640
641 /**
642 * Check the input data.
643 * @param size
644 * @param data
645 * @return result
646 */
QRinput_checkModeKanji(int size,const unsigned char * data)647 static int QRinput_checkModeKanji(int size, const unsigned char *data)
648 {
649 int i;
650 unsigned int val;
651
652 if(size & 1)
653 return -1;
654
655 for(i=0; i<size; i+=2) {
656 val = ((unsigned int)data[i] << 8) | data[i+1];
657 if(val < 0x8140 || (val > 0x9ffc && val < 0xe040) || val > 0xebbf) {
658 return -1;
659 }
660 }
661
662 return 0;
663 }
664
665 /**
666 * Convert the kanji data to a bit stream.
667 * @param entry
668 * @param mqr
669 * @retval 0 success
670 * @retval -1 an error occurred and errno is set to indeicate the error.
671 * See Execptions for the details.
672 * @throw ENOMEM unable to allocate memory.
673 * @throw EINVAL invalid version.
674 */
QRinput_encodeModeKanji(QRinput_List * entry,int version,int mqr)675 static int QRinput_encodeModeKanji(QRinput_List *entry, int version, int mqr)
676 {
677 int ret, i;
678 unsigned int val, h;
679
680 entry->bstream = BitStream_new();
681 if(entry->bstream == NULL) return -1;
682
683 if(mqr) {
684 if(version < 2) {
685 errno = EINVAL;
686 goto ABORT;
687 }
688 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_KANJI);
689 if(ret < 0) goto ABORT;
690 ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2);
691 if(ret < 0) goto ABORT;
692 } else {
693 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_KANJI);
694 if(ret < 0) goto ABORT;
695 ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2);
696 if(ret < 0) goto ABORT;
697 }
698
699 for(i=0; i<entry->size; i+=2) {
700 val = ((unsigned int)entry->data[i] << 8) | entry->data[i+1];
701 if(val <= 0x9ffc) {
702 val -= 0x8140;
703 } else {
704 val -= 0xc140;
705 }
706 h = (val >> 8) * 0xc0;
707 val = (val & 0xff) + h;
708
709 ret = BitStream_appendNum(entry->bstream, 13, val);
710 if(ret < 0) goto ABORT;
711 }
712
713 return 0;
714 ABORT:
715 BitStream_free(entry->bstream);
716 entry->bstream = NULL;
717 return -1;
718 }
719
720 /******************************************************************************
721 * Structured Symbol
722 *****************************************************************************/
723
724 /**
725 * Convert a structure symbol code to a bit stream.
726 * @param entry
727 * @param mqr
728 * @retval 0 success
729 * @retval -1 an error occurred and errno is set to indeicate the error.
730 * See Execptions for the details.
731 * @throw ENOMEM unable to allocate memory.
732 * @throw EINVAL invalid entry.
733 */
QRinput_encodeModeStructure(QRinput_List * entry,int mqr)734 static int QRinput_encodeModeStructure(QRinput_List *entry, int mqr)
735 {
736 int ret;
737
738 if(mqr) {
739 errno = EINVAL;
740 return -1;
741 }
742 entry->bstream = BitStream_new();
743 if(entry->bstream == NULL) return -1;
744
745 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_STRUCTURE);
746 if(ret < 0) goto ABORT;
747 ret = BitStream_appendNum(entry->bstream, 4, entry->data[1] - 1);
748 if(ret < 0) goto ABORT;
749 ret = BitStream_appendNum(entry->bstream, 4, entry->data[0] - 1);
750 if(ret < 0) goto ABORT;
751 ret = BitStream_appendNum(entry->bstream, 8, entry->data[2]);
752 if(ret < 0) goto ABORT;
753
754 return 0;
755 ABORT:
756 BitStream_free(entry->bstream);
757 entry->bstream = NULL;
758 return -1;
759 }
760
761 /******************************************************************************
762 * FNC1
763 *****************************************************************************/
764
QRinput_checkModeFNC1Second(int size,const unsigned char * data)765 static int QRinput_checkModeFNC1Second(int size, const unsigned char *data)
766 {
767 if(size != 1) return -1;
768
769 return 0;
770 }
771
QRinput_encodeModeFNC1Second(QRinput_List * entry,int version)772 static int QRinput_encodeModeFNC1Second(QRinput_List *entry, int version)
773 {
774 int ret;
775
776 entry->bstream = BitStream_new();
777 if(entry->bstream == NULL) return -1;
778
779 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_FNC1SECOND);
780 if(ret < 0) goto ABORT;
781
782 ret = BitStream_appendBytes(entry->bstream, 1, entry->data);
783 if(ret < 0) goto ABORT;
784
785 return 0;
786 ABORT:
787 BitStream_free(entry->bstream);
788 entry->bstream = NULL;
789 return -1;
790 }
791
792 /******************************************************************************
793 * ECI header
794 *****************************************************************************/
QRinput_decodeECIfromByteArray(unsigned char * data)795 static unsigned int QRinput_decodeECIfromByteArray(unsigned char *data)
796 {
797 int i;
798 unsigned int ecinum;
799
800 ecinum = 0;
801 for(i=0; i<4; i++) {
802 ecinum = ecinum << 8;
803 ecinum |= data[3-i];
804 }
805
806 return ecinum;
807 }
808
QRinput_estimateBitsModeECI(unsigned char * data)809 int QRinput_estimateBitsModeECI(unsigned char *data)
810 {
811 unsigned int ecinum;
812
813 ecinum = QRinput_decodeECIfromByteArray(data);;
814
815 /* See Table 4 of JISX 0510:2004 pp.17. */
816 if(ecinum < 128) {
817 return MODE_INDICATOR_SIZE + 8;
818 } else if(ecinum < 16384) {
819 return MODE_INDICATOR_SIZE + 16;
820 } else {
821 return MODE_INDICATOR_SIZE + 24;
822 }
823 }
824
QRinput_encodeModeECI(QRinput_List * entry,int version)825 static int QRinput_encodeModeECI(QRinput_List *entry, int version)
826 {
827 int ret, words;
828 unsigned int ecinum, code;
829
830 entry->bstream = BitStream_new();
831 if(entry->bstream == NULL) return -1;
832
833 ecinum = QRinput_decodeECIfromByteArray(entry->data);;
834
835 /* See Table 4 of JISX 0510:2004 pp.17. */
836 if(ecinum < 128) {
837 words = 1;
838 code = ecinum;
839 } else if(ecinum < 16384) {
840 words = 2;
841 code = 0x8000 + ecinum;
842 } else {
843 words = 3;
844 code = 0xc0000 + ecinum;
845 }
846
847 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_ECI);
848 if(ret < 0) goto ABORT;
849
850 ret = BitStream_appendNum(entry->bstream, words * 8, code);
851 if(ret < 0) goto ABORT;
852
853 return 0;
854 ABORT:
855 BitStream_free(entry->bstream);
856 entry->bstream = NULL;
857 return -1;
858 }
859
860 /******************************************************************************
861 * Validation
862 *****************************************************************************/
863
QRinput_check(QRencodeMode mode,int size,const unsigned char * data)864 int QRinput_check(QRencodeMode mode, int size, const unsigned char *data)
865 {
866 if((mode == QR_MODE_FNC1FIRST && size < 0) || size <= 0) return -1;
867
868 switch(mode) {
869 case QR_MODE_NUM:
870 return QRinput_checkModeNum(size, (const char *)data);
871 case QR_MODE_AN:
872 return QRinput_checkModeAn(size, (const char *)data);
873 case QR_MODE_KANJI:
874 return QRinput_checkModeKanji(size, data);
875 case QR_MODE_8:
876 return 0;
877 case QR_MODE_STRUCTURE:
878 return 0;
879 case QR_MODE_ECI:
880 return 0;
881 case QR_MODE_FNC1FIRST:
882 return 0;
883 case QR_MODE_FNC1SECOND:
884 return QRinput_checkModeFNC1Second(size, data);
885 case QR_MODE_NUL:
886 break;
887 }
888
889 return -1;
890 }
891
892 /******************************************************************************
893 * Estimation of the bit length
894 *****************************************************************************/
895
896 /**
897 * Estimates the length of the encoded bit stream on the current version.
898 * @param entry
899 * @param version version of the symbol
900 * @param mqr
901 * @return number of bits
902 */
QRinput_estimateBitStreamSizeOfEntry(QRinput_List * entry,int version,int mqr)903 static int QRinput_estimateBitStreamSizeOfEntry(QRinput_List *entry, int version, int mqr)
904 {
905 int bits = 0;
906 int l, m;
907 int num;
908
909 if(version == 0) version = 1;
910
911 switch(entry->mode) {
912 case QR_MODE_NUM:
913 bits = QRinput_estimateBitsModeNum(entry->size);
914 break;
915 case QR_MODE_AN:
916 bits = QRinput_estimateBitsModeAn(entry->size);
917 break;
918 case QR_MODE_8:
919 bits = QRinput_estimateBitsMode8(entry->size);
920 break;
921 case QR_MODE_KANJI:
922 bits = QRinput_estimateBitsModeKanji(entry->size);
923 break;
924 case QR_MODE_STRUCTURE:
925 return STRUCTURE_HEADER_SIZE;
926 case QR_MODE_ECI:
927 bits = QRinput_estimateBitsModeECI(entry->data);
928 break;
929 case QR_MODE_FNC1FIRST:
930 return MODE_INDICATOR_SIZE;
931 break;
932 case QR_MODE_FNC1SECOND:
933 return MODE_INDICATOR_SIZE + 8;
934 default:
935 return 0;
936 }
937
938 if(mqr) {
939 l = QRspec_lengthIndicator(entry->mode, version);
940 m = version - 1;
941 bits += l + m;
942 } else {
943 l = QRspec_lengthIndicator(entry->mode, version);
944 m = 1 << l;
945 num = (entry->size + m - 1) / m;
946
947 bits += num * (MODE_INDICATOR_SIZE + l);
948 }
949
950 return bits;
951 }
952
953 /**
954 * Estimates the length of the encoded bit stream of the data.
955 * @param input input data
956 * @param version version of the symbol
957 * @return number of bits
958 */
QRinput_estimateBitStreamSize(QRinput * input,int version)959 __STATIC int QRinput_estimateBitStreamSize(QRinput *input, int version)
960 {
961 QRinput_List *list;
962 int bits = 0;
963
964 list = input->head;
965 while(list != NULL) {
966 bits += QRinput_estimateBitStreamSizeOfEntry(list, version, input->mqr);
967 list = list->next;
968 }
969
970 return bits;
971 }
972
973 /**
974 * Estimates the required version number of the symbol.
975 * @param input input data
976 * @return required version number
977 */
QRinput_estimateVersion(QRinput * input)978 static int QRinput_estimateVersion(QRinput *input)
979 {
980 int bits;
981 int version, prev;
982
983 version = 0;
984 do {
985 prev = version;
986 bits = QRinput_estimateBitStreamSize(input, prev);
987 version = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
988 if (version < 0) {
989 return -1;
990 }
991 } while (version > prev);
992
993 return version;
994 }
995
996 /**
997 * Returns required length in bytes for specified mode, version and bits.
998 * @param mode
999 * @param version
1000 * @param bits
1001 * @return required length of code words in bytes.
1002 */
QRinput_lengthOfCode(QRencodeMode mode,int version,int bits)1003 __STATIC int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits)
1004 {
1005 int payload, size, chunks, remain, maxsize;
1006
1007 payload = bits - 4 - QRspec_lengthIndicator(mode, version);
1008 switch(mode) {
1009 case QR_MODE_NUM:
1010 chunks = payload / 10;
1011 remain = payload - chunks * 10;
1012 size = chunks * 3;
1013 if(remain >= 7) {
1014 size += 2;
1015 } else if(remain >= 4) {
1016 size += 1;
1017 }
1018 break;
1019 case QR_MODE_AN:
1020 chunks = payload / 11;
1021 remain = payload - chunks * 11;
1022 size = chunks * 2;
1023 if(remain >= 6) size++;
1024 break;
1025 case QR_MODE_8:
1026 size = payload / 8;
1027 break;
1028 case QR_MODE_KANJI:
1029 size = (payload / 13) * 2;
1030 break;
1031 case QR_MODE_STRUCTURE:
1032 size = payload / 8;
1033 break;
1034 default:
1035 size = 0;
1036 break;
1037 }
1038 maxsize = QRspec_maximumWords(mode, version);
1039 if(size < 0) size = 0;
1040 if(maxsize > 0 && size > maxsize) size = maxsize;
1041
1042 return size;
1043 }
1044
1045 /******************************************************************************
1046 * Data conversion
1047 *****************************************************************************/
1048
1049 /**
1050 * Convert the input data in the data chunk to a bit stream.
1051 * @param entry
1052 * @return number of bits (>0) or -1 for failure.
1053 */
QRinput_encodeBitStream(QRinput_List * entry,int version,int mqr)1054 static int QRinput_encodeBitStream(QRinput_List *entry, int version, int mqr)
1055 {
1056 int words, ret;
1057 QRinput_List *st1 = NULL, *st2 = NULL;
1058
1059 if(entry->bstream != NULL) {
1060 BitStream_free(entry->bstream);
1061 entry->bstream = NULL;
1062 }
1063
1064 words = QRspec_maximumWords(entry->mode, version);
1065 if(words != 0 && entry->size > words) {
1066 st1 = QRinput_List_newEntry(entry->mode, words, entry->data);
1067 if(st1 == NULL) goto ABORT;
1068 st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]);
1069 if(st2 == NULL) goto ABORT;
1070
1071 ret = QRinput_encodeBitStream(st1, version, mqr);
1072 if(ret < 0) goto ABORT;
1073 ret = QRinput_encodeBitStream(st2, version, mqr);
1074 if(ret < 0) goto ABORT;
1075 entry->bstream = BitStream_new();
1076 if(entry->bstream == NULL) goto ABORT;
1077 ret = BitStream_append(entry->bstream, st1->bstream);
1078 if(ret < 0) goto ABORT;
1079 ret = BitStream_append(entry->bstream, st2->bstream);
1080 if(ret < 0) goto ABORT;
1081 QRinput_List_freeEntry(st1);
1082 QRinput_List_freeEntry(st2);
1083 } else {
1084 ret = 0;
1085 switch(entry->mode) {
1086 case QR_MODE_NUM:
1087 ret = QRinput_encodeModeNum(entry, version, mqr);
1088 break;
1089 case QR_MODE_AN:
1090 ret = QRinput_encodeModeAn(entry, version, mqr);
1091 break;
1092 case QR_MODE_8:
1093 ret = QRinput_encodeMode8(entry, version, mqr);
1094 break;
1095 case QR_MODE_KANJI:
1096 ret = QRinput_encodeModeKanji(entry, version, mqr);
1097 break;
1098 case QR_MODE_STRUCTURE:
1099 ret = QRinput_encodeModeStructure(entry, mqr);
1100 break;
1101 case QR_MODE_ECI:
1102 ret = QRinput_encodeModeECI(entry, version);
1103 break;
1104 case QR_MODE_FNC1SECOND:
1105 ret = QRinput_encodeModeFNC1Second(entry, version);
1106 default:
1107 break;
1108 }
1109 if(ret < 0) return -1;
1110 }
1111
1112 return BitStream_size(entry->bstream);
1113 ABORT:
1114 QRinput_List_freeEntry(st1);
1115 QRinput_List_freeEntry(st2);
1116 return -1;
1117 }
1118
1119 /**
1120 * Convert the input data to a bit stream.
1121 * @param input input data.
1122 * @retval 0 success
1123 * @retval -1 an error occurred and errno is set to indeicate the error.
1124 * See Execptions for the details.
1125 * @throw ENOMEM unable to allocate memory.
1126 */
QRinput_createBitStream(QRinput * input)1127 static int QRinput_createBitStream(QRinput *input)
1128 {
1129 QRinput_List *list;
1130 int bits, total = 0;
1131
1132 list = input->head;
1133 while(list != NULL) {
1134 bits = QRinput_encodeBitStream(list, input->version, input->mqr);
1135 if(bits < 0) return -1;
1136 total += bits;
1137 list = list->next;
1138 }
1139
1140 return total;
1141 }
1142
1143 /**
1144 * Convert the input data to a bit stream.
1145 * When the version number is given and that is not sufficient, it is increased
1146 * automatically.
1147 * @param input input data.
1148 * @retval 0 success
1149 * @retval -1 an error occurred and errno is set to indeicate the error.
1150 * See Execptions for the details.
1151 * @throw ENOMEM unable to allocate memory.
1152 * @throw ERANGE input is too large.
1153 */
QRinput_convertData(QRinput * input)1154 static int QRinput_convertData(QRinput *input)
1155 {
1156 int bits;
1157 int ver;
1158
1159 ver = QRinput_estimateVersion(input);
1160 if(ver > QRinput_getVersion(input)) {
1161 QRinput_setVersion(input, ver);
1162 }
1163
1164 for(;;) {
1165 bits = QRinput_createBitStream(input);
1166 if(bits < 0) return -1;
1167 ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
1168 if(ver < 0) {
1169 errno = ERANGE;
1170 return -1;
1171 } else if(ver > QRinput_getVersion(input)) {
1172 QRinput_setVersion(input, ver);
1173 } else {
1174 break;
1175 }
1176 }
1177
1178 return 0;
1179 }
1180
1181 /**
1182 * Append padding bits for the input data.
1183 * @param bstream Bitstream to be appended.
1184 * @param input input data.
1185 * @retval 0 success
1186 * @retval -1 an error occurred and errno is set to indeicate the error.
1187 * See Execptions for the details.
1188 * @throw ERANGE input data is too large.
1189 * @throw ENOMEM unable to allocate memory.
1190 */
QRinput_appendPaddingBit(BitStream * bstream,QRinput * input)1191 static int QRinput_appendPaddingBit(BitStream *bstream, QRinput *input)
1192 {
1193 int bits, maxbits, words, maxwords, i, ret;
1194 BitStream *padding = NULL;
1195 unsigned char *padbuf;
1196 int padlen;
1197
1198 bits = BitStream_size(bstream);
1199 maxwords = QRspec_getDataLength(input->version, input->level);
1200 maxbits = maxwords * 8;
1201
1202 if(maxbits < bits) {
1203 errno = ERANGE;
1204 return -1;
1205 }
1206 if(maxbits == bits) {
1207 return 0;
1208 }
1209
1210 if(maxbits - bits <= 4) {
1211 ret = BitStream_appendNum(bstream, maxbits - bits, 0);
1212 goto DONE;
1213 }
1214
1215 words = (bits + 4 + 7) / 8;
1216
1217 padding = BitStream_new();
1218 if(padding == NULL) return -1;
1219 ret = BitStream_appendNum(padding, words * 8 - bits, 0);
1220 if(ret < 0) goto DONE;
1221
1222 padlen = maxwords - words;
1223 if(padlen > 0) {
1224 padbuf = (unsigned char *)malloc(padlen);
1225 if(padbuf == NULL) {
1226 ret = -1;
1227 goto DONE;
1228 }
1229 for(i=0; i<padlen; i++) {
1230 padbuf[i] = (i&1)?0x11:0xec;
1231 }
1232 ret = BitStream_appendBytes(padding, padlen, padbuf);
1233 free(padbuf);
1234 if(ret < 0) {
1235 goto DONE;
1236 }
1237 }
1238
1239 ret = BitStream_append(bstream, padding);
1240
1241 DONE:
1242 BitStream_free(padding);
1243 return ret;
1244 }
1245
1246 /**
1247 * Append padding bits for the input data - Micro QR Code version.
1248 * @param bstream Bitstream to be appended.
1249 * @param input input data.
1250 * @retval 0 success
1251 * @retval -1 an error occurred and errno is set to indeicate the error.
1252 * See Execptions for the details.
1253 * @throw ERANGE input data is too large.
1254 * @throw ENOMEM unable to allocate memory.
1255 */
QRinput_appendPaddingBitMQR(BitStream * bstream,QRinput * input)1256 static int QRinput_appendPaddingBitMQR(BitStream *bstream, QRinput *input)
1257 {
1258 int bits, maxbits, words, maxwords, i, ret, termbits;
1259 BitStream *padding = NULL;
1260 unsigned char *padbuf;
1261 int padlen;
1262
1263 bits = BitStream_size(bstream);
1264 maxbits = MQRspec_getDataLengthBit(input->version, input->level);
1265 maxwords = maxbits / 8;
1266
1267 if(maxbits < bits) {
1268 errno = ERANGE;
1269 return -1;
1270 }
1271 if(maxbits == bits) {
1272 return 0;
1273 }
1274
1275 termbits = input->version * 2 + 1;
1276
1277 if(maxbits - bits <= termbits) {
1278 ret = BitStream_appendNum(bstream, maxbits - bits, 0);
1279 goto DONE;
1280 }
1281
1282 bits += termbits;
1283
1284 words = (bits + 7) / 8;
1285 if(maxbits - words * 8 > 0) {
1286 termbits += words * 8 - bits;
1287 if(words == maxwords) termbits += maxbits - words * 8;
1288 } else {
1289 termbits += words * 8 - bits;
1290 }
1291 padding = BitStream_new();
1292 if(padding == NULL) return -1;
1293 ret = BitStream_appendNum(padding, termbits, 0);
1294 if(ret < 0) goto DONE;
1295
1296 padlen = maxwords - words;
1297 if(padlen > 0) {
1298 padbuf = (unsigned char *)malloc(padlen);
1299 if(padbuf == NULL) {
1300 ret = -1;
1301 goto DONE;
1302 }
1303 for(i=0; i<padlen; i++) {
1304 padbuf[i] = (i&1)?0x11:0xec;
1305 }
1306 ret = BitStream_appendBytes(padding, padlen, padbuf);
1307 free(padbuf);
1308 if(ret < 0) {
1309 goto DONE;
1310 }
1311 termbits = maxbits - maxwords * 8;
1312 if(termbits > 0) {
1313 ret = BitStream_appendNum(padding, termbits, 0);
1314 if(ret < 0) goto DONE;
1315 }
1316 }
1317
1318 ret = BitStream_append(bstream, padding);
1319
1320 DONE:
1321 BitStream_free(padding);
1322 return ret;
1323 }
1324
QRinput_insertFNC1Header(QRinput * input)1325 static int QRinput_insertFNC1Header(QRinput *input)
1326 {
1327 QRinput_List *entry = NULL;
1328
1329 if(input->fnc1 == 1) {
1330 entry = QRinput_List_newEntry(QR_MODE_FNC1FIRST, 0, NULL);
1331 } else if(input->fnc1 == 2) {
1332 entry = QRinput_List_newEntry(QR_MODE_FNC1SECOND, 1, &(input->appid));
1333 }
1334 if(entry == NULL) {
1335 return -1;
1336 }
1337
1338 if(input->head->mode != QR_MODE_STRUCTURE || input->head->mode != QR_MODE_ECI) {
1339 entry->next = input->head;
1340 input->head = entry;
1341 } else {
1342 entry->next = input->head->next;
1343 input->head->next = entry;
1344 }
1345
1346 return 0;
1347 }
1348
1349 /**
1350 * Merge all bit streams in the input data.
1351 * @param input input data.
1352 * @return merged bit stream
1353 */
1354
QRinput_mergeBitStream(QRinput * input)1355 __STATIC BitStream *QRinput_mergeBitStream(QRinput *input)
1356 {
1357 BitStream *bstream;
1358 QRinput_List *list;
1359 int ret;
1360
1361 if(input->mqr) {
1362 if(QRinput_createBitStream(input) < 0) {
1363 return NULL;
1364 }
1365 } else {
1366 if(input->fnc1) {
1367 if(QRinput_insertFNC1Header(input) < 0) {
1368 return NULL;
1369 }
1370 }
1371 if(QRinput_convertData(input) < 0) {
1372 return NULL;
1373 }
1374 }
1375
1376 bstream = BitStream_new();
1377 if(bstream == NULL) return NULL;
1378
1379 list = input->head;
1380 while(list != NULL) {
1381 ret = BitStream_append(bstream, list->bstream);
1382 if(ret < 0) {
1383 BitStream_free(bstream);
1384 return NULL;
1385 }
1386 list = list->next;
1387 }
1388
1389 return bstream;
1390 }
1391
1392 /**
1393 * Merge all bit streams in the input data and append padding bits
1394 * @param input input data.
1395 * @return padded merged bit stream
1396 */
1397
QRinput_getBitStream(QRinput * input)1398 __STATIC BitStream *QRinput_getBitStream(QRinput *input)
1399 {
1400 BitStream *bstream;
1401 int ret;
1402
1403 bstream = QRinput_mergeBitStream(input);
1404 if(bstream == NULL) {
1405 return NULL;
1406 }
1407 if(input->mqr) {
1408 ret = QRinput_appendPaddingBitMQR(bstream, input);
1409 } else {
1410 ret = QRinput_appendPaddingBit(bstream, input);
1411 }
1412 if(ret < 0) {
1413 BitStream_free(bstream);
1414 return NULL;
1415 }
1416
1417 return bstream;
1418 }
1419
1420 /**
1421 * Pack all bit streams padding bits into a byte array.
1422 * @param input input data.
1423 * @return padded merged byte stream
1424 */
1425
QRinput_getByteStream(QRinput * input)1426 unsigned char *QRinput_getByteStream(QRinput *input)
1427 {
1428 BitStream *bstream;
1429 unsigned char *array;
1430
1431 bstream = QRinput_getBitStream(input);
1432 if(bstream == NULL) {
1433 return NULL;
1434 }
1435 array = BitStream_toByte(bstream);
1436 BitStream_free(bstream);
1437
1438 return array;
1439 }
1440
1441 /******************************************************************************
1442 * Structured input data
1443 *****************************************************************************/
1444
QRinput_InputList_newEntry(QRinput * input)1445 static QRinput_InputList *QRinput_InputList_newEntry(QRinput *input)
1446 {
1447 QRinput_InputList *entry;
1448
1449 entry = (QRinput_InputList *)malloc(sizeof(QRinput_InputList));
1450 if(entry == NULL) return NULL;
1451
1452 entry->input = input;
1453 entry->next = NULL;
1454
1455 return entry;
1456 }
1457
QRinput_InputList_freeEntry(QRinput_InputList * entry)1458 static void QRinput_InputList_freeEntry(QRinput_InputList *entry)
1459 {
1460 if(entry != NULL) {
1461 QRinput_free(entry->input);
1462 free(entry);
1463 }
1464 }
1465
QRinput_Struct_new(void)1466 QRinput_Struct *QRinput_Struct_new(void)
1467 {
1468 QRinput_Struct *s;
1469
1470 s = (QRinput_Struct *)malloc(sizeof(QRinput_Struct));
1471 if(s == NULL) return NULL;
1472
1473 s->size = 0;
1474 s->parity = -1;
1475 s->head = NULL;
1476 s->tail = NULL;
1477
1478 return s;
1479 }
1480
QRinput_Struct_setParity(QRinput_Struct * s,unsigned char parity)1481 void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity)
1482 {
1483 s->parity = (int)parity;
1484 }
1485
QRinput_Struct_appendInput(QRinput_Struct * s,QRinput * input)1486 int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input)
1487 {
1488 QRinput_InputList *e;
1489
1490 if(input->mqr) {
1491 errno = EINVAL;
1492 return -1;
1493 }
1494
1495 e = QRinput_InputList_newEntry(input);
1496 if(e == NULL) return -1;
1497
1498 s->size++;
1499 if(s->tail == NULL) {
1500 s->head = e;
1501 s->tail = e;
1502 } else {
1503 s->tail->next = e;
1504 s->tail = e;
1505 }
1506
1507 return s->size;
1508 }
1509
QRinput_Struct_free(QRinput_Struct * s)1510 void QRinput_Struct_free(QRinput_Struct *s)
1511 {
1512 QRinput_InputList *list, *next;
1513
1514 if(s != NULL) {
1515 list = s->head;
1516 while(list != NULL) {
1517 next = list->next;
1518 QRinput_InputList_freeEntry(list);
1519 list = next;
1520 }
1521 free(s);
1522 }
1523 }
1524
QRinput_Struct_calcParity(QRinput_Struct * s)1525 static unsigned char QRinput_Struct_calcParity(QRinput_Struct *s)
1526 {
1527 QRinput_InputList *list;
1528 unsigned char parity = 0;
1529
1530 list = s->head;
1531 while(list != NULL) {
1532 parity ^= QRinput_calcParity(list->input);
1533 list = list->next;
1534 }
1535
1536 QRinput_Struct_setParity(s, parity);
1537
1538 return parity;
1539 }
1540
QRinput_List_shrinkEntry(QRinput_List * entry,int bytes)1541 static int QRinput_List_shrinkEntry(QRinput_List *entry, int bytes)
1542 {
1543 unsigned char *data;
1544
1545 data = (unsigned char *)malloc(bytes);
1546 if(data == NULL) return -1;
1547
1548 memcpy(data, entry->data, bytes);
1549 free(entry->data);
1550 entry->data = data;
1551 entry->size = bytes;
1552
1553 return 0;
1554 }
1555
QRinput_splitEntry(QRinput_List * entry,int bytes)1556 __STATIC int QRinput_splitEntry(QRinput_List *entry, int bytes)
1557 {
1558 QRinput_List *e;
1559 int ret;
1560
1561 e = QRinput_List_newEntry(entry->mode, entry->size - bytes, entry->data + bytes);
1562 if(e == NULL) {
1563 return -1;
1564 }
1565
1566 ret = QRinput_List_shrinkEntry(entry, bytes);
1567 if(ret < 0) {
1568 QRinput_List_freeEntry(e);
1569 return -1;
1570 }
1571
1572 e->next = entry->next;
1573 entry->next = e;
1574
1575 return 0;
1576 }
1577
QRinput_splitQRinputToStruct(QRinput * input)1578 QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input)
1579 {
1580 QRinput *p;
1581 QRinput_Struct *s;
1582 int bits, maxbits, nextbits, bytes, ret;
1583 QRinput_List *list, *next, *prev;
1584
1585 if(input->mqr) {
1586 errno = EINVAL;
1587 return NULL;
1588 }
1589
1590 s = QRinput_Struct_new();
1591 if(s == NULL) return NULL;
1592
1593 input = QRinput_dup(input);
1594 if(input == NULL) {
1595 QRinput_Struct_free(s);
1596 return NULL;
1597 }
1598
1599 QRinput_Struct_setParity(s, QRinput_calcParity(input));
1600 maxbits = QRspec_getDataLength(input->version, input->level) * 8 - STRUCTURE_HEADER_SIZE;
1601
1602 if(maxbits <= 0) {
1603 QRinput_Struct_free(s);
1604 QRinput_free(input);
1605 return NULL;
1606 }
1607
1608 bits = 0;
1609 list = input->head;
1610 prev = NULL;
1611 while(list != NULL) {
1612 nextbits = QRinput_estimateBitStreamSizeOfEntry(list, input->version, input->mqr);
1613 if(bits + nextbits <= maxbits) {
1614 ret = QRinput_encodeBitStream(list, input->version, input->mqr);
1615 if(ret < 0) goto ABORT;
1616 bits += ret;
1617 prev = list;
1618 list = list->next;
1619 } else {
1620 bytes = QRinput_lengthOfCode(list->mode, input->version, maxbits - bits);
1621 p = QRinput_new2(input->version, input->level);
1622 if(p == NULL) goto ABORT;
1623 if(bytes > 0) {
1624 /* Splits this entry into 2 entries. */
1625 ret = QRinput_splitEntry(list, bytes);
1626 if(ret < 0) {
1627 QRinput_free(p);
1628 goto ABORT;
1629 }
1630 /* First half is the tail of the current input. */
1631 next = list->next;
1632 list->next = NULL;
1633 /* Second half is the head of the next input, p.*/
1634 p->head = next;
1635 /* Renew QRinput.tail. */
1636 p->tail = input->tail;
1637 input->tail = list;
1638 /* Point to the next entry. */
1639 prev = list;
1640 list = next;
1641 } else {
1642 /* Current entry will go to the next input. */
1643 prev->next = NULL;
1644 p->head = list;
1645 p->tail = input->tail;
1646 input->tail = prev;
1647 }
1648 ret = QRinput_Struct_appendInput(s, input);
1649 if(ret < 0) {
1650 QRinput_free(p);
1651 goto ABORT;
1652 }
1653 input = p;
1654 bits = 0;
1655 }
1656 }
1657 ret = QRinput_Struct_appendInput(s, input);
1658 if(ret < 0) goto ABORT;
1659 if(s->size > MAX_STRUCTURED_SYMBOLS) {
1660 QRinput_Struct_free(s);
1661 errno = ERANGE;
1662 return NULL;
1663 }
1664 ret = QRinput_Struct_insertStructuredAppendHeaders(s);
1665 if(ret < 0) {
1666 QRinput_Struct_free(s);
1667 return NULL;
1668 }
1669
1670 return s;
1671
1672 ABORT:
1673 QRinput_free(input);
1674 QRinput_Struct_free(s);
1675 return NULL;
1676 }
1677
QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct * s)1678 int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s)
1679 {
1680 int num, i;
1681 QRinput_InputList *list;
1682
1683 if(s->parity < 0) {
1684 QRinput_Struct_calcParity(s);
1685 }
1686 num = 0;
1687 list = s->head;
1688 while(list != NULL) {
1689 num++;
1690 list = list->next;
1691 }
1692 i = 1;
1693 list = s->head;
1694 while(list != NULL) {
1695 if(QRinput_insertStructuredAppendHeader(list->input, num, i, s->parity))
1696 return -1;
1697 i++;
1698 list = list->next;
1699 }
1700
1701 return 0;
1702 }
1703
1704 /******************************************************************************
1705 * Extended encoding mode (FNC1 and ECI)
1706 *****************************************************************************/
1707
QRinput_setFNC1First(QRinput * input)1708 int QRinput_setFNC1First(QRinput *input)
1709 {
1710 if(input->mqr) {
1711 errno = EINVAL;
1712 return -1;
1713 }
1714 input->fnc1 = 1;
1715
1716 return 0;
1717 }
1718
QRinput_setFNC1Second(QRinput * input,unsigned char appid)1719 int QRinput_setFNC1Second(QRinput *input, unsigned char appid)
1720 {
1721 if(input->mqr) {
1722 errno = EINVAL;
1723 return -1;
1724 }
1725 input->fnc1 = 2;
1726 input->appid = appid;
1727
1728 return 0;
1729 }
1730