PageRenderTime 169ms CodeModel.GetById 30ms app.highlight 100ms RepoModel.GetById 26ms app.codeStats 0ms

/backend/qr.c

https://github.com/Pastor/zint
C | 2171 lines | 1691 code | 335 blank | 145 comment | 711 complexity | ca082b3d676fcf085fc073a5cc4d7c4b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* qr.c Handles QR Code */
   2
   3/*
   4    libzint - the open source barcode library
   5    Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
   6
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11
  12    This program 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
  15    GNU General Public License for more details.
  16
  17    You should have received a copy of the GNU General Public License along
  18    with this program; if not, write to the Free Software Foundation, Inc.,
  19    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20*/
  21
  22#include <string.h>
  23#include "common.h"
  24#include <stdio.h>
  25#include "sjis.h"
  26#include "qr.h"
  27#include "reedsol.h"
  28
  29int in_alpha(int glyph) {
  30	/* Returns true if input glyph is in the Alphanumeric set */
  31	int retval = 0;
  32	char cglyph = (char) glyph;
  33
  34	if((cglyph >= '0') && (cglyph <= '9')) {
  35		retval = 1;
  36	}
  37	if((cglyph >= 'A') && (cglyph <= 'Z')) {
  38		retval = 1;
  39	}
  40	switch (cglyph) {
  41		case ' ':
  42		case '$':
  43		case '%':
  44		case '*':
  45		case '+':
  46		case '-':
  47		case '.':
  48		case '/':
  49		case ':':
  50			retval = 1;
  51			break;
  52	}
  53
  54	return retval;
  55}
  56
  57void define_mode(char mode[], int jisdata[], int length, int gs1)
  58{
  59	/* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */
  60	int i, mlen, j;
  61
  62	for(i = 0; i < length; i++) {
  63		if(jisdata[i] > 0xff) {
  64			mode[i] = 'K';
  65		} else {
  66			mode[i] = 'B';
  67			if(in_alpha(jisdata[i])) { mode[i] = 'A'; }
  68			if(gs1 && (jisdata[i] == '[')) { mode[i] = 'A'; }
  69			if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { mode[i] = 'N'; }
  70		}
  71	}
  72
  73	/* If less than 6 numeric digits together then don't use numeric mode */
  74	for(i = 0; i < length; i++) {
  75		if(mode[i] == 'N') {
  76			if(((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) {
  77				mlen = 0;
  78				while (((mlen + i) < length) && (mode[mlen + i] == 'N')) {
  79					mlen++;
  80				};
  81				if(mlen < 6) {
  82					for(j = 0; j < mlen; j++) {
  83						mode[i + j] = 'A';
  84					}
  85				}
  86			}
  87		}
  88	}
  89
  90	/* If less than 4 alphanumeric characters together then don't use alphanumeric mode */
  91	for(i = 0; i < length; i++) {
  92		if(mode[i] == 'A') {
  93			if(((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) {
  94				mlen = 0;
  95				while (((mlen + i) < length) && (mode[mlen + i] == 'A')) {
  96					mlen++;
  97				};
  98				if(mlen < 6) {
  99					for(j = 0; j < mlen; j++) {
 100						mode[i + j] = 'B';
 101					}
 102				}
 103			}
 104		}
 105	}
 106}
 107
 108int estimate_binary_length(char mode[], int length, int gs1)
 109{
 110	/* Make an estimate (worst case scenario) of how long the binary string will be */
 111	int i, count = 0;
 112	char current = 0;
 113	int a_count = 0;
 114	int n_count = 0;
 115
 116	if(gs1) { count += 4; }
 117
 118	for(i = 0; i < length; i++) {
 119		if(mode[i] != current) {
 120			switch(mode[i]) {
 121				case 'K': count += 12 + 4; current = 'K'; break;
 122				case 'B': count += 16 + 4; current = 'B'; break;
 123				case 'A': count += 13 + 4; current = 'A'; a_count = 0; break;
 124				case 'N': count += 14 + 4; current = 'N'; n_count = 0; break;
 125			}
 126		}
 127
 128		switch(mode[i]) {
 129		case 'K': count += 13; break;
 130		case 'B': count += 8; break;
 131		case 'A':
 132			a_count++;
 133			if((a_count & 1) == 0) {
 134				count += 5;        // 11 in total
 135				a_count = 0;
 136			}
 137			else
 138				count += 6;
 139			break;
 140		case 'N':
 141			n_count++;
 142			if((n_count % 3) == 0) {
 143				count += 3;        // 10 in total
 144				n_count = 0;
 145			}
 146			else if ((n_count & 1) == 0)
 147				count += 3;        // 7 in total
 148			else
 149				count += 4;
 150			break;
 151		}
 152	}
 153
 154	return count;
 155}
 156
 157void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen)
 158{
 159	/* Convert input data to a binary stream and add padding */
 160	int position = 0, debug = 0;
 161	int short_data_block_length, i, scheme = 1;
 162	char data_block, padbits;
 163	int current_binlen, current_bytes;
 164	int toggle, percent;
 165
 166	char binary[est_binlen + 12];
 167	strcpy(binary, "");
 168
 169	if(gs1) {
 170		concat(binary, "0101"); /* FNC1 */
 171	}
 172
 173	if(version <= 9) {
 174		scheme = 1;
 175	} else if((version >= 10) && (version <= 26)) {
 176		scheme = 2;
 177	} else if(version >= 27) {
 178		scheme = 3;
 179	}
 180
 181	if(debug) {
 182		for(i = 0; i < length; i++) {
 183			printf("%c", mode[i]);
 184		}
 185		printf("\n");
 186	}
 187
 188	percent = 0;
 189
 190	do {
 191		data_block = mode[position];
 192		short_data_block_length = 0;
 193		do {
 194			short_data_block_length++;
 195		} while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block));
 196
 197		switch(data_block) {
 198			case 'K':
 199				/* Kanji mode */
 200				/* Mode indicator */
 201				concat(binary, "1000");
 202
 203				/* Character count indicator */
 204				bscan(binary, short_data_block_length, 0x20 << (scheme*2)); /* scheme = 1..3 */
 205
 206				if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); }
 207
 208				/* Character representation */
 209				for(i = 0; i < short_data_block_length; i++) {
 210					int jis = jisdata[position + i];
 211					int msb, lsb, prod;
 212
 213					if(jis > 0x9fff) { jis -= 0xc140; }
 214					msb = (jis & 0xff00) >> 4;
 215					lsb = (jis & 0xff);
 216					prod = (msb * 0xc0) + lsb;
 217
 218					bscan(binary, prod, 0x1000);
 219
 220					if(debug) { printf("0x%4X ", prod); }
 221				}
 222
 223				if(debug) { printf("\n"); }
 224
 225				break;
 226			case 'B':
 227				/* Byte mode */
 228				/* Mode indicator */
 229				concat(binary, "0100");
 230
 231				/* Character count indicator */
 232				bscan(binary, short_data_block_length, scheme > 1 ? 0x8000 : 0x80); /* scheme = 1..3 */
 233
 234				if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); }
 235
 236				/* Character representation */
 237				for(i = 0; i < short_data_block_length; i++) {
 238					int byte = jisdata[position + i];
 239
 240					if(gs1 && (byte == '[')) {
 241						byte = 0x1d; /* FNC1 */
 242					}
 243
 244					bscan(binary, byte, 0x80);
 245
 246					if(debug) { printf("0x%2X(%d) ", byte, byte); }
 247				}
 248
 249				if(debug) { printf("\n"); }
 250
 251				break;
 252			case 'A':
 253				/* Alphanumeric mode */
 254				/* Mode indicator */
 255				concat(binary, "0010");
 256
 257				/* Character count indicator */
 258				bscan(binary, short_data_block_length, 0x40 << (2 * scheme)); /* scheme = 1..3 */
 259
 260				if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); }
 261
 262				/* Character representation */
 263				i = 0;
 264				while ( i < short_data_block_length ) {
 265					int count;
 266					int first = 0, second = 0, prod;
 267
 268					if(percent == 0) {
 269						if(gs1 && (jisdata[position + i] == '%')) {
 270							first = posn(RHODIUM, '%');
 271							second = posn(RHODIUM, '%');
 272							count = 2;
 273							prod = (first * 45) + second;
 274							i++;
 275						} else {
 276							if(gs1 && (jisdata[position + i] == '[')) {
 277								first = posn(RHODIUM, '%'); /* FNC1 */
 278							} else {
 279								first = posn(RHODIUM, (char) jisdata[position + i]);
 280							}
 281							count = 1;
 282							i++;
 283							prod = first;
 284
 285							if(mode[position + i] == 'A') {
 286								if(gs1 && (jisdata[position + i] == '%')) {
 287									second = posn(RHODIUM, '%');
 288									count = 2;
 289									prod = (first * 45) + second;
 290									percent = 1;
 291								} else {
 292									if(gs1 && (jisdata[position + i] == '[')) {
 293										second = posn(RHODIUM, '%'); /* FNC1 */
 294									} else {
 295										second = posn(RHODIUM, (char) jisdata[position + i]);
 296									}
 297									count = 2;
 298									i++;
 299									prod = (first * 45) + second;
 300								}
 301							}
 302						}
 303					} else {
 304						first = posn(RHODIUM, '%');
 305						count = 1;
 306						i++;
 307						prod = first;
 308						percent = 0;
 309
 310						if(mode[position + i] == 'A') {
 311							if(gs1 && (jisdata[position + i] == '%')) {
 312								second = posn(RHODIUM, '%');
 313								count = 2;
 314								prod = (first * 45) + second;
 315								percent = 1;
 316							} else {
 317								if(gs1 && (jisdata[position + i] == '[')) {
 318									second = posn(RHODIUM, '%'); /* FNC1 */
 319								} else {
 320									second = posn(RHODIUM, (char) jisdata[position + i]);
 321								}
 322								count = 2;
 323								i++;
 324								prod = (first * 45) + second;
 325							}
 326						}
 327					}
 328
 329					bscan(binary, prod, count == 2 ? 0x400 : 0x20); /* count = 1..2 */
 330
 331					if(debug) { printf("0x%4X ", prod); }
 332				};
 333
 334				if(debug) { printf("\n"); }
 335
 336				break;
 337			case 'N':
 338				/* Numeric mode */
 339				/* Mode indicator */
 340				concat(binary, "0001");
 341
 342				/* Character count indicator */
 343				bscan(binary, short_data_block_length, 0x80 << (2 * scheme)); /* scheme = 1..3 */
 344
 345				if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); }
 346
 347								/* Character representation */
 348				i = 0;
 349				while ( i < short_data_block_length ) {
 350					int count;
 351					int first = 0, second = 0, third = 0, prod;
 352
 353					first = posn(NEON, (char) jisdata[position + i]);
 354					count = 1;
 355					prod = first;
 356
 357					if(mode[position + i + 1] == 'N') {
 358						second = posn(NEON, (char) jisdata[position + i + 1]);
 359						count = 2;
 360						prod = (prod * 10) + second;
 361
 362						if(mode[position + i + 2] == 'N') {
 363							third = posn(NEON, (char) jisdata[position + i + 2]);
 364							count = 3;
 365							prod = (prod * 10) + third;
 366						}
 367					}
 368
 369					bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
 370
 371					if(debug) { printf("0x%4X (%d)", prod, prod); }
 372
 373					i += count;
 374				};
 375
 376				if(debug) { printf("\n"); }
 377
 378				break;
 379		}
 380
 381		position += short_data_block_length;
 382	} while (position < length) ;
 383
 384	/* Terminator */
 385	concat(binary, "0000");
 386
 387	current_binlen = strlen(binary);
 388	padbits = 8 - (current_binlen % 8);
 389	if(padbits == 8) { padbits = 0; }
 390	current_bytes = (current_binlen + padbits) / 8;
 391
 392	/* Padding bits */
 393	for(i = 0; i < padbits; i++) {
 394		concat(binary, "0");
 395	}
 396
 397	/* Put data into 8-bit codewords */
 398	for(i = 0; i < current_bytes; i++) {
 399		datastream[i] = 0x00;
 400		if(binary[i * 8] == '1') { datastream[i] += 0x80; }
 401		if(binary[i * 8 + 1] == '1') { datastream[i] += 0x40; }
 402		if(binary[i * 8 + 2] == '1') { datastream[i] += 0x20; }
 403		if(binary[i * 8 + 3] == '1') { datastream[i] += 0x10; }
 404		if(binary[i * 8 + 4] == '1') { datastream[i] += 0x08; }
 405		if(binary[i * 8 + 5] == '1') { datastream[i] += 0x04; }
 406		if(binary[i * 8 + 6] == '1') { datastream[i] += 0x02; }
 407		if(binary[i * 8 + 7] == '1') { datastream[i] += 0x01; }
 408	}
 409
 410	/* Add pad codewords */
 411	toggle = 0;
 412	for(i = current_bytes; i < target_binlen; i++) {
 413		if(toggle == 0) {
 414			datastream[i] = 0xec;
 415			toggle = 1;
 416		} else {
 417			datastream[i] = 0x11;
 418			toggle = 0;
 419		}
 420	}
 421
 422	if(debug) {
 423		printf("Resulting codewords:\n\t");
 424		for(i = 0; i < target_binlen; i++) {
 425			printf("0x%2X ", datastream[i]);
 426		}
 427		printf("\n");
 428	}
 429}
 430
 431void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int blocks)
 432{
 433	/* Split data into blocks, add error correction and then interleave the blocks and error correction data */
 434	int ecc_cw = qr_total_codewords[version - 1] - data_cw;
 435	int short_data_block_length = data_cw / blocks;
 436	int qty_long_blocks = data_cw % blocks;
 437	int qty_short_blocks = blocks - qty_long_blocks;
 438	int ecc_block_length = ecc_cw / blocks;
 439	int i, j, length_this_block, posn, debug = 0;
 440
 441
 442	unsigned char data_block[short_data_block_length + 2];
 443	unsigned char ecc_block[ecc_block_length + 2];
 444	int interleaved_data[data_cw + 2];
 445	int interleaved_ecc[ecc_cw + 2];
 446
 447	posn = 0;
 448
 449	for(i = 0; i < blocks; i++) {
 450		if(i < qty_short_blocks) { length_this_block = short_data_block_length; } else { length_this_block = short_data_block_length + 1; }
 451
 452		for(j = 0; j < ecc_block_length; j++) {
 453			ecc_block[j] = 0;
 454		}
 455
 456		for(j = 0; j < length_this_block; j++) {
 457			data_block[j] = (unsigned char) datastream[posn + j];
 458		}
 459
 460		rs_init_gf(0x11d);
 461		rs_init_code(ecc_block_length, 0);
 462		rs_encode(length_this_block, data_block, ecc_block);
 463		rs_free();
 464
 465		if(debug) {
 466			printf("Block %d: ", i + 1);
 467			for(j = 0; j < length_this_block; j++) {
 468				printf("%2X ", data_block[j]);
 469			}
 470			if(i < qty_short_blocks) {
 471				printf("   ");
 472			}
 473			printf(" // ");
 474			for(j = 0; j < ecc_block_length; j++) {
 475				printf("%2X ", ecc_block[ecc_block_length - j - 1]);
 476			}
 477			printf("\n");
 478		}
 479
 480		for(j = 0; j < short_data_block_length; j++) {
 481			interleaved_data[(j * blocks) + i] = (int) data_block[j];
 482		}
 483
 484		if(i >= qty_short_blocks){
 485			interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length];
 486		}
 487
 488		for(j = 0; j < ecc_block_length; j++) {
 489			interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1];
 490		}
 491
 492		posn += length_this_block;
 493	}
 494
 495	for(j = 0; j < data_cw; j++) {
 496		fullstream[j] = interleaved_data[j];
 497	}
 498	for(j = 0; j < ecc_cw; j++) {
 499		fullstream[j + data_cw] = interleaved_ecc[j];
 500	}
 501
 502	if(debug) {
 503		printf("\nData Stream: \n");
 504		for(j = 0; j < (data_cw + ecc_cw); j++) {
 505			printf("%2X ", fullstream[j]);
 506		}
 507		printf("\n");
 508	}
 509}
 510
 511void place_finder(unsigned char grid[], int size, int x, int y)
 512{
 513	int xp, yp;
 514
 515	int finder[] = {
 516		1, 1, 1, 1, 1, 1, 1,
 517		1, 0, 0, 0, 0, 0, 1,
 518		1, 0, 1, 1, 1, 0, 1,
 519		1, 0, 1, 1, 1, 0, 1,
 520		1, 0, 1, 1, 1, 0, 1,
 521		1, 0, 0, 0, 0, 0, 1,
 522		1, 1, 1, 1, 1, 1, 1
 523	};
 524
 525	for(xp = 0; xp < 7; xp++) {
 526		for(yp = 0; yp < 7; yp++) {
 527			if (finder[xp + (7 * yp)] == 1) {
 528				grid[((yp + y) * size) + (xp + x)] = 0x11;
 529			} else {
 530				grid[((yp + y) * size) + (xp + x)] = 0x10;
 531			}
 532		}
 533	}
 534}
 535
 536void place_align(unsigned char grid[], int size, int x, int y)
 537{
 538	int xp, yp;
 539
 540	int alignment[] = {
 541		1, 1, 1, 1, 1,
 542		1, 0, 0, 0, 1,
 543		1, 0, 1, 0, 1,
 544		1, 0, 0, 0, 1,
 545		1, 1, 1, 1, 1
 546	};
 547
 548	x -= 2;
 549	y -= 2; /* Input values represent centre of pattern */
 550
 551	for(xp = 0; xp < 5; xp++) {
 552		for(yp = 0; yp < 5; yp++) {
 553			if (alignment[xp + (5 * yp)] == 1) {
 554				grid[((yp + y) * size) + (xp + x)] = 0x11;
 555			} else {
 556				grid[((yp + y) * size) + (xp + x)] = 0x10;
 557			}
 558		}
 559	}
 560}
 561
 562void setup_grid(unsigned char* grid, int size, int version)
 563{
 564	int toggle = 1;
 565	int loopsize, x, y, xcoord, ycoord;
 566
 567	/* Add timing patterns */
 568	for(int i = 0; i < size; i++) {
 569		if(toggle == 1) {
 570			grid[(6 * size) + i] = 0x21;
 571			grid[(i * size) + 6] = 0x21;
 572			toggle = 0;
 573		} else {
 574			grid[(6 * size) + i] = 0x20;
 575			grid[(i * size) + 6] = 0x20;
 576			toggle = 1;
 577		}
 578	}
 579
 580	/* Add finder patterns */
 581	place_finder(grid, size, 0, 0);
 582	place_finder(grid, size, 0, size - 7);
 583	place_finder(grid, size, size - 7, 0);
 584
 585	/* Add separators */
 586	for(int i = 0; i < 7; i++) {
 587		grid[(7 * size) + i] = 0x10;
 588		grid[(i * size) + 7] = 0x10;
 589		grid[(7 * size) + (size - 1 - i)] = 0x10;
 590		grid[(i * size) + (size - 8)] = 0x10;
 591		grid[((size - 8) * size) + i] = 0x10;
 592		grid[((size - 1 - i) * size) + 7] = 0x10;
 593	}
 594	grid[(7 * size) + 7] = 0x10;
 595	grid[(7 * size) + (size - 8)] = 0x10;
 596	grid[((size - 8) * size) + 7] = 0x10;
 597
 598	/* Add alignment patterns */
 599	if(version != 1) {
 600		/* Version 1 does not have alignment patterns */
 601
 602		loopsize = qr_align_loopsize[version - 1];
 603		for(x = 0; x < loopsize; x++) {
 604			for(y = 0; y < loopsize; y++) {
 605				xcoord = qr_table_e1[((version - 2) * 7) + x];
 606				ycoord = qr_table_e1[((version - 2) * 7) + y];
 607
 608				if(!(grid[(ycoord * size) + xcoord] & 0x10)) {
 609					place_align(grid, size, xcoord, ycoord);
 610				}
 611			}
 612		}
 613	}
 614
 615	/* Reserve space for format information */
 616	for(int i = 0; i < 8; i++) {
 617		grid[(8 * size) + i] += 0x20;
 618		grid[(i * size) + 8] += 0x20;
 619		grid[(8 * size) + (size - 1 - i)] = 0x20;
 620		grid[((size - 1 - i) * size) + 8] = 0x20;
 621	}
 622	grid[(8 * size) + 8] += 20;
 623	grid[((size - 1 - 7) * size) + 8] = 0x21; /* Dark Module from Figure 25 */
 624
 625	/* Reserve space for version information */
 626	if (version >= 7) {
 627		for (int i = 0; i < 6; i++) {
 628			grid[((size - 9) * size) + i] = 0x20;
 629			grid[((size - 10) * size) + i] = 0x20;
 630			grid[((size - 11) * size) + i] = 0x20;
 631			grid[(i * size) + (size - 9)] = 0x20;
 632			grid[(i * size) + (size - 10)] = 0x20;
 633			grid[(i * size) + (size - 11)] = 0x20;
 634		}
 635	}
 636}
 637
 638int cwbit(int* datastream, int i) {
 639	int word = i >> 3;
 640	int bit = 7 - (i & 7);
 641
 642	return (datastream[word] >> bit) & 1;
 643}
 644
 645void populate_grid(unsigned char* grid, int size, int* datastream, int cw)
 646{
 647	int direction = 1; /* up */
 648	int row = 0; /* right hand side */
 649
 650	int i, n, x, y;
 651
 652	n = cw * 8;
 653	y = size - 1;
 654	i = 0;
 655	do {
 656		x = (size - 2) - (row * 2);
 657		if(x < 6)
 658			x--; /* skip over vertical timing pattern */
 659
 660		if(!(grid[(y * size) + (x + 1)] & 0xf0)) {
 661			if (cwbit(datastream, i)) {
 662				grid[(y * size) + (x + 1)] = 0x01;
 663			} else {
 664				grid[(y * size) + (x + 1)] = 0x00;
 665			}
 666			i++;
 667		}
 668
 669		if(i < n) {
 670			if(!(grid[(y * size) + x] & 0xf0)) {
 671				if (cwbit(datastream, i)) {
 672					grid[(y * size) + x] = 0x01;
 673				} else {
 674					grid[(y * size) + x] = 0x00;
 675				}
 676				i++;
 677			}
 678		}
 679
 680		if(direction) { y--; } else { y++; }
 681		if(y == -1) {
 682			/* reached the top */
 683			row++;
 684			y = 0;
 685			direction = 0;
 686		}
 687		if(y == size) {
 688			/* reached the bottom */
 689			row++;
 690			y = size - 1;
 691			direction = 1;
 692		}
 693	} while (i < n);
 694}
 695
 696int evaluate(unsigned char *grid, int size, int pattern)
 697{
 698	int x, y, block;
 699	int result = 0;
 700	char state;
 701	int p;
 702	int dark_mods;
 703	int percentage, k;
 704
 705	char local[size * size];
 706
 707	for(x = 0; x < size; x++) {
 708		for(y = 0; y < size; y++) {
 709			switch(pattern) {
 710				case 0: if (grid[(y * size) + x] & 0x01) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 711				case 1: if (grid[(y * size) + x] & 0x02) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 712				case 2: if (grid[(y * size) + x] & 0x04) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 713				case 3: if (grid[(y * size) + x] & 0x08) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 714				case 4: if (grid[(y * size) + x] & 0x10) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 715				case 5: if (grid[(y * size) + x] & 0x20) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 716				case 6: if (grid[(y * size) + x] & 0x40) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 717				case 7: if (grid[(y * size) + x] & 0x80) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
 718			}
 719		}
 720	}
 721
 722	/* Test 1: Adjacent modules in row/column in same colour */
 723	/* Vertical */
 724	for(x = 0; x < size; x++) {
 725		state = local[x];
 726		block = 0;
 727		for(y = 0; y < size; y++) {
 728			if(local[(y * size) + x] == state) {
 729				block++;
 730			} else {
 731				if(block > 5) {
 732					result += (3 + block);
 733				}
 734				block = 0;
 735				state = local[(y * size) + x];
 736			}
 737		}
 738		if(block > 5) {
 739			result += (3 + block);
 740		}
 741	}
 742
 743	/* Horizontal */
 744	for(y = 0; y < size; y++) {
 745		state = local[y * size];
 746		block = 0;
 747		for(x = 0; x < size; x++) {
 748			if(local[(y * size) + x] == state) {
 749				block++;
 750			} else {
 751				if(block > 5) {
 752					result += (3 + block);
 753				}
 754				block = 0;
 755				state = local[(y * size) + x];
 756			}
 757		}
 758		if(block > 5) {
 759			result += (3 + block);
 760		}
 761	}
 762
 763	/* Test 2 is not implimented */
 764
 765	/* Test 3: 1:1:3:1:1 ratio pattern in row/column */
 766	/* Vertical */
 767	for(x = 0; x < size; x++) {
 768		for(y = 0; y < (size - 7); y++) {
 769			p = 0;
 770			if(local[(y * size) + x] == '1') { p += 0x40; }
 771			if(local[((y + 1) * size) + x] == '1') { p += 0x20; }
 772			if(local[((y + 2) * size) + x] == '1') { p += 0x10; }
 773			if(local[((y + 3) * size) + x] == '1') { p += 0x08; }
 774			if(local[((y + 4) * size) + x] == '1') { p += 0x04; }
 775			if(local[((y + 5) * size) + x] == '1') { p += 0x02; }
 776			if(local[((y + 6) * size) + x] == '1') { p += 0x01; }
 777			if(p == 0x5d) {
 778				result += 40;
 779			}
 780		}
 781	}
 782
 783	/* Horizontal */
 784	for(y = 0; y < size; y++) {
 785		for(x = 0; x < (size - 7); x++) {
 786			p = 0;
 787			if(local[(y * size) + x] == '1') { p += 0x40; }
 788			if(local[(y * size) + x + 1] == '1') { p += 0x20; }
 789			if(local[(y * size) + x + 2] == '1') { p += 0x10; }
 790			if(local[(y * size) + x + 3] == '1') { p += 0x08; }
 791			if(local[(y * size) + x + 4] == '1') { p += 0x04; }
 792			if(local[(y * size) + x + 5] == '1') { p += 0x02; }
 793			if(local[(y * size) + x + 6] == '1') { p += 0x01; }
 794			if(p == 0x5d) {
 795				result += 40;
 796			}
 797		}
 798	}
 799
 800	/* Test 4: Proportion of dark modules in entire symbol */
 801	dark_mods = 0;
 802	for(x = 0; x < size; x++) {
 803		for(y = 0; y < size; y++) {
 804			if(local[(y * size) + x] == '1') {
 805				dark_mods++;
 806			}
 807		}
 808	}
 809	percentage = 100 * (dark_mods / (size * size));
 810	if(percentage <= 50) {
 811		k = ((100 - percentage) - 50) / 5;
 812	} else {
 813		k = (percentage - 50) / 5;
 814	}
 815
 816	result += 10 * k;
 817
 818	return result;
 819}
 820
 821
 822int apply_bitmask(unsigned char *grid, int size)
 823{
 824	int x, y;
 825	unsigned char p;
 826	int pattern, penalty[8];
 827	int best_val, best_pattern;
 828	int bit;
 829
 830	unsigned char mask[size * size];
 831	unsigned char eval[size * size];
 832
 833	/* Perform data masking */
 834	for(x = 0; x < size; x++) {
 835		for(y = 0; y < size; y++) {
 836			mask[(y * size) + x] = 0x00;
 837
 838			if (!(grid[(y * size) + x] & 0xf0)) {
 839				if(((y + x) & 1) == 0) { mask[(y * size) + x] += 0x01; }
 840				if((y & 1) == 0) { mask[(y * size) + x] += 0x02; }
 841				if((x % 3) == 0) { mask[(y * size) + x] += 0x04; }
 842				if(((y + x) % 3) == 0) { mask[(y * size) + x] += 0x08; }
 843				if((((y / 2) + (x / 3)) & 1) == 0) { mask[(y * size) + x] += 0x10; }
 844				if((((y * x) & 1) + ((y * x) % 3)) == 0) { mask[(y * size) + x] += 0x20; }
 845				if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x40; }
 846				if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x80; }
 847			}
 848		}
 849	}
 850
 851	for(x = 0; x < size; x++) {
 852		for(y = 0; y < size; y++) {
 853			if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; }
 854
 855			eval[(y * size) + x] = mask[(y * size) + x] ^ p;
 856		}
 857	}
 858
 859
 860	/* Evaluate result */
 861	for(pattern = 0; pattern < 8; pattern++) {
 862		penalty[pattern] = evaluate(eval, size, pattern);
 863	}
 864
 865	best_pattern = 0;
 866	best_val = penalty[0];
 867	for(pattern = 1; pattern < 8; pattern++) {
 868		if(penalty[pattern] < best_val) {
 869			best_pattern = pattern;
 870			best_val = penalty[pattern];
 871		}
 872	}
 873
 874	/* Apply mask */
 875	for(x = 0; x < size; x++) {
 876		for(y = 0; y < size; y++) {
 877			bit = 0;
 878			switch(best_pattern) {
 879				case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break;
 880				case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break;
 881				case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break;
 882				case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break;
 883				case 4: if(mask[(y * size) + x] & 0x10) { bit = 1; } break;
 884				case 5: if(mask[(y * size) + x] & 0x20) { bit = 1; } break;
 885				case 6: if(mask[(y * size) + x] & 0x40) { bit = 1; } break;
 886				case 7: if(mask[(y * size) + x] & 0x80) { bit = 1; } break;
 887			}
 888			if(bit == 1) {
 889				if(grid[(y * size) + x] & 0x01) {
 890					grid[(y * size) + x] = 0x00;
 891				} else {
 892					grid[(y * size) + x] = 0x01;
 893				}
 894			}
 895		}
 896	}
 897
 898	return best_pattern;
 899}
 900
 901void add_format_info(unsigned char *grid, int size, int ecc_level, int pattern)
 902{
 903	/* Add format information to grid */
 904
 905	int format = pattern;
 906	unsigned int seq;
 907	int i;
 908
 909	switch(ecc_level) {
 910		case LEVEL_L: format += 0x08; break;
 911		case LEVEL_Q: format += 0x18; break;
 912		case LEVEL_H: format += 0x10; break;
 913	}
 914
 915	seq = qr_annex_c[format];
 916
 917	for(i = 0; i < 6; i++) {
 918		grid[(i * size) + 8] += (seq >> i) & 0x01;
 919	}
 920
 921	for(i = 0; i < 8; i++) {
 922		grid[(8 * size) + (size - i - 1)] += (seq >> i) & 0x01;
 923	}
 924
 925	for(i = 0; i < 6; i++) {
 926		grid[(8 * size) + (5 - i)] += (seq >> (i + 9)) & 0x01;
 927	}
 928
 929	for(i = 0; i < 7; i++) {
 930		grid[(((size - 7) + i) * size) + 8] += (seq >> (i + 8)) & 0x01;
 931	}
 932
 933	grid[(7 * size) + 8] += (seq >> 6) & 0x01;
 934	grid[(8 * size) + 8] += (seq >> 7) & 0x01;
 935	grid[(8 * size) + 7] += (seq >> 8) & 0x01;
 936}
 937
 938void add_version_info(unsigned char *grid, int size, int version)
 939{
 940	/* Add version information */
 941	int i;
 942
 943	long int version_data = qr_annex_d[version - 7];
 944	for(i = 0; i < 6; i++) {
 945		grid[((size - 11) * size) + i] += (version_data >> (i * 3)) & 0x01;
 946		grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x01;
 947		grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x01;
 948		grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x01;
 949		grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x01;
 950		grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x01;
 951	}
 952}
 953
 954int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
 955{
 956	int error_number, glyph, est_binlen;
 957	int ecc_level, autosize, version, max_cw, target_binlen, blocks, size;
 958	int bitmask, gs1;
 959
 960	int utfdata[length + 1];
 961	int jisdata[length + 1];
 962	char mode[length + 1];
 963
 964	gs1 = (symbol->input_mode == GS1_MODE);
 965
 966	switch(symbol->input_mode) {
 967		case DATA_MODE:
 968			for(int i = 0; i < length; i++) {
 969				jisdata[i] = (int)source[i];
 970			}
 971			break;
 972		default:
 973			/* Convert Unicode input to Shift-JIS */
 974			error_number = utf8toutf16(symbol, source, utfdata, &length);
 975			if(error_number != 0) { return error_number; }
 976
 977			for(int i = 0; i < length; i++) {
 978				if(utfdata[i] <= 0xff) {
 979					jisdata[i] = utfdata[i];
 980				} else {
 981					int j = 0;
 982					glyph = 0;
 983					do {
 984						if(sjis_lookup[j * 2] == utfdata[i]) {
 985							glyph = sjis_lookup[(j * 2) + 1];
 986						}
 987						j++;
 988					} while ((j < 6843) && (glyph == 0));
 989					if(glyph == 0) {
 990						strcpy(symbol->errtxt, "Invalid character in input data");
 991						return ZERROR_INVALID_DATA;
 992					}
 993					jisdata[i] = glyph;
 994				}
 995			}
 996			break;
 997	}
 998
 999	define_mode(mode, jisdata, length, gs1);
1000	est_binlen = estimate_binary_length(mode, length, gs1);
1001
1002	ecc_level = LEVEL_L;
1003	max_cw = 2956;
1004	if((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) {
1005		switch (symbol->option_1) {
1006			case 1: ecc_level = LEVEL_L; max_cw = 2956; break;
1007			case 2: ecc_level = LEVEL_M; max_cw = 2334; break;
1008			case 3: ecc_level = LEVEL_Q; max_cw = 1666; break;
1009			case 4: ecc_level = LEVEL_H; max_cw = 1276; break;
1010		}
1011	}
1012
1013	if(est_binlen > (8 * max_cw)) {
1014		strcpy(symbol->errtxt, "Input too long for selected error correction level");
1015		return ZERROR_TOO_LONG;
1016	}
1017
1018	autosize = 40;
1019	for(int i = 39; i >= 0; i--) {
1020		switch(ecc_level) {
1021			case LEVEL_L:
1022				if ((8 * qr_data_codewords_L[i]) >= est_binlen) {
1023					autosize = i + 1;
1024				}
1025				break;
1026			case LEVEL_M:
1027				if ((8 * qr_data_codewords_M[i]) >= est_binlen) {
1028					autosize = i + 1;
1029				}
1030				break;
1031			case LEVEL_Q:
1032				if ((8 * qr_data_codewords_Q[i]) >= est_binlen) {
1033					autosize = i + 1;
1034				}
1035				break;
1036			case LEVEL_H:
1037				if ((8 * qr_data_codewords_H[i]) >= est_binlen) {
1038					autosize = i + 1;
1039				}
1040				break;
1041		}
1042	}
1043
1044	if((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) {
1045		if (symbol->option_2 > autosize) {
1046			version = symbol->option_2;
1047		} else {
1048			version = autosize;
1049		}
1050	} else {
1051		version = autosize;
1052	}
1053
1054	/* Ensure maxium error correction capacity */
1055	if(est_binlen <= qr_data_codewords_M[version - 1]) { ecc_level = LEVEL_M; }
1056	if(est_binlen <= qr_data_codewords_Q[version - 1]) { ecc_level = LEVEL_Q; }
1057	if(est_binlen <= qr_data_codewords_H[version - 1]) { ecc_level = LEVEL_H; }
1058
1059	target_binlen = qr_data_codewords_L[version - 1]; blocks = qr_blocks_L[version - 1];
1060	switch(ecc_level) {
1061		case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; blocks = qr_blocks_M[version - 1]; break;
1062		case LEVEL_Q: target_binlen = qr_data_codewords_Q[version - 1]; blocks = qr_blocks_Q[version - 1]; break;
1063		case LEVEL_H: target_binlen = qr_data_codewords_H[version - 1]; blocks = qr_blocks_H[version - 1]; break;
1064	}
1065
1066	int datastream[target_binlen + 1];
1067	int fullstream[qr_total_codewords[version - 1] + 1];
1068
1069	qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen);
1070	add_ecc(fullstream, datastream, version, target_binlen, blocks);
1071
1072	size = qr_sizes[version - 1];
1073	unsigned char grid[size * size];
1074
1075	for (int i = 0; i < size; i++) {
1076		for(int j = 0; j < size; j++) {
1077			grid[(i * size) + j] = 0;
1078		}
1079	}
1080
1081	setup_grid(grid, size, version);
1082	populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]);
1083	bitmask = apply_bitmask(grid, size);
1084	add_format_info(grid, size, ecc_level, bitmask);
1085	if (version >= 7) {
1086		add_version_info(grid, size, version);
1087	}
1088
1089	symbol->width = size;
1090	symbol->rows = size;
1091
1092	for (int i = 0; i < size; i++) {
1093		for (int j = 0; j < size; j++) {
1094			if (grid[(i * size) + j] & 0x01) {
1095				set_module(symbol, i, j);
1096			}
1097		}
1098		symbol->row_height[i] = 1;
1099	}
1100
1101	return 0;
1102}
1103
1104/* NOTE: From this point forward concerns Micro QR Code only */
1105
1106int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, int *kanji_used, int *alphanum_used, int *byte_used)
1107{
1108	/* Convert input data to an "intermediate stage" where data is binary encoded but
1109	   control information is not */
1110	int position = 0, debug = 0;
1111	int short_data_block_length, i;
1112	char data_block;
1113	char buffer[2];
1114
1115	strcpy(binary, "");
1116
1117	if(debug) {
1118		for(i = 0; i < length; i++) {
1119			printf("%c", mode[i]);
1120		}
1121		printf("\n");
1122	}
1123
1124	do {
1125		if(strlen(binary) > 128) {
1126			return ZERROR_TOO_LONG;
1127		}
1128
1129		data_block = mode[position];
1130		short_data_block_length = 0;
1131		do {
1132			short_data_block_length++;
1133		} while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block));
1134
1135		switch(data_block) {
1136			case 'K':
1137				/* Kanji mode */
1138				/* Mode indicator */
1139				concat(binary, "K");
1140				*kanji_used = 1;
1141
1142				/* Character count indicator */
1143				buffer[0] = short_data_block_length;
1144				buffer[1] = '\0';
1145				concat(binary, buffer);
1146
1147				if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); }
1148
1149				/* Character representation */
1150				for(i = 0; i < short_data_block_length; i++) {
1151					int jis = jisdata[position + i];
1152					int msb, lsb, prod;
1153
1154					if(jis > 0x9fff) { jis -= 0xc140; }
1155					msb = (jis & 0xff00) >> 4;
1156					lsb = (jis & 0xff);
1157					prod = (msb * 0xc0) + lsb;
1158
1159					bscan(binary, prod, 0x1000);
1160
1161					if(debug) { printf("0x%4X ", prod); }
1162
1163					if(strlen(binary) > 128) {
1164						return ZERROR_TOO_LONG;
1165					}
1166				}
1167
1168				if(debug) { printf("\n"); }
1169
1170				break;
1171			case 'B':
1172				/* Byte mode */
1173				/* Mode indicator */
1174				concat(binary, "B");
1175				*byte_used = 1;
1176
1177				/* Character count indicator */
1178				buffer[0] = short_data_block_length;
1179				buffer[1] = '\0';
1180				concat(binary, buffer);
1181
1182				if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); }
1183
1184				/* Character representation */
1185				for(i = 0; i < short_data_block_length; i++) {
1186					int byte = jisdata[position + i];
1187
1188					bscan(binary, byte, 0x80);
1189
1190					if(debug) { printf("0x%4X ", byte); }
1191
1192					if(strlen(binary) > 128) {
1193						return ZERROR_TOO_LONG;
1194					}
1195				}
1196
1197				if(debug) { printf("\n"); }
1198
1199				break;
1200			case 'A':
1201				/* Alphanumeric mode */
1202				/* Mode indicator */
1203				concat(binary, "A");
1204				*alphanum_used = 1;
1205
1206				/* Character count indicator */
1207				buffer[0] = short_data_block_length;
1208				buffer[1] = '\0';
1209				concat(binary, buffer);
1210
1211				if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); }
1212
1213				/* Character representation */
1214				i = 0;
1215				while ( i < short_data_block_length ) {
1216					int count;
1217					int first = 0, second = 0, prod;
1218
1219					first = posn(RHODIUM, (char) jisdata[position + i]);
1220					count = 1;
1221					prod = first;
1222
1223					if(mode[position + i + 1] == 'A') {
1224						second = posn(RHODIUM, (char) jisdata[position + i + 1]);
1225						count = 2;
1226						prod = (first * 45) + second;
1227					}
1228
1229					bscan(binary, prod, 1 << (5 * count)); /* count = 1..2 */
1230
1231					if(debug) { printf("0x%4X ", prod); }
1232
1233					if(strlen(binary) > 128) {
1234						return ZERROR_TOO_LONG;
1235					}
1236
1237					i += 2;
1238				};
1239
1240				if(debug) { printf("\n"); }
1241
1242				break;
1243			case 'N':
1244				/* Numeric mode */
1245				/* Mode indicator */
1246				concat(binary, "N");
1247
1248				/* Character count indicator */
1249				buffer[0] = short_data_block_length;
1250				buffer[1] = '\0';
1251				concat(binary, buffer);
1252
1253				if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); }
1254
1255				/* Character representation */
1256				i = 0;
1257				while ( i < short_data_block_length ) {
1258					int count;
1259					int first = 0, second = 0, third = 0, prod;
1260
1261					first = posn(NEON, (char) jisdata[position + i]);
1262					count = 1;
1263					prod = first;
1264
1265					if(mode[position + i + 1] == 'N') {
1266						second = posn(NEON, (char) jisdata[position + i + 1]);
1267						count = 2;
1268						prod = (prod * 10) + second;
1269					}
1270
1271					if(mode[position + i + 2] == 'N') {
1272						third = posn(NEON, (char) jisdata[position + i + 2]);
1273						count = 3;
1274						prod = (prod * 10) + third;
1275					}
1276
1277					bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
1278
1279					if(debug) { printf("0x%4X (%d)", prod, prod); }
1280
1281					if(strlen(binary) > 128) {
1282						return ZERROR_TOO_LONG;
1283					}
1284
1285					i += 3;
1286				};
1287
1288				if(debug) { printf("\n"); }
1289
1290				break;
1291		}
1292
1293		position += short_data_block_length;
1294	} while (position < length - 1) ;
1295
1296	return 0;
1297}
1298
1299void get_bitlength(int count[], char stream[]) {
1300	int length, i;
1301
1302	length = strlen(stream);
1303
1304	for(i = 0; i < 4; i++) {
1305		count[i] = 0;
1306	}
1307
1308	i = 0;
1309	do {
1310		if((stream[i] == '0') || (stream[i] == '1')) {
1311			count[0]++;
1312			count[1]++;
1313			count[2]++;
1314			count[3]++;
1315			i++;
1316		} else {
1317			switch(stream[i]) {
1318				case 'K':
1319					count[2] += 5;
1320					count[3] += 7;
1321					i += 2;
1322					break;
1323				case 'B':
1324					count[2] += 6;
1325					count[3] += 8;
1326					i += 2;
1327					break;
1328				case 'A':
1329					count[1] += 4;
1330					count[2] += 6;
1331					count[3] += 8;
1332					i += 2;
1333					break;
1334				case 'N':
1335					count[0] += 3;
1336					count[1] += 5;
1337					count[2] += 7;
1338					count[3] += 9;
1339					i += 2;
1340					break;
1341			}
1342		}
1343	} while (i < length);
1344}
1345
1346void microqr_expand_binary(char binary_stream[], char full_stream[], int version)
1347{
1348	int i, length;
1349
1350	length = strlen(binary_stream);
1351
1352	i = 0;
1353	do {
1354		switch(binary_stream[i]) {
1355			case '1': concat(full_stream, "1"); i++; break;
1356			case '0': concat(full_stream, "0"); i++; break;
1357			case 'N':
1358				/* Numeric Mode */
1359				/* Mode indicator */
1360				switch(version) {
1361					case 1: concat(full_stream, "0"); break;
1362					case 2: concat(full_stream, "00"); break;
1363					case 3: concat(full_stream, "000"); break;
1364				}
1365
1366				/* Character count indicator */
1367				bscan(full_stream, binary_stream[i + 1], 4 << version); /* version = 0..3 */
1368
1369				i += 2;
1370				break;
1371			case 'A':
1372				/* Alphanumeric Mode */
1373				/* Mode indicator */
1374				switch(version) {
1375					case 1: concat(full_stream, "1"); break;
1376					case 2: concat(full_stream, "01"); break;
1377					case 3: concat(full_stream, "001"); break;
1378				}
1379
1380				/* Character count indicator */
1381				bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 1..3 */
1382
1383				i += 2;
1384				break;
1385			case 'B':
1386				/* Byte Mode */
1387				/* Mode indicator */
1388				switch(version) {
1389					case 2: concat(full_stream, "10"); break;
1390					case 3: concat(full_stream, "010"); break;
1391				}
1392
1393				/* Character count indicator */
1394				bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 2..3 */
1395				
1396				i += 2;
1397				break;
1398			case 'K':
1399				/* Kanji Mode */
1400				/* Mode indicator */
1401				switch(version) {
1402					case 2: concat(full_stream, "11"); break;
1403					case 3: concat(full_stream, "011"); break;
1404				}
1405
1406				/* Character count indicator */
1407				bscan(full_stream, binary_stream[i + 1], 1 << version); /* version = 2..3 */
1408
1409				i += 2;
1410				break;
1411		}
1412
1413	} while (i < length);
1414}
1415
1416void micro_qr_m1(char binary_data[])
1417{
1418	int i, latch;
1419	int bits_total, bits_left, remainder;
1420	int data_codewords, ecc_codewords;
1421	unsigned char data_blocks[4], ecc_blocks[3];
1422
1423	bits_total = 20;
1424	latch = 0;
1425
1426	/* Add terminator */
1427	bits_left = bits_total - strlen(binary_data);
1428	if(bits_left <= 3) {
1429		for(i = 0; i < bits_left; i++) {
1430			concat(binary_data, "0");
1431		}
1432		latch = 1;
1433	} else {
1434		concat(binary_data, "000");
1435	}
1436
1437	if(latch == 0) {
1438		/* Manage last (4-bit) block */
1439		bits_left = bits_total - strlen(binary_data);
1440		if(bits_left <= 4) {
1441			for(i = 0; i < bits_left; i++) {
1442				concat(binary_data, "0");
1443			}
1444			latch = 1;
1445		}
1446	}
1447
1448	if(latch == 0) {
1449		/* Complete current byte */
1450		remainder = 8 - (strlen(binary_data) % 8);
1451		if(remainder == 8) { remainder = 0; }
1452		for(i = 0; i < remainder; i++) {
1453			concat(binary_data, "0");
1454		}
1455
1456		/* Add padding */
1457		bits_left = bits_total - strlen(binary_data);
1458		if(bits_left > 4) {
1459			remainder = (bits_left - 4) / 8;
1460			for(i = 0; i < remainder; i++) {
1461				concat(binary_data, i & 1 ? "00010001" : "11101100");
1462			}
1463		}
1464		concat(binary_data, "0000");
1465	}
1466
1467	data_codewords = 3;
1468	ecc_codewords = 2;
1469
1470	/* Copy data into codewords */
1471	for(i = 0; i < (data_codewords - 1); i++) {
1472		data_blocks[i] = 0;
1473		if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
1474		if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
1475		if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
1476		if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
1477		if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
1478		if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
1479		if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
1480		if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
1481	}
1482	data_blocks[2] = 0;
1483	if(binary_data[16] == '1') { data_blocks[2] += 0x08; }
1484	if(binary_data[17] == '1') { data_blocks[2] += 0x04; }
1485	if(binary_data[18] == '1') { data_blocks[2] += 0x02; }
1486	if(binary_data[19] == '1') { data_blocks[2] += 0x01; }
1487
1488	/* Calculate Reed-Solomon error codewords */
1489	rs_init_gf(0x11d);
1490	rs_init_code(ecc_codewords, 0);
1491	rs_encode(data_codewords,data_blocks,ecc_blocks);
1492	rs_free();
1493
1494	/* Add Reed-Solomon codewords to binary data */
1495	for(i = 0; i < ecc_codewords; i++) {
1496		bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
1497	}
1498}
1499
1500void micro_qr_m2(char binary_data[], int ecc_mode)
1501{
1502	int i, latch;
1503	int bits_total, bits_left, remainder;
1504	int data_codewords, ecc_codewords;
1505	unsigned char data_blocks[6], ecc_blocks[7];
1506
1507	latch = 0;
1508
1509	if(ecc_mode == LEVEL_L) { bits_total = 40; }
1510	if(ecc_mode == LEVEL_M) { bits_total = 32; }
1511
1512	/* Add terminator */
1513	bits_left = bits_total - strlen(binary_data);
1514	if(bits_left <= 5) {
1515		for(i = 0; i < bits_left; i++) {
1516			concat(binary_data, "0");
1517		}
1518		latch = 1;
1519	} else {
1520		concat(binary_data, "00000");
1521	}
1522
1523	if(latch == 0) {
1524		/* Complete current byte */
1525		remainder = 8 - (strlen(binary_data) % 8);
1526		if(remainder == 8) { remainder = 0; }
1527		for(i = 0; i < remainder; i++) {
1528			concat(binary_data, "0");
1529		}
1530
1531		/* Add padding */
1532		bits_left = bits_total - strlen(binary_data);
1533		remainder = bits_left / 8;
1534		for(i = 0; i < remainder; i++) {
1535			concat(binary_data, i & 1 ? "00010001" : "11101100");
1536		}
1537	}
1538
1539	if(ecc_mode == LEVEL_L) { data_codewords = 5; ecc_codewords = 5; }
1540	if(ecc_mode == LEVEL_M) { data_codewords = 4; ecc_codewords = 6; }
1541
1542	/* Copy data into codewords */
1543	for(i = 0; i < data_codewords; i++) {
1544		data_blocks[i] = 0;
1545		if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
1546		if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
1547		if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
1548		if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
1549		if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
1550		if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
1551		if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
1552		if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
1553	}
1554
1555	/* Calculate Reed-Solomon error codewords */
1556	rs_init_gf(0x11d);
1557	rs_init_code(ecc_codewords, 0);
1558	rs_encode(data_codewords,data_blocks,ecc_blocks);
1559	rs_free();
1560
1561	/* Add Reed-Solomon codewords to binary data */
1562	for(i = 0; i < ecc_codewords; i++) {
1563		bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
1564	}
1565
1566	return;
1567}
1568
1569void micro_qr_m3(char binary_data[], int ecc_mode)
1570{
1571	int i, latch;
1572	int bits_total, bits_left, remainder;
1573	int data_codewords, ecc_codewords;
1574	unsigned char data_blocks[12], ecc_blocks[9];
1575
1576	latch = 0;
1577
1578	if(ecc_mode == LEVEL_L) { bits_total = 84; }
1579	if(ecc_mode == LEVEL_M) { bits_total = 68; }
1580
1581	/* Add terminator */
1582	bits_left = bits_total - strlen(binary_data);
1583	if(bits_left <= 7) {
1584		for(i = 0; i < bits_left; i++) {
1585			concat(binary_data, "0");
1586		}
1587		latch = 1;
1588	} else {
1589		concat(binary_data, "0000000");
1590	}
1591
1592	if(latch == 0) {
1593		/* Manage last (4-bit) block */
1594		bits_left = bits_total - strlen(binary_data);
1595		if(bits_left <= 4) {
1596			for(i = 0; i < bits_left; i++) {
1597				concat(binary_data, "0");
1598			}
1599			latch = 1;
1600		}
1601	}
1602
1603	if(latch == 0) {
1604		/* Complete current byte */
1605		remainder = 8 - (strlen(binary_data) % 8);
1606		if(remainder == 8) { remainder = 0; }
1607		for(i = 0; i < remainder; i++) {
1608			concat(binary_data, "0");
1609		}
1610
1611		/* Add padding */
1612		bits_left = bits_total - strlen(binary_data);
1613		if(bits_left > 4) {
1614			remainder = (bits_left - 4) / 8;
1615			for(i = 0; i < remainder; i++) {
1616				concat(binary_data, i & 1 ? "00010001" : "11101100");
1617			}
1618		}
1619		concat(binary_data, "0000");
1620	}
1621
1622	if(ecc_mode == LEVEL_L) { data_codewords = 11; ecc_codewords = 6; }
1623	if(ecc_mode == LEVEL_M) { data_codewords = 9; ecc_codewords = 8; }
1624
1625	/* Copy data into codewords */
1626	for(i = 0; i < (data_codewords - 1); i++) {
1627		data_blocks[i] = 0;
1628		if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
1629		if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
1630		if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
1631		if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
1632		if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
1633		if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
1634		if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
1635		if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
1636	}
1637
1638	if(ecc_mode == LEVEL_L) {
1639		data_blocks[11] = 0;
1640		if(binary_data[80] == '1') { data_blocks[2] += 0x08; }
1641		if(binary_data[81] == '1') { data_blocks[2] += 0x04; }
1642		if(binary_data[82] == '1') { data_blocks[2] += 0x02; }
1643		if(binary_data[83] == '1') { data_blocks[2] += 0x01; }
1644	}
1645
1646	if(ecc_mode == LEVEL_M) {
1647		data_blocks[9] = 0;
1648		if(binary_data[64] == '1') { data_blocks[2] += 0x08; }
1649		if(binary_data[65] == '1') { data_blocks[2] += 0x04; }
1650		if(binary_data[66] == '1') { data_blocks[2] += 0x02; }
1651		if(binary_data[67] == '1') { data_blocks[2] += 0x01; }
1652	}
1653
1654	/* Calculate Reed-Solomon error codewords */
1655	rs_init_gf(0x11d);
1656	rs_init_code(ecc_codewords, 0);
1657	rs_encode(data_codewords,data_blocks,ecc_blocks);
1658	rs_free();
1659
1660	/* Add Reed-Solomon codewords to binary data */
1661	for(i = 0; i < ecc_codewords; i++) {
1662		bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
1663	}
1664
1665	return;
1666}
1667
1668void micro_qr_m4(char binary_data[], int ecc_mode)
1669{
1670	int i, latch;
1671	int bits_total, bits_left, remainder;
1672	int data_codewords, ecc_codewords;
1673	unsigned char data_blocks[17], ecc_blocks[15];
1674
1675	latch = 0;
1676
1677	if(ecc_mode == LEVEL_L) { bits_total = 128; }
1678	if(ecc_mode == LEVEL_M) { bits_total = 112; }
1679	if(ecc_mode == LEVEL_Q) { bits_total = 80; }
1680
1681	/* Add terminator */
1682	bits_left = bits_total - strlen(binary_data);
1683	if(bits_left <= 9) {
1684		for(i = 0; i < bits_left; i++) {
1685			concat(binary_data, "0");
1686		}
1687		latch = 1;
1688	} else {
1689		concat(binary_data, "000000000");
1690	}
1691
1692	if(latch == 0) {
1693		/* Complete current byte */
1694		remainder = 8 - (strlen(binary_data) % 8);
1695		if(remainder == 8) { remainder = 0; }
1696		for(i = 0; i < remainder; i++) {
1697			concat(binary_data, "0");
1698		}
1699
1700		/* Add padding */
1701		bits_left = bits_total - strlen(binary_data);
1702		remainder = bits_left / 8;
1703		for(i = 0; i < remainder; i++) {
1704			concat(binary_data, i & 1 ? "00010001" : "11101100");
1705		}
1706	}
1707
1708	if(ecc_mode == LEVEL_L) { data_codewords = 16; ecc_codewords = 8; }
1709	if(ecc_mode == LEVEL_M) { data_codewords = 14; ecc_codewords = 10; }
1710	if(ecc_mode == LEVEL_Q) { data_codewords = 10; ecc_codewords = 14; }
1711
1712	/* Copy data into codewords */
1713	for(i = 0; i < data_codewords; i++) {
1714		data_blocks[i] = 0;
1715		if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
1716		if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
1717		if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
1718		if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
1719		if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
1720		if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
1721		if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
1722		if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
1723	}
1724
1725	/* Calculate Reed-Solomon error codewords */
1726	rs_init_gf(0x11d);
1727	rs_init_code(ecc_codewords, 0);
1728	rs_encode(data_codewords,data_blocks,ecc_blocks);
1729	rs_free();
1730
1731	/* Add Reed-Solomon codewords to binary data */
1732	for(i = 0; i < ecc_codewords; i++) {
1733		bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
1734	}
1735}
1736
1737void micro_setup_grid(unsigned char* grid, int size)
1738{
1739	int i, toggle = 1;
1740
1741	/* Add timing patterns */
1742	for(i = 0; i < size; i++) {
1743		if(toggle == 1) {
1744			grid[i] = 0x21;
1745			grid[(i * size)] = 0x21;
1746			toggle = 0;
1747		} else {
1748			grid[i] = 0x20;
1749			grid[(i * size)] = 0x20;
1750			toggle = 1;
1751		}
1752	}
1753
1754	/* Add finder patterns */
1755	place_finder(grid, size, 0, 0);
1756
1757	/* Add separators */
1758	for(i = 0; i < 7; i++) {
1759		grid[(7 * size) + i] = 0x10;
1760		grid[(i * size) + 7] = 0x10;
1761	}
1762	grid[(7 * size) + 7] = 0x10;
1763
1764
1765	/* Reserve space for format information */
1766	for(i = 0; i < 8; i++) {
1767		grid[(8 * size) + i] += 0x20;
1768		grid[(i * size) + 8] += 0x20;
1769	}
1770	grid[(8 * size) + 8] += 20;
1771}
1772
1773void micro_populate_grid(unsigned char* grid, int size, char full_stream[])
1774{
1775	int direction = 1; /* up */
1776	int row = 0; /* right hand side */
1777
1778	int i, n, x, y;
1779
1780	n = strlen(full_stream);
1781	y = size - 1;
1782	i = 0;
1783	do {
1784		x = (size - 2) - (row * 2);
1785
1786		if(!(grid[(y * size) + (x + 1)] & 0xf0)) {
1787			if (full_stream[i] == '1') {
1788				grid[(y * size) + (x + 1)] = 0x01;
1789			} else {
1790				grid[(y * size) + (x + 1)] = 0x00;
1791			}
1792			i++;
1793		}
1794
1795		if(i < n) {
1796			if(!(grid[(y * size) + x] & 0xf0)) {
1797				if (full_stream[i] == '1') {
1798					grid[(y * size) + x] = 0x01;
1799				} else {
1800					grid[(y * size) + x] = 0x00;
1801				}
1802				i++;
1803			}
1804		}
1805
1806		if(direction) { y--; } else { y++; }
1807		if(y == 0) {
1808			/* reached the top */
1809			row++;
1810			y = 1;
1811			direction = 0;
1812		}
1813		if(y == size) {
1814			/* reached the bottom */
1815			row++;
1816			y = size - 1;
1817			direction = 1;
1818		}
1819	} while (i < n);
1820}
1821
1822int micro_evaluate(unsigned char *grid, int size, int pattern)
1823{
1824	int sum1, sum2, i, filter = 0, retval;
1825
1826	switch(pattern) {
1827		case 0: filter = 0x01; break;
1828		case 1: filter = 0x02; break;
1829		case 2: filter = 0x04; break;
1830		case 3: filter = 0x08; break;
1831	}
1832
1833	sum1 = 0;
1834	sum2 = 0;
1835	for(i = 1; i < size; i++) {
1836		if(grid[(i * size) + size - 1] & filter) { sum1++; }
1837		if(grid[((size - 1) * size) + i] & filter) { sum2++; }
1838	}
1839
1840	if(sum1 <= sum2) { retval = (sum1 * 16) + sum2; } else { retval = (sum2 * 16) + sum1; }
1841
1842	return retval;
1843}
1844
1845int micro_apply_bitmask(unsigned char *grid, int size)
1846{
1847	int x, y;
1848	unsigned char p;
1849	int pattern, value[8];
1850	int best_val, best_pattern;
1851	int bit;
1852
1853	unsigned char mask[size * size];
1854	unsigned char eval[size * size];
1855
1856	/* Perform data masking */
1857	for(x = 0; x < size; x++) {
1858		for(y = 0; y < size; y++) {
1859			mask[(y * size) + x] = 0x00;
1860
1861			if (!(grid[(y * size) + x] & 0xf0)) {
1862				if((y & 1) == 0) {
1863					mask[(y * size) + x] += 0x01;
1864				}
1865
1866				if((((y / 2) + (x / 3)) & 1) == 0) {
1867					mask[(y * size) + x] += 0x02;
1868				}
1869
1870				if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) {
1871					mask[(y * size) + x] += 0x04;
1872				}
1873
1874				if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) {
1875					mask[(y * size) + x] += 0x08;
1876				}
1877			}
1878		}
1879	}
1880
1881	for(x = 0; x < size; x++) {
1882		for(y = 0; y < size; y++) {
1883			if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; }
1884
1885			eval[(y * size) + x] = mask[(y * size) + x] ^ p;
1886		}
1887	}
1888
1889
1890	/* Evaluate result */
1891	for(pattern = 0; pattern < 8; pattern++) {
1892		value[pattern] = micro_evaluate(eval, size, pattern);
1893	}
1894
1895	best_pattern = 0;
1896	best_val = value[0];
1897	for(pattern = 1; pattern < 4; pattern++) {
1898		if(value[pattern] > best_val) {
1899			best_pattern = pattern;
1900			best_val = value[pattern];
1901		}
1902	}
1903
1904	/* Apply mask */
1905	for(x = 0; x < size; x++) {
1906		for(y = 0; y < size; y++) {
1907			bit = 0;
1908			switch(best_pattern) {
1909				case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break;
1910				case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break;
1911				case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break;
1912				case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break;
1913			}
1914			if(bit == 1) {
1915				if(grid[(y * size) + x] & 0x01) {
1916					grid[(y * size) + x] = 0x00;
1917				} else {
1918					grid[(y * size) + x] = 0x01;
1919				}
1920			}
1921		}
1922	}
1923
1924	return best_pattern;
1925}
1926
1927int microqr(struct zint_symbol *symbol, unsigned char source[], int length)
1928{
1929	int glyph, size;
1930	char binary_stream[200];
1931	char full_stream[200];
1932	int utfdata[40];
1933	int jisdata[40];
1934	char mode[40];
1935	int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0;
1936	int version_valid[4];
1937	int binary_count[4];
1938	int ecc_level, autoversion, version;
1939	int n_count, a_count, bitmask, format, format_full;
1940
1941	if(length > 35) {
1942		strcpy(symbol->errtxt, "Input data too long");
1943		return ZERROR_TOO_LONG;
1944	}
1945
1946	for(int i = 0; i < 4; i++) {
1947		version_valid[i] = 1;
1948	}
1949
1950	switch(symbol->input_mode) {
1951		case DATA_MODE:
1952			for(int i = 0; i < length; i++) {
1953				jisdata[i] = (int)source[i];
1954			}
1955			break;
1956		default:
1957			/* Convert Unicode input to Shift-JIS */
1958			error_number = utf8toutf16(symbol, source, utfdata, &length);
1959			if(error_number != 0) { return error_number; }
1960
1961			for(int i = 0; i < length; i++) {
1962				if(utfdata[i] <= 0xff) {
1963					jisdata[i] = utfdata[i];
1964				} else {
1965					int j = 0;
1966					glyph = 0;
1967					do {
1968						if(sjis_lookup[j * 2] == utfdata[i]) {
1969							glyph = sjis_lookup[(j * 2) + 1];
1970						}
1971						j++;
1972					} while ((j < 6843) && (glyph == 0));
1973					if(glyph == 0) {
1974						strcpy(symbol->errtxt, "Invalid character in input data");
1975						return ZERROR_INVALID_DATA;
1976					}
1977					jisdata[i] = glyph;
1978				}
1979			}
1980			break;
1981	}
1982
1983	define_mode(mode, jisdata, length, 0);
1984
1985	n_count = 0;
1986	a_count = 0;
1987	for (int i = 0; i < length; i++) {
1988		if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { n_count++; }
1989		if(in_alpha(jisdata[i])) { a_count++; }
1990	}
1991
1992	if (a_count == length) {
1993		/* All data can be encoded in Alphanumeric mode */
1994		for (int i = 0; i < length; i++) {
1995			mode[i] = 'A';
1996		}
1997	}
1998
1999	if (n_count == length) {
2000		/* All data can be encoded in Numeric mode */
2001		for (int i = 0; i < length; i++) {
2002			mode[i] = 'N';
2003		}
2004	}
2005
2006	error_number = micr

Large files files are truncated, but you can click here to view the full file