示例#1
0
文件: gridmtx.c 项目: 383530895/zint
void add_shift_char(char binary[], int shifty)
{
	/* Add a control character to the data stream */
	int i, debug = 0;
	int glyph = 0;

	for(i = 0; i < 64; i++) {
		if(shift_set[i] == shifty) {
			glyph = i;
		}
	}

	if(debug) { printf("SHIFT [%d] ", glyph); }

	bscan(binary, glyph, 0x20);
}
示例#2
0
bstat()
{
	register int		p;

	for(p = A1; p <= H8; p++) {
		ban1[p] = 0;
		ban2[p] = 0;
		ban3[p] = 0;
		ban4[p] = 0;
	}

	bscan(A1, VECT5, 2, 1, 8);
	bscan(A2, VECT5, 2, 1, 8);
	bscan(A3, VECT5, 2, 1, 8);
	bscan(A4, VECT5, 2, 1, 8);
	bscan(A5, VECT5, 2, 1, 8);
	bscan(A6, VECT5, 2, 1, 8);
	bscan(A7, VECT5, 2, 1, 8);
	bscan(A8, VECT5, 2, 1, 8);

	bscan(A1, VECT7, 2, 1, 8);
	bscan(B1, VECT7, 2, 1, 8);
	bscan(C1, VECT7, 2, 1, 8);
	bscan(D1, VECT7, 2, 1, 8);
	bscan(E1, VECT7, 2, 1, 8);
	bscan(F1, VECT7, 2, 1, 8);
	bscan(G1, VECT7, 2, 1, 8);
	bscan(H1, VECT7, 2, 1, 8);

	bscan(F1, VECT8, 1, 2, 4);
	bscan(E1, VECT8, 1, 2, 4);
	bscan(D1, VECT8, 1, 2, 4);
	bscan(C1, VECT8, 1, 2, 4);
	bscan(B1, VECT8, 1, 2, 4);
	bscan(A1, VECT8, 1, 2, 4);
	bscan(A2, VECT8, 1, 2, 4);
	bscan(A3, VECT8, 1, 2, 4);
	bscan(A4, VECT8, 1, 2, 4);
	bscan(A5, VECT8, 1, 2, 4);
	bscan(A6, VECT8, 1, 2, 4);

	bscan(C1, VECT6, 1, 2, 4);
	bscan(D1, VECT6, 1, 2, 4);
	bscan(E1, VECT6, 1, 2, 4);
	bscan(F1, VECT6, 1, 2, 4);
	bscan(G1, VECT6, 1, 2, 4);
	bscan(H1, VECT6, 1, 2, 4);
	bscan(H2, VECT6, 1, 2, 4);
	bscan(H3, VECT6, 1, 2, 4);
	bscan(H4, VECT6, 1, 2, 4);
	bscan(H5, VECT6, 1, 2, 4);
	bscan(H6, VECT6, 1, 2, 4);
}
示例#3
0
文件: gridmtx.c 项目: 383530895/zint
int gm_encode(int gbdata[], int length, char binary[], int reader)
{
	/* Create a binary stream representation of the input data.
	   7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
	   Mixed numerals and latters, Control characters and 8-bit binary data */
	int sp, current_mode, next_mode, last_mode, glyph = 0;
	int c1, c2, done;
	int p = 0, ppos;
	int numbuf[3], punt = 0;
	int number_pad_posn, debug = 0;
	int byte_count_posn = 0, byte_count = 0;
	int shift, i;

	strcpy(binary, "");

	sp = 0;
	current_mode = 0;
	last_mode = 0;
	number_pad_posn = 0;

	if(reader) {
		concat(binary, "1010"); /* FNC3 - Reader Initialisation */
	}

	do {
		next_mode = seek_forward(gbdata, length, sp, current_mode);

		if(next_mode != current_mode) {
			switch(current_mode) {
				case 0:
					switch(next_mode) {
						case GM_CHINESE: concat(binary, "0001"); break;
						case GM_NUMBER: concat(binary, "0010"); break;
						case GM_LOWER: concat(binary, "0011"); break;
						case GM_UPPER: concat(binary, "0100"); break;
						case GM_MIXED: concat(binary, "0101"); break;
						case GM_BYTE: concat(binary, "0111"); break;
					}
					break;
				case GM_CHINESE:
					switch(next_mode) {
						case GM_NUMBER: concat(binary, "1111111100001"); break; // 8161
						case GM_LOWER: concat(binary, "1111111100010"); break; // 8162
						case GM_UPPER: concat(binary, "1111111100011"); break; // 8163
						case GM_MIXED: concat(binary, "1111111100100"); break; // 8164
						case GM_BYTE: concat(binary, "1111111100101"); break; // 8165
					}
					break;
				case GM_NUMBER:
					/* add numeric block padding value */
					switch(p) {
						case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits
						case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit
						case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits
					}
					switch(next_mode) {
						case GM_CHINESE: concat(binary, "1111111011"); break; // 1019
						case GM_LOWER: concat(binary, "1111111100"); break; // 1020
						case GM_UPPER: concat(binary, "1111111101"); break; // 1021
						case GM_MIXED: concat(binary, "1111111110"); break; // 1022
						case GM_BYTE: concat(binary, "1111111111"); break; // 1023
					}
					break;
				case GM_LOWER:
				case GM_UPPER:
					switch(next_mode) {
						case GM_CHINESE: concat(binary, "11100"); break; // 28
						case GM_NUMBER: concat(binary, "11101"); break; // 29
						case GM_LOWER:
						case GM_UPPER: concat(binary, "11110"); break; // 30
						case GM_MIXED: concat(binary, "1111100"); break; // 124
						case GM_BYTE: concat(binary, "1111110"); break; // 126
					}
					break;
				case GM_MIXED:
					switch(next_mode) {
						case GM_CHINESE: concat(binary, "1111110001"); break; // 1009
						case GM_NUMBER: concat(binary, "1111110010"); break; // 1010
						case GM_LOWER: concat(binary, "1111110011"); break; // 1011
						case GM_UPPER: concat(binary, "1111110100"); break; // 1012
						case GM_BYTE: concat(binary, "1111110111"); break; // 1015
					}
					break;
				case GM_BYTE:
					/* add byte block length indicator */
					add_byte_count(binary, byte_count_posn, byte_count);
					byte_count = 0;
					switch(next_mode) {
						case GM_CHINESE: concat(binary, "0001"); break; // 1
						case GM_NUMBER: concat(binary, "0010"); break; // 2
						case GM_LOWER: concat(binary, "0011"); break; // 3
						case GM_UPPER: concat(binary, "0100"); break; // 4
						case GM_MIXED: concat(binary, "0101"); break; // 5
					}
					break;
			}
			if(debug) {
				switch(next_mode) {
					case GM_CHINESE: printf("CHIN "); break;
					case GM_NUMBER: printf("NUMB "); break;
					case GM_LOWER: printf("LOWR "); break;
					case GM_UPPER: printf("UPPR "); break;
					case GM_MIXED: printf("MIXD "); break;
					case GM_BYTE: printf("BYTE "); break;
				}
			}
		}
		last_mode = current_mode;
		current_mode = next_mode;

		switch(current_mode) {
			case GM_CHINESE:
				done = 0;
				if(gbdata[sp] > 0xff) {
					/* GB2312 character */
					c1 = (gbdata[sp] >> 8) & 0xff;
					c2 = gbdata[sp] & 0xff;

					if((c1 >= 0xa0) && (c1 <= 0xa9)) {
						glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0);
					}
					if((c1 >= 0xb0) && (c1 <= 0xf7)) {
						glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2  - 0xa0);
					}
					done = 1;
				}
				if(!(done)) {
					if(sp != (length - 1)) {
						if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) {
							/* End of Line */
							glyph = 7776;
							sp++;
						}
						done = 1;
					}
				}
				if(!(done)) {
					if(sp != (length - 1)) {
						if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) &&
							((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) {
							/* Two digits */
							glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0');
							sp++;
						}
					}
				}
				if(!(done)) {
					/* Byte value */
					glyph = 7777 + gbdata[sp];
				}

				if(debug) { printf("[%d] ", glyph); }

				bscan(binary, glyph, 0x1000);
				sp++;
				break;

			case GM_NUMBER:
				if(last_mode != current_mode) {
					/* Reserve a space for numeric digit padding value (2 bits) */
					number_pad_posn = strlen(binary);
					concat(binary, "XX");
				}
				p = 0;
				ppos = -1;

				/* Numeric compression can also include certain combinations of
				   non-numeric character */

				numbuf[0] = '0';
				numbuf[1] = '0';
				numbuf[2] = '0';
				do {
					if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) {
						numbuf[p] = gbdata[sp];
						sp++;
						p++;
					}
					switch(gbdata[sp]) {
						case ' ':
						case '+':
						case '-':
						case '.':
						case ',':
							punt = gbdata[sp];
							sp++;
							ppos = p;
							break;
					}
					if(sp < (length - 1)) {
						if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) {
							/* <end of line> */
							punt = gbdata[sp];
							sp += 2;
							ppos = p;
						}
					}
				} while ((p < 3) && (sp < length));

				if(ppos != -1) {
					switch(punt) {
						case ' ': glyph = 0; break;
						case '+': glyph = 3; break;
						case '-': glyph = 6; break;
						case '.': glyph = 9; break;
						case ',': glyph = 12; break;
						case 0x13: glyph = 15; break;
					}
					glyph += ppos;
					glyph += 1000;

					if(debug) { printf("[%d] ", glyph); }

					bscan(binary, glyph, 0x200);
				}

				glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0');
				if(debug) { printf("[%d] ", glyph); }

				bscan(binary, glyph, 0x200);
				break;

			case GM_BYTE:
				if(last_mode != current_mode) {
					/* Reserve space for byte block length indicator (9 bits) */
					byte_count_posn = strlen(binary);
					concat(binary, "LLLLLLLLL");
				}
				if(byte_count == 512) {
					/* Maximum byte block size is 512 bytes. If longer is needed then start a new block */
					add_byte_count(binary, byte_count_posn, byte_count);
					concat(binary, "0111");
					byte_count_posn = strlen(binary);
					concat(binary, "LLLLLLLLL");
					byte_count = 0;
				}

				glyph = gbdata[sp];
				if(debug) { printf("[%d] ", glyph); }
				bscan(binary, glyph, 0x80);
				sp++;
				byte_count++;
				break;

			case GM_MIXED:
				shift = 1;
				if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { shift = 0; }
				if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; }
				if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; }
				if(gbdata[sp] == ' ') { shift = 0; }

				if(shift == 0) {
					/* Mixed Mode character */
					glyph = posn(EUROPIUM, gbdata[sp]);
					if(debug) { printf("[%d] ", glyph); }

					bscan(binary, glyph, 0x20);
				} else {
					/* Shift Mode character */
					concat(binary, "1111110110"); /* 1014 - shift indicator */
					add_shift_char(binary, gbdata[sp]);
				}

				sp++;
				break;

			case GM_UPPER:
				shift = 1;
				if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; }
				if(gbdata[sp] == ' ') { shift = 0; }

				if(shift == 0) {
					/* Upper Case character */
					glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]);
					if(debug) { printf("[%d] ", glyph); }

					bscan(binary, glyph, 0x10);
				} else {
					/* Shift Mode character */
					concat(binary, "1111101"); /* 127 - shift indicator */
					add_shift_char(binary, gbdata[sp]);
				}

				sp++;
				break;

			case GM_LOWER:
				shift = 1;
				if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; }
				if(gbdata[sp] == ' ') { shift = 0; }

				if(shift == 0) {
					/* Lower Case character */
					glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]);
					if(debug) { printf("[%d] ", glyph); }

					bscan(binary, glyph, 0x10);
				} else {
					/* Shift Mode character */
					concat(binary, "1111101"); /* 127 - shift indicator */
					add_shift_char(binary, gbdata[sp]);
				}

				sp++;
				break;
		}
		if(strlen(binary) > 9191) {
			return ZERROR_TOO_LONG;
		}

	} while(sp < length);
