1/* 2 * qrencode - QR Code encoder 3 * 4 * Copyright (C) 2006-2012 Kentaro Fukuchi <kentaro@fukuchi.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#if HAVE_CONFIG_H 22# include "config.h" 23#endif 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <errno.h> 28 29#include "qrencode.h" 30#include "qrspec.h" 31#include "mqrspec.h" 32#include "bitstream.h" 33#include "qrinput.h" 34#include "rscode.h" 35#include "split.h" 36#include "mask.h" 37#include "mmask.h" 38 39/****************************************************************************** 40 * Raw code 41 *****************************************************************************/ 42 43typedef struct { 44 int dataLength; 45 unsigned char *data; 46 int eccLength; 47 unsigned char *ecc; 48} RSblock; 49 50typedef struct { 51 int version; 52 int dataLength; 53 int eccLength; 54 unsigned char *datacode; 55 unsigned char *ecccode; 56 int b1; 57 int blocks; 58 RSblock *rsblock; 59 int count; 60} QRRawCode; 61 62static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc, RS *rs) 63{ 64 block->dataLength = dl; 65 block->data = data; 66 block->eccLength = el; 67 block->ecc = ecc; 68 69 encode_rs_char(rs, data, ecc); 70} 71 72static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc) 73{ 74 int i; 75 RSblock *block; 76 unsigned char *dp, *ep; 77 RS *rs; 78 int el, dl; 79 80 dl = QRspec_rsDataCodes1(spec); 81 el = QRspec_rsEccCodes1(spec); 82 rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el); 83 if(rs == NULL) return -1; 84 85 block = blocks; 86 dp = data; 87 ep = ecc; 88 for(i=0; i<QRspec_rsBlockNum1(spec); i++) { 89 RSblock_initBlock(block, dl, dp, el, ep, rs); 90 dp += dl; 91 ep += el; 92 block++; 93 } 94 95 if(QRspec_rsBlockNum2(spec) == 0) return 0; 96 97 dl = QRspec_rsDataCodes2(spec); 98 el = QRspec_rsEccCodes2(spec); 99 rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el); 100 if(rs == NULL) return -1; 101 for(i=0; i<QRspec_rsBlockNum2(spec); i++) { 102 RSblock_initBlock(block, dl, dp, el, ep, rs); 103 dp += dl; 104 ep += el; 105 block++; 106 } 107 108 return 0; 109} 110 111__STATIC void QRraw_free(QRRawCode *raw); 112__STATIC QRRawCode *QRraw_new(QRinput *input) 113{ 114 QRRawCode *raw; 115 int spec[5], ret; 116 117 raw = (QRRawCode *)malloc(sizeof(QRRawCode)); 118 if(raw == NULL) return NULL; 119 120 raw->datacode = QRinput_getByteStream(input); 121 if(raw->datacode == NULL) { 122 free(raw); 123 return NULL; 124 } 125 126 QRspec_getEccSpec(input->version, input->level, spec); 127 128 raw->version = input->version; 129 raw->b1 = QRspec_rsBlockNum1(spec); 130 raw->dataLength = QRspec_rsDataLength(spec); 131 raw->eccLength = QRspec_rsEccLength(spec); 132 raw->ecccode = (unsigned char *)malloc(raw->eccLength); 133 if(raw->ecccode == NULL) { 134 free(raw->datacode); 135 free(raw); 136 return NULL; 137 } 138 139 raw->blocks = QRspec_rsBlockNum(spec); 140 raw->rsblock = (RSblock *)calloc(sizeof(RSblock), raw->blocks); 141 if(raw->rsblock == NULL) { 142 QRraw_free(raw); 143 return NULL; 144 } 145 ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode); 146 if(ret < 0) { 147 QRraw_free(raw); 148 return NULL; 149 } 150 151 raw->count = 0; 152 153 return raw; 154} 155 156/** 157 * Return a code (byte). 158 * This function can be called iteratively. 159 * @param raw raw code. 160 * @return code 161 */ 162__STATIC unsigned char QRraw_getCode(QRRawCode *raw) 163{ 164 int col, row; 165 unsigned char ret; 166 167 if(raw->count < raw->dataLength) { 168 row = raw->count % raw->blocks; 169 col = raw->count / raw->blocks; 170 if(col >= raw->rsblock[0].dataLength) { 171 row += raw->b1; 172 } 173 ret = raw->rsblock[row].data[col]; 174 } else if(raw->count < raw->dataLength + raw->eccLength) { 175 row = (raw->count - raw->dataLength) % raw->blocks; 176 col = (raw->count - raw->dataLength) / raw->blocks; 177 ret = raw->rsblock[row].ecc[col]; 178 } else { 179 return 0; 180 } 181 raw->count++; 182 return ret; 183} 184 185__STATIC void QRraw_free(QRRawCode *raw) 186{ 187 if(raw != NULL) { 188 free(raw->datacode); 189 free(raw->ecccode); 190 free(raw->rsblock); 191 free(raw); 192 } 193} 194 195/****************************************************************************** 196 * Raw code for Micro QR Code 197 *****************************************************************************/ 198 199typedef struct { 200 int version; 201 int dataLength; 202 int eccLength; 203 unsigned char *datacode; 204 unsigned char *ecccode; 205 RSblock *rsblock; 206 int oddbits; 207 int count; 208} MQRRawCode; 209 210__STATIC void MQRraw_free(MQRRawCode *raw); 211__STATIC MQRRawCode *MQRraw_new(QRinput *input) 212{ 213 MQRRawCode *raw; 214 RS *rs; 215 216 raw = (MQRRawCode *)malloc(sizeof(MQRRawCode)); 217 if(raw == NULL) return NULL; 218 219 raw->version = input->version; 220 raw->dataLength = MQRspec_getDataLength(input->version, input->level); 221 raw->eccLength = MQRspec_getECCLength(input->version, input->level); 222 raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level); 223 raw->datacode = QRinput_getByteStream(input); 224 if(raw->datacode == NULL) { 225 free(raw); 226 return NULL; 227 } 228 raw->ecccode = (unsigned char *)malloc(raw->eccLength); 229 if(raw->ecccode == NULL) { 230 free(raw->datacode); 231 free(raw); 232 return NULL; 233 } 234 235 raw->rsblock = (RSblock *)calloc(sizeof(RSblock), 1); 236 if(raw->rsblock == NULL) { 237 MQRraw_free(raw); 238 return NULL; 239 } 240 241 rs = init_rs(8, 0x11d, 0, 1, raw->eccLength, 255 - raw->dataLength - raw->eccLength); 242 if(rs == NULL) { 243 MQRraw_free(raw); 244 return NULL; 245 } 246 247 RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode, rs); 248 249 raw->count = 0; 250 251 return raw; 252} 253 254/** 255 * Return a code (byte). 256 * This function can be called iteratively. 257 * @param raw raw code. 258 * @return code 259 */ 260__STATIC unsigned char MQRraw_getCode(MQRRawCode *raw) 261{ 262 unsigned char ret; 263 264 if(raw->count < raw->dataLength) { 265 ret = raw->datacode[raw->count]; 266 } else if(raw->count < raw->dataLength + raw->eccLength) { 267 ret = raw->ecccode[raw->count - raw->dataLength]; 268 } else { 269 return 0; 270 } 271 raw->count++; 272 return ret; 273} 274 275__STATIC void MQRraw_free(MQRRawCode *raw) 276{ 277 if(raw != NULL) { 278 free(raw->datacode); 279 free(raw->ecccode); 280 free(raw->rsblock); 281 free(raw); 282 } 283} 284 285 286/****************************************************************************** 287 * Frame filling 288 *****************************************************************************/ 289 290typedef struct { 291 int width; 292 unsigned char *frame; 293 int x, y; 294 int dir; 295 int bit; 296 int mqr; 297} FrameFiller; 298 299static FrameFiller *FrameFiller_new(int width, unsigned char *frame, int mqr) 300{ 301 FrameFiller *filler; 302 303 filler = (FrameFiller *)malloc(sizeof(FrameFiller)); 304 if(filler == NULL) return NULL; 305 filler->width = width; 306 filler->frame = frame; 307 filler->x = width - 1; 308 filler->y = width - 1; 309 filler->dir = -1; 310 filler->bit = -1; 311 filler->mqr = mqr; 312 313 return filler; 314} 315 316static unsigned char *FrameFiller_next(FrameFiller *filler) 317{ 318 unsigned char *p; 319 int x, y, w; 320 321 if(filler->bit == -1) { 322 filler->bit = 0; 323 return filler->frame + filler->y * filler->width + filler->x; 324 } 325 326 x = filler->x; 327 y = filler->y; 328 p = filler->frame; 329 w = filler->width; 330 331 if(filler->bit == 0) { 332 x--; 333 filler->bit++; 334 } else { 335 x++; 336 y += filler->dir; 337 filler->bit--; 338 } 339 340 if(filler->dir < 0) { 341 if(y < 0) { 342 y = 0; 343 x -= 2; 344 filler->dir = 1; 345 if(!filler->mqr && x == 6) { 346 x--; 347 y = 9; 348 } 349 } 350 } else { 351 if(y == w) { 352 y = w - 1; 353 x -= 2; 354 filler->dir = -1; 355 if(!filler->mqr && x == 6) { 356 x--; 357 y -= 8; 358 } 359 } 360 } 361 if(x < 0 || y < 0) return NULL; 362 363 filler->x = x; 364 filler->y = y; 365 366 if(p[y * w + x] & 0x80) { 367 // This tail recursion could be optimized. 368 return FrameFiller_next(filler); 369 } 370 return &p[y * w + x]; 371} 372 373#ifdef WITH_TESTS 374extern unsigned char *FrameFiller_test(int version) 375{ 376 int width; 377 unsigned char *frame, *p; 378 FrameFiller *filler; 379 int i, length; 380 381 width = QRspec_getWidth(version); 382 frame = QRspec_newFrame(version); 383 if(frame == NULL) return NULL; 384 filler = FrameFiller_new(width, frame, 0); 385 if(filler == NULL) { 386 free(frame); 387 return NULL; 388 } 389 length = QRspec_getDataLength(version, QR_ECLEVEL_L) * 8 390 + QRspec_getECCLength(version, QR_ECLEVEL_L) * 8 391 + QRspec_getRemainder(version); 392 for(i=0; i<length; i++) { 393 p = FrameFiller_next(filler); 394 if(p == NULL) { 395 free(filler); 396 free(frame); 397 return NULL; 398 } 399 *p = (unsigned char)(i & 0x7f) | 0x80; 400 } 401 free(filler); 402 return frame; 403} 404 405extern unsigned char *FrameFiller_testMQR(int version) 406{ 407 int width; 408 unsigned char *frame, *p; 409 FrameFiller *filler; 410 int i, length; 411 412 width = MQRspec_getWidth(version); 413 frame = MQRspec_newFrame(version); 414 if(frame == NULL) return NULL; 415 filler = FrameFiller_new(width, frame, 1); 416 if(filler == NULL) { 417 free(frame); 418 return NULL; 419 } 420 length = MQRspec_getDataLengthBit(version, QR_ECLEVEL_L) 421 + MQRspec_getECCLength(version, QR_ECLEVEL_L) * 8; 422 for(i=0; i<length; i++) { 423 p = FrameFiller_next(filler); 424 if(p == NULL) { 425 fprintf(stderr, "Frame filler run over the frame!\n"); 426 free(filler); 427 return frame; 428 } 429 *p = (unsigned char)(i & 0x7f) | 0x80; 430 } 431 free(filler); 432 return frame; 433} 434#endif 435 436 437/****************************************************************************** 438 * QR-code encoding 439 *****************************************************************************/ 440 441__STATIC QRcode *QRcode_new(int version, int width, unsigned char *data) 442{ 443 QRcode *qrcode; 444 445 qrcode = (QRcode *)malloc(sizeof(QRcode)); 446 if(qrcode == NULL) return NULL; 447 448 qrcode->version = version; 449 qrcode->width = width; 450 qrcode->data = data; 451 452 return qrcode; 453} 454 455void QRcode_free(QRcode *qrcode) 456{ 457 if(qrcode != NULL) { 458 free(qrcode->data); 459 free(qrcode); 460 } 461} 462 463__STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask) 464{ 465 int width, version; 466 QRRawCode *raw; 467 unsigned char *frame, *masked, *p, code, bit; 468 FrameFiller *filler; 469 int i, j; 470 QRcode *qrcode = NULL; 471 472 if(input->mqr) { 473 errno = EINVAL; 474 return NULL; 475 } 476 if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) { 477 errno = EINVAL; 478 return NULL; 479 } 480 if(input->level > QR_ECLEVEL_H) { 481 errno = EINVAL; 482 return NULL; 483 } 484 485 raw = QRraw_new(input); 486 if(raw == NULL) return NULL; 487 488 version = raw->version; 489 width = QRspec_getWidth(version); 490 frame = QRspec_newFrame(version); 491 if(frame == NULL) { 492 QRraw_free(raw); 493 return NULL; 494 } 495 filler = FrameFiller_new(width, frame, 0); 496 if(filler == NULL) { 497 QRraw_free(raw); 498 free(frame); 499 return NULL; 500 } 501 502 /* inteleaved data and ecc codes */ 503 for(i=0; i<raw->dataLength + raw->eccLength; i++) { 504 code = QRraw_getCode(raw); 505 bit = 0x80; 506 for(j=0; j<8; j++) { 507 p = FrameFiller_next(filler); 508 if(p == NULL) goto EXIT; 509 *p = 0x02 | ((bit & code) != 0); 510 bit = bit >> 1; 511 } 512 } 513 QRraw_free(raw); 514 raw = NULL; 515 /* remainder bits */ 516 j = QRspec_getRemainder(version); 517 for(i=0; i<j; i++) { 518 p = FrameFiller_next(filler); 519 if(p == NULL) goto EXIT; 520 *p = 0x02; 521 } 522 523 /* masking */ 524 if(mask == -2) { // just for debug purpose 525 masked = (unsigned char *)malloc(width * width); 526 memcpy(masked, frame, width * width); 527 } else if(mask < 0) { 528 masked = Mask_mask(width, frame, input->level); 529 } else { 530 masked = Mask_makeMask(width, frame, mask, input->level); 531 } 532 if(masked == NULL) { 533 goto EXIT; 534 } 535 qrcode = QRcode_new(version, width, masked); 536 537EXIT: 538 QRraw_free(raw); 539 free(filler); 540 free(frame); 541 return qrcode; 542} 543 544__STATIC QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask) 545{ 546 int width, version; 547 MQRRawCode *raw; 548 unsigned char *frame, *masked, *p, code, bit; 549 FrameFiller *filler; 550 int i, j; 551 QRcode *qrcode = NULL; 552 553 if(!input->mqr) { 554 errno = EINVAL; 555 return NULL; 556 } 557 if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) { 558 errno = EINVAL; 559 return NULL; 560 } 561 if(input->level > QR_ECLEVEL_Q) { 562 errno = EINVAL; 563 return NULL; 564 } 565 566 raw = MQRraw_new(input); 567 if(raw == NULL) return NULL; 568 569 version = raw->version; 570 width = MQRspec_getWidth(version); 571 frame = MQRspec_newFrame(version); 572 if(frame == NULL) { 573 MQRraw_free(raw); 574 return NULL; 575 } 576 filler = FrameFiller_new(width, frame, 1); 577 if(filler == NULL) { 578 MQRraw_free(raw); 579 free(frame); 580 return NULL; 581 } 582 583 /* inteleaved data and ecc codes */ 584 for(i=0; i<raw->dataLength + raw->eccLength; i++) { 585 code = MQRraw_getCode(raw); 586 if(raw->oddbits && i == raw->dataLength - 1) { 587 bit = 1 << raw->oddbits; 588 for(j=0; j<raw->oddbits; j++) { 589 p = FrameFiller_next(filler); 590 if(p == NULL) goto EXIT; 591 *p = 0x02 | ((bit & code) != 0); 592 bit = bit >> 1; 593 } 594 } else { 595 bit = 0x80; 596 for(j=0; j<8; j++) { 597 p = FrameFiller_next(filler); 598 if(p == NULL) goto EXIT; 599 *p = 0x02 | ((bit & code) != 0); 600 bit = bit >> 1; 601 } 602 } 603 } 604 MQRraw_free(raw); 605 raw = NULL; 606 607 /* masking */ 608 if(mask < 0) { 609 masked = MMask_mask(version, frame, input->level); 610 } else { 611 masked = MMask_makeMask(version, frame, mask, input->level); 612 } 613 if(masked == NULL) { 614 goto EXIT; 615 } 616 617 qrcode = QRcode_new(version, width, masked); 618 619EXIT: 620 MQRraw_free(raw); 621 free(filler); 622 free(frame); 623 return qrcode; 624} 625 626QRcode *QRcode_encodeInput(QRinput *input) 627{ 628 if(input->mqr) { 629 return QRcode_encodeMaskMQR(input, -1); 630 } else { 631 return QRcode_encodeMask(input, -1); 632 } 633} 634 635static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int mqr, QRencodeMode hint, int casesensitive) 636{ 637 QRinput *input; 638 QRcode *code; 639 int ret; 640 641 if(string == NULL) { 642 errno = EINVAL; 643 return NULL; 644 } 645 if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) { 646 errno = EINVAL; 647 return NULL; 648 } 649 650 if(mqr) { 651 input = QRinput_newMQR(version, level); 652 } else { 653 input = QRinput_new2(version, level); 654 } 655 if(input == NULL) return NULL; 656 657 ret = Split_splitStringToQRinput(string, input, hint, casesensitive); 658 if(ret < 0) { 659 QRinput_free(input); 660 return NULL; 661 } 662 code = QRcode_encodeInput(input); 663 QRinput_free(input); 664 665 return code; 666} 667 668QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) 669{ 670 return QRcode_encodeStringReal(string, version, level, 0, hint, casesensitive); 671} 672 673QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) 674{ 675 return QRcode_encodeStringReal(string, version, level, 1, hint, casesensitive); 676} 677 678static QRcode *QRcode_encodeDataReal(const unsigned char *data, int length, int version, QRecLevel level, int mqr) 679{ 680 QRinput *input; 681 QRcode *code; 682 int ret; 683 684 if(data == NULL || length == 0) { 685 errno = EINVAL; 686 return NULL; 687 } 688 689 if(mqr) { 690 input = QRinput_newMQR(version, level); 691 } else { 692 input = QRinput_new2(version, level); 693 } 694 if(input == NULL) return NULL; 695 696 ret = QRinput_append(input, QR_MODE_8, length, data); 697 if(ret < 0) { 698 QRinput_free(input); 699 return NULL; 700 } 701 code = QRcode_encodeInput(input); 702 QRinput_free(input); 703 704 return code; 705} 706 707QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level) 708{ 709 return QRcode_encodeDataReal(data, size, version, level, 0); 710} 711 712QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level) 713{ 714 if(string == NULL) { 715 errno = EINVAL; 716 return NULL; 717 } 718 return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 0); 719} 720 721QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level) 722{ 723 return QRcode_encodeDataReal(data, size, version, level, 1); 724} 725 726QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level) 727{ 728 if(string == NULL) { 729 errno = EINVAL; 730 return NULL; 731 } 732 return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 1); 733} 734 735 736/****************************************************************************** 737 * Structured QR-code encoding 738 *****************************************************************************/ 739 740static QRcode_List *QRcode_List_newEntry(void) 741{ 742 QRcode_List *entry; 743 744 entry = (QRcode_List *)malloc(sizeof(QRcode_List)); 745 if(entry == NULL) return NULL; 746 747 entry->next = NULL; 748 entry->code = NULL; 749 750 return entry; 751} 752 753static void QRcode_List_freeEntry(QRcode_List *entry) 754{ 755 if(entry != NULL) { 756 QRcode_free(entry->code); 757 free(entry); 758 } 759} 760 761void QRcode_List_free(QRcode_List *qrlist) 762{ 763 QRcode_List *list = qrlist, *next; 764 765 while(list != NULL) { 766 next = list->next; 767 QRcode_List_freeEntry(list); 768 list = next; 769 } 770} 771 772int QRcode_List_size(QRcode_List *qrlist) 773{ 774 QRcode_List *list = qrlist; 775 int size = 0; 776 777 while(list != NULL) { 778 size++; 779 list = list->next; 780 } 781 782 return size; 783} 784 785#if 0 786static unsigned char QRcode_parity(const char *str, int size) 787{ 788 unsigned char parity = 0; 789 int i; 790 791 for(i=0; i<size; i++) { 792 parity ^= str[i]; 793 } 794 795 return parity; 796} 797#endif 798 799QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s) 800{ 801 QRcode_List *head = NULL; 802 QRcode_List *tail = NULL; 803 QRcode_List *entry; 804 QRinput_InputList *list = s->head; 805 806 while(list != NULL) { 807 if(head == NULL) { 808 entry = QRcode_List_newEntry(); 809 if(entry == NULL) goto ABORT; 810 head = entry; 811 tail = head; 812 } else { 813 entry = QRcode_List_newEntry(); 814 if(entry == NULL) goto ABORT; 815 tail->next = entry; 816 tail = tail->next; 817 } 818 tail->code = QRcode_encodeInput(list->input); 819 if(tail->code == NULL) { 820 goto ABORT; 821 } 822 list = list->next; 823 } 824 825 return head; 826ABORT: 827 QRcode_List_free(head); 828 return NULL; 829} 830 831static QRcode_List *QRcode_encodeInputToStructured(QRinput *input) 832{ 833 QRinput_Struct *s; 834 QRcode_List *codes; 835 836 s = QRinput_splitQRinputToStruct(input); 837 if(s == NULL) return NULL; 838 839 codes = QRcode_encodeInputStructured(s); 840 QRinput_Struct_free(s); 841 842 return codes; 843} 844 845static QRcode_List *QRcode_encodeDataStructuredReal( 846 int size, const unsigned char *data, 847 int version, QRecLevel level, 848 int eightbit, QRencodeMode hint, int casesensitive) 849{ 850 QRinput *input; 851 QRcode_List *codes; 852 int ret; 853 854 if(version <= 0) { 855 errno = EINVAL; 856 return NULL; 857 } 858 if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) { 859 errno = EINVAL; 860 return NULL; 861 } 862 863 input = QRinput_new2(version, level); 864 if(input == NULL) return NULL; 865 866 if(eightbit) { 867 ret = QRinput_append(input, QR_MODE_8, size, data); 868 } else { 869 ret = Split_splitStringToQRinput((char *)data, input, hint, casesensitive); 870 } 871 if(ret < 0) { 872 QRinput_free(input); 873 return NULL; 874 } 875 codes = QRcode_encodeInputToStructured(input); 876 QRinput_free(input); 877 878 return codes; 879} 880 881QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level) { 882 return QRcode_encodeDataStructuredReal(size, data, version, level, 1, QR_MODE_NUL, 0); 883} 884 885QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level) { 886 if(string == NULL) { 887 errno = EINVAL; 888 return NULL; 889 } 890 return QRcode_encodeDataStructured(strlen(string), (unsigned char *)string, version, level); 891} 892 893QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) 894{ 895 if(string == NULL) { 896 errno = EINVAL; 897 return NULL; 898 } 899 return QRcode_encodeDataStructuredReal(strlen(string), (unsigned char *)string, version, level, 0, hint, casesensitive); 900} 901 902/****************************************************************************** 903 * System utilities 904 *****************************************************************************/ 905 906void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version) 907{ 908 if(major_version != NULL) { 909 *major_version = MAJOR_VERSION; 910 } 911 if(minor_version != NULL) { 912 *minor_version = MINOR_VERSION; 913 } 914 if(micro_version != NULL) { 915 *micro_version = MICRO_VERSION; 916 } 917} 918 919char *QRcode_APIVersionString(void) 920{ 921 return VERSION; 922} 923 924void QRcode_clearCache(void) 925{ 926 QRspec_clearCache(); 927 MQRspec_clearCache(); 928 free_rs_cache(); 929} 930