static void set_format(scanner_t* scanner, int ecl, byte mask) { bch_t format = (ecl_to_code[ecl] << 3) | mask; format = bch_encode(bch_format_gen, format) ^ bch_format_mask; bch_t copy = format; // top-left for (int i = 0; i <= 5; i++) { P(i,8) = format & 1; format >>= 1; } P(7,8) = format & 1; format >>= 1; P(8,8) = format & 1; format >>= 1; P(8,7) = format & 1; format >>= 1; for (int i = 5; i >= 0; i--) { P(8,i) = format & 1; format >>= 1; } // bottom-left and top-right format = copy; size_t s = scanner->s; for (int i = 1; i <= 8; i++) { P(8, s-i) = format & 1; format >>= 1; } for (int i = 7; i >= 1; i--) { P(s-i, 8) = format & 1; format >>= 1; } }
void qrc_encode(scanner_t* scanner, const char* data) { // generate bit stream stream_t stream; stream.a = 0; stream.d = NULL; stream.vr = 0; int v; while (1) { encode_in_range(&stream, data); v = size_to_version(scanner->c, stream.n); if (v < 0) { fprintf(stderr, "The data cannot fit in any QR-code\n"); exit(1); } size_t vr = version_range[v]; if (vr == stream.vr) break; stream.vr = vr; } scanner->v = v; // compute size size_t s = 17 + 4*v; scanner->s = s; // create image byte* d = (byte*) calloc(s*s, sizeof(byte)); if (d == NULL) { fprintf(stderr, "Could not allocate image\n"); exit(1); } scanner->d = d; // finder patterns set_finder(scanner, 0, 0); set_finder(scanner, s-7, 0); set_finder(scanner, 0, s-7); // timing patterns for (size_t i = 8; i < s-8; i += 2) { P(i, 6) = 1; P(6, i) = 1; } // alignment patterns const byte* xy = pattern_alignment_pos[v]; for (const byte* a = xy; *a; a++) for (const byte* b = xy; *b; b++) { if (*a < 8 && *b < 8) continue; if (*a < 8 && *b > s-9) continue; if (*b < 8 && *a > s-9) continue; set_alignment(scanner, *a, *b); } // version information if (v >= 7) { bch_t version = bch_encode(bch_version_gen, v) ^ bch_version_mask; for (int i = 0; i <= 5; i++) for (int j = 0; j <= 2; j++) { byte bit = version & 1; P(i, s-11+j) = bit; P(s-11+j, i) = bit; version >>= 1; } }
int main(int argc, char **argv) { struct bch_code_t *bch; // Переменная для хранения "кода" unsigned int in_buf_size; // Размер буфера ввода unsigned int out_buf_size; // размер буфера вывода unsigned char *in_buf; // Буфер ввода unsigned char *out_buf; // Буфер вывода size_t rec; // Результат выданый функциями ввода вывода unsigned int i; // Вспомогательная переменная enum{INIT, IS_OPTION, IS_MEM, IS_READ, IS_WRITE, IS_EOF, IS_TAIL} state = INIT; enum{INIT, IS_OPTION, IS_MEM, IS_READ, IS_WRITE, IS_EOF, IS_TAIL} state = INIT; enum{false, true} ok = true; argv_0 = argv[0]; if( ok ) { state = IS_OPTION; options(argc, argv); ok = (NULL != generate && 0 != alpha && 0 != mod); } if( ok ) bch = new_bch_code(generate, deg_generate, mod, alpha); if( ok ) if( doit == INFO ) { fprintf(stderr, "Информация по коду:\n"); fprintf(stderr, "Неприводимый многочлен: %llu [%llx]\n", bch->_gf2n->_mod, bch->_gf2n->_mod); fprintf(stderr, "Корень порождающего многочлена: %u [%x]\n", bch->_alpha, bch->_alpha); fprintf(stderr, "Порождающий многочлен: "); for(i = 0; i <= bch->_degg; ++i) fprintf(stderr, "%c", bch->_g[i] + '0'); fprintf(stderr, "\n"); fprintf(stderr, "n: %u\nk: %u\nd: %u\nt: %u\n", bch->_n, bch->_k, bch->_d, bch->_t); exit(-1); } if( ok ) { if( doit&ENCODE ) { in_buf_size = bch->_k + 1; out_buf_size = bch->_n; } else { in_buf_size = bch->_n; out_buf_size = bch->_k + 1; } } if( ok ) { state = IS_MEM; ok = (NULL != (in_buf = (unsigned char *)malloc(in_buf_size))); } if( ok ) { state = IS_MEM; ok = (NULL != (out_buf = (unsigned char *)malloc(out_buf_size))); } while( ok && IS_EOF != state ) { if( ok ) { state = IS_READ; rec = fread(in_buf, 1, in_buf_size, stdin); ok = (0 == ferror(stdin)); } if( ok && in_buf_size != rec ) { state = IS_EOF; break; } if( ok ) { for(i = in_buf_size; i != -1; --i) in_buf[i] -= '0'; if( doit&ENCODE ) bch_encode(bch, in_buf, out_buf); else bch_decode(bch, in_buf, out_buf); for(i = out_buf_size; i != -1; --i) out_buf[i] += '0'; } if( ok ) { state = IS_WRITE; fwrite(out_buf, out_buf_size, 1, stdout); ok = (0 == ferror(stdin)); } } if( IS_EOF == state ) { state = IS_TAIL; ok = (0 == rec); } if( ok ) delete_bch_code(bch); if( ok ) goto __return_0; switch( state ) { case IS_MEM: fprintf(stderr, "%s: %s\n", argv_0, strerror(errno)); break; case IS_OPTION: fprintf(stderr, "%s: Указаны не все опции.\n", argv_0); break; case IS_READ: fprintf(stderr, "%s: read: %s\n", argv[0], strerror(errno)); break; case IS_WRITE: fprintf(stderr, "%s: write: %s\n", argv[0], strerror(errno)); break; case IS_TAIL: fprintf(stderr, "%s: Неожиданый конец входного потока (файл не выровнен).\n", argv_0); break; default: assert( 0 ); } goto __return_1; __return_0: free(in_buf); free(out_buf); return 0; __return_1: free(in_buf); free(out_buf); return -1; }