示例#4
0
int aztec(struct zint_symbol *symbol, uint8_t source[], int length)
{
    int x, y, i, j, v, data_blocks, ecc_blocks, layers, total_bits;
    char binary_string[20000], bit_pattern[20045], descriptor[42];
    char adjusted_string[20000];
    uint8_t desc_data[4], desc_ecc[6];
    int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length;
    int remainder, padbits, count, gs1, adjustment_size;
    int debug = 0, reader = 0;
    int comp_loop = 4;

    uint8_t local_source[length + 1];

    memset(binary_string,0,20000);
    memset(adjusted_string,0,20000);

    if(symbol->input_mode == GS1_MODE) {
        gs1 = 1;
    }
    else {
        gs1 = 0;
    }
    if(symbol->output_options & READER_INIT) {
        reader = 1;
        comp_loop = 1;
    }
    if((gs1 == 1) && (reader == 1)) {
        strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time");
        return ZERROR_INVALID_OPTION;
    }

    switch(symbol->input_mode) {
    case DATA_MODE:
    case GS1_MODE:
        memcpy(local_source, source, length);
        local_source[length] = '\0';
        break;
    case UNICODE_MODE:
        err_code = latin1_process(symbol, source, local_source, &length);
        if(err_code != 0) {
            return err_code;
        }
        break;
    }

    err_code = aztec_text_process(local_source, length, binary_string, gs1);


    if(err_code != 0) {
        strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters");
        return err_code;
    }

    if(!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) {
        strcpy(symbol->errtxt, "Invalid error correction level - using default instead");
        err_code = ZWARN_INVALID_OPTION;
        symbol->option_1 = -1;
    }

    ecc_level = symbol->option_1;

    if((ecc_level == -1) || (ecc_level == 0)) {
        ecc_level = 2;
    }

    data_length = strlen(binary_string);

    layers = 0; /* Keep compiler happy! */
    data_maxsize = 0; /* Keep compiler happy! */
    adjustment_size = 0;
    if(symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */
        do {
            /* Decide what size symbol to use - the smallest that fits the data */
            compact = 0; /* 1 = Aztec Compact, 0 = Normal Aztec */
            layers = 0;

            switch(ecc_level) {
            /* For each level of error correction work out the smallest symbol which
            the data will fit in */
            case 1:
                for(i = 32; i > 0; i--) {
                    if((data_length + adjustment_size) < Aztec10DataSizes[i - 1]) {
                        layers = i;
                        compact = 0;
                        data_maxsize = Aztec10DataSizes[i - 1];
                    }
                }
                for(i = comp_loop; i > 0; i--) {
                    if((data_length + adjustment_size) < AztecCompact10DataSizes[i - 1]) {
                        layers = i;
                        compact = 1;
                        data_maxsize = AztecCompact10DataSizes[i - 1];
                    }
                }
                break;
            case 2:
                for(i = 32; i > 0; i--) {
                    if((data_length + adjustment_size) < Aztec23DataSizes[i - 1]) {
                        layers = i;
                        compact = 0;
                        data_maxsize = Aztec23DataSizes[i - 1];
                    }
                }
                for(i = comp_loop; i > 0; i--) {
                    if((data_length + adjustment_size) < AztecCompact23DataSizes[i - 1]) {
                        layers = i;
                        compact = 1;
                        data_maxsize = AztecCompact23DataSizes[i - 1];
                    }
                }
                break;
            case 3:
                for(i = 32; i > 0; i--) {
                    if((data_length + adjustment_size) < Aztec36DataSizes[i - 1]) {
                        layers = i;
                        compact = 0;
                        data_maxsize = Aztec36DataSizes[i - 1];
                    }
                }
                for(i = comp_loop; i > 0; i--) {
                    if((data_length + adjustment_size) < AztecCompact36DataSizes[i - 1]) {
                        layers = i;
                        compact = 1;
                        data_maxsize = AztecCompact36DataSizes[i - 1];
                    }
                }
                break;
            case 4:
                for(i = 32; i > 0; i--) {
                    if((data_length + adjustment_size) < Aztec50DataSizes[i - 1]) {
                        layers = i;
                        compact = 0;
                        data_maxsize = Aztec50DataSizes[i - 1];
                    }
                }
                for(i = comp_loop; i > 0; i--) {
                    if((data_length + adjustment_size) < AztecCompact50DataSizes[i - 1]) {
                        layers = i;
                        compact = 1;
                        data_maxsize = AztecCompact50DataSizes[i - 1];
                    }
                }
                break;
            }

            if(layers == 0) { /* Couldn't find a symbol which fits the data */
                strcpy(symbol->errtxt, "Input too long (too many bits for selected ECC)");
                return ZERROR_TOO_LONG;
            }

            /* Determine codeword bitlength - Table 3 */
            codeword_size = 6; /* if (layers <= 2) */
            if((layers >= 3) && (layers <= 8)) {
                codeword_size = 8;
            }
            if((layers >= 9) && (layers <= 22)) {
                codeword_size = 10;
            }
            if(layers >= 23) {
                codeword_size = 12;
            }

            j = 0;
            i = 0;
            do {
                if((j + 1) % codeword_size == 0) {
                    /* Last bit of codeword */
                    int t, done = 0;
                    count = 0;

                    /* Discover how many '1's in current codeword */
                    for(t = 0; t < (codeword_size - 1); t++) {
                        if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++;
                    }

                    if(count == (codeword_size - 1)) {
                        adjusted_string[j] = '0';
                        j++;
                        done = 1;
                    }

                    if(count == 0) {
                        adjusted_string[j] = '1';
                        j++;
                        done = 1;
                    }

                    if(done == 0) {
                        adjusted_string[j] = binary_string[i];
                        j++;
                        i++;
                    }
                }
                adjusted_string[j] = binary_string[i];
                j++;
                i++;
            } while (i <= (data_length + 1));
            adjusted_string[j] = '\0';
            adjusted_length = strlen(adjusted_string);
            adjustment_size = adjusted_length - data_length;

            /* Add padding */
            remainder = adjusted_length % codeword_size;

            padbits = codeword_size - remainder;
            if(padbits == codeword_size) {
                padbits = 0;
            }

            for(i = 0; i < padbits; i++) {
                concat(adjusted_string, "1");
            }
            adjusted_length = strlen(adjusted_string);

            count = 0;
            for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
                if(adjusted_string[i] == '1') {
                    count++;
                }
            }
            if(count == codeword_size) {
                adjusted_string[adjusted_length - 1] = '0';
            }

            if(debug) {
                printf("Codewords:\n");
                for(i = 0; i < (adjusted_length / codeword_size); i++) {
                    for(j = 0; j < codeword_size; j++) {
                        printf("%c", adjusted_string[(i * codeword_size) + j]);
                    }
                    printf("\n");
                }
            }

        } while(adjusted_length > data_maxsize);
        /* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s
        means that the binary string has had to be lengthened beyond the maximum number of bits that can
        be encoded in a symbol of the selected size */

    } else { /* The size of the symbol has been specified by the user */
        if((reader == 1) && ((symbol->option_2 >= 2) && (symbol->option_2 <= 4))) {
            symbol->option_2 = 5;
        }
        if((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) {
            compact = 1;
            layers = symbol->option_2;
        }
        if((symbol->option_2 >= 5) && (symbol->option_2 <= 36)) {
            compact = 0;
            layers = symbol->option_2 - 4;
        }
        if((symbol->option_2 < 0) || (symbol->option_2 > 36)) {
            strcpy(symbol->errtxt, "Invalid Aztec Code size");
            return ZERROR_INVALID_OPTION;
        }

        /* Determine codeword bitlength - Table 3 */
        if((layers >= 0) && (layers <= 2)) {
            codeword_size = 6;
        }
        if((layers >= 3) && (layers <= 8)) {
            codeword_size = 8;
        }
        if((layers >= 9) && (layers <= 22)) {
            codeword_size = 10;
        }
        if(layers >= 23) {
            codeword_size = 12;
        }

        j = 0;
        i = 0;
        do {
            if((j + 1) % codeword_size == 0) {
                /* Last bit of codeword */
                int t, done = 0;
                count = 0;

                /* Discover how many '1's in current codeword */
                for(t = 0; t < (codeword_size - 1); t++) {
                    if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++;
                }

                if(count == (codeword_size - 1)) {
                    adjusted_string[j] = '0';
                    j++;
                    done = 1;
                }

                if(count == 0) {
                    adjusted_string[j] = '1';
                    j++;
                    done = 1;
                }

                if(done == 0) {
                    adjusted_string[j] = binary_string[i];
                    j++;
                    i++;
                }
            }
            adjusted_string[j] = binary_string[i];
            j++;
            i++;
        } while (i <= (data_length + 1));
        adjusted_string[j] = '\0';
        adjusted_length = strlen(adjusted_string);

        remainder = adjusted_length % codeword_size;

        padbits = codeword_size - remainder;
        if(padbits == codeword_size) {
            padbits = 0;
        }

        for(i = 0; i < padbits; i++) {
            concat(adjusted_string, "1");
        }
        adjusted_length = strlen(adjusted_string);

        count = 0;
        for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
            if(adjusted_string[i] == '1') {
                count++;
            }
        }
        if(count == codeword_size) {
            adjusted_string[adjusted_length - 1] = '0';
        }

        /* Check if the data actually fits into the selected symbol size */
        if (compact) {
            data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
        } else {
            data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3);
        }

        if(adjusted_length > data_maxsize) {
            strcpy(symbol->errtxt, "Data too long for specified Aztec Code symbol size");
            return ZERROR_TOO_LONG;
        }

        if(debug) {
            printf("Codewords:\n");
            for(i = 0; i < (adjusted_length / codeword_size); i++) {
                for(j = 0; j < codeword_size; j++) {
                    printf("%c", adjusted_string[(i * codeword_size) + j]);
                }
                printf("\n");
            }
        }

    }

    if(reader && (layers > 22)) {
        strcpy(symbol->errtxt, "Data too long for reader initialisation symbol");
        return ZERROR_TOO_LONG;
    }

    data_blocks = adjusted_length / codeword_size;

    if(compact) {
        ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks;
    } else {
        ecc_blocks = AztecSizes[layers - 1] - data_blocks;
    }

    if(debug) {
        printf("Generating a ");
        if(compact) {
            printf("compact");
        }
        else {
            printf("full-size");
        }
        printf(" symbol with %d layers\n", layers);
        printf("Requires ");
        if(compact) {
            printf("%d", AztecCompactSizes[layers - 1]);
        }
        else {
            printf("%d", AztecSizes[layers - 1]);
        }
        printf(" codewords of %d-bits\n", codeword_size);
        printf("    (%d data words, %d ecc words)\n", data_blocks, ecc_blocks);
    }

    unsigned int data_part[data_blocks + 3], ecc_part[ecc_blocks + 3];
    /* Copy across data into separate integers */
    memset(data_part,0,(data_blocks + 2)*sizeof(int));
    memset(ecc_part,0,(ecc_blocks + 2)*sizeof(int));

    /* Split into codewords and calculate reed-colomon error correction codes */
    switch(codeword_size) {
    case 6:
        for(i = 0; i < data_blocks; i++) {
            if(adjusted_string[i * codeword_size] == '1') {
                data_part[i] += 32;
            }
            if(adjusted_string[(i * codeword_size) + 1] == '1') {
                data_part[i] += 16;
            }
            if(adjusted_string[(i * codeword_size) + 2] == '1') {
                data_part[i] += 8;
            }
            if(adjusted_string[(i * codeword_size) + 3] == '1') {
                data_part[i] += 4;
            }
            if(adjusted_string[(i * codeword_size) + 4] == '1') {
                data_part[i] += 2;
            }
            if(adjusted_string[(i * codeword_size) + 5] == '1') {
                data_part[i] += 1;
            }
        }
        rs_init_gf(0x43);
        rs_init_code(ecc_blocks, 1);
        rs_encode_long(data_blocks, data_part, ecc_part);
        for (i = (ecc_blocks - 1); i >= 0; i--) {
            bscan(adjusted_string, ecc_part[i], 0x20);
        }
        rs_free();
        break;
    case 8:
        for(i = 0; i < data_blocks; i++) {
            if(adjusted_string[i * codeword_size] == '1') {
                data_part[i] += 128;
            }
            if(adjusted_string[(i * codeword_size) + 1] == '1') {
                data_part[i] += 64;
            }
            if(adjusted_string[(i * codeword_size) + 2] == '1') {
                data_part[i] += 32;
            }
            if(adjusted_string[(i * codeword_size) + 3] == '1') {
                data_part[i] += 16;
            }
            if(adjusted_string[(i * codeword_size) + 4] == '1') {
                data_part[i] += 8;
            }
            if(adjusted_string[(i * codeword_size) + 5] == '1') {
                data_part[i] += 4;
            }
            if(adjusted_string[(i * codeword_size) + 6] == '1') {
                data_part[i] += 2;
            }
            if(adjusted_string[(i * codeword_size) + 7] == '1') {
                data_part[i] += 1;
            }
        }
        rs_init_gf(0x12d);
        rs_init_code(ecc_blocks, 1);
        rs_encode_long(data_blocks, data_part, ecc_part);
        for (i = (ecc_blocks - 1); i >= 0; i--) {
            bscan(adjusted_string, ecc_part[i], 0x80);
        }
        rs_free();
        break;
    case 10:
        for(i = 0; i < data_blocks; i++) {
            if(adjusted_string[i * codeword_size] == '1') {
                data_part[i] += 512;
            }
            if(adjusted_string[(i * codeword_size) + 1] == '1') {
                data_part[i] += 256;
            }
            if(adjusted_string[(i * codeword_size) + 2] == '1') {
                data_part[i] += 128;
            }
            if(adjusted_string[(i * codeword_size) + 3] == '1') {
                data_part[i] += 64;
            }
            if(adjusted_string[(i * codeword_size) + 4] == '1') {
                data_part[i] += 32;
            }
            if(adjusted_string[(i * codeword_size) + 5] == '1') {
                data_part[i] += 16;
            }
            if(adjusted_string[(i * codeword_size) + 6] == '1') {
                data_part[i] += 8;
            }
            if(adjusted_string[(i * codeword_size) + 7] == '1') {
                data_part[i] += 4;
            }
            if(adjusted_string[(i * codeword_size) + 8] == '1') {
                data_part[i] += 2;
            }
            if(adjusted_string[(i * codeword_size) + 9] == '1') {
                data_part[i] += 1;
            }
        }
        rs_init_gf(0x409);
        rs_init_code(ecc_blocks, 1);
        rs_encode_long(data_blocks, data_part, ecc_part);
        for(i = (ecc_blocks - 1); i >= 0; i--) {
            bscan(adjusted_string, ecc_part[i], 0x200);
        }
        rs_free();
        break;
    case 12:
        for(i = 0; i < data_blocks; i++) {
            if(adjusted_string[i * codeword_size] == '1') {
                data_part[i] += 2048;
            }
            if(adjusted_string[(i * codeword_size) + 1] == '1') {
                data_part[i] += 1024;
            }
            if(adjusted_string[(i * codeword_size) + 2] == '1') {
                data_part[i] += 512;
            }
            if(adjusted_string[(i * codeword_size) + 3] == '1') {
                data_part[i] += 256;
            }
            if(adjusted_string[(i * codeword_size) + 4] == '1') {
                data_part[i] += 128;
            }
            if(adjusted_string[(i * codeword_size) + 5] == '1') {
                data_part[i] += 64;
            }
            if(adjusted_string[(i * codeword_size) + 6] == '1') {
                data_part[i] += 32;
            }
            if(adjusted_string[(i * codeword_size) + 7] == '1') {
                data_part[i] += 16;
            }
            if(adjusted_string[(i * codeword_size) + 8] == '1') {
                data_part[i] += 8;
            }
            if(adjusted_string[(i * codeword_size) + 9] == '1') {
                data_part[i] += 4;
            }
            if(adjusted_string[(i * codeword_size) + 10] == '1') {
                data_part[i] += 2;
            }
            if(adjusted_string[(i * codeword_size) + 11] == '1') {
                data_part[i] += 1;
            }
        }
        rs_init_gf(0x1069);
        rs_init_code(ecc_blocks, 1);
        rs_encode_long(data_blocks, data_part, ecc_part);
        for(i = (ecc_blocks - 1); i >= 0; i--) {
            bscan(adjusted_string, ecc_part[i], 0x800);
        }
        rs_free();
        break;
    }

    /* Invert the data so that actual data is on the outside and reed-solomon on the inside */
    memset(bit_pattern,'0',20045);

    total_bits = (data_blocks + ecc_blocks) * codeword_size;
    for(i = 0; i < total_bits; i++) {
        bit_pattern[i] = adjusted_string[total_bits - i - 1];
    }

    /* Now add the symbol descriptor */
    memset(desc_data,0,4);
    memset(desc_ecc,0,6);
    memset(descriptor,0,42);

    if(compact) {
        /* The first 2 bits represent the number of layers minus 1 */
        descriptor[0] = ((layers - 1) & 2) ? '1' : '0';
        descriptor[1] = ((layers - 1) & 1) ? '1' : '0';
        /* The next 6 bits represent the number of data blocks minus 1 */
        if(reader) {
            descriptor[2] = '1';
        } else {
            descriptor[2] = ((data_blocks - 1) & 0x20) ? '1' : '0';
        }
        for (i = 3, v = 0x10; v; v >>= 1)
            descriptor[i++] = ((data_blocks - 1) & v) ? '1' : '0';
        descriptor[8] = '\0';
        if(debug) printf("Mode Message = %s\n", descriptor);
    } else {
        /* The first 5 bits represent the number of layers minus 1 */
        for (i = 0, v = 0x10; v; v >>= 1)
示例#5
0
/**
 * Encode input data into a binary string
 */
int aztec_text_process(uint8_t source[], const unsigned int src_len, char binary_string[], int gs1)
{
    int bytes, i, j, k;
    int curtable, newtable, lasttable, chartype, maplength, blocks, debug;
    int charmap[src_len * 2], typemap[src_len * 2];
    int blockmap[2][src_len];
    /* Lookup input string in encoding table */
    maplength = 0;
    debug = 0;

    for(i = 0; i < (int)src_len; i++) {
        if(gs1 && (i == 0)) {
            /* Add FNC1 to beginning of GS1 messages */
            charmap[maplength] = 0;
            typemap[maplength++] = PUNC;
            charmap[maplength] = 400;
            typemap[maplength++] = PUNC;
        }
        if((gs1) && (source[i] == '[')) {
            /* FNC1 represented by FLG(0) */
            charmap[maplength] = 0;
            typemap[maplength++] = PUNC;
            charmap[maplength] = 400;
            typemap[maplength++] = PUNC;
        } else {
            if(source[i] > 127 || source[i] == 0) {
                charmap[maplength] = source[i];
                typemap[maplength++] = BINARY;
            } else {
                charmap[maplength] = AztecSymbolChar[source[i]];
                typemap[maplength++] = AztecCodeSet[source[i]];
            }
        }
    }

    /* Look for double character encoding possibilities */
    i = 0;
    do {
        if(((charmap[i] == 300) && (charmap[i + 1] == 11)) && ((typemap[i] == PUNC) && (typemap[i + 1] == PUNC))) {
            /* CR LF combination */
            charmap[i] = 2;
            typemap[i] = PUNC;
            mapshorten(charmap, typemap, i, maplength);
            maplength--;
        }

        if(((charmap[i] == 302) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) {
            /* . SP combination */
            charmap[i] = 3;
            typemap[i] = PUNC;
            mapshorten(charmap, typemap, i, maplength);
            maplength--;
        }

        if(((charmap[i] == 301) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) {
            /* , SP combination */
            charmap[i] = 4;
            typemap[i] = PUNC;
            mapshorten(charmap, typemap, i, maplength);
            maplength--;
        }

        if(((charmap[i] == 21) && (charmap[i + 1] == 1)) && ((typemap[i] == PUNC) && (typemap[i + 1] == 23))) {
            /* : SP combination */
            charmap[i] = 5;
            typemap[i] = PUNC;
            mapshorten(charmap, typemap, i, maplength);
            maplength--;
        }

        i++;
    } while(i < (maplength - 1));

    /* look for blocks of characters which use the same table */
    blocks = 1;
    blockmap[0][0] = typemap[0];
    blockmap[1][0] = 1;
    for(i = 1; i < maplength; i++) {
        if(typemap[i] == typemap[i - 1]) {
            blockmap[1][blocks - 1]++;
        } else {
            blocks++;
            blockmap[0][blocks - 1] = typemap[i];
            blockmap[1][blocks - 1] = 1;
        }
    }

    for (i = 1; i <= 8; i <<= 1) {
        if (blockmap[0][0] & i) {
            blockmap[0][0] = i;
            break;
        }
    }

    if(blocks > 1) {
        /* look for adjacent blocks which can use the same table (left to right search) */
        for(i = 1; i < blocks; i++) {
            if(blockmap[0][i] & blockmap[0][i - 1]) {
                blockmap[0][i] = (blockmap[0][i] & blockmap[0][i - 1]);
            }
        }


        for (i = 1; i <= 8; i <<= 1) {
            if (blockmap[0][blocks - 1] & i) {
                blockmap[0][blocks - 1] = i;
                break;
            }
        }

        /* look for adjacent blocks which can use the same table (right to left search) */
        for(i = blocks - 1; i > 0; i--) {
            if(blockmap[0][i] & blockmap[0][i + 1]) {
                blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]);
            }
        }

        /* determine the encoding table for characters which do not fit
           with adjacent blocks */
        for (i = 1; i < blocks; i++) {
            for (j = 8; j; j >>= 1) {
                if (blockmap[0][i] & j) {
                    blockmap[0][i] = j;
                    break;
                }
            }
        }

        /* Combine blocks of the same type */
        i = 0;
        do {
            if(blockmap[0][i] == blockmap[0][i + 1]) {
                blockmap[1][i] += blockmap[1][i + 1];
                for(j = i + 1; j < blocks; j++) {
                    blockmap[0][j] = blockmap[0][j + 1];
                    blockmap[1][j] = blockmap[1][j + 1];
                }
                blocks--;
            } else {
                i++;
            }
        } while (i < blocks);
    }

    /* Put the adjusted block data back into typemap */
    j = 0;
    for(i = 0; i < blocks; i++) {
        if((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) { /* Shift character(s) needed */
            for(k = 0; k < blockmap[1][i]; k++) {
                typemap[j + k] = blockmap[0][i] + 64;
            }
        } else { /* Latch character (or byte mode) needed */
            for(k = 0; k < blockmap[1][i]; k++) {
                typemap[j + k] = blockmap[0][i];
            }
        }
        j += blockmap[1][i];
    }

    /* Don't shift an initial capital letter */
    if(typemap[0] == 65) {
        typemap[0] = 1;
    };

    /* Problem characters (those that appear in different tables with different values) can now be resolved into their tables */
    for(i = 0; i < maplength; i++) {
        if((charmap[i] >= 300) && (charmap[i] < 400)) {
            curtable = typemap[i];
            if(curtable > 64) {
                curtable -= 64;
            }
            switch(charmap[i]) {
            case 300: /* Carriage Return */
                switch(curtable) {
                case PUNC:
                    charmap[i] = 1;
                    break;
                case MIXED:
                    charmap[i] = 14;
                    break;
                }
                break;
            case 301: /* Comma */
                switch(curtable) {
                case PUNC:
                    charmap[i] = 17;
                    break;
                case DIGIT:
                    charmap[i] = 12;
                    break;
                }
                break;
            case 302: /* Full Stop */
                switch(curtable) {
                case PUNC:
                    charmap[i] = 19;
                    break;
                case DIGIT:
                    charmap[i] = 13;
                    break;
                }
                break;
            }
        }
    }
    *binary_string  = '\0';

    curtable = UPPER; /* start with UPPER table */
    lasttable = UPPER;
    for(i = 0; i < maplength; i++) {
        newtable = curtable;
        if((typemap[i] != curtable) && (charmap[i] < 400)) {
            /* Change table */
            if(curtable == BINARY) {
                /* If ending binary mode the current table is the same as when entering binary mode */
                curtable = lasttable;
                newtable = lasttable;
            }
            if(typemap[i] > 64) {
                /* Shift character */
                switch(typemap[i]) {
                case (64 + UPPER): /* To UPPER */
                    switch(curtable) {
                    case LOWER: /* US */
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("US ");
                        break;
                    case MIXED: /* UL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    case PUNC: /* UL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    case DIGIT: /* US */
                        concat(binary_string, pentbit[15]);
                        if(debug) printf("US ");
                        break;
                    }
                    break;
                case (64 + LOWER): /* To LOWER */
                    switch(curtable) {
                    case UPPER: /* LL */
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case MIXED: /* LL */
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case PUNC: /* UL LL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case DIGIT: /* UL LL */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    }
                    break;
                case (64 + MIXED): /* To MIXED */
                    switch(curtable) {
                    case UPPER: /* ML */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case LOWER: /* ML */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case PUNC: /* UL ML */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case DIGIT: /* UL ML */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    }
                    break;
                case (64 + PUNC): /* To PUNC */
                    switch(curtable) {
                    case UPPER: /* PS */
                        concat(binary_string, hexbit[0]);
                        if(debug) printf("PS ");
                        break;
                    case LOWER: /* PS */
                        concat(binary_string, hexbit[0]);
                        if(debug) printf("PS ");
                        break;
                    case MIXED: /* PS */
                        concat(binary_string, hexbit[0]);
                        if(debug) printf("PS ");
                        break;
                    case DIGIT: /* PS */
                        concat(binary_string, pentbit[0]);
                        if(debug) printf("PS ");
                        break;
                    }
                    break;
                case (64 + DIGIT): /* To DIGIT */
                    switch(curtable) {
                    case UPPER: /* DL */
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case LOWER: /* DL */
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case MIXED: /* UL DL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case PUNC: /* UL DL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    }
                    break;
                }
            } else {
                /* Latch character */
                switch(typemap[i]) {
                case UPPER: /* To UPPER */
                    switch(curtable) {
                    case LOWER: /* ML UL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    case MIXED: /* UL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    case PUNC: /* UL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    case DIGIT: /* UL */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        newtable = UPPER;
                        break;
                    }
                    break;
                case LOWER: /* To LOWER */
                    switch(curtable) {
                    case UPPER: /* LL */
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case MIXED: /* LL */
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case PUNC: /* UL LL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    case DIGIT: /* UL LL */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[28]);
                        if(debug) printf("LL ");
                        newtable = LOWER;
                        break;
                    }
                    break;
                case MIXED: /* To MIXED */
                    switch(curtable) {
                    case UPPER: /* ML */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case LOWER: /* ML */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case PUNC: /* UL ML */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    case DIGIT: /* UL ML */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        newtable = MIXED;
                        break;
                    }
                    break;
                case PUNC: /* To PUNC */
                    switch(curtable) {
                    case UPPER: /* ML PL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("PL ");
                        newtable = PUNC;
                        break;
                    case LOWER: /* ML PL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("PL ");
                        newtable = PUNC;
                        break;
                    case MIXED: /* PL */
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("PL ");
                        newtable = PUNC;
                        break;
                    case DIGIT: /* UL ML PL */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("ML ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("PL ");
                        newtable = PUNC;
                        break;
                    }
                    break;
                case DIGIT: /* To DIGIT */
                    switch(curtable) {
                    case UPPER: /* DL */
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case LOWER: /* DL */
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case MIXED: /* UL DL */
                        concat(binary_string, hexbit[29]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    case PUNC: /* UL DL */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[30]);
                        if(debug) printf("DL ");
                        newtable = DIGIT;
                        break;
                    }
                    break;
                case BINARY: /* To BINARY */
                    lasttable = curtable;
                    switch(curtable) {
                    case UPPER: /* BS */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("BS ");
                        newtable = BINARY;
                        break;
                    case LOWER: /* BS */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("BS ");
                        newtable = BINARY;
                        break;
                    case MIXED: /* BS */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("BS ");
                        newtable = BINARY;
                        break;
                    case PUNC: /* UL BS */
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("BS ");
                        newtable = BINARY;
                        break;
                    case DIGIT: /* UL BS */
                        concat(binary_string, pentbit[14]);
                        if(debug) printf("UL ");
                        concat(binary_string, hexbit[31]);
                        if(debug) printf("BS ");
                        newtable = BINARY;
                        break;
                    }

                    bytes = 0;
                    do {
                        bytes++;
                    } while(typemap[i + (bytes - 1)] == BINARY);
                    bytes--;

                    if(bytes > 2079) {
                        return ZERROR_TOO_LONG;
                    }

                    if(bytes > 31) { /* Put 00000 followed by 11-bit number of bytes less 31 */
                        int adjusted;

                        adjusted = bytes - 31;
                        concat(binary_string, "00000");
                        bscan(binary_string, adjusted, 0x400);
                    } else { /* Put 5-bit number of bytes */
                        bscan(binary_string, bytes, 0x10);
                    }
                    if(debug) printf("(%d bytes) ", bytes);

                    break;
                }
            }
        }
        /* Add data to the binary string */
        curtable = newtable;
        chartype = typemap[i];
        if(chartype > 64) {
            chartype -= 64;
        }
        switch(chartype) {
        case UPPER:
        case LOWER:
        case MIXED:
        case PUNC:
            if(charmap[i] >= 400) {
                concat(binary_string, tribit[charmap[i] - 400]);
                if(debug) printf("FLG(%d) ",charmap[i] - 400);
            } else {
                concat(binary_string, hexbit[charmap[i]]);
                if(!((chartype == PUNC) && (charmap[i] == 0)))
                    if(debug) printf("%d ",charmap[i]);
            }
            break;
        case DIGIT:
            concat(binary_string, pentbit[charmap[i]]);
            if(debug) printf("%d ",charmap[i]);
            break;
        case BINARY:
            bscan(binary_string, charmap[i], 0x80);
            if (debug)
                printf("%d ",charmap[i]);
            break;
        }

    }

    if(debug) printf("\n");

    if(strlen(binary_string) > 14970) {
        return ZERROR_TOO_LONG;
    }

    return 0;
}