Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 1725 lines (1468 sloc) 38.964 kB
e3a6145
fukuchi authored
1 /*
4cb5019
fukuchi authored
2 * qrencode - QR Code encoder
e3a6145
fukuchi authored
3 *
4cb5019
fukuchi authored
4 * Input data chunk class
fe2e1e8 @fukuchi Copyright year updated.
authored
5 * Copyright (C) 2006-2011 Kentaro Fukuchi <kentaro@fukuchi.org>
e3a6145
fukuchi authored
6 *
5c34170
fukuchi authored
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.
e3a6145
fukuchi authored
11 *
5c34170
fukuchi authored
12 * This library is distributed in the hope that it will be useful,
e3a6145
fukuchi authored
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5c34170
fukuchi authored
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
e3a6145
fukuchi authored
16 *
5c34170
fukuchi authored
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
e3a6145
fukuchi authored
20 */
21
4cbbca7 @fukuchi config.h is now included at the top of the code.
authored
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
e3a6145
fukuchi authored
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
28 #include <errno.h>
e3a6145
fukuchi authored
29
30 #include "qrencode.h"
31 #include "qrspec.h"
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
32 #include "mqrspec.h"
e3a6145
fukuchi authored
33 #include "bitstream.h"
7685c22
fukuchi authored
34 #include "qrinput.h"
e3a6145
fukuchi authored
35
36 /******************************************************************************
ad4d46a
fukuchi authored
37 * Utilities
38 *****************************************************************************/
39 int QRinput_isSplittableMode(QRencodeMode mode)
40 {
41 return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI);
42 }
43
44 /******************************************************************************
0be9661
fukuchi authored
45 * Entry of input data
e3a6145
fukuchi authored
46 *****************************************************************************/
47
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
48 static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data)
e3a6145
fukuchi authored
49 {
151db75
fukuchi authored
50 QRinput_List *entry;
e3a6145
fukuchi authored
51
4ee4f8d
fukuchi authored
52 if(QRinput_check(mode, size, data)) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
53 errno = EINVAL;
e3a6145
fukuchi authored
54 return NULL;
55 }
56
151db75
fukuchi authored
57 entry = (QRinput_List *)malloc(sizeof(QRinput_List));
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
58 if(entry == NULL) return NULL;
59
e3a6145
fukuchi authored
60 entry->mode = mode;
61 entry->size = size;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
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);
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
69 }
e3a6145
fukuchi authored
70 entry->bstream = NULL;
71 entry->next = NULL;
72
73 return entry;
74 }
75
fc33e4f Merged from 3.1.0.
fukuchi authored
76 static void QRinput_List_freeEntry(QRinput_List *entry)
e3a6145
fukuchi authored
77 {
fc33e4f Merged from 3.1.0.
fukuchi authored
78 if(entry != NULL) {
79 free(entry->data);
e3a6145
fukuchi authored
80 BitStream_free(entry->bstream);
fc33e4f Merged from 3.1.0.
fukuchi authored
81 free(entry);
e3a6145
fukuchi authored
82 }
83 }
84
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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
e3a6145
fukuchi authored
106 /******************************************************************************
98ae1dd
fukuchi authored
107 * Input Data
e3a6145
fukuchi authored
108 *****************************************************************************/
109
4ee4f8d
fukuchi authored
110 QRinput *QRinput_new(void)
e32df13
fukuchi authored
111 {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
112 return QRinput_new2(0, QR_ECLEVEL_L);
113 }
114
115 QRinput *QRinput_new2(int version, QRecLevel level)
116 {
98ae1dd
fukuchi authored
117 QRinput *input;
e32df13
fukuchi authored
118
fc33e4f Merged from 3.1.0.
fukuchi authored
119 if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
120 errno = EINVAL;
121 return NULL;
122 }
123
98ae1dd
fukuchi authored
124 input = (QRinput *)malloc(sizeof(QRinput));
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
125 if(input == NULL) return NULL;
126
98ae1dd
fukuchi authored
127 input->head = NULL;
128 input->tail = NULL;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
129 input->version = version;
130 input->level = level;
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
131 input->mqr = 0;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
132 input->fnc1 = 0;
e32df13
fukuchi authored
133
98ae1dd
fukuchi authored
134 return input;
e32df13
fukuchi authored
135 }
136
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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
151db75
fukuchi authored
156 int QRinput_getVersion(QRinput *input)
e3a6145
fukuchi authored
157 {
98ae1dd
fukuchi authored
158 return input->version;
e3a6145
fukuchi authored
159 }
160
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
161 int QRinput_setVersion(QRinput *input, int version)
e3a6145
fukuchi authored
162 {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
163 if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
164 errno = EINVAL;
165 return -1;
166 }
e3a6145
fukuchi authored
167
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
168 input->version = version;
169
170 return 0;
e3a6145
fukuchi authored
171 }
172
151db75
fukuchi authored
173 QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input)
e3a6145
fukuchi authored
174 {
98ae1dd
fukuchi authored
175 return input->level;
e3a6145
fukuchi authored
176 }
177
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
178 int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level)
e3a6145
fukuchi authored
179 {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
180 if(input->mqr || level > QR_ECLEVEL_H) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
181 errno = EINVAL;
e3a6145
fukuchi authored
182 return -1;
183 }
184
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
185 input->level = level;
186
187 return 0;
188 }
189
4006013 QRinput_setVersionAndErrorCorrectionLevel() has been added.
fukuchi authored
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
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
210 static void QRinput_appendEntry(QRinput *input, QRinput_List *entry)
211 {
98ae1dd
fukuchi authored
212 if(input->tail == NULL) {
213 input->head = entry;
214 input->tail = entry;
e3a6145
fukuchi authored
215 } else {
98ae1dd
fukuchi authored
216 input->tail->next = entry;
217 input->tail = entry;
e3a6145
fukuchi authored
218 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
219 entry->next = NULL;
220 }
221
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
fc33e4f Merged from 3.1.0.
fukuchi authored
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 */
247 __STATIC int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity)
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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;
e3a6145
fukuchi authored
271
272 return 0;
273 }
274
ad4d46a
fukuchi authored
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
98ae1dd
fukuchi authored
293 void QRinput_free(QRinput *input)
e3a6145
fukuchi authored
294 {
fc33e4f Merged from 3.1.0.
fukuchi authored
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);
e3a6145
fukuchi authored
305 }
306 }
307
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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
327 QRinput *QRinput_dup(QRinput *input)
328 {
329 QRinput *n;
330 QRinput_List *list, *e;
331
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
332 if(input->mqr) {
333 n = QRinput_newMQR(input->version, input->level);
334 } else {
335 n = QRinput_new2(input->version, input->level);
336 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
337 if(n == NULL) return NULL;
338
339 list = input->head;
340 while(list != NULL) {
341 e = QRinput_List_dup(list);
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
342 if(e == NULL) {
343 QRinput_free(n);
344 return NULL;
345 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
346 QRinput_appendEntry(n, e);
347 list = list->next;
348 }
349
350 return n;
351 }
352
e3a6145
fukuchi authored
353 /******************************************************************************
354 * Numeric data
355 *****************************************************************************/
356
357 /**
358 * Check the input data.
359 * @param size
360 * @param data
361 * @return result
362 */
151db75
fukuchi authored
363 static int QRinput_checkModeNum(int size, const char *data)
e3a6145
fukuchi authored
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.
61c843c
fukuchi authored
377 * @param size
e3a6145
fukuchi authored
378 * @return number of bits
379 */
61c843c
fukuchi authored
380 int QRinput_estimateBitsModeNum(int size)
e3a6145
fukuchi authored
381 {
382 int w;
383 int bits;
384
61c843c
fukuchi authored
385 w = size / 3;
e3a6145
fukuchi authored
386 bits = w * 10;
61c843c
fukuchi authored
387 switch(size - w * 3) {
e3a6145
fukuchi authored
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 /**
98ae1dd
fukuchi authored
402 * Convert the number data to a bit stream.
e3a6145
fukuchi authored
403 * @param entry
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
404 * @param mqr
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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.
e3a6145
fukuchi authored
409 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
410 static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
411 {
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
412 int words, i, ret;
e3a6145
fukuchi authored
413 unsigned int val;
414
415 entry->bstream = BitStream_new();
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
416 if(entry->bstream == NULL) return -1;
e3a6145
fukuchi authored
417
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
418 if(mqr) {
419 if(version > 1) {
a9c3306 * qrencode.h:
fukuchi authored
420 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 {
a9c3306 * qrencode.h:
fukuchi authored
426 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
427 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
428
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
429 ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size);
430 if(ret < 0) goto ABORT;
431 }
e3a6145
fukuchi authored
432
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
433 words = entry->size / 3;
e3a6145
fukuchi authored
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
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
439 ret = BitStream_appendNum(entry->bstream, 10, val);
440 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
441 }
442
443 if(entry->size - words * 3 == 1) {
444 val = entry->data[words*3] - '0';
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
445 ret = BitStream_appendNum(entry->bstream, 4, val);
446 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
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);
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
451 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
452 }
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
453
454 return 0;
455 ABORT:
456 BitStream_free(entry->bstream);
457 entry->bstream = NULL;
458 return -1;
e3a6145
fukuchi authored
459 }
460
461 /******************************************************************************
462 * Alphabet-numeric data
463 *****************************************************************************/
464
fc33e4f Merged from 3.1.0.
fukuchi authored
465 const signed char QRinput_anTable[128] = {
e3a6145
fukuchi authored
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,
13fffb7 Synchronized to 2.0.0.
fukuchi authored
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
e3a6145
fukuchi authored
474 };
475
476 /**
477 * Check the input data.
478 * @param size
479 * @param data
480 * @return result
481 */
151db75
fukuchi authored
482 static int QRinput_checkModeAn(int size, const char *data)
e3a6145
fukuchi authored
483 {
484 int i;
485
486 for(i=0; i<size; i++) {
151db75
fukuchi authored
487 if(QRinput_lookAnTable(data[i]) < 0)
e3a6145
fukuchi authored
488 return -1;
489 }
490
491 return 0;
492 }
493
494 /**
495 * Estimates the length of the encoded bit stream of alphabet-numeric data.
61c843c
fukuchi authored
496 * @param size
e3a6145
fukuchi authored
497 * @return number of bits
498 */
61c843c
fukuchi authored
499 int QRinput_estimateBitsModeAn(int size)
e3a6145
fukuchi authored
500 {
501 int w;
502 int bits;
503
61c843c
fukuchi authored
504 w = size / 2;
e3a6145
fukuchi authored
505 bits = w * 11;
61c843c
fukuchi authored
506 if(size & 1) {
e3a6145
fukuchi authored
507 bits += 6;
508 }
509
510 return bits;
511 }
512
513 /**
98ae1dd
fukuchi authored
514 * Convert the alphabet-numeric data to a bit stream.
e3a6145
fukuchi authored
515 * @param entry
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
516 * @param mqr
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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.
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
521 * @throw EINVAL invalid version.
e3a6145
fukuchi authored
522 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
523 static int QRinput_encodeModeAn(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
524 {
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
525 int words, i, ret;
e3a6145
fukuchi authored
526 unsigned int val;
527
528 entry->bstream = BitStream_new();
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
529 if(entry->bstream == NULL) return -1;
e3a6145
fukuchi authored
530
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
531 if(mqr) {
532 if(version < 2) {
533 errno = EINVAL;
534 goto ABORT;
535 }
a9c3306 * qrencode.h:
fukuchi authored
536 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_AN);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 {
a9c3306 * qrencode.h:
fukuchi authored
541 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_AN);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 }
e3a6145
fukuchi authored
546
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
547 words = entry->size / 2;
e3a6145
fukuchi authored
548 for(i=0; i<words; i++) {
151db75
fukuchi authored
549 val = (unsigned int)QRinput_lookAnTable(entry->data[i*2 ]) * 45;
550 val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]);
e3a6145
fukuchi authored
551
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
552 ret = BitStream_appendNum(entry->bstream, 11, val);
553 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
554 }
555
556 if(entry->size & 1) {
151db75
fukuchi authored
557 val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]);
e3a6145
fukuchi authored
558
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
559 ret = BitStream_appendNum(entry->bstream, 6, val);
560 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
561 }
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
562
563 return 0;
564 ABORT:
565 BitStream_free(entry->bstream);
566 entry->bstream = NULL;
567 return -1;
e3a6145
fukuchi authored
568 }
569
570 /******************************************************************************
571 * 8 bit data
572 *****************************************************************************/
573
574 /**
575 * Estimates the length of the encoded bit stream of 8 bit data.
61c843c
fukuchi authored
576 * @param size
e3a6145
fukuchi authored
577 * @return number of bits
578 */
61c843c
fukuchi authored
579 int QRinput_estimateBitsMode8(int size)
e3a6145
fukuchi authored
580 {
61c843c
fukuchi authored
581 return size * 8;
e3a6145
fukuchi authored
582 }
583
584 /**
98ae1dd
fukuchi authored
585 * Convert the 8bits data to a bit stream.
e3a6145
fukuchi authored
586 * @param entry
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
587 * @param mqr
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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.
e3a6145
fukuchi authored
592 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
593 static int QRinput_encodeMode8(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
594 {
ad4d46a
fukuchi authored
595 int ret;
e3a6145
fukuchi authored
596
597 entry->bstream = BitStream_new();
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
598 if(entry->bstream == NULL) return -1;
e3a6145
fukuchi authored
599
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
600 if(mqr) {
601 if(version < 3) {
602 errno = EINVAL;
603 goto ABORT;
604 }
a9c3306 * qrencode.h:
fukuchi authored
605 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_8);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 {
a9c3306 * qrencode.h:
fukuchi authored
610 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_8);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 }
e3a6145
fukuchi authored
615
ad4d46a
fukuchi authored
616 ret = BitStream_appendBytes(entry->bstream, entry->size, entry->data);
617 if(ret < 0) goto ABORT;
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
618
619 return 0;
620 ABORT:
621 BitStream_free(entry->bstream);
622 entry->bstream = NULL;
623 return -1;
e3a6145
fukuchi authored
624 }
625
626
627 /******************************************************************************
628 * Kanji data
629 *****************************************************************************/
630
631 /**
632 * Estimates the length of the encoded bit stream of kanji data.
61c843c
fukuchi authored
633 * @param size
e3a6145
fukuchi authored
634 * @return number of bits
635 */
61c843c
fukuchi authored
636 int QRinput_estimateBitsModeKanji(int size)
e3a6145
fukuchi authored
637 {
61c843c
fukuchi authored
638 return (size / 2) * 13;
e3a6145
fukuchi authored
639 }
640
641 /**
642 * Check the input data.
643 * @param size
644 * @param data
645 * @return result
646 */
151db75
fukuchi authored
647 static int QRinput_checkModeKanji(int size, const unsigned char *data)
e3a6145
fukuchi authored
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 /**
98ae1dd
fukuchi authored
666 * Convert the kanji data to a bit stream.
e3a6145
fukuchi authored
667 * @param entry
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
668 * @param mqr
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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.
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
673 * @throw EINVAL invalid version.
e3a6145
fukuchi authored
674 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
675 static int QRinput_encodeModeKanji(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
676 {
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
677 int ret, i;
e3a6145
fukuchi authored
678 unsigned int val, h;
679
680 entry->bstream = BitStream_new();
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
681 if(entry->bstream == NULL) return -1;
e3a6145
fukuchi authored
682
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
683 if(mqr) {
684 if(version < 2) {
685 errno = EINVAL;
686 goto ABORT;
687 }
a9c3306 * qrencode.h:
fukuchi authored
688 ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_KANJI);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 {
a9c3306 * qrencode.h:
fukuchi authored
693 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_KANJI);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 }
e3a6145
fukuchi authored
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
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
709 ret = BitStream_appendNum(entry->bstream, 13, val);
710 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
711 }
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
712
713 return 0;
714 ABORT:
715 BitStream_free(entry->bstream);
716 entry->bstream = NULL;
717 return -1;
e3a6145
fukuchi authored
718 }
719
720 /******************************************************************************
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
721 * Structured Symbol
e3a6145
fukuchi authored
722 *****************************************************************************/
723
724 /**
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
725 * Convert a structure symbol code to a bit stream.
726 * @param entry
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
727 * @param mqr
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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.
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
732 * @throw EINVAL invalid entry.
e3a6145
fukuchi authored
733 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
734 static int QRinput_encodeModeStructure(QRinput_List *entry, int mqr)
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
735 {
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
736 int ret;
737
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
738 if(mqr) {
739 errno = EINVAL;
740 return -1;
741 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
742 entry->bstream = BitStream_new();
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
743 if(entry->bstream == NULL) return -1;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
744
a9c3306 * qrencode.h:
fukuchi authored
745 ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_STRUCTURE);
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
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;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
759 }
760
761 /******************************************************************************
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
762 * FNC1
763 *****************************************************************************/
764
765 static int QRinput_checkModeFNC1Second(int size, const unsigned char *data)
766 {
767 if(size != 1) return -1;
768
769 return 0;
770 }
771
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 /******************************************************************************
ad4d46a
fukuchi authored
793 * ECI header
794 *****************************************************************************/
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
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
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 /******************************************************************************
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
861 * Validation
862 *****************************************************************************/
863
4ee4f8d
fukuchi authored
864 int QRinput_check(QRencodeMode mode, int size, const unsigned char *data)
e3a6145
fukuchi authored
865 {
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
866 if((mode == QR_MODE_FNC1FIRST && size < 0) || size <= 0) return -1;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
867
e3a6145
fukuchi authored
868 switch(mode) {
869 case QR_MODE_NUM:
151db75
fukuchi authored
870 return QRinput_checkModeNum(size, (const char *)data);
e3a6145
fukuchi authored
871 case QR_MODE_AN:
151db75
fukuchi authored
872 return QRinput_checkModeAn(size, (const char *)data);
e3a6145
fukuchi authored
873 case QR_MODE_KANJI:
151db75
fukuchi authored
874 return QRinput_checkModeKanji(size, data);
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
875 case QR_MODE_8:
876 return 0;
877 case QR_MODE_STRUCTURE:
878 return 0;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
879 case QR_MODE_ECI:
ad4d46a
fukuchi authored
880 return 0;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
881 case QR_MODE_FNC1FIRST:
882 return 0;
883 case QR_MODE_FNC1SECOND:
884 return QRinput_checkModeFNC1Second(size, data);
885 case QR_MODE_NUL:
e3a6145
fukuchi authored
886 break;
887 }
888
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
889 return -1;
e3a6145
fukuchi authored
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
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
900 * @param mqr
e3a6145
fukuchi authored
901 * @return number of bits
902 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
903 static int QRinput_estimateBitStreamSizeOfEntry(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
904 {
905 int bits = 0;
906 int l, m;
907 int num;
908
7dbf4f6 QRinput_splitQRinputToStruct() now returns NULL when version = 0.
fukuchi authored
909 if(version == 0) version = 1;
910
e3a6145
fukuchi authored
911 switch(entry->mode) {
912 case QR_MODE_NUM:
61c843c
fukuchi authored
913 bits = QRinput_estimateBitsModeNum(entry->size);
e3a6145
fukuchi authored
914 break;
915 case QR_MODE_AN:
61c843c
fukuchi authored
916 bits = QRinput_estimateBitsModeAn(entry->size);
e3a6145
fukuchi authored
917 break;
918 case QR_MODE_8:
61c843c
fukuchi authored
919 bits = QRinput_estimateBitsMode8(entry->size);
e3a6145
fukuchi authored
920 break;
921 case QR_MODE_KANJI:
61c843c
fukuchi authored
922 bits = QRinput_estimateBitsModeKanji(entry->size);
e3a6145
fukuchi authored
923 break;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
924 case QR_MODE_STRUCTURE:
ad4d46a
fukuchi authored
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;
608b948 3.0.0rc2 is merged to the main trunk.
fukuchi authored
934 default:
935 return 0;
e3a6145
fukuchi authored
936 }
937
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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;
e3a6145
fukuchi authored
946
ad4d46a
fukuchi authored
947 bits += num * (MODE_INDICATOR_SIZE + l);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
948 }
e3a6145
fukuchi authored
949
950 return bits;
951 }
952
953 /**
98ae1dd
fukuchi authored
954 * Estimates the length of the encoded bit stream of the data.
955 * @param input input data
e3a6145
fukuchi authored
956 * @param version version of the symbol
957 * @return number of bits
958 */
fc33e4f Merged from 3.1.0.
fukuchi authored
959 __STATIC int QRinput_estimateBitStreamSize(QRinput *input, int version)
e3a6145
fukuchi authored
960 {
151db75
fukuchi authored
961 QRinput_List *list;
e3a6145
fukuchi authored
962 int bits = 0;
963
98ae1dd
fukuchi authored
964 list = input->head;
e3a6145
fukuchi authored
965 while(list != NULL) {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
966 bits += QRinput_estimateBitStreamSizeOfEntry(list, version, input->mqr);
e3a6145
fukuchi authored
967 list = list->next;
968 }
969
970 return bits;
971 }
972
973 /**
974 * Estimates the required version number of the symbol.
98ae1dd
fukuchi authored
975 * @param input input data
e3a6145
fukuchi authored
976 * @return required version number
977 */
151db75
fukuchi authored
978 static int QRinput_estimateVersion(QRinput *input)
e3a6145
fukuchi authored
979 {
980 int bits;
f8898ad
fukuchi authored
981 int version, prev;
e3a6145
fukuchi authored
982
f8898ad
fukuchi authored
983 version = 0;
e3a6145
fukuchi authored
984 do {
f8898ad
fukuchi authored
985 prev = version;
151db75
fukuchi authored
986 bits = QRinput_estimateBitStreamSize(input, prev);
f8898ad
fukuchi authored
987 version = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
988 if (version < 0) {
e3a6145
fukuchi authored
989 return -1;
990 }
f8898ad
fukuchi authored
991 } while (version > prev);
e3a6145
fukuchi authored
992
f8898ad
fukuchi authored
993 return version;
e3a6145
fukuchi authored
994 }
995
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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 */
fc33e4f Merged from 3.1.0.
fukuchi authored
1003 __STATIC int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits)
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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;
ad4d46a
fukuchi authored
1040 if(maxsize > 0 && size > maxsize) size = maxsize;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1041
1042 return size;
1043 }
1044
e3a6145
fukuchi authored
1045 /******************************************************************************
1046 * Data conversion
1047 *****************************************************************************/
1048
1049 /**
98ae1dd
fukuchi authored
1050 * Convert the input data in the data chunk to a bit stream.
e3a6145
fukuchi authored
1051 * @param entry
b62c825 More return value checks. Mainly for ENOMEM error.
fukuchi authored
1052 * @return number of bits (>0) or -1 for failure.
e3a6145
fukuchi authored
1053 */
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1054 static int QRinput_encodeBitStream(QRinput_List *entry, int version, int mqr)
e3a6145
fukuchi authored
1055 {
fc33e4f Merged from 3.1.0.
fukuchi authored
1056 int words, ret;
1057 QRinput_List *st1 = NULL, *st2 = NULL;
e3a6145
fukuchi authored
1058
1059 if(entry->bstream != NULL) {
1060 BitStream_free(entry->bstream);
1061 entry->bstream = NULL;
1062 }
1063
1064 words = QRspec_maximumWords(entry->mode, version);
ad4d46a
fukuchi authored
1065 if(words != 0 && entry->size > words) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1066 st1 = QRinput_List_newEntry(entry->mode, words, entry->data);
fc33e4f Merged from 3.1.0.
fukuchi authored
1067 if(st1 == NULL) goto ABORT;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1068 st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]);
fc33e4f Merged from 3.1.0.
fukuchi authored
1069 if(st2 == NULL) goto ABORT;
1070
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1071 ret = QRinput_encodeBitStream(st1, version, mqr);
fc33e4f Merged from 3.1.0.
fukuchi authored
1072 if(ret < 0) goto ABORT;
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1073 ret = QRinput_encodeBitStream(st2, version, mqr);
fc33e4f Merged from 3.1.0.
fukuchi authored
1074 if(ret < 0) goto ABORT;
e3a6145
fukuchi authored
1075 entry->bstream = BitStream_new();
fc33e4f Merged from 3.1.0.
fukuchi authored
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;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1081 QRinput_List_freeEntry(st1);
1082 QRinput_List_freeEntry(st2);
e3a6145
fukuchi authored
1083 } else {
fc33e4f Merged from 3.1.0.
fukuchi authored
1084 ret = 0;
e3a6145
fukuchi authored
1085 switch(entry->mode) {
1086 case QR_MODE_NUM:
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1087 ret = QRinput_encodeModeNum(entry, version, mqr);
e3a6145
fukuchi authored
1088 break;
1089 case QR_MODE_AN:
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1090 ret = QRinput_encodeModeAn(entry, version, mqr);
e3a6145
fukuchi authored
1091 break;
1092 case QR_MODE_8:
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1093 ret = QRinput_encodeMode8(entry, version, mqr);
e3a6145
fukuchi authored
1094 break;
1095 case QR_MODE_KANJI:
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1096 ret = QRinput_encodeModeKanji(entry, version, mqr);
e3a6145
fukuchi authored
1097 break;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1098 case QR_MODE_STRUCTURE:
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1099 ret = QRinput_encodeModeStructure(entry, mqr);
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1100 break;
ad4d46a
fukuchi authored
1101 case QR_MODE_ECI:
1102 ret = QRinput_encodeModeECI(entry, version);
1103 break;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
1104 case QR_MODE_FNC1SECOND:
1105 ret = QRinput_encodeModeFNC1Second(entry, version);
e3a6145
fukuchi authored
1106 default:
1107 break;
1108 }
fc33e4f Merged from 3.1.0.
fukuchi authored
1109 if(ret < 0) return -1;
e3a6145
fukuchi authored
1110 }
1111
1112 return BitStream_size(entry->bstream);
fc33e4f Merged from 3.1.0.
fukuchi authored
1113 ABORT:
1114 QRinput_List_freeEntry(st1);
1115 QRinput_List_freeEntry(st2);
1116 return -1;
e3a6145
fukuchi authored
1117 }
1118
1119 /**
98ae1dd
fukuchi authored
1120 * Convert the input data to a bit stream.
1121 * @param input input data.
fc33e4f Merged from 3.1.0.
fukuchi authored
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.
e3a6145
fukuchi authored
1126 */
151db75
fukuchi authored
1127 static int QRinput_createBitStream(QRinput *input)
e3a6145
fukuchi authored
1128 {
151db75
fukuchi authored
1129 QRinput_List *list;
fc33e4f Merged from 3.1.0.
fukuchi authored
1130 int bits, total = 0;
e3a6145
fukuchi authored
1131
98ae1dd
fukuchi authored
1132 list = input->head;
e3a6145
fukuchi authored
1133 while(list != NULL) {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1134 bits = QRinput_encodeBitStream(list, input->version, input->mqr);
fc33e4f Merged from 3.1.0.
fukuchi authored
1135 if(bits < 0) return -1;
1136 total += bits;
e3a6145
fukuchi authored
1137 list = list->next;
1138 }
1139
fc33e4f Merged from 3.1.0.
fukuchi authored
1140 return total;
e3a6145
fukuchi authored
1141 }
1142
1143 /**
98ae1dd
fukuchi authored
1144 * Convert the input data to a bit stream.
e3a6145
fukuchi authored
1145 * When the version number is given and that is not sufficient, it is increased
1146 * automatically.
98ae1dd
fukuchi authored
1147 * @param input input data.
fc33e4f Merged from 3.1.0.
fukuchi authored
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.
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1152 * @throw ERANGE input is too large.
e3a6145
fukuchi authored
1153 */
151db75
fukuchi authored
1154 static int QRinput_convertData(QRinput *input)
e3a6145
fukuchi authored
1155 {
1156 int bits;
1157 int ver;
1158
151db75
fukuchi authored
1159 ver = QRinput_estimateVersion(input);
1160 if(ver > QRinput_getVersion(input)) {
1161 QRinput_setVersion(input, ver);
cc939f5
fukuchi authored
1162 }
e3a6145
fukuchi authored
1163
1164 for(;;) {
151db75
fukuchi authored
1165 bits = QRinput_createBitStream(input);
fc33e4f Merged from 3.1.0.
fukuchi authored
1166 if(bits < 0) return -1;
98ae1dd
fukuchi authored
1167 ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
e3a6145
fukuchi authored
1168 if(ver < 0) {
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1169 errno = ERANGE;
e3a6145
fukuchi authored
1170 return -1;
151db75
fukuchi authored
1171 } else if(ver > QRinput_getVersion(input)) {
1172 QRinput_setVersion(input, ver);
e3a6145
fukuchi authored
1173 } else {
1174 break;
1175 }
1176 }
1177
1178 return 0;
1179 }
1180
1181 /**
fc33e4f Merged from 3.1.0.
fukuchi authored
1182 * Append padding bits for the input data.
1183 * @param bstream Bitstream to be appended.
98ae1dd
fukuchi authored
1184 * @param input input data.
fc33e4f Merged from 3.1.0.
fukuchi authored
1185 * @retval 0 success
1186 * @retval -1 an error occurred and errno is set to indeicate the error.
1187 * See Execptions for the details.
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1188 * @throw ERANGE input data is too large.
fc33e4f Merged from 3.1.0.
fukuchi authored
1189 * @throw ENOMEM unable to allocate memory.
e3a6145
fukuchi authored
1190 */
fc33e4f Merged from 3.1.0.
fukuchi authored
1191 static int QRinput_appendPaddingBit(BitStream *bstream, QRinput *input)
e3a6145
fukuchi authored
1192 {
fc33e4f Merged from 3.1.0.
fukuchi authored
1193 int bits, maxbits, words, maxwords, i, ret;
6b89e6b Possible memory errors fixed.
fukuchi authored
1194 BitStream *padding = NULL;
fc33e4f Merged from 3.1.0.
fukuchi authored
1195 unsigned char *padbuf;
1196 int padlen;
e3a6145
fukuchi authored
1197
fc33e4f Merged from 3.1.0.
fukuchi authored
1198 bits = BitStream_size(bstream);
98ae1dd
fukuchi authored
1199 maxwords = QRspec_getDataLength(input->version, input->level);
e3a6145
fukuchi authored
1200 maxbits = maxwords * 8;
61c843c
fukuchi authored
1201
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1202 if(maxbits < bits) {
1203 errno = ERANGE;
1204 return -1;
1205 }
c7b998e * configure.ac:
fukuchi authored
1206 if(maxbits == bits) {
fc33e4f Merged from 3.1.0.
fukuchi authored
1207 return 0;
e3a6145
fukuchi authored
1208 }
1209
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1210 if(maxbits - bits <= 4) {
fc33e4f Merged from 3.1.0.
fukuchi authored
1211 ret = BitStream_appendNum(bstream, maxbits - bits, 0);
1212 goto DONE;
e3a6145
fukuchi authored
1213 }
1214
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 }
61c843c
fukuchi authored
1245
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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.
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1253 * @throw ERANGE input data is too large.
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1254 * @throw ENOMEM unable to allocate memory.
1255 */
1256 static int QRinput_appendPaddingBitMQR(BitStream *bstream, QRinput *input)
1257 {
1258 int bits, maxbits, words, maxwords, i, ret, termbits;
6b89e6b Possible memory errors fixed.
fukuchi authored
1259 BitStream *padding = NULL;
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1260 unsigned char *padbuf;
1261 int padlen;
1262
1263 bits = BitStream_size(bstream);
db35a2e Follows changes of mqrspec.c.
fukuchi authored
1264 maxbits = MQRspec_getDataLengthBit(input->version, input->level);
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1265 maxwords = maxbits / 8;
1266
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1267 if(maxbits < bits) {
1268 errno = ERANGE;
1269 return -1;
1270 }
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
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 }
fc33e4f Merged from 3.1.0.
fukuchi authored
1291 padding = BitStream_new();
1292 if(padding == NULL) return -1;
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1293 ret = BitStream_appendNum(padding, termbits, 0);
fc33e4f Merged from 3.1.0.
fukuchi authored
1294 if(ret < 0) goto DONE;
1295
1296 padlen = maxwords - words;
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1297 if(padlen > 0) {
fc33e4f Merged from 3.1.0.
fukuchi authored
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 }
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1311 termbits = maxbits - maxwords * 8;
1312 if(termbits > 0) {
1313 ret = BitStream_appendNum(padding, termbits, 0);
1314 if(ret < 0) goto DONE;
1315 }
e3a6145
fukuchi authored
1316 }
1317
fc33e4f Merged from 3.1.0.
fukuchi authored
1318 ret = BitStream_append(bstream, padding);
1319
1320 DONE:
1321 BitStream_free(padding);
1322 return ret;
e3a6145
fukuchi authored
1323 }
1324
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
1325 static int QRinput_insertFNC1Header(QRinput *input)
1326 {
4cbbca7 @fukuchi config.h is now included at the top of the code.
authored
1327 QRinput_List *entry = NULL;
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
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
e3a6145
fukuchi authored
1349 /**
98ae1dd
fukuchi authored
1350 * Merge all bit streams in the input data.
1351 * @param input input data.
e3a6145
fukuchi authored
1352 * @return merged bit stream
1353 */
1354
fc33e4f Merged from 3.1.0.
fukuchi authored
1355 __STATIC BitStream *QRinput_mergeBitStream(QRinput *input)
e3a6145
fukuchi authored
1356 {
1357 BitStream *bstream;
151db75
fukuchi authored
1358 QRinput_List *list;
fc33e4f Merged from 3.1.0.
fukuchi authored
1359 int ret;
e3a6145
fukuchi authored
1360
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1361 if(input->mqr) {
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
1362 if(QRinput_createBitStream(input) < 0) {
1363 return NULL;
1364 }
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1365 } else {
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored
1366 if(input->fnc1) {
1367 if(QRinput_insertFNC1Header(input) < 0) {
1368 return NULL;
1369 }
1370 }
fa3bb06 VERSION_MAX moved to qrencode.h.
fukuchi authored
1371 if(QRinput_convertData(input) < 0) {
1372 return NULL;
1373 }
e3a6145
fukuchi authored
1374 }
1375
1376 bstream = BitStream_new();
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1377 if(bstream == NULL) return NULL;
1378
98ae1dd
fukuchi authored
1379 list = input->head;
e3a6145
fukuchi authored
1380 while(list != NULL) {
fc33e4f Merged from 3.1.0.
fukuchi authored
1381 ret = BitStream_append(bstream, list->bstream);
1382 if(ret < 0) {
1383 BitStream_free(bstream);
1384 return NULL;
1385 }
e3a6145
fukuchi authored
1386 list = list->next;
1387 }
1388
1389 return bstream;
1390 }
1391
1392 /**
98ae1dd
fukuchi authored
1393 * Merge all bit streams in the input data and append padding bits
1394 * @param input input data.
e3a6145
fukuchi authored
1395 * @return padded merged bit stream
1396 */
1397
fc33e4f Merged from 3.1.0.
fukuchi authored
1398 __STATIC BitStream *QRinput_getBitStream(QRinput *input)
e3a6145
fukuchi authored
1399 {
1400 BitStream *bstream;
fc33e4f Merged from 3.1.0.
fukuchi authored
1401 int ret;
e3a6145
fukuchi authored
1402
151db75
fukuchi authored
1403 bstream = QRinput_mergeBitStream(input);
e3a6145
fukuchi authored
1404 if(bstream == NULL) {
1405 return NULL;
1406 }
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1407 if(input->mqr) {
1408 ret = QRinput_appendPaddingBitMQR(bstream, input);
1409 } else {
1410 ret = QRinput_appendPaddingBit(bstream, input);
1411 }
fc33e4f Merged from 3.1.0.
fukuchi authored
1412 if(ret < 0) {
1413 BitStream_free(bstream);
1414 return NULL;
61c843c
fukuchi authored
1415 }
e3a6145
fukuchi authored
1416
1417 return bstream;
1418 }
1419
1420 /**
1421 * Pack all bit streams padding bits into a byte array.
98ae1dd
fukuchi authored
1422 * @param input input data.
e3a6145
fukuchi authored
1423 * @return padded merged byte stream
1424 */
1425
151db75
fukuchi authored
1426 unsigned char *QRinput_getByteStream(QRinput *input)
e3a6145
fukuchi authored
1427 {
1428 BitStream *bstream;
1429 unsigned char *array;
1430
151db75
fukuchi authored
1431 bstream = QRinput_getBitStream(input);
7f8ae3d
fukuchi authored
1432 if(bstream == NULL) {
1433 return NULL;
1434 }
e3a6145
fukuchi authored
1435 array = BitStream_toByte(bstream);
1436 BitStream_free(bstream);
1437
1438 return array;
1439 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1440
1441 /******************************************************************************
1442 * Structured input data
1443 *****************************************************************************/
1444
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
fc33e4f Merged from 3.1.0.
fukuchi authored
1458 static void QRinput_InputList_freeEntry(QRinput_InputList *entry)
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1459 {
fc33e4f Merged from 3.1.0.
fukuchi authored
1460 if(entry != NULL) {
1461 QRinput_free(entry->input);
1462 free(entry);
1463 }
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1464 }
1465
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
1481 void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity)
1482 {
1483 s->parity = (int)parity;
1484 }
1485
1486 int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input)
1487 {
1488 QRinput_InputList *e;
1489
d4b1856 mqr check has been added.
fukuchi authored
1490 if(input->mqr) {
1491 errno = EINVAL;
1492 return -1;
1493 }
1494
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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
1510 void QRinput_Struct_free(QRinput_Struct *s)
1511 {
fc33e4f Merged from 3.1.0.
fukuchi authored
1512 QRinput_InputList *list, *next;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1513
fc33e4f Merged from 3.1.0.
fukuchi authored
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);
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1522 }
1523 }
1524
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
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
fc33e4f Merged from 3.1.0.
fukuchi authored
1556 __STATIC int QRinput_splitEntry(QRinput_List *entry, int bytes)
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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
1578 QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input)
1579 {
1580 QRinput *p;
1581 QRinput_Struct *s;
fc33e4f Merged from 3.1.0.
fukuchi authored
1582 int bits, maxbits, nextbits, bytes, ret;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1583 QRinput_List *list, *next, *prev;
1584
d4b1856 mqr check has been added.
fukuchi authored
1585 if(input->mqr) {
1586 errno = EINVAL;
1587 return NULL;
1588 }
1589
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
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));
ad4d46a
fukuchi authored
1600 maxbits = QRspec_getDataLength(input->version, input->level) * 8 - STRUCTURE_HEADER_SIZE;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1601
7dbf4f6 QRinput_splitQRinputToStruct() now returns NULL when version = 0.
fukuchi authored
1602 if(maxbits <= 0) {
1603 QRinput_Struct_free(s);
d725a78 Merged from 3.1.0.
fukuchi authored
1604 QRinput_free(input);
7dbf4f6 QRinput_splitQRinputToStruct() now returns NULL when version = 0.
fukuchi authored
1605 return NULL;
1606 }
1607
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1608 bits = 0;
1609 list = input->head;
1610 prev = NULL;
1611 while(list != NULL) {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1612 nextbits = QRinput_estimateBitStreamSizeOfEntry(list, input->version, input->mqr);
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1613 if(bits + nextbits <= maxbits) {
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1614 ret = QRinput_encodeBitStream(list, input->version, input->mqr);
fc33e4f Merged from 3.1.0.
fukuchi authored
1615 if(ret < 0) goto ABORT;
1616 bits += ret;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1617 prev = list;
1618 list = list->next;
1619 } else {
1620 bytes = QRinput_lengthOfCode(list->mode, input->version, maxbits - bits);
1621 if(bytes > 0) {
1622 /* Splits this entry into 2 entries. */
fc33e4f Merged from 3.1.0.
fukuchi authored
1623 ret = QRinput_splitEntry(list, bytes);
1624 if(ret < 0) goto ABORT;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1625 /* First half is the tail of the current input. */
1626 next = list->next;
1627 list->next = NULL;
1628 /* Second half is the head of the next input, p.*/
1629 p = QRinput_new2(input->version, input->level);
fc33e4f Merged from 3.1.0.
fukuchi authored
1630 if(p == NULL) goto ABORT;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1631 p->head = next;
1632 /* Renew QRinput.tail. */
1633 p->tail = input->tail;
1634 input->tail = list;
1635 /* Point to the next entry. */
1636 prev = list;
1637 list = next;
1638 } else {
1639 /* Current entry will go to the next input. */
1640 prev->next = NULL;
1641 p = QRinput_new2(input->version, input->level);
fc33e4f Merged from 3.1.0.
fukuchi authored
1642 if(p == NULL) goto ABORT;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1643 p->head = list;
1644 p->tail = input->tail;
1645 input->tail = prev;
1646 }
fc33e4f Merged from 3.1.0.
fukuchi authored
1647 ret = QRinput_Struct_appendInput(s, input);
1648 if(ret < 0) goto ABORT;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1649 input = p;
1650 bits = 0;
1651 }
1652 }
1653 QRinput_Struct_appendInput(s, input);
1654 if(s->size > MAX_STRUCTURED_SYMBOLS) {
1655 QRinput_Struct_free(s);
1656 errno = ERANGE;
1657 return NULL;
1658 }
fc33e4f Merged from 3.1.0.
fukuchi authored
1659 ret = QRinput_Struct_insertStructuredAppendHeaders(s);
1660 if(ret < 0) {
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1661 QRinput_Struct_free(s);
1662 return NULL;
1663 }
1664
1665 return s;
fc33e4f Merged from 3.1.0.
fukuchi authored
1666
1667 ABORT:
1668 QRinput_free(input);
1669 QRinput_Struct_free(s);
1670 return NULL;
5600a47 3.0.0rc1 is merged to the main trunk.
fukuchi authored
1671 }
1672
1673 int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s)
1674 {
1675 int num, i;
1676 QRinput_InputList *list;
1677
1678 if(s->parity < 0) {
1679 QRinput_Struct_calcParity(s);
1680 }
1681 num = 0;
1682 list = s->head;
1683 while(list != NULL) {
1684 num++;
1685 list = list->next;
1686 }
1687 i = 1;
1688 list = s->head;
1689 while(list != NULL) {
1690 if(QRinput_insertStructuredAppendHeader(list->input, num, i, s->parity))
1691 return -1;
1692 i++;
1693 list = list->next;
1694 }
1695
1696 return 0;
1697 }
01ad229 Functions for Micro QR Code encoding have been added.
fukuchi authored
1698
1699 /******************************************************************************
6befd5b - Added new functions to set FNC1 flag.
fukuchi authored