zint/backend/qr.c

138 lines
3.3 KiB
C
Raw Normal View History

2008-07-14 09:15:55 +12:00
/* qr.c Handles QR Code by utilising libqrencode */
/*
libzint - the open source barcode library
2008-11-17 21:47:42 +13:00
Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
2008-07-14 09:15:55 +12:00
Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include "common.h"
2008-09-19 02:37:45 +12:00
#ifndef NO_QR
2008-09-03 07:49:08 +12:00
#include <qrencode.h>
2009-08-09 20:45:58 +12:00
#include <stdio.h>
2008-09-03 07:49:08 +12:00
2009-08-09 20:45:58 +12:00
QRcode *encode(int security, int size, const unsigned char *intext, int kanji, int gs1, char nullchar, int input_length)
2008-07-14 09:15:55 +12:00
{
int version;
QRecLevel level;
QRencodeMode hint;
QRcode *code;
2009-08-09 20:45:58 +12:00
hint = 0;
2008-07-14 09:15:55 +12:00
if(kanji) {
hint = QR_MODE_KANJI;
2009-08-09 20:45:58 +12:00
}
if(gs1) {
hint = QR_MODE_GS1;
}
if(hint == 0) {
2008-07-14 09:15:55 +12:00
hint = QR_MODE_8;
}
2009-01-15 22:06:13 +13:00
level = QR_ECLEVEL_L;
2008-07-14 09:15:55 +12:00
if((security >= 1) && (security <= 4)) {
switch (security) {
case 1: level = QR_ECLEVEL_L; break;
case 2: level = QR_ECLEVEL_M; break;
case 3: level = QR_ECLEVEL_Q; break;
case 4: level = QR_ECLEVEL_H; break;
}
}
if((size >= 1) && (size <= 40)) {
version = size;
} else {
version = 0;
}
2009-08-09 03:25:17 +12:00
if(nullchar == '\0') {
/* No NULL characters in data */
code = QRcode_encodeString((char*)intext, version, level, hint, 1);
} else {
/* NULL characters in data */
code = QRcode_encodeString8bit((char*)intext, version, level, input_length);
}
2008-07-14 09:15:55 +12:00
return code;
}
int qr_code(struct zint_symbol *symbol, unsigned char source[])
{
QRcode *code;
/*int errno = 0;*/
2008-07-14 09:15:55 +12:00
int i, j;
2009-08-09 20:45:58 +12:00
int kanji, gs1;
2009-08-09 03:25:17 +12:00
int input_length;
char nullify;
2008-07-14 09:15:55 +12:00
2009-08-09 03:25:17 +12:00
input_length = ustrlen(source);
nullify = symbol->nullchar;
if((symbol->input_mode == KANJI_MODE) || (symbol->input_mode == SJIS_MODE)) { kanji = 1; } else { kanji = 0; }
2009-08-09 20:45:58 +12:00
if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; }
2009-08-09 03:25:17 +12:00
/* Null character handling */
j = 0;
if(nullify != '\0') {
for(i = 0; i < input_length; i++) {
if(source[i] == nullify) {
source[i] = '\0';
j++;
}
}
}
if(j == 0) {
/* nullchar was set but there are no NULL characters in the input data */
nullify = '\0';
}
2009-08-09 20:45:58 +12:00
code = encode(symbol->option_1, symbol->option_2, source, kanji, gs1, nullify, input_length);
2008-07-14 09:15:55 +12:00
if(code == NULL) {
strcpy(symbol->errtxt, "libqrencode failed to encode the input data");
2008-07-14 09:15:55 +12:00
return ERROR_ENCODING_PROBLEM;
}
symbol->width = code->width;
symbol->rows = code->width;
for(i = 0; i < code->width; i++) {
for(j = 0; j < code->width; j++) {
if((*(code->data + (i * code->width) + j) & 0x01) != 0) {
set_module(symbol, i, j);
2008-07-14 09:15:55 +12:00
}
}
symbol->row_height[i] = 1;
}
QRcode_free(code);
return 0;
2008-07-14 09:15:55 +12:00
}
2008-09-03 07:49:08 +12:00
#else
/* Handler if no QR Encode library is available */
int qr_code(struct zint_symbol *symbol, unsigned char source[])
{
strcpy(symbol->errtxt, "QR Code library <qrencode> not available");
2008-09-03 07:49:08 +12:00
return ERROR_INVALID_OPTION;
}
#endif