int code_one()

in Sharing/Src/External/zint-2.4.3/src/backend/code1.c [1024:1526]


int code_one(struct zint_symbol *symbol, unsigned char source[], int length)
{
	int size = 1, i, j, data_blocks;

	char datagrid[136][120];
	int row, col;
	int sub_version = 0;

	if((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
		strcpy(symbol->errtxt, "Invalid symbol size");
		return ZINT_ERROR_INVALID_OPTION;
	}

	if(symbol->option_2 == 9) {
		/* Version S */
		int codewords;
		short int elreg[112];
		unsigned int data[15], ecc[15];
		int stream[30];
		int block_width;

		if(length > 18) {
			strcpy(symbol->errtxt, "Input data too long");
			return ZINT_ERROR_TOO_LONG;
		}
		if(is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
			strcpy(symbol->errtxt, "Invalid input data (Version S encodes numeric input only)");
			return ZINT_ERROR_INVALID_DATA;
		}

		sub_version = 3; codewords = 12; block_width = 6; /* Version S-30 */
		if(length <= 12) { sub_version = 2; codewords = 8; block_width = 4; } /* Version S-20 */
		if(length <= 6) { sub_version = 1; codewords = 4; block_width = 2; } /* Version S-10 */

		binary_load(elreg, (char *)source, length);
		hex_dump(elreg);
		
		for(i = 0; i < 15; i++) {
			data[i] = 0;
			ecc[i] = 0;
		}
		
		for(i = 0; i < codewords; i++) {
			data[codewords - i - 1] += 1 * elreg[(i * 5)];
			data[codewords - i - 1] += 2 * elreg[(i * 5) + 1];
			data[codewords - i - 1] += 4 * elreg[(i * 5) + 2];
			data[codewords - i - 1] += 8 * elreg[(i * 5) + 3];
			data[codewords - i - 1] += 16 * elreg[(i * 5) + 4];
		}

		rs_init_gf(0x25);
		rs_init_code(codewords, 1);
		rs_encode_long(codewords, data, ecc);
		rs_free();
		
		for(i = 0; i < codewords; i++) {
			stream[i] = data[i];
			stream[i + codewords] = ecc[codewords - i - 1];
		}
		
		for(i = 0; i < 136; i++) {
			for(j = 0; j < 120; j++) {
				datagrid[i][j] = '0';
			}
		}
		
		i = 0;
		for(row = 0; row < 2; row++) {
			for(col = 0; col < block_width; col++) {
				if(stream[i] & 0x10) { datagrid[row * 2][col * 5] = '1'; }
				if(stream[i] & 0x08) { datagrid[row * 2][(col * 5) + 1] = '1'; }
				if(stream[i] & 0x04) { datagrid[row * 2][(col * 5) + 2] = '1'; }
				if(stream[i] & 0x02) { datagrid[(row * 2) + 1][col * 5] = '1'; }
				if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 1] = '1'; }
				if(stream[i + 1] & 0x10) { datagrid[row * 2][(col * 5) + 3] = '1'; }
				if(stream[i + 1] & 0x08) { datagrid[row * 2][(col * 5) + 4] = '1'; }
				if(stream[i + 1] & 0x04) { datagrid[(row * 2) + 1][(col * 5) + 2] = '1'; }
				if(stream[i + 1] & 0x02) { datagrid[(row * 2) + 1][(col * 5) + 3] = '1'; }
				if(stream[i + 1] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 4] = '1'; }
				i += 2;
			}
		}
		
		size = 9;	
		symbol->rows = 8;
		symbol->width = 10 * sub_version + 1;
	}

	if(symbol->option_2 == 10) {
		/* Version T */
		unsigned int data[40], ecc[25];
		unsigned int stream[65];
		int data_length;
		int data_cw, ecc_cw, block_width;
		
		for(i = 0; i < 40; i++) { data[i] = 0; }
		data_length = c1_encode(symbol, source, data, length);

		if(data_length == 0) {
			return ZINT_ERROR_TOO_LONG;
		}

		if(data_length > 38) {
			strcpy(symbol->errtxt, "Input data too long");
			return ZINT_ERROR_TOO_LONG;
		}

		size = 10;
		sub_version = 3; data_cw = 38; ecc_cw = 22; block_width = 12;
		if(data_length <= 24) { sub_version = 2; data_cw = 24; ecc_cw = 16; block_width = 8; }
		if(data_length <= 10) { sub_version = 1; data_cw = 10; ecc_cw = 10; block_width = 4; }
		
		for(i = data_length; i < data_cw; i++) {
			data[i] = 129; /* Pad */
		}

		/* Calculate error correction data */
		rs_init_gf(0x12d);
		rs_init_code(ecc_cw, 1);	
		rs_encode_long(data_cw, data, ecc);
		rs_free();

		/* "Stream" combines data and error correction data */
		for(i = 0; i < data_cw; i++) {
			stream[i] = data[i];
		}
		for(i = 0; i < ecc_cw; i++) {
			stream[data_cw + i] = ecc[ecc_cw - i - 1];
		}
	
		for(i = 0; i < 136; i++) {
			for(j = 0; j < 120; j++) {
				datagrid[i][j] = '0';
			}
		}
		
		i = 0;
		for(row = 0; row < 5; row++) {
			for(col = 0; col < block_width; col++) {
				if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; }
				if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; }
				if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; }
				if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; }
				if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; }
				if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; }
				if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; }
				if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; }
				i++;
			}
		}

		symbol->rows = 16;
		symbol->width = (sub_version * 16) + 1;
	}

	if((symbol->option_2 != 9) && (symbol->option_2 != 10)) {
		/* Version A to H */
		unsigned int data[1500], ecc[600];
		unsigned int sub_data[190], sub_ecc[75];
		unsigned int stream[2100];
		int data_length;
				
		for(i = 0; i < 1500; i++) { data[i] = 0; }
		data_length = c1_encode(symbol, source, data, length);
		
		if(data_length == 0) {
			return ZINT_ERROR_TOO_LONG;
		}
		
		for(i = 7; i >= 0; i--) {
			if(c1_data_length[i] >= data_length) {
				size = i + 1;
			}
		}
		
		if(symbol->option_2 > size) {
			size = symbol->option_2;
		}
		
		for(i = data_length; i < c1_data_length[size - 1]; i++) {
			data[i] = 129; /* Pad */
		}

		/* Calculate error correction data */
		data_length = c1_data_length[size - 1];
		for(i = 0; i < 190; i++) { sub_data[i] = 0; }
		for(i = 0; i < 75; i++) { sub_ecc[i] = 0; }
		
		data_blocks = c1_blocks[size - 1];

		rs_init_gf(0x12d);
		rs_init_code(c1_ecc_blocks[size - 1], 0);	
		for(i = 0; i < data_blocks; i++) {
			for(j = 0; j < c1_data_blocks[size - 1]; j++) {
				
				sub_data[j] = data[j * data_blocks + i];
			}
			rs_encode_long(c1_data_blocks[size - 1], sub_data, sub_ecc);
			for(j = 0; j < c1_ecc_blocks[size - 1]; j++) {
				ecc[c1_ecc_length[size - 1] - (j * data_blocks + i) - 1] = sub_ecc[j];
			}
		}
		rs_free();

		/* "Stream" combines data and error correction data */
		for(i = 0; i < data_length; i++) {
			stream[i] = data[i];
		}
		for(i = 0; i < c1_ecc_length[size - 1]; i++) {
			stream[data_length + i] = ecc[i];
		}
	
		for(i = 0; i < 136; i++) {
			for(j = 0; j < 120; j++) {
				datagrid[i][j] = '0';
			}
		}
		
		i = 0;
		for(row = 0; row < c1_grid_height[size - 1]; row++) {
			for(col = 0; col < c1_grid_width[size - 1]; col++) {
				if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; }
				if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; }
				if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; }
				if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; }
				if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; }
				if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; }
				if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; }
				if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; }
				i++;
			}
		}
		
		/* for(i = 0; i < (c1_grid_height[size - 1] * 2); i++) {
			for(j = 0; j < (c1_grid_width[size - 1] * 4); j++) {
				printf("%c", datagrid[i][j]);
			}
			printf("\n");
		} */
		
		symbol->rows = c1_height[size - 1];
		symbol->width = c1_width[size - 1];
	}

	switch(size) {
		case 1: /* Version A */
			central_finder(symbol, 6, 3, 1);
			vert(symbol, 4, 6, 1);
			vert(symbol, 12, 5, 0); 
			set_module(symbol, 5, 12);
			spigot(symbol, 0);
			spigot(symbol, 15);
			block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2);
			block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0);
			block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2);
			break;
		case 2: /* Version B */
			central_finder(symbol, 8, 4, 1);
			vert(symbol, 4, 8, 1);
			vert(symbol, 16, 7, 0); 
			set_module(symbol, 7, 16);
			spigot(symbol, 0);
			spigot(symbol, 21);
			block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2);
			block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0);
			block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2);
			break;
		case 3: /* Version C */
			central_finder(symbol, 11, 4, 2);
			vert(symbol, 4, 11, 1);
			vert(symbol, 26, 13, 1);
			vert(symbol, 4, 10, 0);
			vert(symbol, 26, 10, 0); 
			spigot(symbol, 0);
			spigot(symbol, 27);
			block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2);
			block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4);
			block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0);
			block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2);
			block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4);
			break;
		case 4: /* Version D */
			central_finder(symbol, 16, 5, 1); 
			vert(symbol, 4, 16, 1);
			vert(symbol, 20, 16, 1);
			vert(symbol, 36, 16, 1);
			vert(symbol, 4, 15, 0);
			vert(symbol, 20, 15, 0);
			vert(symbol, 36, 15, 0);
			spigot(symbol, 0);
			spigot(symbol, 12);
			spigot(symbol, 27);
			spigot(symbol, 39);
			block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2);
			block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4);
			block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6);
			block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0);
			block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2);
			block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4);
			block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6);
			break;
		case 5: /* Version E */
			central_finder(symbol, 22, 5, 2); 
			vert(symbol, 4, 22, 1);
			vert(symbol, 26, 24, 1);
			vert(symbol, 48, 22, 1);
			vert(symbol, 4, 21, 0);
			vert(symbol, 26, 21, 0);
			vert(symbol, 48, 21, 0);
			spigot(symbol, 0);
			spigot(symbol, 12);
			spigot(symbol, 39);
			spigot(symbol, 51);
			block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2);
			block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4);
			block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6);
			block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0);
			block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2);
			block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4);
			block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6);
			break;
		case 6: /* Version F */
			central_finder(symbol, 31, 5, 3); 
			vert(symbol, 4, 31, 1);
			vert(symbol, 26, 35, 1);
			vert(symbol, 48, 31, 1);
			vert(symbol, 70, 35, 1);
			vert(symbol, 4, 30, 0);
			vert(symbol, 26, 30, 0);
			vert(symbol, 48, 30, 0);
			vert(symbol, 70, 30, 0);
			spigot(symbol, 0);
			spigot(symbol, 12);
			spigot(symbol, 24);
			spigot(symbol, 45);
			spigot(symbol, 57);
			spigot(symbol, 69);
			block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0);
			block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2);
			block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4);
			block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6);
			block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8);
			block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0);
			block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2);
			block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4);
			block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6);
			block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8);
			break;
		case 7: /* Version G */
			central_finder(symbol, 47, 6, 2); 
			vert(symbol, 6, 47, 1);
			vert(symbol, 27, 49, 1);
			vert(symbol, 48, 47, 1);
			vert(symbol, 69, 49, 1);
			vert(symbol, 90, 47, 1);
			vert(symbol, 6, 46, 0);
			vert(symbol, 27, 46, 0);
			vert(symbol, 48, 46, 0);
			vert(symbol, 69, 46, 0);
			vert(symbol, 90, 46, 0);
			spigot(symbol, 0);
			spigot(symbol, 12);
			spigot(symbol, 24);
			spigot(symbol, 36);
			spigot(symbol, 67);
			spigot(symbol, 79);
			spigot(symbol, 91);
			spigot(symbol, 103);
			block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0);
			block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2);
			block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4);
			block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6);
			block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8);
			block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10);
			block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0);
			block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2);
			block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4);
			block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6);
			block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8);
			block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10);
			break;
		case 8: /* Version H */
			central_finder(symbol, 69, 6, 3);
			vert(symbol, 6, 69, 1);
			vert(symbol, 26, 73, 1);
			vert(symbol, 46, 69, 1);
			vert(symbol, 66, 73, 1);
			vert(symbol, 86, 69, 1);
			vert(symbol, 106, 73, 1);
			vert(symbol, 126, 69, 1);
			vert(symbol, 6, 68, 0);
			vert(symbol, 26, 68, 0);
			vert(symbol, 46, 68, 0);
			vert(symbol, 66, 68, 0);
			vert(symbol, 86, 68, 0);
			vert(symbol, 106, 68, 0);
			vert(symbol, 126, 68, 0); 
			spigot(symbol, 0);
			spigot(symbol, 12);
			spigot(symbol, 24);
			spigot(symbol, 36);
			spigot(symbol, 48);
			spigot(symbol, 60);
			spigot(symbol, 87);
			spigot(symbol, 99);
			spigot(symbol, 111);
			spigot(symbol, 123);
			spigot(symbol, 135);
			spigot(symbol, 147);
			block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0);
			block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2);
			block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4);
			block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6);
			block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8);
			block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10);
			block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12);
			block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14);
			block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0);
			block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2);
			block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4);
			block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6);
			block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8);
			block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10);
			block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12);
			block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14);
			break;
		case 9: /* Version S */
			horiz(symbol, 5, 1);
			horiz(symbol, 7, 1);
			set_module(symbol, 6, 0);
			set_module(symbol, 6, symbol->width - 1);
			unset_module(symbol, 7, 1);
			unset_module(symbol, 7, symbol->width - 2);
			switch(sub_version) {
				case 1: /* Version S-10 */
					set_module(symbol, 0, 5);
					block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0);
					block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1);
					break;
				case 2: /* Version S-20 */
					set_module(symbol, 0, 10);
					set_module(symbol, 4, 10);
					block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0);
					block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1);
					break;
				case 3: /* Version S-30 */
					set_module(symbol, 0, 15);
					set_module(symbol, 4, 15);
					set_module(symbol, 6, 15);
					block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0);
					block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1);
					break;
			}
			break;
		case 10: /* Version T */
			horiz(symbol, 11, 1);
			horiz(symbol, 13, 1);
			horiz(symbol, 15, 1);
			set_module(symbol, 12, 0);
			set_module(symbol, 12, symbol->width - 1);
			set_module(symbol, 14, 0);
			set_module(symbol, 14, symbol->width - 1);
			unset_module(symbol, 13, 1);
			unset_module(symbol, 13, symbol->width - 2);
			unset_module(symbol, 15, 1);
			unset_module(symbol, 15, symbol->width - 2);
			switch(sub_version) {
				case 1: /* Version T-16 */
					set_module(symbol, 0, 8);
					set_module(symbol, 10, 8);
					block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0);
					block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1);
					break;
				case 2: /* Version T-32 */
					set_module(symbol, 0, 16);
					set_module(symbol, 10, 16);
					set_module(symbol, 12, 16);
					block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0);
					block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1);
					break;
				case 3: /* Verion T-48 */
					set_module(symbol, 0, 24);
					set_module(symbol, 10, 24);
					set_module(symbol, 12, 24);
					set_module(symbol, 14, 24);
					block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0);
					block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1);
					break;
			}
			break;
	}
	
	for(i = 0; i < symbol->rows; i++) {
		symbol->row_height[i] = 1;
	}

	return 0;
}