+49
-49
@@ -1,49 +1,49 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2013-04-25T18:27:50
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = 121
|
||||
TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES +=\
|
||||
bitstream.cpp \
|
||||
mask.cpp \
|
||||
qrenc.cpp \
|
||||
qrencode.cpp \
|
||||
qrinput.cpp \
|
||||
qrspec.cpp \
|
||||
rscode.cpp \
|
||||
split.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
bistream.h \
|
||||
mask.h \
|
||||
qrencode_inner.h \
|
||||
qrinput.h \
|
||||
qrspec.h \
|
||||
rscode.h \
|
||||
split.h \
|
||||
mainwindow.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unix:!macx: LIBS += -L$$PWD/../../../../../../../usr/local/lib/ -lqrencode
|
||||
|
||||
INCLUDEPATH += $$PWD/../../../../../../../usr/local/include
|
||||
DEPENDPATH += $$PWD/../../../../../../../usr/local/include
|
||||
|
||||
unix:!macx: LIBS += -lpng12
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2013-04-25T18:27:50
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = 121
|
||||
TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES +=\
|
||||
bitstream.cpp \
|
||||
mask.cpp \
|
||||
qrenc.cpp \
|
||||
qrencode.cpp \
|
||||
qrinput.cpp \
|
||||
qrspec.cpp \
|
||||
rscode.cpp \
|
||||
split.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
bistream.h \
|
||||
mask.h \
|
||||
qrencode_inner.h \
|
||||
qrinput.h \
|
||||
qrspec.h \
|
||||
rscode.h \
|
||||
split.h \
|
||||
mainwindow.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unix:!macx: LIBS += -L$$PWD/../../../../../../../usr/local/lib/ -lqrencode
|
||||
|
||||
INCLUDEPATH += $$PWD/../../../../../../../usr/local/include
|
||||
DEPENDPATH += $$PWD/../../../../../../../usr/local/include
|
||||
|
||||
unix:!macx: LIBS += -lpng12
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
+43
-43
@@ -1,43 +1,43 @@
|
||||
#ifndef BISTREAM_H
|
||||
#define BISTREAM_H
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __BITSTREAM_H__
|
||||
#define __BITSTREAM_H__
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
} BitStream;
|
||||
|
||||
extern BitStream *BitStream_new(void);
|
||||
extern void BitStream_append(BitStream *bstream, BitStream *arg);
|
||||
extern void BitStream_appendNum(BitStream *bstream, int bits, unsigned int num);
|
||||
extern void BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data);
|
||||
extern unsigned int BitStream_size(BitStream *bstream);
|
||||
extern unsigned char *BitStream_toByte(BitStream *bstream);
|
||||
extern void BitStream_free(BitStream *bstream);
|
||||
|
||||
#endif /* __BITSTREAM_H__ */
|
||||
|
||||
|
||||
#endif // BISTREAM_H
|
||||
#ifndef BISTREAM_H
|
||||
#define BISTREAM_H
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __BITSTREAM_H__
|
||||
#define __BITSTREAM_H__
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
} BitStream;
|
||||
|
||||
extern BitStream *BitStream_new(void);
|
||||
extern void BitStream_append(BitStream *bstream, BitStream *arg);
|
||||
extern void BitStream_appendNum(BitStream *bstream, int bits, unsigned int num);
|
||||
extern void BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data);
|
||||
extern unsigned int BitStream_size(BitStream *bstream);
|
||||
extern unsigned char *BitStream_toByte(BitStream *bstream);
|
||||
extern void BitStream_free(BitStream *bstream);
|
||||
|
||||
#endif /* __BITSTREAM_H__ */
|
||||
|
||||
|
||||
#endif // BISTREAM_H
|
||||
|
||||
+231
-231
@@ -1,231 +1,231 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bitstream.h"
|
||||
|
||||
#define DEFAULT_BUFSIZE (128)
|
||||
|
||||
BitStream *BitStream_new(void)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->length = 0;
|
||||
bstream->data = (unsigned char *)malloc(DEFAULT_BUFSIZE);
|
||||
if(bstream->data == NULL) {
|
||||
free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
bstream->datasize = DEFAULT_BUFSIZE;
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
BitStream *BitStream_newWithBits(size_t size, unsigned char *bits)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
if(size == 0) return BitStream_new();
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->data = (unsigned char *)malloc(size);
|
||||
if(bstream->data == NULL) {
|
||||
free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bstream->length = size;
|
||||
bstream->datasize = size;
|
||||
memcpy(bstream->data, bits, size);
|
||||
|
||||
return bstream;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int BitStream_expand(BitStream *bstream)
|
||||
{
|
||||
unsigned char *data;
|
||||
|
||||
data = (unsigned char *)realloc(bstream->data, bstream->datasize * 2);
|
||||
if(data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bstream->data = data;
|
||||
bstream->datasize *= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num)
|
||||
{
|
||||
unsigned int mask;
|
||||
size_t i;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
mask = 1U << (bits - 1);
|
||||
for(i = 0; i < bits; i++) {
|
||||
if(num & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
size_t i, j;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
for(i = 0; i < size; i++) {
|
||||
mask = 0x80;
|
||||
for(j = 0; j < 8; j++) {
|
||||
if(data[i] & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BitStream_append(BitStream *bstream, BitStream *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(arg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(arg->length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(bstream->length + arg->length > bstream->datasize) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
|
||||
memcpy(bstream->data + bstream->length, arg->data, arg->length);
|
||||
bstream->length += arg->length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(bits == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < bits) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeNum(bstream->data + bstream->length, bits, num);
|
||||
bstream->length += bits;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(size == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < size * 8) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeBytes(bstream->data + bstream->length, size, data);
|
||||
bstream->length += size * 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *BitStream_toByte(BitStream *bstream)
|
||||
{
|
||||
size_t i, j, size, bytes, oddbits;
|
||||
unsigned char *data, v;
|
||||
unsigned char *p;
|
||||
|
||||
size = BitStream_size(bstream);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
data = (unsigned char *)malloc((size + 7) / 8);
|
||||
if(data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = size / 8;
|
||||
|
||||
p = bstream->data;
|
||||
for(i = 0; i < bytes; i++) {
|
||||
v = 0;
|
||||
for(j = 0; j < 8; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[i] = v;
|
||||
}
|
||||
oddbits = size & 7;
|
||||
if(oddbits > 0) {
|
||||
v = 0;
|
||||
for(j = 0; j < oddbits; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[bytes] = (unsigned char)(v << (8 - oddbits));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void BitStream_free(BitStream *bstream)
|
||||
{
|
||||
if(bstream != NULL) {
|
||||
free(bstream->data);
|
||||
free(bstream);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bitstream.h"
|
||||
|
||||
#define DEFAULT_BUFSIZE (128)
|
||||
|
||||
BitStream *BitStream_new(void)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->length = 0;
|
||||
bstream->data = (unsigned char *)malloc(DEFAULT_BUFSIZE);
|
||||
if(bstream->data == NULL) {
|
||||
free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
bstream->datasize = DEFAULT_BUFSIZE;
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
BitStream *BitStream_newWithBits(size_t size, unsigned char *bits)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
if(size == 0) return BitStream_new();
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
if(bstream == NULL) return NULL;
|
||||
|
||||
bstream->data = (unsigned char *)malloc(size);
|
||||
if(bstream->data == NULL) {
|
||||
free(bstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bstream->length = size;
|
||||
bstream->datasize = size;
|
||||
memcpy(bstream->data, bits, size);
|
||||
|
||||
return bstream;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int BitStream_expand(BitStream *bstream)
|
||||
{
|
||||
unsigned char *data;
|
||||
|
||||
data = (unsigned char *)realloc(bstream->data, bstream->datasize * 2);
|
||||
if(data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bstream->data = data;
|
||||
bstream->datasize *= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num)
|
||||
{
|
||||
unsigned int mask;
|
||||
size_t i;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
mask = 1U << (bits - 1);
|
||||
for(i = 0; i < bits; i++) {
|
||||
if(num & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
size_t i, j;
|
||||
unsigned char *p;
|
||||
|
||||
p = dest;
|
||||
for(i = 0; i < size; i++) {
|
||||
mask = 0x80;
|
||||
for(j = 0; j < 8; j++) {
|
||||
if(data[i] & mask) {
|
||||
*p = 1;
|
||||
} else {
|
||||
*p = 0;
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BitStream_append(BitStream *bstream, BitStream *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(arg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(arg->length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(bstream->length + arg->length > bstream->datasize) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
|
||||
memcpy(bstream->data + bstream->length, arg->data, arg->length);
|
||||
bstream->length += arg->length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(bits == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < bits) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeNum(bstream->data + bstream->length, bits, num);
|
||||
bstream->length += bits;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(size == 0) return 0;
|
||||
|
||||
while(bstream->datasize - bstream->length < size * 8) {
|
||||
ret = BitStream_expand(bstream);
|
||||
if(ret < 0) return ret;
|
||||
}
|
||||
BitStream_writeBytes(bstream->data + bstream->length, size, data);
|
||||
bstream->length += size * 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *BitStream_toByte(BitStream *bstream)
|
||||
{
|
||||
size_t i, j, size, bytes, oddbits;
|
||||
unsigned char *data, v;
|
||||
unsigned char *p;
|
||||
|
||||
size = BitStream_size(bstream);
|
||||
if(size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
data = (unsigned char *)malloc((size + 7) / 8);
|
||||
if(data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = size / 8;
|
||||
|
||||
p = bstream->data;
|
||||
for(i = 0; i < bytes; i++) {
|
||||
v = 0;
|
||||
for(j = 0; j < 8; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[i] = v;
|
||||
}
|
||||
oddbits = size & 7;
|
||||
if(oddbits > 0) {
|
||||
v = 0;
|
||||
for(j = 0; j < oddbits; j++) {
|
||||
v = (unsigned char)(v << 1);
|
||||
v |= *p;
|
||||
p++;
|
||||
}
|
||||
data[bytes] = (unsigned char)(v << (8 - oddbits));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void BitStream_free(BitStream *bstream)
|
||||
{
|
||||
if(bstream != NULL) {
|
||||
free(bstream->data);
|
||||
free(bstream);
|
||||
}
|
||||
}
|
||||
|
||||
+180
-180
@@ -1,180 +1,180 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bistream.h"
|
||||
|
||||
BitStream *BitStream_new(void)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
bstream->data = NULL;
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
static BitStream *BitStream_newFromNum(int bits, unsigned int num)
|
||||
{
|
||||
unsigned int mask;
|
||||
int i;
|
||||
char *p;
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = BitStream_new();
|
||||
bstream->data = (char *)malloc(bits + 1);
|
||||
|
||||
p = bstream->data;
|
||||
mask = 1 << (bits - 1);
|
||||
for(i=0; i<bits; i++) {
|
||||
if(num & mask) {
|
||||
*p = '1';
|
||||
} else {
|
||||
*p = '0';
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
static BitStream *BitStream_newFromBytes(int size, unsigned char *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
int i, j;
|
||||
char *p;
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = BitStream_new();
|
||||
bstream->data = (char *)malloc(size * 8 + 1);
|
||||
|
||||
p = bstream->data;
|
||||
for(i=0; i<size; i++) {
|
||||
mask = 0x80;
|
||||
for(j=0; j<8; j++) {
|
||||
if(data[i] & mask) {
|
||||
*p = '1';
|
||||
} else {
|
||||
*p = '0';
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
void BitStream_append(BitStream *bstream, BitStream *arg)
|
||||
{
|
||||
int l1, l2;
|
||||
char *_new;
|
||||
|
||||
if(arg == NULL || arg->data == NULL) {
|
||||
return;
|
||||
}
|
||||
if(bstream->data == NULL) {
|
||||
bstream->data = strdup(arg->data);
|
||||
return;
|
||||
}
|
||||
|
||||
l1 = strlen(bstream->data);
|
||||
l2 = strlen(arg->data);
|
||||
_new = (char *)malloc(l1 + l2 + 1);
|
||||
strcpy(_new, bstream->data);
|
||||
strcat(_new, arg->data);
|
||||
|
||||
free(bstream->data);
|
||||
bstream->data = _new;
|
||||
}
|
||||
|
||||
void BitStream_appendNum(BitStream *bstream, int bits, unsigned int num)
|
||||
{
|
||||
BitStream *b;
|
||||
|
||||
b = BitStream_newFromNum(bits, num);
|
||||
BitStream_append(bstream, b);
|
||||
BitStream_free(b);
|
||||
}
|
||||
|
||||
void BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data)
|
||||
{
|
||||
BitStream *b;
|
||||
|
||||
b = BitStream_newFromBytes(size, data);
|
||||
BitStream_append(bstream, b);
|
||||
BitStream_free(b);
|
||||
}
|
||||
|
||||
unsigned int BitStream_size(BitStream *bstream)
|
||||
{
|
||||
if(bstream->data == NULL) return 0;
|
||||
|
||||
return strlen(bstream->data);
|
||||
}
|
||||
|
||||
unsigned char *BitStream_toByte(BitStream *bstream)
|
||||
{
|
||||
int i, j, size, bytes;
|
||||
unsigned char *data, v;
|
||||
char *p;
|
||||
|
||||
size = BitStream_size(bstream);
|
||||
data = (unsigned char *)malloc((size + 7) / 8);
|
||||
bytes = size / 8;
|
||||
|
||||
p = bstream->data;
|
||||
for(i=0; i<bytes; i++) {
|
||||
v = 0;
|
||||
for(j=0; j<8; j++) {
|
||||
v = v << 1;
|
||||
v |= *p == '1';
|
||||
p++;
|
||||
}
|
||||
data[i] = v;
|
||||
}
|
||||
if(size & 7) {
|
||||
v = 0;
|
||||
for(j=0; j<(size & 7); j++) {
|
||||
v = v << 1;
|
||||
v |= *p == '1';
|
||||
p++;
|
||||
}
|
||||
data[bytes] = v;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void BitStream_free(BitStream *bstream)
|
||||
{
|
||||
if(bstream->data != NULL) {
|
||||
free(bstream->data);
|
||||
}
|
||||
free(bstream);
|
||||
}
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bistream.h"
|
||||
|
||||
BitStream *BitStream_new(void)
|
||||
{
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = (BitStream *)malloc(sizeof(BitStream));
|
||||
bstream->data = NULL;
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
static BitStream *BitStream_newFromNum(int bits, unsigned int num)
|
||||
{
|
||||
unsigned int mask;
|
||||
int i;
|
||||
char *p;
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = BitStream_new();
|
||||
bstream->data = (char *)malloc(bits + 1);
|
||||
|
||||
p = bstream->data;
|
||||
mask = 1 << (bits - 1);
|
||||
for(i=0; i<bits; i++) {
|
||||
if(num & mask) {
|
||||
*p = '1';
|
||||
} else {
|
||||
*p = '0';
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
static BitStream *BitStream_newFromBytes(int size, unsigned char *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
int i, j;
|
||||
char *p;
|
||||
BitStream *bstream;
|
||||
|
||||
bstream = BitStream_new();
|
||||
bstream->data = (char *)malloc(size * 8 + 1);
|
||||
|
||||
p = bstream->data;
|
||||
for(i=0; i<size; i++) {
|
||||
mask = 0x80;
|
||||
for(j=0; j<8; j++) {
|
||||
if(data[i] & mask) {
|
||||
*p = '1';
|
||||
} else {
|
||||
*p = '0';
|
||||
}
|
||||
p++;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return bstream;
|
||||
}
|
||||
|
||||
void BitStream_append(BitStream *bstream, BitStream *arg)
|
||||
{
|
||||
int l1, l2;
|
||||
char *_new;
|
||||
|
||||
if(arg == NULL || arg->data == NULL) {
|
||||
return;
|
||||
}
|
||||
if(bstream->data == NULL) {
|
||||
bstream->data = strdup(arg->data);
|
||||
return;
|
||||
}
|
||||
|
||||
l1 = strlen(bstream->data);
|
||||
l2 = strlen(arg->data);
|
||||
_new = (char *)malloc(l1 + l2 + 1);
|
||||
strcpy(_new, bstream->data);
|
||||
strcat(_new, arg->data);
|
||||
|
||||
free(bstream->data);
|
||||
bstream->data = _new;
|
||||
}
|
||||
|
||||
void BitStream_appendNum(BitStream *bstream, int bits, unsigned int num)
|
||||
{
|
||||
BitStream *b;
|
||||
|
||||
b = BitStream_newFromNum(bits, num);
|
||||
BitStream_append(bstream, b);
|
||||
BitStream_free(b);
|
||||
}
|
||||
|
||||
void BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data)
|
||||
{
|
||||
BitStream *b;
|
||||
|
||||
b = BitStream_newFromBytes(size, data);
|
||||
BitStream_append(bstream, b);
|
||||
BitStream_free(b);
|
||||
}
|
||||
|
||||
unsigned int BitStream_size(BitStream *bstream)
|
||||
{
|
||||
if(bstream->data == NULL) return 0;
|
||||
|
||||
return strlen(bstream->data);
|
||||
}
|
||||
|
||||
unsigned char *BitStream_toByte(BitStream *bstream)
|
||||
{
|
||||
int i, j, size, bytes;
|
||||
unsigned char *data, v;
|
||||
char *p;
|
||||
|
||||
size = BitStream_size(bstream);
|
||||
data = (unsigned char *)malloc((size + 7) / 8);
|
||||
bytes = size / 8;
|
||||
|
||||
p = bstream->data;
|
||||
for(i=0; i<bytes; i++) {
|
||||
v = 0;
|
||||
for(j=0; j<8; j++) {
|
||||
v = v << 1;
|
||||
v |= *p == '1';
|
||||
p++;
|
||||
}
|
||||
data[i] = v;
|
||||
}
|
||||
if(size & 7) {
|
||||
v = 0;
|
||||
for(j=0; j<(size & 7); j++) {
|
||||
v = v << 1;
|
||||
v |= *p == '1';
|
||||
p++;
|
||||
}
|
||||
data[bytes] = v;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void BitStream_free(BitStream *bstream)
|
||||
{
|
||||
if(bstream->data != NULL) {
|
||||
free(bstream->data);
|
||||
}
|
||||
free(bstream);
|
||||
}
|
||||
|
||||
|
||||
+43
-43
@@ -1,43 +1,43 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
typedef struct {
|
||||
size_t length;
|
||||
size_t datasize;
|
||||
unsigned char *data;
|
||||
} BitStream;
|
||||
|
||||
extern BitStream *BitStream_new(void);
|
||||
#ifdef WITH_TESTS
|
||||
extern BitStream *BitStream_newWithBits(size_t size, unsigned char *bits);
|
||||
#endif
|
||||
extern int BitStream_append(BitStream *bstream, BitStream *arg);
|
||||
extern int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num);
|
||||
extern int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data);
|
||||
#define BitStream_size(__bstream__) (__bstream__->length)
|
||||
#define BitStream_reset(__bstream__) (__bstream__->length = 0)
|
||||
extern unsigned char *BitStream_toByte(BitStream *bstream);
|
||||
extern void BitStream_free(BitStream *bstream);
|
||||
|
||||
#endif /* BITSTREAM_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Binary sequence class.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
typedef struct {
|
||||
size_t length;
|
||||
size_t datasize;
|
||||
unsigned char *data;
|
||||
} BitStream;
|
||||
|
||||
extern BitStream *BitStream_new(void);
|
||||
#ifdef WITH_TESTS
|
||||
extern BitStream *BitStream_newWithBits(size_t size, unsigned char *bits);
|
||||
#endif
|
||||
extern int BitStream_append(BitStream *bstream, BitStream *arg);
|
||||
extern int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num);
|
||||
extern int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data);
|
||||
#define BitStream_size(__bstream__) (__bstream__->length)
|
||||
#define BitStream_reset(__bstream__) (__bstream__->length = 0)
|
||||
extern unsigned char *BitStream_toByte(BitStream *bstream);
|
||||
extern void BitStream_free(BitStream *bstream);
|
||||
|
||||
#endif /* BITSTREAM_H */
|
||||
|
||||
+19
-19
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>662</width>
|
||||
<height>388</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>662</width>
|
||||
<height>388</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
|
||||
|
||||
|
||||
+25
-25
@@ -1,25 +1,25 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_pushButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_pushButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
+173
-173
@@ -1,173 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>435</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>350</y>
|
||||
<width>99</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>encode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>290</y>
|
||||
<width>541</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>270</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Message</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBox_size">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>450</x>
|
||||
<y>240</y>
|
||||
<width>85</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBox_level">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>240</y>
|
||||
<width>85</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>L</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>M</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>H</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Q</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>370</x>
|
||||
<y>240</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>230</x>
|
||||
<y>250</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>level:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labQRImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>10</y>
|
||||
<width>431</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>435</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>350</y>
|
||||
<width>99</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>encode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>290</y>
|
||||
<width>541</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>270</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Message</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBox_size">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>450</x>
|
||||
<y>240</y>
|
||||
<width>85</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBox_level">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>240</y>
|
||||
<width>85</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>L</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>M</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>H</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Q</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>370</x>
|
||||
<y>240</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>230</x>
|
||||
<y>250</y>
|
||||
<width>67</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>level:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labQRImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>10</y>
|
||||
<width>431</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
+357
-357
@@ -1,357 +1,357 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrspec.h"
|
||||
#include "mask.h"
|
||||
|
||||
STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
int blacks = 0;
|
||||
|
||||
format = QRspec_getFormatInfo(mask, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * 8 + width - 1 - i] = v;
|
||||
if(i < 6) {
|
||||
frame[width * i + 8] = v;
|
||||
} else {
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * (width - 7 + i) + 8] = v;
|
||||
if(i == 0) {
|
||||
frame[width * 8 + 7] = v;
|
||||
} else {
|
||||
frame[width * 8 + 6 - i] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
|
||||
return blacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demerit coefficients.
|
||||
* See Section 8.8.2, pp.45, JIS X0510:2004.
|
||||
*/
|
||||
#define N1 (3)
|
||||
#define N2 (3)
|
||||
#define N3 (40)
|
||||
#define N4 (10)
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
int b = 0;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
b += (int)(*d & 1);\
|
||||
s++; d++;\
|
||||
}\
|
||||
}\
|
||||
return b;
|
||||
|
||||
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(x%3)
|
||||
}
|
||||
|
||||
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((x*y)&1)+(x*y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
|
||||
}
|
||||
|
||||
#define maskNum (8)
|
||||
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
|
||||
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
Mask_writeFormatInformation(width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
|
||||
//static int n1;
|
||||
//static int n2;
|
||||
//static int n3;
|
||||
//static int n4;
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
|
||||
{
|
||||
int i;
|
||||
int demerit = 0;
|
||||
int fact;
|
||||
|
||||
for(i = 0; i < length; i++) {
|
||||
if(runLength[i] >= 5) {
|
||||
demerit += N1 + (runLength[i] - 5);
|
||||
//n1 += N1 + (runLength[i] - 5);
|
||||
}
|
||||
if((i & 1)) {
|
||||
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
|
||||
fact = runLength[i] / 3;
|
||||
if(runLength[i-2] == fact &&
|
||||
runLength[i-1] == fact &&
|
||||
runLength[i+1] == fact &&
|
||||
runLength[i+2] == fact) {
|
||||
if(i == 3 || runLength[i-3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
} else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
unsigned char b22, w22;
|
||||
int demerit = 0;
|
||||
|
||||
p = frame + width + 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
for(x = 1; x < width; x++) {
|
||||
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
|
||||
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
|
||||
if((b22 | (w22 ^ 1))&1) {
|
||||
demerit += N2;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i * width] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i * width];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
int demerit = 0;
|
||||
int runLength[QRSPEC_WIDTH_MAX + 1];
|
||||
int length;
|
||||
|
||||
demerit += Mask_calcN2(width, frame);
|
||||
|
||||
for(y = 0; y < width; y++) {
|
||||
length = Mask_calcRunLengthH(width, frame + y * width, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
for(x = 0; x < width; x++) {
|
||||
length = Mask_calcRunLengthV(width, frame + x, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int minDemerit = INT_MAX;
|
||||
int blacks;
|
||||
int bratio;
|
||||
int demerit;
|
||||
int w2 = width * width;
|
||||
|
||||
mask = (unsigned char *)malloc((size_t)w2);
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = (unsigned char *)malloc((size_t)w2);
|
||||
if(bestMask == NULL) {
|
||||
free(mask);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
// n1 = n2 = n3 = n4 = 0;
|
||||
demerit = 0;
|
||||
blacks = maskMakers[i](width, frame, mask);
|
||||
blacks += Mask_writeFormatInformation(width, mask, i, level);
|
||||
bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
|
||||
demerit = (abs(bratio - 50) / 5) * N4;
|
||||
// n4 = demerit;
|
||||
demerit += Mask_evaluateSymbol(width, mask);
|
||||
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
|
||||
if(demerit < minDemerit) {
|
||||
minDemerit = demerit;
|
||||
memcpy(bestMask, mask, (size_t)w2);
|
||||
}
|
||||
}
|
||||
free(mask);
|
||||
return bestMask;
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrspec.h"
|
||||
#include "mask.h"
|
||||
|
||||
STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
int blacks = 0;
|
||||
|
||||
format = QRspec_getFormatInfo(mask, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * 8 + width - 1 - i] = v;
|
||||
if(i < 6) {
|
||||
frame[width * i + 8] = v;
|
||||
} else {
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * (width - 7 + i) + 8] = v;
|
||||
if(i == 0) {
|
||||
frame[width * 8 + 7] = v;
|
||||
} else {
|
||||
frame[width * 8 + 6 - i] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
|
||||
return blacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demerit coefficients.
|
||||
* See Section 8.8.2, pp.45, JIS X0510:2004.
|
||||
*/
|
||||
#define N1 (3)
|
||||
#define N2 (3)
|
||||
#define N3 (40)
|
||||
#define N4 (10)
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
int b = 0;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
b += (int)(*d & 1);\
|
||||
s++; d++;\
|
||||
}\
|
||||
}\
|
||||
return b;
|
||||
|
||||
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(x%3)
|
||||
}
|
||||
|
||||
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((x*y)&1)+(x*y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
|
||||
}
|
||||
|
||||
#define maskNum (8)
|
||||
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
|
||||
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
Mask_writeFormatInformation(width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
|
||||
//static int n1;
|
||||
//static int n2;
|
||||
//static int n3;
|
||||
//static int n4;
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
|
||||
{
|
||||
int i;
|
||||
int demerit = 0;
|
||||
int fact;
|
||||
|
||||
for(i = 0; i < length; i++) {
|
||||
if(runLength[i] >= 5) {
|
||||
demerit += N1 + (runLength[i] - 5);
|
||||
//n1 += N1 + (runLength[i] - 5);
|
||||
}
|
||||
if((i & 1)) {
|
||||
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
|
||||
fact = runLength[i] / 3;
|
||||
if(runLength[i-2] == fact &&
|
||||
runLength[i-1] == fact &&
|
||||
runLength[i+1] == fact &&
|
||||
runLength[i+2] == fact) {
|
||||
if(i == 3 || runLength[i-3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
} else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
unsigned char b22, w22;
|
||||
int demerit = 0;
|
||||
|
||||
p = frame + width + 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
for(x = 1; x < width; x++) {
|
||||
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
|
||||
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
|
||||
if((b22 | (w22 ^ 1))&1) {
|
||||
demerit += N2;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
|
||||
{
|
||||
int head;
|
||||
int i;
|
||||
unsigned char prev;
|
||||
|
||||
if(frame[0] & 1) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
} else {
|
||||
head = 0;
|
||||
}
|
||||
runLength[head] = 1;
|
||||
prev = frame[0];
|
||||
|
||||
for(i = 1; i < width; i++) {
|
||||
if((frame[i * width] ^ prev) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
prev = frame[i * width];
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
|
||||
return head + 1;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
int demerit = 0;
|
||||
int runLength[QRSPEC_WIDTH_MAX + 1];
|
||||
int length;
|
||||
|
||||
demerit += Mask_calcN2(width, frame);
|
||||
|
||||
for(y = 0; y < width; y++) {
|
||||
length = Mask_calcRunLengthH(width, frame + y * width, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
for(x = 0; x < width; x++) {
|
||||
length = Mask_calcRunLengthV(width, frame + x, runLength);
|
||||
demerit += Mask_calcN1N3(length, runLength);
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int minDemerit = INT_MAX;
|
||||
int blacks;
|
||||
int bratio;
|
||||
int demerit;
|
||||
int w2 = width * width;
|
||||
|
||||
mask = (unsigned char *)malloc((size_t)w2);
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = (unsigned char *)malloc((size_t)w2);
|
||||
if(bestMask == NULL) {
|
||||
free(mask);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
// n1 = n2 = n3 = n4 = 0;
|
||||
demerit = 0;
|
||||
blacks = maskMakers[i](width, frame, mask);
|
||||
blacks += Mask_writeFormatInformation(width, mask, i, level);
|
||||
bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
|
||||
demerit = (abs(bratio - 50) / 5) * N4;
|
||||
// n4 = demerit;
|
||||
demerit += Mask_evaluateSymbol(width, mask);
|
||||
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
|
||||
if(demerit < minDemerit) {
|
||||
minDemerit = demerit;
|
||||
memcpy(bestMask, mask, (size_t)w2);
|
||||
}
|
||||
}
|
||||
free(mask);
|
||||
return bestMask;
|
||||
}
|
||||
|
||||
+257
-257
@@ -1,257 +1,257 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "qrencode.h"
|
||||
#include "qrencode_inner.h"
|
||||
#include "qrspec.h"
|
||||
#include "mask.h"
|
||||
|
||||
/**
|
||||
* Demerit coefficients.
|
||||
* See Section 8.8.2, pp.45, JIS X0510:2004.
|
||||
*/
|
||||
#define N1 (3)
|
||||
#define N2 (3)
|
||||
#define N3 (40)
|
||||
#define N4 (10)
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
unsigned int b = 0;\
|
||||
\
|
||||
for(y=0; y<width; y++) {\
|
||||
for(x=0; x<width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
b += (*d & 1);\
|
||||
s++; d++;\
|
||||
}\
|
||||
}\
|
||||
return b;
|
||||
|
||||
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(x%3)
|
||||
}
|
||||
|
||||
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((x*y)&1)+(x*y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
|
||||
}
|
||||
|
||||
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
|
||||
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
|
||||
};
|
||||
|
||||
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc(width * width);
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
static int runLength[QRSPEC_WIDTH_MAX + 1];
|
||||
|
||||
//static int n1;
|
||||
//static int n2;
|
||||
//static int n3;
|
||||
//static int n4;
|
||||
|
||||
static int Mask_calcN1N3(int length, int *runLength)
|
||||
{
|
||||
int i;
|
||||
int demerit = 0;
|
||||
int fact;
|
||||
|
||||
for(i=0; i<length; i++) {
|
||||
if(runLength[i] >= 5) {
|
||||
demerit += N1 + (runLength[i] - 5);
|
||||
//n1 += N1 + (runLength[i] - 5);
|
||||
}
|
||||
if((i & 1)) {
|
||||
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
|
||||
fact = runLength[i] / 3;
|
||||
if(runLength[i-2] == fact &&
|
||||
runLength[i-1] == fact &&
|
||||
runLength[i+1] == fact &&
|
||||
runLength[i+2] == fact) {
|
||||
if(runLength[i-3] < 0 || runLength[i-3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
} else if(i+3 >= length || runLength[i+3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
int Mask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
unsigned char b22, w22;
|
||||
unsigned int i;
|
||||
int head;
|
||||
int demerit = 0;
|
||||
|
||||
p = frame;
|
||||
i = 0;
|
||||
for(y=0; y<width; y++) {
|
||||
head = 0;
|
||||
runLength[0] = 1;
|
||||
for(x=0; x<width; x++) {
|
||||
if(x > 0 && y > 0) {
|
||||
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
|
||||
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
|
||||
if((b22 | (w22 ^ 1))&1) {
|
||||
demerit += N2;
|
||||
}
|
||||
}
|
||||
if(x == 0 && (p[0] & 1)) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
runLength[head] = 1;
|
||||
} else if(x > 0) {
|
||||
if((p[0] ^ p[-1]) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
demerit += Mask_calcN1N3(head+1, runLength);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for(x=0; x<width; x++) {
|
||||
head = 0;
|
||||
runLength[0] = 1;
|
||||
p = frame + x;
|
||||
for(y=0; y<width; y++) {
|
||||
if(y == 0 && (p[0] & 1)) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
runLength[head] = 1;
|
||||
} else if(y > 0) {
|
||||
if((p[0] ^ p[-width]) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
p+=width;
|
||||
}
|
||||
demerit += Mask_calcN1N3(head+1, runLength);
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int minDemerit = INT_MAX;
|
||||
int bestMaskNum = 0;
|
||||
int blacks;
|
||||
int demerit;
|
||||
|
||||
bestMask = NULL;
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
// n1 = n2 = n3 = n4 = 0;
|
||||
demerit = 0;
|
||||
mask = (unsigned char *)malloc(width * width);
|
||||
blacks = maskMakers[i](width, frame, mask);
|
||||
blacks += QRcode_writeFormatInformation(width, mask, i, level);
|
||||
blacks = 100 * blacks / (width * width);
|
||||
demerit = (abs(blacks - 50) / 5) * N4;
|
||||
// n4 = demerit;
|
||||
if(demerit > minDemerit) {
|
||||
free(mask);
|
||||
continue;
|
||||
}
|
||||
demerit += Mask_evaluateSymbol(width, mask);
|
||||
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
|
||||
if(demerit < minDemerit) {
|
||||
minDemerit = demerit;
|
||||
bestMaskNum = i;
|
||||
if(bestMask != NULL) {
|
||||
free(bestMask);
|
||||
}
|
||||
bestMask = mask;
|
||||
} else {
|
||||
free(mask);
|
||||
}
|
||||
}
|
||||
|
||||
return bestMask;
|
||||
}
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "qrencode.h"
|
||||
#include "qrencode_inner.h"
|
||||
#include "qrspec.h"
|
||||
#include "mask.h"
|
||||
|
||||
/**
|
||||
* Demerit coefficients.
|
||||
* See Section 8.8.2, pp.45, JIS X0510:2004.
|
||||
*/
|
||||
#define N1 (3)
|
||||
#define N2 (3)
|
||||
#define N3 (40)
|
||||
#define N4 (10)
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
unsigned int b = 0;\
|
||||
\
|
||||
for(y=0; y<width; y++) {\
|
||||
for(x=0; x<width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
b += (*d & 1);\
|
||||
s++; d++;\
|
||||
}\
|
||||
}\
|
||||
return b;
|
||||
|
||||
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(x%3)
|
||||
}
|
||||
|
||||
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((x+y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((x*y)&1)+(x*y)%3)
|
||||
}
|
||||
|
||||
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
|
||||
}
|
||||
|
||||
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
|
||||
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
|
||||
};
|
||||
|
||||
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc(width * width);
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
static int runLength[QRSPEC_WIDTH_MAX + 1];
|
||||
|
||||
//static int n1;
|
||||
//static int n2;
|
||||
//static int n3;
|
||||
//static int n4;
|
||||
|
||||
static int Mask_calcN1N3(int length, int *runLength)
|
||||
{
|
||||
int i;
|
||||
int demerit = 0;
|
||||
int fact;
|
||||
|
||||
for(i=0; i<length; i++) {
|
||||
if(runLength[i] >= 5) {
|
||||
demerit += N1 + (runLength[i] - 5);
|
||||
//n1 += N1 + (runLength[i] - 5);
|
||||
}
|
||||
if((i & 1)) {
|
||||
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
|
||||
fact = runLength[i] / 3;
|
||||
if(runLength[i-2] == fact &&
|
||||
runLength[i-1] == fact &&
|
||||
runLength[i+1] == fact &&
|
||||
runLength[i+2] == fact) {
|
||||
if(runLength[i-3] < 0 || runLength[i-3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
} else if(i+3 >= length || runLength[i+3] >= 4 * fact) {
|
||||
demerit += N3;
|
||||
//n3 += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
int Mask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
unsigned char b22, w22;
|
||||
unsigned int i;
|
||||
int head;
|
||||
int demerit = 0;
|
||||
|
||||
p = frame;
|
||||
i = 0;
|
||||
for(y=0; y<width; y++) {
|
||||
head = 0;
|
||||
runLength[0] = 1;
|
||||
for(x=0; x<width; x++) {
|
||||
if(x > 0 && y > 0) {
|
||||
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
|
||||
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
|
||||
if((b22 | (w22 ^ 1))&1) {
|
||||
demerit += N2;
|
||||
}
|
||||
}
|
||||
if(x == 0 && (p[0] & 1)) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
runLength[head] = 1;
|
||||
} else if(x > 0) {
|
||||
if((p[0] ^ p[-1]) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
demerit += Mask_calcN1N3(head+1, runLength);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for(x=0; x<width; x++) {
|
||||
head = 0;
|
||||
runLength[0] = 1;
|
||||
p = frame + x;
|
||||
for(y=0; y<width; y++) {
|
||||
if(y == 0 && (p[0] & 1)) {
|
||||
runLength[0] = -1;
|
||||
head = 1;
|
||||
runLength[head] = 1;
|
||||
} else if(y > 0) {
|
||||
if((p[0] ^ p[-width]) & 1) {
|
||||
head++;
|
||||
runLength[head] = 1;
|
||||
} else {
|
||||
runLength[head]++;
|
||||
}
|
||||
}
|
||||
p+=width;
|
||||
}
|
||||
demerit += Mask_calcN1N3(head+1, runLength);
|
||||
}
|
||||
|
||||
return demerit;
|
||||
}
|
||||
|
||||
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int minDemerit = INT_MAX;
|
||||
int bestMaskNum = 0;
|
||||
int blacks;
|
||||
int demerit;
|
||||
|
||||
bestMask = NULL;
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
// n1 = n2 = n3 = n4 = 0;
|
||||
demerit = 0;
|
||||
mask = (unsigned char *)malloc(width * width);
|
||||
blacks = maskMakers[i](width, frame, mask);
|
||||
blacks += QRcode_writeFormatInformation(width, mask, i, level);
|
||||
blacks = 100 * blacks / (width * width);
|
||||
demerit = (abs(blacks - 50) / 5) * N4;
|
||||
// n4 = demerit;
|
||||
if(demerit > minDemerit) {
|
||||
free(mask);
|
||||
continue;
|
||||
}
|
||||
demerit += Mask_evaluateSymbol(width, mask);
|
||||
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
|
||||
if(demerit < minDemerit) {
|
||||
minDemerit = demerit;
|
||||
bestMaskNum = i;
|
||||
if(bestMask != NULL) {
|
||||
free(bestMask);
|
||||
}
|
||||
bestMask = mask;
|
||||
} else {
|
||||
free(mask);
|
||||
}
|
||||
}
|
||||
|
||||
return bestMask;
|
||||
}
|
||||
|
||||
|
||||
+38
-38
@@ -1,38 +1,38 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MASK_H
|
||||
#define MASK_H
|
||||
|
||||
extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int Mask_calcN2(int width, unsigned char *frame);
|
||||
extern int Mask_calcN1N3(int length, int *runLength);
|
||||
extern int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MASK_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MASK_H
|
||||
#define MASK_H
|
||||
|
||||
extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int Mask_calcN2(int width, unsigned char *frame);
|
||||
extern int Mask_calcN1N3(int length, int *runLength);
|
||||
extern int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength);
|
||||
extern int Mask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MASK_H */
|
||||
|
||||
+177
-177
@@ -1,177 +1,177 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "mqrspec.h"
|
||||
#include "mmask.h"
|
||||
|
||||
STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
|
||||
format = MQRspec_getFormatInfo(mask, version, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * 8 + 7 - i] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
s++; d++;\
|
||||
}\
|
||||
}
|
||||
|
||||
static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x+y)&1)+((x*y)%3))&1)
|
||||
}
|
||||
|
||||
#define maskNum (4)
|
||||
typedef void MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
int width;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
MMask_writeFormatInformation(version, width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
int sum1 = 0, sum2 = 0;
|
||||
|
||||
p = frame + width * (width - 1);
|
||||
for(x = 1; x < width; x++) {
|
||||
sum1 += (p[x] & 1);
|
||||
}
|
||||
|
||||
p = frame + width * 2 - 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
sum2 += (*p & 1);
|
||||
p += width;
|
||||
}
|
||||
|
||||
return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
|
||||
}
|
||||
|
||||
unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int maxScore = 0;
|
||||
int score;
|
||||
int width;
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
|
||||
mask = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = NULL;
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
score = 0;
|
||||
maskMakers[i](width, frame, mask);
|
||||
MMask_writeFormatInformation(version, width, mask, i, level);
|
||||
score = MMask_evaluateSymbol(width, mask);
|
||||
if(score > maxScore) {
|
||||
maxScore = score;
|
||||
free(bestMask);
|
||||
bestMask = mask;
|
||||
mask = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(mask == NULL) break;
|
||||
}
|
||||
}
|
||||
free(mask);
|
||||
return bestMask;
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "mqrspec.h"
|
||||
#include "mmask.h"
|
||||
|
||||
STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
|
||||
format = MQRspec_getFormatInfo(mask, version, level);
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
for(i = 0; i < 7; i++) {
|
||||
v = 0x84 | (format & 1);
|
||||
frame[width * 8 + 7 - i] = v;
|
||||
format = format >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define MASKMAKER(__exp__) \
|
||||
int x, y;\
|
||||
\
|
||||
for(y = 0; y < width; y++) {\
|
||||
for(x = 0; x < width; x++) {\
|
||||
if(*s & 0x80) {\
|
||||
*d = *s;\
|
||||
} else {\
|
||||
*d = *s ^ ((__exp__) == 0);\
|
||||
}\
|
||||
s++; d++;\
|
||||
}\
|
||||
}
|
||||
|
||||
static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(y&1)
|
||||
}
|
||||
|
||||
static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER(((y/2)+(x/3))&1)
|
||||
}
|
||||
|
||||
static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
|
||||
}
|
||||
|
||||
static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
|
||||
{
|
||||
MASKMAKER((((x+y)&1)+((x*y)%3))&1)
|
||||
}
|
||||
|
||||
#define maskNum (4)
|
||||
typedef void MaskMaker(int, const unsigned char *, unsigned char *);
|
||||
static MaskMaker *maskMakers[maskNum] = {
|
||||
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3
|
||||
};
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask)
|
||||
{
|
||||
unsigned char *masked;
|
||||
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
|
||||
return masked;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned char *masked;
|
||||
int width;
|
||||
|
||||
if(mask < 0 || mask >= maskNum) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
masked = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(masked == NULL) return NULL;
|
||||
|
||||
maskMakers[mask](width, frame, masked);
|
||||
MMask_writeFormatInformation(version, width, masked, mask, level);
|
||||
|
||||
return masked;
|
||||
}
|
||||
|
||||
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *p;
|
||||
int sum1 = 0, sum2 = 0;
|
||||
|
||||
p = frame + width * (width - 1);
|
||||
for(x = 1; x < width; x++) {
|
||||
sum1 += (p[x] & 1);
|
||||
}
|
||||
|
||||
p = frame + width * 2 - 1;
|
||||
for(y = 1; y < width; y++) {
|
||||
sum2 += (*p & 1);
|
||||
p += width;
|
||||
}
|
||||
|
||||
return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
|
||||
}
|
||||
|
||||
unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level)
|
||||
{
|
||||
int i;
|
||||
unsigned char *mask, *bestMask;
|
||||
int maxScore = 0;
|
||||
int score;
|
||||
int width;
|
||||
|
||||
width = MQRspec_getWidth(version);
|
||||
|
||||
mask = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(mask == NULL) return NULL;
|
||||
bestMask = NULL;
|
||||
|
||||
for(i = 0; i < maskNum; i++) {
|
||||
score = 0;
|
||||
maskMakers[i](width, frame, mask);
|
||||
MMask_writeFormatInformation(version, width, mask, i, level);
|
||||
score = MMask_evaluateSymbol(width, mask);
|
||||
if(score > maxScore) {
|
||||
maxScore = score;
|
||||
free(bestMask);
|
||||
bestMask = mask;
|
||||
mask = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(mask == NULL) break;
|
||||
}
|
||||
}
|
||||
free(mask);
|
||||
return bestMask;
|
||||
}
|
||||
|
||||
+34
-34
@@ -1,34 +1,34 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MMASK_H
|
||||
#define MMASK_H
|
||||
|
||||
extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int MMask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MMASK_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Masking for Micro QR Code.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MMASK_H
|
||||
#define MMASK_H
|
||||
|
||||
extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level);
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int MMask_evaluateSymbol(int width, unsigned char *frame);
|
||||
extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level);
|
||||
extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask);
|
||||
#endif
|
||||
|
||||
#endif /* MMASK_H */
|
||||
|
||||
+232
-232
@@ -1,232 +1,232 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mqrspec.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width; ///< Edge length of the symbol
|
||||
int ec[4]; ///< Number of ECC code (bytes)
|
||||
} MQRspec_Capacity;
|
||||
|
||||
/**
|
||||
* Table of the capacity of symbols
|
||||
* See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = {
|
||||
{ 0, {0, 0, 0, 0}},
|
||||
{ 11, {2, 0, 0, 0}},
|
||||
{ 13, {5, 6, 0, 0}},
|
||||
{ 15, {6, 8, 0, 0}},
|
||||
{ 17, {8, 10, 14, 0}}
|
||||
};
|
||||
|
||||
int MQRspec_getDataLengthBit(int version, QRecLevel level)
|
||||
{
|
||||
int w;
|
||||
int ecc;
|
||||
|
||||
w = mqrspecCapacity[version].width - 1;
|
||||
ecc = mqrspecCapacity[version].ec[level];
|
||||
if(ecc == 0) return 0;
|
||||
return w * w - 64 - ecc * 8;
|
||||
}
|
||||
|
||||
int MQRspec_getDataLength(int version, QRecLevel level)
|
||||
{
|
||||
return (MQRspec_getDataLengthBit(version, level) + 4) / 8;
|
||||
}
|
||||
|
||||
int MQRspec_getECCLength(int version, QRecLevel level)
|
||||
{
|
||||
return mqrspecCapacity[version].ec[level];
|
||||
}
|
||||
|
||||
int MQRspec_getWidth(int version)
|
||||
{
|
||||
return mqrspecCapacity[version].width;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* See Table 3 (pp.107) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const int lengthTableBits[4][4] = {
|
||||
{ 3, 4, 5, 6},
|
||||
{ 0, 3, 4, 5},
|
||||
{ 0, 0, 4, 5},
|
||||
{ 0, 0, 3, 4}
|
||||
};
|
||||
|
||||
int MQRspec_lengthIndicator(QRencodeMode mode, int version)
|
||||
{
|
||||
return lengthTableBits[mode][version - 1];
|
||||
}
|
||||
|
||||
int MQRspec_maximumWords(QRencodeMode mode, int version)
|
||||
{
|
||||
int bits;
|
||||
int words;
|
||||
|
||||
bits = lengthTableBits[mode][version - 1];
|
||||
words = (1 << bits) - 1;
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
words *= 2; // the number of bytes is required
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/* See calcFormatInfo in tests/test_mqrspec.c */
|
||||
static const unsigned int formatInfo[4][8] = {
|
||||
{0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3},
|
||||
{0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4},
|
||||
{0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d},
|
||||
{0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba}
|
||||
};
|
||||
|
||||
/* See Table 10 of Appendix 1. (pp.115) */
|
||||
static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = {
|
||||
{-1, -1, -1},
|
||||
{ 0, -1, -1},
|
||||
{ 1, 2, -1},
|
||||
{ 3, 4, -1},
|
||||
{ 5, 6, 7}
|
||||
};
|
||||
|
||||
unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level)
|
||||
{
|
||||
int type;
|
||||
|
||||
if(mask < 0 || mask > 3) return 0;
|
||||
if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0;
|
||||
if(level == QR_ECLEVEL_H) return 0;
|
||||
type = typeTable[version][level];
|
||||
if(type < 0) return 0;
|
||||
|
||||
return formatInfo[mask][type];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Put a finder pattern.
|
||||
* @param frame
|
||||
* @param width
|
||||
* @param ox,oy upper-left coordinate of the pattern
|
||||
*/
|
||||
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
|
||||
{
|
||||
static const unsigned char finder[] = {
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
};
|
||||
int x, y;
|
||||
const unsigned char *s;
|
||||
|
||||
frame += oy * width + ox;
|
||||
s = finder;
|
||||
for(y = 0; y < 7; y++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
frame[x] = s[x];
|
||||
}
|
||||
frame += width;
|
||||
s += 7;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *MQRspec_createFrame(int version)
|
||||
{
|
||||
unsigned char *frame, *p, *q;
|
||||
int width;
|
||||
int x, y;
|
||||
|
||||
width = mqrspecCapacity[version].width;
|
||||
frame = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(frame == NULL) return NULL;
|
||||
|
||||
memset(frame, 0, (size_t)(width * width));
|
||||
/* Finder pattern */
|
||||
putFinderPattern(frame, width, 0, 0);
|
||||
/* Separator */
|
||||
p = frame;
|
||||
for(y = 0; y < 7; y++) {
|
||||
p[7] = 0xc0;
|
||||
p += width;
|
||||
}
|
||||
memset(frame + width * 7, 0xc0, 8);
|
||||
/* Mask format information area */
|
||||
memset(frame + width * 8 + 1, 0x84, 8);
|
||||
p = frame + width + 8;
|
||||
for(y = 0; y < 7; y++) {
|
||||
*p = 0x84;
|
||||
p += width;
|
||||
}
|
||||
/* Timing pattern */
|
||||
p = frame + 8;
|
||||
q = frame + width * 8;
|
||||
for(x = 1; x < width-7; x++) {
|
||||
*p = 0x90 | (x & 1);
|
||||
*q = 0x90 | (x & 1);
|
||||
p++;
|
||||
q += width;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
unsigned char *MQRspec_newFrame(int version)
|
||||
{
|
||||
if(version < 1 || version > MQRSPEC_VERSION_MAX) return NULL;
|
||||
|
||||
return MQRspec_createFrame(version);
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mqrspec.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width; ///< Edge length of the symbol
|
||||
int ec[4]; ///< Number of ECC code (bytes)
|
||||
} MQRspec_Capacity;
|
||||
|
||||
/**
|
||||
* Table of the capacity of symbols
|
||||
* See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = {
|
||||
{ 0, {0, 0, 0, 0}},
|
||||
{ 11, {2, 0, 0, 0}},
|
||||
{ 13, {5, 6, 0, 0}},
|
||||
{ 15, {6, 8, 0, 0}},
|
||||
{ 17, {8, 10, 14, 0}}
|
||||
};
|
||||
|
||||
int MQRspec_getDataLengthBit(int version, QRecLevel level)
|
||||
{
|
||||
int w;
|
||||
int ecc;
|
||||
|
||||
w = mqrspecCapacity[version].width - 1;
|
||||
ecc = mqrspecCapacity[version].ec[level];
|
||||
if(ecc == 0) return 0;
|
||||
return w * w - 64 - ecc * 8;
|
||||
}
|
||||
|
||||
int MQRspec_getDataLength(int version, QRecLevel level)
|
||||
{
|
||||
return (MQRspec_getDataLengthBit(version, level) + 4) / 8;
|
||||
}
|
||||
|
||||
int MQRspec_getECCLength(int version, QRecLevel level)
|
||||
{
|
||||
return mqrspecCapacity[version].ec[level];
|
||||
}
|
||||
|
||||
int MQRspec_getWidth(int version)
|
||||
{
|
||||
return mqrspecCapacity[version].width;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* See Table 3 (pp.107) of Appendix 1, JIS X0510:2004.
|
||||
*/
|
||||
static const int lengthTableBits[4][4] = {
|
||||
{ 3, 4, 5, 6},
|
||||
{ 0, 3, 4, 5},
|
||||
{ 0, 0, 4, 5},
|
||||
{ 0, 0, 3, 4}
|
||||
};
|
||||
|
||||
int MQRspec_lengthIndicator(QRencodeMode mode, int version)
|
||||
{
|
||||
return lengthTableBits[mode][version - 1];
|
||||
}
|
||||
|
||||
int MQRspec_maximumWords(QRencodeMode mode, int version)
|
||||
{
|
||||
int bits;
|
||||
int words;
|
||||
|
||||
bits = lengthTableBits[mode][version - 1];
|
||||
words = (1 << bits) - 1;
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
words *= 2; // the number of bytes is required
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/* See calcFormatInfo in tests/test_mqrspec.c */
|
||||
static const unsigned int formatInfo[4][8] = {
|
||||
{0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3},
|
||||
{0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4},
|
||||
{0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d},
|
||||
{0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba}
|
||||
};
|
||||
|
||||
/* See Table 10 of Appendix 1. (pp.115) */
|
||||
static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = {
|
||||
{-1, -1, -1},
|
||||
{ 0, -1, -1},
|
||||
{ 1, 2, -1},
|
||||
{ 3, 4, -1},
|
||||
{ 5, 6, 7}
|
||||
};
|
||||
|
||||
unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level)
|
||||
{
|
||||
int type;
|
||||
|
||||
if(mask < 0 || mask > 3) return 0;
|
||||
if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0;
|
||||
if(level == QR_ECLEVEL_H) return 0;
|
||||
type = typeTable[version][level];
|
||||
if(type < 0) return 0;
|
||||
|
||||
return formatInfo[mask][type];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Put a finder pattern.
|
||||
* @param frame
|
||||
* @param width
|
||||
* @param ox,oy upper-left coordinate of the pattern
|
||||
*/
|
||||
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
|
||||
{
|
||||
static const unsigned char finder[] = {
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
|
||||
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
|
||||
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
|
||||
};
|
||||
int x, y;
|
||||
const unsigned char *s;
|
||||
|
||||
frame += oy * width + ox;
|
||||
s = finder;
|
||||
for(y = 0; y < 7; y++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
frame[x] = s[x];
|
||||
}
|
||||
frame += width;
|
||||
s += 7;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *MQRspec_createFrame(int version)
|
||||
{
|
||||
unsigned char *frame, *p, *q;
|
||||
int width;
|
||||
int x, y;
|
||||
|
||||
width = mqrspecCapacity[version].width;
|
||||
frame = (unsigned char *)malloc((size_t)(width * width));
|
||||
if(frame == NULL) return NULL;
|
||||
|
||||
memset(frame, 0, (size_t)(width * width));
|
||||
/* Finder pattern */
|
||||
putFinderPattern(frame, width, 0, 0);
|
||||
/* Separator */
|
||||
p = frame;
|
||||
for(y = 0; y < 7; y++) {
|
||||
p[7] = 0xc0;
|
||||
p += width;
|
||||
}
|
||||
memset(frame + width * 7, 0xc0, 8);
|
||||
/* Mask format information area */
|
||||
memset(frame + width * 8 + 1, 0x84, 8);
|
||||
p = frame + width + 8;
|
||||
for(y = 0; y < 7; y++) {
|
||||
*p = 0x84;
|
||||
p += width;
|
||||
}
|
||||
/* Timing pattern */
|
||||
p = frame + 8;
|
||||
q = frame + width * 8;
|
||||
for(x = 1; x < width-7; x++) {
|
||||
*p = 0x90 | (x & 1);
|
||||
*q = 0x90 | (x & 1);
|
||||
p++;
|
||||
q += width;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
unsigned char *MQRspec_newFrame(int version)
|
||||
{
|
||||
if(version < 1 || version > MQRSPEC_VERSION_MAX) return NULL;
|
||||
|
||||
return MQRspec_createFrame(version);
|
||||
}
|
||||
|
||||
+150
-150
@@ -1,150 +1,150 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MQRSPEC_H
|
||||
#define MQRSPEC_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum width of a symbol
|
||||
*/
|
||||
#define MQRSPEC_WIDTH_MAX 17
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bits) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bits)
|
||||
*/
|
||||
extern int MQRspec_getDataLengthBit(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getDataLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum error correction code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return ECC size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getECCLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return a version number that satisfies the input code length.
|
||||
* @param size input code length (byte)
|
||||
* @param level error correction level
|
||||
* @return version number
|
||||
*/
|
||||
extern int MQRspec_getMinimumVersion(int size, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the width of the symbol for the version.
|
||||
* @param version version of the symbol
|
||||
* @return width
|
||||
*/
|
||||
extern int MQRspec_getWidth(int version);
|
||||
|
||||
/**
|
||||
* Return the numer of remainder bits.
|
||||
* @param version version of the symbol
|
||||
* @return number of remainder bits
|
||||
*/
|
||||
extern int MQRspec_getRemainder(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return the size of length indicator for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the size of the appropriate length indicator (bits).
|
||||
*/
|
||||
extern int MQRspec_lengthIndicator(QRencodeMode mode, int version);
|
||||
|
||||
/**
|
||||
* Return the maximum length for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the maximum length (bytes)
|
||||
*/
|
||||
extern int MQRspec_maximumWords(QRencodeMode mode, int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Version information pattern
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded version information pattern that is used for the symbol
|
||||
* of version 7 or greater. Use lower 18 bits.
|
||||
* @param version vesion of the symbol
|
||||
* @return BCH encoded version information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getVersionPattern(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded format information pattern.
|
||||
* @param mask mask number
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return BCH encoded format information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a copy of initialized frame.
|
||||
* @param version version of the symbol
|
||||
* @return Array of unsigned char. You can free it by free().
|
||||
*/
|
||||
extern unsigned char *MQRspec_newFrame(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Mode indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107.
|
||||
*/
|
||||
#define MQRSPEC_MODEID_NUM 0
|
||||
#define MQRSPEC_MODEID_AN 1
|
||||
#define MQRSPEC_MODEID_8 2
|
||||
#define MQRSPEC_MODEID_KANJI 3
|
||||
|
||||
#endif /* MQRSPEC_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Micro QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MQRSPEC_H
|
||||
#define MQRSPEC_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum width of a symbol
|
||||
*/
|
||||
#define MQRSPEC_WIDTH_MAX 17
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bits) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bits)
|
||||
*/
|
||||
extern int MQRspec_getDataLengthBit(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getDataLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum error correction code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return ECC size (bytes)
|
||||
*/
|
||||
extern int MQRspec_getECCLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return a version number that satisfies the input code length.
|
||||
* @param size input code length (byte)
|
||||
* @param level error correction level
|
||||
* @return version number
|
||||
*/
|
||||
extern int MQRspec_getMinimumVersion(int size, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the width of the symbol for the version.
|
||||
* @param version version of the symbol
|
||||
* @return width
|
||||
*/
|
||||
extern int MQRspec_getWidth(int version);
|
||||
|
||||
/**
|
||||
* Return the numer of remainder bits.
|
||||
* @param version version of the symbol
|
||||
* @return number of remainder bits
|
||||
*/
|
||||
extern int MQRspec_getRemainder(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return the size of length indicator for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the size of the appropriate length indicator (bits).
|
||||
*/
|
||||
extern int MQRspec_lengthIndicator(QRencodeMode mode, int version);
|
||||
|
||||
/**
|
||||
* Return the maximum length for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the maximum length (bytes)
|
||||
*/
|
||||
extern int MQRspec_maximumWords(QRencodeMode mode, int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Version information pattern
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded version information pattern that is used for the symbol
|
||||
* of version 7 or greater. Use lower 18 bits.
|
||||
* @param version vesion of the symbol
|
||||
* @return BCH encoded version information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getVersionPattern(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded format information pattern.
|
||||
* @param mask mask number
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return BCH encoded format information pattern
|
||||
*/
|
||||
extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a copy of initialized frame.
|
||||
* @param version version of the symbol
|
||||
* @return Array of unsigned char. You can free it by free().
|
||||
*/
|
||||
extern unsigned char *MQRspec_newFrame(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Mode indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107.
|
||||
*/
|
||||
#define MQRSPEC_MODEID_NUM 0
|
||||
#define MQRSPEC_MODEID_AN 1
|
||||
#define MQRSPEC_MODEID_8 2
|
||||
#define MQRSPEC_MODEID_KANJI 3
|
||||
|
||||
#endif /* MQRSPEC_H */
|
||||
|
||||
+216
-216
@@ -1,216 +1,216 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QImage>
|
||||
#include <getopt.h>
|
||||
#include <qrencode.h>
|
||||
#include <qdebug.h>
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
char *intext = " ";
|
||||
static int casesensitive = 0;
|
||||
static int eightbit = 0;
|
||||
static int kanji = 0;
|
||||
static int version = 0;
|
||||
static int Size = 3;
|
||||
static int margin = 4;
|
||||
static QRecLevel level = QR_ECLEVEL_L;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->textEdit->setText(tr("1234567893233695"));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
enum {
|
||||
O_HELP,
|
||||
O_OUTPUT,
|
||||
O_SIZE,
|
||||
O_VERSION,
|
||||
O_LEVEL,
|
||||
O_MARGIN,
|
||||
O_KANJI,
|
||||
O_CASE,
|
||||
O_8BIT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{"h", no_argument , NULL, O_HELP},
|
||||
{"o", required_argument, NULL, O_OUTPUT},
|
||||
{"l", required_argument, NULL, O_LEVEL},
|
||||
{"s", required_argument, NULL, O_SIZE},
|
||||
{"v", required_argument, NULL, O_VERSION},
|
||||
{"m", required_argument, NULL, O_MARGIN},
|
||||
{"k", no_argument , NULL, O_KANJI},
|
||||
{"c", no_argument , NULL, O_CASE},
|
||||
{"8", no_argument , NULL, O_8BIT},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
qDebug()<<(
|
||||
"qrencode version %s\n\n"
|
||||
"Usage: qrencode [OPTION]... [STRING]\n"
|
||||
"Encode input data in a QR Code and save as a PNG image.\n\n"
|
||||
" -h display this message.\n"
|
||||
" -o FILENAME write PNG image to FILENAME. If '-' is specified, the result\n"
|
||||
" will be output to standard output.\n"
|
||||
" -s NUMBER specify the size of dot (pixel). (default=3)\n"
|
||||
" -l {LMQH} specify error collectin level from L (lowest) to H (highest).\n"
|
||||
" (default=L)\n"
|
||||
" -v NUMBER specify the version of the symbol. (default=auto)\n"
|
||||
" -m NUMBER specify the width of margin. (default=4)\n"
|
||||
" -k assume that the input text contains kanji (shift-jis).\n"
|
||||
" -c encode alphabet characters in 8-bit mode. If your application\n"
|
||||
" is case-sensitive, choose this.\n"
|
||||
" -8 encode entire data in 8-bit mode. -c and -k will be ignored.\n"
|
||||
" [STRING] input data. If it is not specified, data will be taken from\n"
|
||||
" standard input.\n"
|
||||
);
|
||||
}
|
||||
|
||||
#define MAX_DATA_SIZE 7090 /* from the specification */
|
||||
static char *readStdin(void)
|
||||
{
|
||||
char *buffer;
|
||||
int ret;
|
||||
|
||||
buffer = (char *)malloc(MAX_DATA_SIZE);
|
||||
ret = fread(buffer, 1, MAX_DATA_SIZE, stdin);
|
||||
if(ret == 0) {
|
||||
fprintf(stderr, "No input data.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(!feof(stdin)) {
|
||||
fprintf(stderr, "Input data is too large.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buffer[ret] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static QRcode *encode(const char *intext)
|
||||
{
|
||||
QRencodeMode hint;
|
||||
QRcode *code;
|
||||
|
||||
if(kanji) {
|
||||
hint = QR_MODE_KANJI;
|
||||
} else {
|
||||
hint = QR_MODE_8;
|
||||
}
|
||||
|
||||
if(eightbit) {
|
||||
code = QRcode_encodeString8bit(intext, version, level);
|
||||
} else {
|
||||
code = QRcode_encodeString(intext, version, level, hint, casesensitive);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static void qrencode(const char *intext, const char *outfile)
|
||||
{
|
||||
FILE *fp;
|
||||
QRcode *qrcode;
|
||||
//png_structp png_ptr;
|
||||
//png_infop info_ptr;
|
||||
unsigned char *row, *p, *q;
|
||||
int x, y, xx, yy, bit;
|
||||
int realwidth;
|
||||
|
||||
qrcode = encode(intext);
|
||||
if(qrcode == NULL) {
|
||||
fprintf(stderr, "Failed to encode the input data.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
realwidth = (qrcode->width + margin * 2) * Size;
|
||||
|
||||
row = (unsigned char *)malloc(realwidth);
|
||||
|
||||
// top margin
|
||||
memset(row, 0x0, realwidth );
|
||||
|
||||
qDebug()<<"1: "<< qrcode->width<<realwidth<<margin<<Size<<sizeof(intext);
|
||||
|
||||
// realwidth = (qrcode->width + margin * 2) * Size;
|
||||
QImage QRImage(realwidth,qrcode->width*Size,QImage::Format_ARGB32 );
|
||||
QImage *img;
|
||||
img = &QRImage;
|
||||
img->fill(0x00ffffff);
|
||||
|
||||
/* data */
|
||||
p = qrcode->data;
|
||||
int ypos=0;//margin * Size;
|
||||
int xpos=0;
|
||||
for(y=0; y<qrcode->width; y++) {
|
||||
bit = 7;
|
||||
bit = 7 - (margin * Size % 8);
|
||||
xpos=margin * Size;
|
||||
for(x=0; x<qrcode->width; x++) {
|
||||
for(xx=0; xx<Size; xx++) {
|
||||
if((*p & 1) << bit){
|
||||
for(yy=0; yy<Size; yy++) {
|
||||
img->setPixel(xpos,ypos+yy,0xff000000);
|
||||
}
|
||||
}
|
||||
xpos++;
|
||||
|
||||
}
|
||||
p++;
|
||||
bit--;
|
||||
if(bit < 0) {
|
||||
//q++;
|
||||
bit = 7;
|
||||
}
|
||||
}
|
||||
ypos+=Size;
|
||||
}
|
||||
img->save("Myqr.bmp");
|
||||
|
||||
free(row);
|
||||
QRcode_free(qrcode);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_pushButton_clicked()
|
||||
{
|
||||
QString in;
|
||||
//usage();
|
||||
in = ui->textEdit->toPlainText();
|
||||
//intext = in.toLatin1().data();
|
||||
intext = (char *)malloc(in.length()*2);
|
||||
memset(intext,0,sizeof(intext));
|
||||
//intext =in.unicode();
|
||||
//memcpy(&intext[0], in.unicode (),2*in.length());
|
||||
memcpy(intext,in.toLocal8Bit().data(),2*in.length());
|
||||
|
||||
qDebug()<<in<< intext;
|
||||
Size = ui->comboBox_size->currentIndex()+3;
|
||||
qrencode(intext,outfile);
|
||||
QImage img("Myqr.bmp",0);
|
||||
ui->labQRImage->setPixmap( QPixmap::fromImage(img,Qt::AutoColor));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QImage>
|
||||
#include <getopt.h>
|
||||
#include <qrencode.h>
|
||||
#include <qdebug.h>
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
char *intext = " ";
|
||||
static int casesensitive = 0;
|
||||
static int eightbit = 0;
|
||||
static int kanji = 0;
|
||||
static int version = 0;
|
||||
static int Size = 3;
|
||||
static int margin = 4;
|
||||
static QRecLevel level = QR_ECLEVEL_L;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->textEdit->setText(tr("1234567893233695"));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
enum {
|
||||
O_HELP,
|
||||
O_OUTPUT,
|
||||
O_SIZE,
|
||||
O_VERSION,
|
||||
O_LEVEL,
|
||||
O_MARGIN,
|
||||
O_KANJI,
|
||||
O_CASE,
|
||||
O_8BIT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{"h", no_argument , NULL, O_HELP},
|
||||
{"o", required_argument, NULL, O_OUTPUT},
|
||||
{"l", required_argument, NULL, O_LEVEL},
|
||||
{"s", required_argument, NULL, O_SIZE},
|
||||
{"v", required_argument, NULL, O_VERSION},
|
||||
{"m", required_argument, NULL, O_MARGIN},
|
||||
{"k", no_argument , NULL, O_KANJI},
|
||||
{"c", no_argument , NULL, O_CASE},
|
||||
{"8", no_argument , NULL, O_8BIT},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
qDebug()<<(
|
||||
"qrencode version %s\n\n"
|
||||
"Usage: qrencode [OPTION]... [STRING]\n"
|
||||
"Encode input data in a QR Code and save as a PNG image.\n\n"
|
||||
" -h display this message.\n"
|
||||
" -o FILENAME write PNG image to FILENAME. If '-' is specified, the result\n"
|
||||
" will be output to standard output.\n"
|
||||
" -s NUMBER specify the size of dot (pixel). (default=3)\n"
|
||||
" -l {LMQH} specify error collectin level from L (lowest) to H (highest).\n"
|
||||
" (default=L)\n"
|
||||
" -v NUMBER specify the version of the symbol. (default=auto)\n"
|
||||
" -m NUMBER specify the width of margin. (default=4)\n"
|
||||
" -k assume that the input text contains kanji (shift-jis).\n"
|
||||
" -c encode alphabet characters in 8-bit mode. If your application\n"
|
||||
" is case-sensitive, choose this.\n"
|
||||
" -8 encode entire data in 8-bit mode. -c and -k will be ignored.\n"
|
||||
" [STRING] input data. If it is not specified, data will be taken from\n"
|
||||
" standard input.\n"
|
||||
);
|
||||
}
|
||||
|
||||
#define MAX_DATA_SIZE 7090 /* from the specification */
|
||||
static char *readStdin(void)
|
||||
{
|
||||
char *buffer;
|
||||
int ret;
|
||||
|
||||
buffer = (char *)malloc(MAX_DATA_SIZE);
|
||||
ret = fread(buffer, 1, MAX_DATA_SIZE, stdin);
|
||||
if(ret == 0) {
|
||||
fprintf(stderr, "No input data.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(!feof(stdin)) {
|
||||
fprintf(stderr, "Input data is too large.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buffer[ret] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static QRcode *encode(const char *intext)
|
||||
{
|
||||
QRencodeMode hint;
|
||||
QRcode *code;
|
||||
|
||||
if(kanji) {
|
||||
hint = QR_MODE_KANJI;
|
||||
} else {
|
||||
hint = QR_MODE_8;
|
||||
}
|
||||
|
||||
if(eightbit) {
|
||||
code = QRcode_encodeString8bit(intext, version, level);
|
||||
} else {
|
||||
code = QRcode_encodeString(intext, version, level, hint, casesensitive);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static void qrencode(const char *intext, const char *outfile)
|
||||
{
|
||||
FILE *fp;
|
||||
QRcode *qrcode;
|
||||
//png_structp png_ptr;
|
||||
//png_infop info_ptr;
|
||||
unsigned char *row, *p, *q;
|
||||
int x, y, xx, yy, bit;
|
||||
int realwidth;
|
||||
|
||||
qrcode = encode(intext);
|
||||
if(qrcode == NULL) {
|
||||
fprintf(stderr, "Failed to encode the input data.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
realwidth = (qrcode->width + margin * 2) * Size;
|
||||
|
||||
row = (unsigned char *)malloc(realwidth);
|
||||
|
||||
// top margin
|
||||
memset(row, 0x0, realwidth );
|
||||
|
||||
qDebug()<<"1: "<< qrcode->width<<realwidth<<margin<<Size<<sizeof(intext);
|
||||
|
||||
// realwidth = (qrcode->width + margin * 2) * Size;
|
||||
QImage QRImage(realwidth,qrcode->width*Size,QImage::Format_ARGB32 );
|
||||
QImage *img;
|
||||
img = &QRImage;
|
||||
img->fill(0x00ffffff);
|
||||
|
||||
/* data */
|
||||
p = qrcode->data;
|
||||
int ypos=0;//margin * Size;
|
||||
int xpos=0;
|
||||
for(y=0; y<qrcode->width; y++) {
|
||||
bit = 7;
|
||||
bit = 7 - (margin * Size % 8);
|
||||
xpos=margin * Size;
|
||||
for(x=0; x<qrcode->width; x++) {
|
||||
for(xx=0; xx<Size; xx++) {
|
||||
if((*p & 1) << bit){
|
||||
for(yy=0; yy<Size; yy++) {
|
||||
img->setPixel(xpos,ypos+yy,0xff000000);
|
||||
}
|
||||
}
|
||||
xpos++;
|
||||
|
||||
}
|
||||
p++;
|
||||
bit--;
|
||||
if(bit < 0) {
|
||||
//q++;
|
||||
bit = 7;
|
||||
}
|
||||
}
|
||||
ypos+=Size;
|
||||
}
|
||||
img->save("Myqr.bmp");
|
||||
|
||||
free(row);
|
||||
QRcode_free(qrcode);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_pushButton_clicked()
|
||||
{
|
||||
QString in;
|
||||
//usage();
|
||||
in = ui->textEdit->toPlainText();
|
||||
//intext = in.toLatin1().data();
|
||||
intext = (char *)malloc(in.length()*2);
|
||||
memset(intext,0,sizeof(intext));
|
||||
//intext =in.unicode();
|
||||
//memcpy(&intext[0], in.unicode (),2*in.length());
|
||||
memcpy(intext,in.toLocal8Bit().data(),2*in.length());
|
||||
|
||||
qDebug()<<in<< intext;
|
||||
Size = ui->comboBox_size->currentIndex()+3;
|
||||
qrencode(intext,outfile);
|
||||
QImage img("Myqr.bmp",0);
|
||||
ui->labQRImage->setPixmap( QPixmap::fromImage(img,Qt::AutoColor));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
+924
-924
File diff suppressed because it is too large
Load Diff
+419
-419
@@ -1,419 +1,419 @@
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrencode_inner.h"
|
||||
#include "qrspec.h"
|
||||
#include "bistream.h"
|
||||
#include "qrinput.h"
|
||||
#include "rscode.h"
|
||||
#include "split.h"
|
||||
#include "mask.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
static void RSblock_init(RSblock *block, int dl, unsigned char *data, int el)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
block->dataLength = dl;
|
||||
block->data = data;
|
||||
block->eccLength = el;
|
||||
block->ecc = (unsigned char *)malloc(el);
|
||||
|
||||
rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el);
|
||||
encode_rs_char(rs, data, block->ecc);
|
||||
}
|
||||
|
||||
QRRawCode *QRraw_new(QRinput *input)
|
||||
{
|
||||
QRRawCode *raw;
|
||||
int *spec;
|
||||
int i;
|
||||
RSblock *rsblock;
|
||||
unsigned char *p;
|
||||
|
||||
p = QRinput_getByteStream(input);
|
||||
if(p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw = (QRRawCode *)malloc(sizeof(QRRawCode));
|
||||
raw->datacode = p;
|
||||
spec = QRspec_getEccSpec(input->version, input->level);
|
||||
raw->version = input->version;
|
||||
raw->blocks = QRspec_rsBlockNum(spec);
|
||||
raw->rsblock = (RSblock *)malloc(sizeof(RSblock) * raw->blocks);
|
||||
|
||||
rsblock = raw->rsblock;
|
||||
p = raw->datacode;
|
||||
for(i=0; i<QRspec_rsBlockNum1(spec); i++) {
|
||||
RSblock_init(rsblock, QRspec_rsDataCodes1(spec), p,
|
||||
QRspec_rsEccCodes1(spec));
|
||||
p += QRspec_rsDataCodes1(spec);
|
||||
rsblock++;
|
||||
}
|
||||
for(i=0; i<QRspec_rsBlockNum2(spec); i++) {
|
||||
RSblock_init(rsblock, QRspec_rsDataCodes2(spec), p,
|
||||
QRspec_rsEccCodes2(spec));
|
||||
p += QRspec_rsDataCodes2(spec);
|
||||
rsblock++;
|
||||
}
|
||||
raw->b1 = QRspec_rsBlockNum1(spec);
|
||||
raw->dataLength = QRspec_rsBlockNum1(spec) * QRspec_rsDataCodes1(spec)
|
||||
+ QRspec_rsBlockNum2(spec) * QRspec_rsDataCodes2(spec);
|
||||
raw->eccLength = QRspec_rsBlockNum(spec) * QRspec_rsEccCodes1(spec);
|
||||
raw->count = 0;
|
||||
free(spec);
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a code (byte).
|
||||
* This function can be called iteratively.
|
||||
* @param raw raw code.
|
||||
* @return code
|
||||
*/
|
||||
unsigned char QRraw_getCode(QRRawCode *raw)
|
||||
{
|
||||
int col, row;
|
||||
unsigned char ret;
|
||||
|
||||
if(raw->count < raw->dataLength) {
|
||||
row = raw->count % raw->blocks;
|
||||
col = raw->count / raw->blocks;
|
||||
if(col >= raw->rsblock[row].dataLength) {
|
||||
row += raw->b1;
|
||||
}
|
||||
ret = raw->rsblock[row].data[col];
|
||||
} else if(raw->count < raw->dataLength + raw->eccLength) {
|
||||
row = (raw->count - raw->dataLength) % raw->blocks;
|
||||
col = (raw->count - raw->dataLength) / raw->blocks;
|
||||
ret = raw->rsblock[row].ecc[col];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
raw->count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QRraw_free(QRRawCode *raw)
|
||||
{
|
||||
int i;
|
||||
|
||||
free(raw->datacode);
|
||||
for(i=0; i<raw->blocks; i++) {
|
||||
free(raw->rsblock[i].ecc);
|
||||
}
|
||||
free(raw->rsblock);
|
||||
free(raw);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
unsigned char *frame;
|
||||
int x, y;
|
||||
int dir;
|
||||
int bit;
|
||||
} FrameFiller;
|
||||
|
||||
static FrameFiller *FrameFiller_new(int width, unsigned char *frame)
|
||||
{
|
||||
FrameFiller *filler;
|
||||
|
||||
filler = (FrameFiller *)malloc(sizeof(FrameFiller));
|
||||
filler->width = width;
|
||||
filler->frame = frame;
|
||||
filler->x = width - 1;
|
||||
filler->y = width - 1;
|
||||
filler->dir = -1;
|
||||
filler->bit = -1;
|
||||
|
||||
return filler;
|
||||
}
|
||||
|
||||
static unsigned char *FrameFiller_next(FrameFiller *filler)
|
||||
{
|
||||
unsigned char *p;
|
||||
int x, y, w;
|
||||
|
||||
if(filler->bit == -1) {
|
||||
filler->bit = 0;
|
||||
return filler->frame + filler->y * filler->width + filler->x;
|
||||
}
|
||||
|
||||
x = filler->x;
|
||||
y = filler->y;
|
||||
p = filler->frame;
|
||||
w = filler->width;
|
||||
|
||||
if(filler->bit == 0) {
|
||||
x--;
|
||||
filler->bit++;
|
||||
} else {
|
||||
x++;
|
||||
y += filler->dir;
|
||||
filler->bit--;
|
||||
}
|
||||
|
||||
if(filler->dir < 0) {
|
||||
if(y < 0) {
|
||||
y = 0;
|
||||
x -= 2;
|
||||
filler->dir = 1;
|
||||
if(x == 6) {
|
||||
x--;
|
||||
y = 9;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y == w) {
|
||||
y = w - 1;
|
||||
x -= 2;
|
||||
filler->dir = -1;
|
||||
if(x == 6) {
|
||||
x--;
|
||||
y -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(x < 0 || y < 0) return NULL;
|
||||
|
||||
filler->x = x;
|
||||
filler->y = y;
|
||||
|
||||
if(p[y * w + x] & 0x80) {
|
||||
// This tail recursion could be optimized.
|
||||
return FrameFiller_next(filler);
|
||||
}
|
||||
return &p[y * w + x];
|
||||
}
|
||||
|
||||
unsigned char *FrameFiller_fillerTest(int version)
|
||||
{
|
||||
int width, length;
|
||||
unsigned char *frame, *p;
|
||||
FrameFiller *filler;
|
||||
int i, j;
|
||||
unsigned char cl = 1;
|
||||
unsigned char ch = 0;
|
||||
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
filler = FrameFiller_new(width, frame);
|
||||
length = QRspec_getDataLength(version, QR_ECLEVEL_L)
|
||||
+ QRspec_getECCLength(version, QR_ECLEVEL_L);
|
||||
|
||||
for(i=0; i<length; i++) {
|
||||
for(j=0; j<8; j++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = ch | cl;
|
||||
cl++;
|
||||
if(cl == 9) {
|
||||
cl = 1;
|
||||
ch += 0x10;
|
||||
}
|
||||
}
|
||||
}
|
||||
length = QRspec_getRemainder(version);
|
||||
for(i=0; i<length; i++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0xa0;
|
||||
}
|
||||
p = FrameFiller_next(filler);
|
||||
free(filler);
|
||||
if(p != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
int QRcode_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
int blacks = 0;
|
||||
|
||||
format = QRspec_getFormatInfo(mask, level);
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * 8 + width - 1 - i] = v;
|
||||
if(i < 6) {
|
||||
frame[width * i + 8] = v;
|
||||
} else {
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
for(i=0; i<7; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * (width - 7 + i) + 8] = v;
|
||||
if(i == 0) {
|
||||
frame[width * 8 + 7] = v;
|
||||
} else {
|
||||
frame[width * 8 + 6 - i] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
|
||||
return blacks;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
|
||||
static QRcode *QRcode_new(int version, int width, unsigned char *data)
|
||||
{
|
||||
QRcode *qrcode;
|
||||
|
||||
qrcode = (QRcode *)malloc(sizeof(QRcode));
|
||||
qrcode->version = version;
|
||||
qrcode->width = width;
|
||||
qrcode->data = data;
|
||||
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
void QRcode_free(QRcode *qrcode)
|
||||
{
|
||||
if(qrcode == NULL) return;
|
||||
|
||||
if(qrcode->data != NULL) {
|
||||
free(qrcode->data);
|
||||
}
|
||||
free(qrcode);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeMask(QRinput *input, int version, QRecLevel level, int mask)
|
||||
{
|
||||
int width;
|
||||
QRRawCode *raw;
|
||||
unsigned char *frame, *masked, *p, code, bit;
|
||||
FrameFiller *filler;
|
||||
int i, j;
|
||||
QRcode *qrcode;
|
||||
|
||||
QRinput_setVersion(input, version);
|
||||
QRinput_setErrorCorrectionLevel(input, level);
|
||||
|
||||
raw = QRraw_new(input);
|
||||
if(raw == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
version = raw->version;
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
filler = FrameFiller_new(width, frame);
|
||||
|
||||
/* inteleaved data and ecc codes */
|
||||
for(i=0; i<raw->dataLength + raw->eccLength; i++) {
|
||||
code = QRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
for(j=0; j<8; j++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0x02 | ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
QRraw_free(raw);
|
||||
/* remainder bits */
|
||||
j = QRspec_getRemainder(version);
|
||||
for(i=0; i<j; i++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0x02;
|
||||
}
|
||||
free(filler);
|
||||
/* masking */
|
||||
if(mask < 0) {
|
||||
masked = Mask_mask(width, frame, level);
|
||||
} else {
|
||||
masked = Mask_makeMask(width, frame, mask);
|
||||
QRcode_writeFormatInformation(width, masked, mask, QRinput_getErrorCorrectionLevel(input));
|
||||
}
|
||||
qrcode = QRcode_new(version, width, masked);
|
||||
|
||||
free(frame);
|
||||
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeInput(QRinput *input, int version, QRecLevel level)
|
||||
{
|
||||
return QRcode_encodeMask(input, version, level, -1);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
|
||||
input = QRinput_new();
|
||||
QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
|
||||
code = QRcode_encodeInput(input, version, level);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
|
||||
if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input = QRinput_new();
|
||||
Split_splitStringToQRinput(string, input, version, hint, casesensitive);
|
||||
code = QRcode_encodeInput(input, version, level);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrencode_inner.h"
|
||||
#include "qrspec.h"
|
||||
#include "bistream.h"
|
||||
#include "qrinput.h"
|
||||
#include "rscode.h"
|
||||
#include "split.h"
|
||||
#include "mask.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
static void RSblock_init(RSblock *block, int dl, unsigned char *data, int el)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
block->dataLength = dl;
|
||||
block->data = data;
|
||||
block->eccLength = el;
|
||||
block->ecc = (unsigned char *)malloc(el);
|
||||
|
||||
rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el);
|
||||
encode_rs_char(rs, data, block->ecc);
|
||||
}
|
||||
|
||||
QRRawCode *QRraw_new(QRinput *input)
|
||||
{
|
||||
QRRawCode *raw;
|
||||
int *spec;
|
||||
int i;
|
||||
RSblock *rsblock;
|
||||
unsigned char *p;
|
||||
|
||||
p = QRinput_getByteStream(input);
|
||||
if(p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw = (QRRawCode *)malloc(sizeof(QRRawCode));
|
||||
raw->datacode = p;
|
||||
spec = QRspec_getEccSpec(input->version, input->level);
|
||||
raw->version = input->version;
|
||||
raw->blocks = QRspec_rsBlockNum(spec);
|
||||
raw->rsblock = (RSblock *)malloc(sizeof(RSblock) * raw->blocks);
|
||||
|
||||
rsblock = raw->rsblock;
|
||||
p = raw->datacode;
|
||||
for(i=0; i<QRspec_rsBlockNum1(spec); i++) {
|
||||
RSblock_init(rsblock, QRspec_rsDataCodes1(spec), p,
|
||||
QRspec_rsEccCodes1(spec));
|
||||
p += QRspec_rsDataCodes1(spec);
|
||||
rsblock++;
|
||||
}
|
||||
for(i=0; i<QRspec_rsBlockNum2(spec); i++) {
|
||||
RSblock_init(rsblock, QRspec_rsDataCodes2(spec), p,
|
||||
QRspec_rsEccCodes2(spec));
|
||||
p += QRspec_rsDataCodes2(spec);
|
||||
rsblock++;
|
||||
}
|
||||
raw->b1 = QRspec_rsBlockNum1(spec);
|
||||
raw->dataLength = QRspec_rsBlockNum1(spec) * QRspec_rsDataCodes1(spec)
|
||||
+ QRspec_rsBlockNum2(spec) * QRspec_rsDataCodes2(spec);
|
||||
raw->eccLength = QRspec_rsBlockNum(spec) * QRspec_rsEccCodes1(spec);
|
||||
raw->count = 0;
|
||||
free(spec);
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a code (byte).
|
||||
* This function can be called iteratively.
|
||||
* @param raw raw code.
|
||||
* @return code
|
||||
*/
|
||||
unsigned char QRraw_getCode(QRRawCode *raw)
|
||||
{
|
||||
int col, row;
|
||||
unsigned char ret;
|
||||
|
||||
if(raw->count < raw->dataLength) {
|
||||
row = raw->count % raw->blocks;
|
||||
col = raw->count / raw->blocks;
|
||||
if(col >= raw->rsblock[row].dataLength) {
|
||||
row += raw->b1;
|
||||
}
|
||||
ret = raw->rsblock[row].data[col];
|
||||
} else if(raw->count < raw->dataLength + raw->eccLength) {
|
||||
row = (raw->count - raw->dataLength) % raw->blocks;
|
||||
col = (raw->count - raw->dataLength) / raw->blocks;
|
||||
ret = raw->rsblock[row].ecc[col];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
raw->count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QRraw_free(QRRawCode *raw)
|
||||
{
|
||||
int i;
|
||||
|
||||
free(raw->datacode);
|
||||
for(i=0; i<raw->blocks; i++) {
|
||||
free(raw->rsblock[i].ecc);
|
||||
}
|
||||
free(raw->rsblock);
|
||||
free(raw);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
unsigned char *frame;
|
||||
int x, y;
|
||||
int dir;
|
||||
int bit;
|
||||
} FrameFiller;
|
||||
|
||||
static FrameFiller *FrameFiller_new(int width, unsigned char *frame)
|
||||
{
|
||||
FrameFiller *filler;
|
||||
|
||||
filler = (FrameFiller *)malloc(sizeof(FrameFiller));
|
||||
filler->width = width;
|
||||
filler->frame = frame;
|
||||
filler->x = width - 1;
|
||||
filler->y = width - 1;
|
||||
filler->dir = -1;
|
||||
filler->bit = -1;
|
||||
|
||||
return filler;
|
||||
}
|
||||
|
||||
static unsigned char *FrameFiller_next(FrameFiller *filler)
|
||||
{
|
||||
unsigned char *p;
|
||||
int x, y, w;
|
||||
|
||||
if(filler->bit == -1) {
|
||||
filler->bit = 0;
|
||||
return filler->frame + filler->y * filler->width + filler->x;
|
||||
}
|
||||
|
||||
x = filler->x;
|
||||
y = filler->y;
|
||||
p = filler->frame;
|
||||
w = filler->width;
|
||||
|
||||
if(filler->bit == 0) {
|
||||
x--;
|
||||
filler->bit++;
|
||||
} else {
|
||||
x++;
|
||||
y += filler->dir;
|
||||
filler->bit--;
|
||||
}
|
||||
|
||||
if(filler->dir < 0) {
|
||||
if(y < 0) {
|
||||
y = 0;
|
||||
x -= 2;
|
||||
filler->dir = 1;
|
||||
if(x == 6) {
|
||||
x--;
|
||||
y = 9;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y == w) {
|
||||
y = w - 1;
|
||||
x -= 2;
|
||||
filler->dir = -1;
|
||||
if(x == 6) {
|
||||
x--;
|
||||
y -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(x < 0 || y < 0) return NULL;
|
||||
|
||||
filler->x = x;
|
||||
filler->y = y;
|
||||
|
||||
if(p[y * w + x] & 0x80) {
|
||||
// This tail recursion could be optimized.
|
||||
return FrameFiller_next(filler);
|
||||
}
|
||||
return &p[y * w + x];
|
||||
}
|
||||
|
||||
unsigned char *FrameFiller_fillerTest(int version)
|
||||
{
|
||||
int width, length;
|
||||
unsigned char *frame, *p;
|
||||
FrameFiller *filler;
|
||||
int i, j;
|
||||
unsigned char cl = 1;
|
||||
unsigned char ch = 0;
|
||||
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
filler = FrameFiller_new(width, frame);
|
||||
length = QRspec_getDataLength(version, QR_ECLEVEL_L)
|
||||
+ QRspec_getECCLength(version, QR_ECLEVEL_L);
|
||||
|
||||
for(i=0; i<length; i++) {
|
||||
for(j=0; j<8; j++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = ch | cl;
|
||||
cl++;
|
||||
if(cl == 9) {
|
||||
cl = 1;
|
||||
ch += 0x10;
|
||||
}
|
||||
}
|
||||
}
|
||||
length = QRspec_getRemainder(version);
|
||||
for(i=0; i<length; i++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0xa0;
|
||||
}
|
||||
p = FrameFiller_next(filler);
|
||||
free(filler);
|
||||
if(p != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
int QRcode_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
|
||||
{
|
||||
unsigned int format;
|
||||
unsigned char v;
|
||||
int i;
|
||||
int blacks = 0;
|
||||
|
||||
format = QRspec_getFormatInfo(mask, level);
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * 8 + width - 1 - i] = v;
|
||||
if(i < 6) {
|
||||
frame[width * i + 8] = v;
|
||||
} else {
|
||||
frame[width * (i + 1) + 8] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
for(i=0; i<7; i++) {
|
||||
if(format & 1) {
|
||||
blacks += 2;
|
||||
v = 0x85;
|
||||
} else {
|
||||
v = 0x84;
|
||||
}
|
||||
frame[width * (width - 7 + i) + 8] = v;
|
||||
if(i == 0) {
|
||||
frame[width * 8 + 7] = v;
|
||||
} else {
|
||||
frame[width * 8 + 6 - i] = v;
|
||||
}
|
||||
format= format >> 1;
|
||||
}
|
||||
|
||||
return blacks;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
|
||||
static QRcode *QRcode_new(int version, int width, unsigned char *data)
|
||||
{
|
||||
QRcode *qrcode;
|
||||
|
||||
qrcode = (QRcode *)malloc(sizeof(QRcode));
|
||||
qrcode->version = version;
|
||||
qrcode->width = width;
|
||||
qrcode->data = data;
|
||||
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
void QRcode_free(QRcode *qrcode)
|
||||
{
|
||||
if(qrcode == NULL) return;
|
||||
|
||||
if(qrcode->data != NULL) {
|
||||
free(qrcode->data);
|
||||
}
|
||||
free(qrcode);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeMask(QRinput *input, int version, QRecLevel level, int mask)
|
||||
{
|
||||
int width;
|
||||
QRRawCode *raw;
|
||||
unsigned char *frame, *masked, *p, code, bit;
|
||||
FrameFiller *filler;
|
||||
int i, j;
|
||||
QRcode *qrcode;
|
||||
|
||||
QRinput_setVersion(input, version);
|
||||
QRinput_setErrorCorrectionLevel(input, level);
|
||||
|
||||
raw = QRraw_new(input);
|
||||
if(raw == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
version = raw->version;
|
||||
width = QRspec_getWidth(version);
|
||||
frame = QRspec_newFrame(version);
|
||||
filler = FrameFiller_new(width, frame);
|
||||
|
||||
/* inteleaved data and ecc codes */
|
||||
for(i=0; i<raw->dataLength + raw->eccLength; i++) {
|
||||
code = QRraw_getCode(raw);
|
||||
bit = 0x80;
|
||||
for(j=0; j<8; j++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0x02 | ((bit & code) != 0);
|
||||
bit = bit >> 1;
|
||||
}
|
||||
}
|
||||
QRraw_free(raw);
|
||||
/* remainder bits */
|
||||
j = QRspec_getRemainder(version);
|
||||
for(i=0; i<j; i++) {
|
||||
p = FrameFiller_next(filler);
|
||||
*p = 0x02;
|
||||
}
|
||||
free(filler);
|
||||
/* masking */
|
||||
if(mask < 0) {
|
||||
masked = Mask_mask(width, frame, level);
|
||||
} else {
|
||||
masked = Mask_makeMask(width, frame, mask);
|
||||
QRcode_writeFormatInformation(width, masked, mask, QRinput_getErrorCorrectionLevel(input));
|
||||
}
|
||||
qrcode = QRcode_new(version, width, masked);
|
||||
|
||||
free(frame);
|
||||
|
||||
return qrcode;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeInput(QRinput *input, int version, QRecLevel level)
|
||||
{
|
||||
return QRcode_encodeMask(input, version, level, -1);
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
|
||||
input = QRinput_new();
|
||||
QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
|
||||
code = QRcode_encodeInput(input, version, level);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
QRinput *input;
|
||||
QRcode *code;
|
||||
|
||||
if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input = QRinput_new();
|
||||
Split_splitStringToQRinput(string, input, version, hint, casesensitive);
|
||||
code = QRcode_encodeInput(input, version, level);
|
||||
QRinput_free(input);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
+576
-576
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
|
||||
|
||||
|
||||
+88
-88
@@ -1,88 +1,88 @@
|
||||
/**
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Header for test use
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRENCODE_INNER_H
|
||||
#define QRENCODE_INNER_H
|
||||
|
||||
/**
|
||||
* This header file includes definitions for test use.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *data;
|
||||
unsigned char *ecc;
|
||||
} RSblock;
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
int b1;
|
||||
int blocks;
|
||||
RSblock *rsblock;
|
||||
int count;
|
||||
} QRRawCode;
|
||||
|
||||
extern QRRawCode *QRraw_new(QRinput *input);
|
||||
extern unsigned char QRraw_getCode(QRRawCode *raw);
|
||||
extern void QRraw_free(QRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code for Micro QR Code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
RSblock *rsblock;
|
||||
int oddbits;
|
||||
int count;
|
||||
} MQRRawCode;
|
||||
|
||||
extern MQRRawCode *MQRraw_new(QRinput *input);
|
||||
extern unsigned char MQRraw_getCode(MQRRawCode *raw);
|
||||
extern void MQRraw_free(MQRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
extern unsigned char *FrameFiller_test(int version);
|
||||
extern unsigned char *FrameFiller_testMQR(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_new(int version, int width, unsigned char *data);
|
||||
|
||||
#endif /* QRENCODE_INNER_H */
|
||||
/**
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Header for test use
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRENCODE_INNER_H
|
||||
#define QRENCODE_INNER_H
|
||||
|
||||
/**
|
||||
* This header file includes definitions for test use.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *data;
|
||||
unsigned char *ecc;
|
||||
} RSblock;
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
int b1;
|
||||
int blocks;
|
||||
RSblock *rsblock;
|
||||
int count;
|
||||
} QRRawCode;
|
||||
|
||||
extern QRRawCode *QRraw_new(QRinput *input);
|
||||
extern unsigned char QRraw_getCode(QRRawCode *raw);
|
||||
extern void QRraw_free(QRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Raw code for Micro QR Code
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int dataLength;
|
||||
int eccLength;
|
||||
unsigned char *datacode;
|
||||
unsigned char *ecccode;
|
||||
RSblock *rsblock;
|
||||
int oddbits;
|
||||
int count;
|
||||
} MQRRawCode;
|
||||
|
||||
extern MQRRawCode *MQRraw_new(QRinput *input);
|
||||
extern unsigned char MQRraw_getCode(MQRRawCode *raw);
|
||||
extern void MQRraw_free(MQRRawCode *raw);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame filling
|
||||
*****************************************************************************/
|
||||
extern unsigned char *FrameFiller_test(int version);
|
||||
extern unsigned char *FrameFiller_testMQR(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* QR-code encoding
|
||||
*****************************************************************************/
|
||||
extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);
|
||||
extern QRcode *QRcode_new(int version, int width, unsigned char *data);
|
||||
|
||||
#endif /* QRENCODE_INNER_H */
|
||||
|
||||
+1639
-1639
File diff suppressed because it is too large
Load Diff
+776
-776
File diff suppressed because it is too large
Load Diff
+124
-124
@@ -1,124 +1,124 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data chunk class
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRINPUT_H
|
||||
#define QRINPUT_H
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
int QRinput_isSplittableMode(QRencodeMode mode);
|
||||
|
||||
/******************************************************************************
|
||||
* Entry of input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_List QRinput_List;
|
||||
|
||||
struct _QRinput_List {
|
||||
QRencodeMode mode;
|
||||
int size; ///< Size of data chunk (byte).
|
||||
unsigned char *data; ///< Data chunk.
|
||||
BitStream *bstream;
|
||||
QRinput_List *next;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Input Data
|
||||
*****************************************************************************/
|
||||
struct _QRinput {
|
||||
int version;
|
||||
QRecLevel level;
|
||||
QRinput_List *head;
|
||||
QRinput_List *tail;
|
||||
int mqr;
|
||||
int fnc1;
|
||||
unsigned char appid;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Structured append input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_InputList QRinput_InputList;
|
||||
|
||||
struct _QRinput_InputList {
|
||||
QRinput *input;
|
||||
QRinput_InputList *next;
|
||||
};
|
||||
|
||||
struct _QRinput_Struct {
|
||||
int size; ///< number of structured symbols
|
||||
int parity;
|
||||
QRinput_InputList *head;
|
||||
QRinput_InputList *tail;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pack all bit streams padding bits into a byte array.
|
||||
* @param input input data.
|
||||
* @return padded merged byte stream
|
||||
*/
|
||||
extern unsigned char *QRinput_getByteStream(QRinput *input);
|
||||
|
||||
|
||||
extern int QRinput_estimateBitsModeNum(int size);
|
||||
extern int QRinput_estimateBitsModeAn(int size);
|
||||
extern int QRinput_estimateBitsMode8(int size);
|
||||
extern int QRinput_estimateBitsModeKanji(int size);
|
||||
|
||||
extern QRinput *QRinput_dup(QRinput *input);
|
||||
|
||||
extern const signed char QRinput_anTable[128];
|
||||
|
||||
/**
|
||||
* Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
|
||||
* @param __c__ character
|
||||
* @return value
|
||||
*/
|
||||
#define QRinput_lookAnTable(__c__) \
|
||||
((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
|
||||
|
||||
/**
|
||||
* Length of a standard mode indicator in bits.
|
||||
*/
|
||||
|
||||
#define MODE_INDICATOR_SIZE 4
|
||||
|
||||
/**
|
||||
* Length of a segment of structured-append header.
|
||||
*/
|
||||
#define STRUCTURE_HEADER_SIZE 20
|
||||
|
||||
/**
|
||||
* Maximum number of symbols in a set of structured-appended symbols.
|
||||
*/
|
||||
#define MAX_STRUCTURED_SYMBOLS 16
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int QRinput_mergeBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_getBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_estimateBitStreamSize(QRinput *input, int version);
|
||||
extern int QRinput_splitEntry(QRinput_List *entry, int bytes);
|
||||
extern int QRinput_estimateVersion(QRinput *input);
|
||||
extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits);
|
||||
extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity);
|
||||
#endif
|
||||
|
||||
#endif /* QRINPUT_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data chunk class
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRINPUT_H
|
||||
#define QRINPUT_H
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
int QRinput_isSplittableMode(QRencodeMode mode);
|
||||
|
||||
/******************************************************************************
|
||||
* Entry of input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_List QRinput_List;
|
||||
|
||||
struct _QRinput_List {
|
||||
QRencodeMode mode;
|
||||
int size; ///< Size of data chunk (byte).
|
||||
unsigned char *data; ///< Data chunk.
|
||||
BitStream *bstream;
|
||||
QRinput_List *next;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Input Data
|
||||
*****************************************************************************/
|
||||
struct _QRinput {
|
||||
int version;
|
||||
QRecLevel level;
|
||||
QRinput_List *head;
|
||||
QRinput_List *tail;
|
||||
int mqr;
|
||||
int fnc1;
|
||||
unsigned char appid;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Structured append input data
|
||||
*****************************************************************************/
|
||||
typedef struct _QRinput_InputList QRinput_InputList;
|
||||
|
||||
struct _QRinput_InputList {
|
||||
QRinput *input;
|
||||
QRinput_InputList *next;
|
||||
};
|
||||
|
||||
struct _QRinput_Struct {
|
||||
int size; ///< number of structured symbols
|
||||
int parity;
|
||||
QRinput_InputList *head;
|
||||
QRinput_InputList *tail;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pack all bit streams padding bits into a byte array.
|
||||
* @param input input data.
|
||||
* @return padded merged byte stream
|
||||
*/
|
||||
extern unsigned char *QRinput_getByteStream(QRinput *input);
|
||||
|
||||
|
||||
extern int QRinput_estimateBitsModeNum(int size);
|
||||
extern int QRinput_estimateBitsModeAn(int size);
|
||||
extern int QRinput_estimateBitsMode8(int size);
|
||||
extern int QRinput_estimateBitsModeKanji(int size);
|
||||
|
||||
extern QRinput *QRinput_dup(QRinput *input);
|
||||
|
||||
extern const signed char QRinput_anTable[128];
|
||||
|
||||
/**
|
||||
* Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
|
||||
* @param __c__ character
|
||||
* @return value
|
||||
*/
|
||||
#define QRinput_lookAnTable(__c__) \
|
||||
((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
|
||||
|
||||
/**
|
||||
* Length of a standard mode indicator in bits.
|
||||
*/
|
||||
|
||||
#define MODE_INDICATOR_SIZE 4
|
||||
|
||||
/**
|
||||
* Length of a segment of structured-append header.
|
||||
*/
|
||||
#define STRUCTURE_HEADER_SIZE 20
|
||||
|
||||
/**
|
||||
* Maximum number of symbols in a set of structured-appended symbols.
|
||||
*/
|
||||
#define MAX_STRUCTURED_SYMBOLS 16
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
extern int QRinput_mergeBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_getBitStream(QRinput *input, BitStream *bstream);
|
||||
extern int QRinput_estimateBitStreamSize(QRinput *input, int version);
|
||||
extern int QRinput_splitEntry(QRinput_List *entry, int bytes);
|
||||
extern int QRinput_estimateVersion(QRinput *input);
|
||||
extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits);
|
||||
extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity);
|
||||
#endif
|
||||
|
||||
#endif /* QRINPUT_H */
|
||||
|
||||
+514
-514
File diff suppressed because it is too large
Load Diff
+574
-574
File diff suppressed because it is too large
Load Diff
+174
-174
@@ -1,174 +1,174 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRSPEC_H
|
||||
#define QRSPEC_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum width of a symbol
|
||||
*/
|
||||
#define QRSPEC_WIDTH_MAX 177
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bytes)
|
||||
*/
|
||||
extern int QRspec_getDataLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum error correction code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return ECC size (bytes)
|
||||
*/
|
||||
extern int QRspec_getECCLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return a version number that satisfies the input code length.
|
||||
* @param size input code length (byte)
|
||||
* @param level error correction level
|
||||
* @return version number
|
||||
*/
|
||||
extern int QRspec_getMinimumVersion(int size, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the width of the symbol for the version.
|
||||
* @param version vesion of the symbol
|
||||
* @return width of the symbol
|
||||
*/
|
||||
extern int QRspec_getWidth(int version);
|
||||
|
||||
/**
|
||||
* Return the numer of remainder bits.
|
||||
* @param version vesion of the symbol
|
||||
* @return number of remainder bits
|
||||
*/
|
||||
extern int QRspec_getRemainder(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return the size of length indicator for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the size of the appropriate length indicator (bits).
|
||||
*/
|
||||
extern int QRspec_lengthIndicator(QRencodeMode mode, int version);
|
||||
|
||||
/**
|
||||
* Return the maximum length for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the maximum length (bytes)
|
||||
*/
|
||||
extern int QRspec_maximumWords(QRencodeMode mode, int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Error correction code
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return an array of ECC specification.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @param spec an array of ECC specification contains as following:
|
||||
* {# of type1 blocks, # of data code, # of ecc code,
|
||||
* # of type2 blocks, # of data code}
|
||||
*/
|
||||
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]);
|
||||
|
||||
#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3])
|
||||
#define QRspec_rsBlockNum1(__spec__) (__spec__[0])
|
||||
#define QRspec_rsDataCodes1(__spec__) (__spec__[1])
|
||||
#define QRspec_rsEccCodes1(__spec__) (__spec__[2])
|
||||
#define QRspec_rsBlockNum2(__spec__) (__spec__[3])
|
||||
#define QRspec_rsDataCodes2(__spec__) (__spec__[4])
|
||||
#define QRspec_rsEccCodes2(__spec__) (__spec__[2])
|
||||
|
||||
#define QRspec_rsDataLength(__spec__) \
|
||||
((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \
|
||||
(QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__)))
|
||||
#define QRspec_rsEccLength(__spec__) \
|
||||
(QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__))
|
||||
|
||||
/******************************************************************************
|
||||
* Version information pattern
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded version information pattern that is used for the symbol
|
||||
* of version 7 or greater. Use lower 18 bits.
|
||||
* @param version version of the symbol
|
||||
* @return BCH encoded version information pattern
|
||||
*/
|
||||
extern unsigned int QRspec_getVersionPattern(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded format information pattern.
|
||||
* @param mask mask number
|
||||
* @param level error correction level
|
||||
* @return BCH encoded format information pattern
|
||||
*/
|
||||
extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a copy of initialized frame.
|
||||
* @param version version of the symbol
|
||||
* @return Array of unsigned char. You can free it by free().
|
||||
*/
|
||||
extern unsigned char *QRspec_newFrame(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Mode indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Mode indicator. See Table 2 of JIS X0510:2004, pp.16.
|
||||
*/
|
||||
#define QRSPEC_MODEID_ECI 7
|
||||
#define QRSPEC_MODEID_NUM 1
|
||||
#define QRSPEC_MODEID_AN 2
|
||||
#define QRSPEC_MODEID_8 4
|
||||
#define QRSPEC_MODEID_KANJI 8
|
||||
#define QRSPEC_MODEID_FNC1FIRST 5
|
||||
#define QRSPEC_MODEID_FNC1SECOND 9
|
||||
#define QRSPEC_MODEID_STRUCTURE 3
|
||||
#define QRSPEC_MODEID_TERMINATOR 0
|
||||
|
||||
#endif /* QRSPEC_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* QR Code specification in convenient format.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef QRSPEC_H
|
||||
#define QRSPEC_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Version and capacity
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Maximum width of a symbol
|
||||
*/
|
||||
#define QRSPEC_WIDTH_MAX 177
|
||||
|
||||
/**
|
||||
* Return maximum data code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return maximum size (bytes)
|
||||
*/
|
||||
extern int QRspec_getDataLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return maximum error correction code length (bytes) for the version.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @return ECC size (bytes)
|
||||
*/
|
||||
extern int QRspec_getECCLength(int version, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return a version number that satisfies the input code length.
|
||||
* @param size input code length (byte)
|
||||
* @param level error correction level
|
||||
* @return version number
|
||||
*/
|
||||
extern int QRspec_getMinimumVersion(int size, QRecLevel level);
|
||||
|
||||
/**
|
||||
* Return the width of the symbol for the version.
|
||||
* @param version vesion of the symbol
|
||||
* @return width of the symbol
|
||||
*/
|
||||
extern int QRspec_getWidth(int version);
|
||||
|
||||
/**
|
||||
* Return the numer of remainder bits.
|
||||
* @param version vesion of the symbol
|
||||
* @return number of remainder bits
|
||||
*/
|
||||
extern int QRspec_getRemainder(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Length indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return the size of length indicator for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the size of the appropriate length indicator (bits).
|
||||
*/
|
||||
extern int QRspec_lengthIndicator(QRencodeMode mode, int version);
|
||||
|
||||
/**
|
||||
* Return the maximum length for the mode and version.
|
||||
* @param mode encode mode
|
||||
* @param version vesion of the symbol
|
||||
* @return the maximum length (bytes)
|
||||
*/
|
||||
extern int QRspec_maximumWords(QRencodeMode mode, int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Error correction code
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return an array of ECC specification.
|
||||
* @param version version of the symbol
|
||||
* @param level error correction level
|
||||
* @param spec an array of ECC specification contains as following:
|
||||
* {# of type1 blocks, # of data code, # of ecc code,
|
||||
* # of type2 blocks, # of data code}
|
||||
*/
|
||||
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]);
|
||||
|
||||
#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3])
|
||||
#define QRspec_rsBlockNum1(__spec__) (__spec__[0])
|
||||
#define QRspec_rsDataCodes1(__spec__) (__spec__[1])
|
||||
#define QRspec_rsEccCodes1(__spec__) (__spec__[2])
|
||||
#define QRspec_rsBlockNum2(__spec__) (__spec__[3])
|
||||
#define QRspec_rsDataCodes2(__spec__) (__spec__[4])
|
||||
#define QRspec_rsEccCodes2(__spec__) (__spec__[2])
|
||||
|
||||
#define QRspec_rsDataLength(__spec__) \
|
||||
((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \
|
||||
(QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__)))
|
||||
#define QRspec_rsEccLength(__spec__) \
|
||||
(QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__))
|
||||
|
||||
/******************************************************************************
|
||||
* Version information pattern
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded version information pattern that is used for the symbol
|
||||
* of version 7 or greater. Use lower 18 bits.
|
||||
* @param version version of the symbol
|
||||
* @return BCH encoded version information pattern
|
||||
*/
|
||||
extern unsigned int QRspec_getVersionPattern(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Format information
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return BCH encoded format information pattern.
|
||||
* @param mask mask number
|
||||
* @param level error correction level
|
||||
* @return BCH encoded format information pattern
|
||||
*/
|
||||
extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level);
|
||||
|
||||
/******************************************************************************
|
||||
* Frame
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a copy of initialized frame.
|
||||
* @param version version of the symbol
|
||||
* @return Array of unsigned char. You can free it by free().
|
||||
*/
|
||||
extern unsigned char *QRspec_newFrame(int version);
|
||||
|
||||
/******************************************************************************
|
||||
* Mode indicator
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Mode indicator. See Table 2 of JIS X0510:2004, pp.16.
|
||||
*/
|
||||
#define QRSPEC_MODEID_ECI 7
|
||||
#define QRSPEC_MODEID_NUM 1
|
||||
#define QRSPEC_MODEID_AN 2
|
||||
#define QRSPEC_MODEID_8 4
|
||||
#define QRSPEC_MODEID_KANJI 8
|
||||
#define QRSPEC_MODEID_FNC1FIRST 5
|
||||
#define QRSPEC_MODEID_FNC1SECOND 9
|
||||
#define QRSPEC_MODEID_STRUCTURE 3
|
||||
#define QRSPEC_MODEID_TERMINATOR 0
|
||||
|
||||
#endif /* QRSPEC_H */
|
||||
|
||||
+291
-291
@@ -1,291 +1,291 @@
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon encoder. This code is taken from Phil Karn's libfec then
|
||||
* editted and packed into a pair of .c and .h files.
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* (libfec is released under the GNU Lesser General Public License.)
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rscode.h"
|
||||
|
||||
/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs
|
||||
*
|
||||
*/
|
||||
typedef unsigned char data_t;
|
||||
|
||||
|
||||
/**
|
||||
* Reed-Solomon codec control block
|
||||
*/
|
||||
struct _RS {
|
||||
int mm; /* Bits per symbol */
|
||||
int nn; /* Symbols per block (= (1<<mm)-1) */
|
||||
data_t *alpha_to; /* log lookup table */
|
||||
data_t *index_of; /* Antilog lookup table */
|
||||
data_t *genpoly; /* Generator polynomial */
|
||||
int nroots; /* Number of generator roots = number of parity symbols */
|
||||
int fcr; /* First consecutive root, index form */
|
||||
int prim; /* Primitive element, index form */
|
||||
int iprim; /* prim-th root of 1, index form */
|
||||
int pad; /* Padding bytes in shortened block */
|
||||
int gfpoly;
|
||||
struct _RS *next;
|
||||
};
|
||||
|
||||
RS *rslist = NULL;
|
||||
|
||||
static inline int modnn(RS *rs, int x){
|
||||
while (x >= rs->nn) {
|
||||
x -= rs->nn;
|
||||
x = (x >> rs->mm) + (x & rs->nn);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
#define MODNN(x) modnn(rs,x)
|
||||
|
||||
#define MM (rs->mm)
|
||||
#define NN (rs->nn)
|
||||
#define ALPHA_TO (rs->alpha_to)
|
||||
#define INDEX_OF (rs->index_of)
|
||||
#define GENPOLY (rs->genpoly)
|
||||
#define NROOTS (rs->nroots)
|
||||
#define FCR (rs->fcr)
|
||||
#define PRIM (rs->prim)
|
||||
#define IPRIM (rs->iprim)
|
||||
#define PAD (rs->pad)
|
||||
#define A0 (NN)
|
||||
|
||||
|
||||
/* Initialize a Reed-Solomon codec
|
||||
* symsize = symbol size, bits
|
||||
* gfpoly = Field generator polynomial coefficients
|
||||
* fcr = first root of RS code generator polynomial, index form
|
||||
* prim = primitive element to generate polynomial roots
|
||||
* nroots = RS code generator polynomial degree (number of roots)
|
||||
* pad = padding bytes at front of shortened block
|
||||
*/
|
||||
static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
|
||||
/* Common code for intializing a Reed-Solomon control block (char or int symbols)
|
||||
* Copyright 2004 Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
*/
|
||||
//#undef NULL
|
||||
//#define NULL ((RS *)0)
|
||||
|
||||
int i, j, sr,root,iprim;
|
||||
|
||||
rs = NULL;
|
||||
/* Check parameter ranges */
|
||||
if(symsize < 0 || symsize > 8*sizeof(data_t)){
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(fcr < 0 || fcr >= (1<<symsize))
|
||||
goto done;
|
||||
if(prim <= 0 || prim >= (1<<symsize))
|
||||
goto done;
|
||||
if(nroots < 0 || nroots >= (1<<symsize))
|
||||
goto done; /* Can't have more roots than symbol values! */
|
||||
if(pad < 0 || pad >= ((1<<symsize) -1 - nroots))
|
||||
goto done; /* Too much padding */
|
||||
|
||||
rs = (RS *)calloc(1,sizeof(RS));
|
||||
if(rs == NULL)
|
||||
goto done;
|
||||
|
||||
rs->mm = symsize;
|
||||
rs->nn = (1<<symsize)-1;
|
||||
rs->pad = pad;
|
||||
|
||||
rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
|
||||
if(rs->alpha_to == NULL){
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
|
||||
if(rs->index_of == NULL){
|
||||
free(rs->alpha_to);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Generate Galois field lookup tables */
|
||||
rs->index_of[0] = A0; /* log(zero) = -inf */
|
||||
rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
|
||||
sr = 1;
|
||||
for(i=0;i<rs->nn;i++){
|
||||
rs->index_of[sr] = i;
|
||||
rs->alpha_to[i] = sr;
|
||||
sr <<= 1;
|
||||
if(sr & (1<<symsize))
|
||||
sr ^= gfpoly;
|
||||
sr &= rs->nn;
|
||||
}
|
||||
if(sr != 1){
|
||||
/* field generator polynomial is not primitive! */
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Form RS code generator polynomial from its roots */
|
||||
rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1));
|
||||
if(rs->genpoly == NULL){
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
rs->fcr = fcr;
|
||||
rs->prim = prim;
|
||||
rs->nroots = nroots;
|
||||
rs->gfpoly = gfpoly;
|
||||
|
||||
/* Find prim-th root of 1, used in decoding */
|
||||
for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
|
||||
;
|
||||
rs->iprim = iprim / prim;
|
||||
|
||||
rs->genpoly[0] = 1;
|
||||
for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
|
||||
rs->genpoly[i+1] = 1;
|
||||
|
||||
/* Multiply rs->genpoly[] by @**(root + x) */
|
||||
for (j = i; j > 0; j--){
|
||||
if (rs->genpoly[j] != 0)
|
||||
rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
|
||||
else
|
||||
rs->genpoly[j] = rs->genpoly[j-1];
|
||||
}
|
||||
/* rs->genpoly[0] can never be zero */
|
||||
rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
|
||||
}
|
||||
/* convert rs->genpoly[] to index form for quicker encoding */
|
||||
for (i = 0; i <= nroots; i++)
|
||||
rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
|
||||
done:;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
for(rs = rslist; rs != NULL; rs = rs->next) {
|
||||
if(rs->mm != symsize) continue;
|
||||
if(rs->gfpoly != gfpoly) continue;
|
||||
if(rs->fcr != fcr) continue;
|
||||
if(rs->prim != prim) continue;
|
||||
if(rs->nroots != nroots) continue;
|
||||
if(rs->pad != pad) continue;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad);
|
||||
rs->next = rslist;
|
||||
rslist = rs;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
void free_rs_char(RS *rs)
|
||||
{
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs->genpoly);
|
||||
free(rs);
|
||||
}
|
||||
|
||||
/* The guts of the Reed-Solomon encoder, meant to be #included
|
||||
* into a function body with the following typedefs, macros and variables supplied
|
||||
* according to the code parameters:
|
||||
|
||||
* data_t - a typedef for the data symbol
|
||||
* data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded
|
||||
* data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols
|
||||
* NROOTS - the number of roots in the RS code generator polynomial,
|
||||
* which is the same as the number of parity symbols in a block.
|
||||
Integer variable or literal.
|
||||
*
|
||||
* NN - the total number of symbols in a RS block. Integer variable or literal.
|
||||
* PAD - the number of pad symbols in a block. Integer variable or literal.
|
||||
* ALPHA_TO - The address of an array of NN elements to convert Galois field
|
||||
* elements in index (log) form to polynomial form. Read only.
|
||||
* INDEX_OF - The address of an array of NN elements to convert Galois field
|
||||
* elements in polynomial form to index (log) form. Read only.
|
||||
* MODNN - a function to reduce its argument modulo NN. May be inline or a macro.
|
||||
* GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form
|
||||
|
||||
* The memset() and memmove() functions are used. The appropriate header
|
||||
* file declaring these functions (usually <string.h>) must be included by the calling
|
||||
* program.
|
||||
|
||||
* Copyright 2004, Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
*/
|
||||
|
||||
#undef A0
|
||||
#define A0 (NN) /* Special reserved value encoding zero in index form */
|
||||
|
||||
void encode_rs_char(RS *rs, const data_t *data, data_t *parity)
|
||||
{
|
||||
int i, j;
|
||||
data_t feedback;
|
||||
|
||||
memset(parity,0,NROOTS*sizeof(data_t));
|
||||
|
||||
for(i=0;i<NN-NROOTS-PAD;i++){
|
||||
feedback = INDEX_OF[data[i] ^ parity[0]];
|
||||
if(feedback != A0){ /* feedback term is non-zero */
|
||||
#ifdef UNNORMALIZED
|
||||
/* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
|
||||
* always be for the polynomials constructed by init_rs()
|
||||
*/
|
||||
feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
|
||||
#endif
|
||||
for(j=1;j<NROOTS;j++)
|
||||
parity[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
|
||||
}
|
||||
/* Shift */
|
||||
memmove(&parity[0],&parity[1],sizeof(data_t)*(NROOTS-1));
|
||||
if(feedback != A0)
|
||||
parity[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
|
||||
else
|
||||
parity[NROOTS-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon encoder. This code is taken from Phil Karn's libfec then
|
||||
* editted and packed into a pair of .c and .h files.
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* (libfec is released under the GNU Lesser General Public License.)
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rscode.h"
|
||||
|
||||
/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs
|
||||
*
|
||||
*/
|
||||
typedef unsigned char data_t;
|
||||
|
||||
|
||||
/**
|
||||
* Reed-Solomon codec control block
|
||||
*/
|
||||
struct _RS {
|
||||
int mm; /* Bits per symbol */
|
||||
int nn; /* Symbols per block (= (1<<mm)-1) */
|
||||
data_t *alpha_to; /* log lookup table */
|
||||
data_t *index_of; /* Antilog lookup table */
|
||||
data_t *genpoly; /* Generator polynomial */
|
||||
int nroots; /* Number of generator roots = number of parity symbols */
|
||||
int fcr; /* First consecutive root, index form */
|
||||
int prim; /* Primitive element, index form */
|
||||
int iprim; /* prim-th root of 1, index form */
|
||||
int pad; /* Padding bytes in shortened block */
|
||||
int gfpoly;
|
||||
struct _RS *next;
|
||||
};
|
||||
|
||||
RS *rslist = NULL;
|
||||
|
||||
static inline int modnn(RS *rs, int x){
|
||||
while (x >= rs->nn) {
|
||||
x -= rs->nn;
|
||||
x = (x >> rs->mm) + (x & rs->nn);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
#define MODNN(x) modnn(rs,x)
|
||||
|
||||
#define MM (rs->mm)
|
||||
#define NN (rs->nn)
|
||||
#define ALPHA_TO (rs->alpha_to)
|
||||
#define INDEX_OF (rs->index_of)
|
||||
#define GENPOLY (rs->genpoly)
|
||||
#define NROOTS (rs->nroots)
|
||||
#define FCR (rs->fcr)
|
||||
#define PRIM (rs->prim)
|
||||
#define IPRIM (rs->iprim)
|
||||
#define PAD (rs->pad)
|
||||
#define A0 (NN)
|
||||
|
||||
|
||||
/* Initialize a Reed-Solomon codec
|
||||
* symsize = symbol size, bits
|
||||
* gfpoly = Field generator polynomial coefficients
|
||||
* fcr = first root of RS code generator polynomial, index form
|
||||
* prim = primitive element to generate polynomial roots
|
||||
* nroots = RS code generator polynomial degree (number of roots)
|
||||
* pad = padding bytes at front of shortened block
|
||||
*/
|
||||
static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
|
||||
/* Common code for intializing a Reed-Solomon control block (char or int symbols)
|
||||
* Copyright 2004 Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
*/
|
||||
//#undef NULL
|
||||
//#define NULL ((RS *)0)
|
||||
|
||||
int i, j, sr,root,iprim;
|
||||
|
||||
rs = NULL;
|
||||
/* Check parameter ranges */
|
||||
if(symsize < 0 || symsize > 8*sizeof(data_t)){
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(fcr < 0 || fcr >= (1<<symsize))
|
||||
goto done;
|
||||
if(prim <= 0 || prim >= (1<<symsize))
|
||||
goto done;
|
||||
if(nroots < 0 || nroots >= (1<<symsize))
|
||||
goto done; /* Can't have more roots than symbol values! */
|
||||
if(pad < 0 || pad >= ((1<<symsize) -1 - nroots))
|
||||
goto done; /* Too much padding */
|
||||
|
||||
rs = (RS *)calloc(1,sizeof(RS));
|
||||
if(rs == NULL)
|
||||
goto done;
|
||||
|
||||
rs->mm = symsize;
|
||||
rs->nn = (1<<symsize)-1;
|
||||
rs->pad = pad;
|
||||
|
||||
rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
|
||||
if(rs->alpha_to == NULL){
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
|
||||
if(rs->index_of == NULL){
|
||||
free(rs->alpha_to);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Generate Galois field lookup tables */
|
||||
rs->index_of[0] = A0; /* log(zero) = -inf */
|
||||
rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
|
||||
sr = 1;
|
||||
for(i=0;i<rs->nn;i++){
|
||||
rs->index_of[sr] = i;
|
||||
rs->alpha_to[i] = sr;
|
||||
sr <<= 1;
|
||||
if(sr & (1<<symsize))
|
||||
sr ^= gfpoly;
|
||||
sr &= rs->nn;
|
||||
}
|
||||
if(sr != 1){
|
||||
/* field generator polynomial is not primitive! */
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Form RS code generator polynomial from its roots */
|
||||
rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1));
|
||||
if(rs->genpoly == NULL){
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
rs = NULL;
|
||||
goto done;
|
||||
}
|
||||
rs->fcr = fcr;
|
||||
rs->prim = prim;
|
||||
rs->nroots = nroots;
|
||||
rs->gfpoly = gfpoly;
|
||||
|
||||
/* Find prim-th root of 1, used in decoding */
|
||||
for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
|
||||
;
|
||||
rs->iprim = iprim / prim;
|
||||
|
||||
rs->genpoly[0] = 1;
|
||||
for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
|
||||
rs->genpoly[i+1] = 1;
|
||||
|
||||
/* Multiply rs->genpoly[] by @**(root + x) */
|
||||
for (j = i; j > 0; j--){
|
||||
if (rs->genpoly[j] != 0)
|
||||
rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
|
||||
else
|
||||
rs->genpoly[j] = rs->genpoly[j-1];
|
||||
}
|
||||
/* rs->genpoly[0] can never be zero */
|
||||
rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
|
||||
}
|
||||
/* convert rs->genpoly[] to index form for quicker encoding */
|
||||
for (i = 0; i <= nroots; i++)
|
||||
rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
|
||||
done:;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad)
|
||||
{
|
||||
RS *rs;
|
||||
|
||||
for(rs = rslist; rs != NULL; rs = rs->next) {
|
||||
if(rs->mm != symsize) continue;
|
||||
if(rs->gfpoly != gfpoly) continue;
|
||||
if(rs->fcr != fcr) continue;
|
||||
if(rs->prim != prim) continue;
|
||||
if(rs->nroots != nroots) continue;
|
||||
if(rs->pad != pad) continue;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad);
|
||||
rs->next = rslist;
|
||||
rslist = rs;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
void free_rs_char(RS *rs)
|
||||
{
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs->genpoly);
|
||||
free(rs);
|
||||
}
|
||||
|
||||
/* The guts of the Reed-Solomon encoder, meant to be #included
|
||||
* into a function body with the following typedefs, macros and variables supplied
|
||||
* according to the code parameters:
|
||||
|
||||
* data_t - a typedef for the data symbol
|
||||
* data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded
|
||||
* data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols
|
||||
* NROOTS - the number of roots in the RS code generator polynomial,
|
||||
* which is the same as the number of parity symbols in a block.
|
||||
Integer variable or literal.
|
||||
*
|
||||
* NN - the total number of symbols in a RS block. Integer variable or literal.
|
||||
* PAD - the number of pad symbols in a block. Integer variable or literal.
|
||||
* ALPHA_TO - The address of an array of NN elements to convert Galois field
|
||||
* elements in index (log) form to polynomial form. Read only.
|
||||
* INDEX_OF - The address of an array of NN elements to convert Galois field
|
||||
* elements in polynomial form to index (log) form. Read only.
|
||||
* MODNN - a function to reduce its argument modulo NN. May be inline or a macro.
|
||||
* GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form
|
||||
|
||||
* The memset() and memmove() functions are used. The appropriate header
|
||||
* file declaring these functions (usually <string.h>) must be included by the calling
|
||||
* program.
|
||||
|
||||
* Copyright 2004, Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
*/
|
||||
|
||||
#undef A0
|
||||
#define A0 (NN) /* Special reserved value encoding zero in index form */
|
||||
|
||||
void encode_rs_char(RS *rs, const data_t *data, data_t *parity)
|
||||
{
|
||||
int i, j;
|
||||
data_t feedback;
|
||||
|
||||
memset(parity,0,NROOTS*sizeof(data_t));
|
||||
|
||||
for(i=0;i<NN-NROOTS-PAD;i++){
|
||||
feedback = INDEX_OF[data[i] ^ parity[0]];
|
||||
if(feedback != A0){ /* feedback term is non-zero */
|
||||
#ifdef UNNORMALIZED
|
||||
/* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
|
||||
* always be for the polynomials constructed by init_rs()
|
||||
*/
|
||||
feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
|
||||
#endif
|
||||
for(j=1;j<NROOTS;j++)
|
||||
parity[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
|
||||
}
|
||||
/* Shift */
|
||||
memmove(&parity[0],&parity[1],sizeof(data_t)*(NROOTS-1));
|
||||
if(feedback != A0)
|
||||
parity[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
|
||||
else
|
||||
parity[NROOTS-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+47
-47
@@ -1,47 +1,47 @@
|
||||
#ifndef RSCODE_H
|
||||
#define RSCODE_H
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon encoder. This code is taken from Phil Karn's libfec then
|
||||
* editted and packed into a pair of .c and .h files.
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* (libfec is released under the GNU Lesser General Public License.)
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __RSCODE_H__
|
||||
#define __RSCODE_H__
|
||||
|
||||
/*
|
||||
* General purpose RS codec, 8-bit symbols.
|
||||
*/
|
||||
|
||||
typedef struct _RS RS;
|
||||
|
||||
/* WARNING: Thread unsafe!!! */
|
||||
extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad);
|
||||
extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity);
|
||||
extern void free_rs_char(RS *rs);
|
||||
|
||||
#endif /* __RSCODE_H__ */
|
||||
|
||||
|
||||
#endif // RSCODE_H
|
||||
#ifndef RSCODE_H
|
||||
#define RSCODE_H
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon encoder. This code is taken from Phil Karn's libfec then
|
||||
* editted and packed into a pair of .c and .h files.
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* (libfec is released under the GNU Lesser General Public License.)
|
||||
*
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __RSCODE_H__
|
||||
#define __RSCODE_H__
|
||||
|
||||
/*
|
||||
* General purpose RS codec, 8-bit symbols.
|
||||
*/
|
||||
|
||||
typedef struct _RS RS;
|
||||
|
||||
/* WARNING: Thread unsafe!!! */
|
||||
extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad);
|
||||
extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity);
|
||||
extern void free_rs_char(RS *rs);
|
||||
|
||||
#endif /* __RSCODE_H__ */
|
||||
|
||||
|
||||
#endif // RSCODE_H
|
||||
|
||||
+149
-149
@@ -1,149 +1,149 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon error correction code encoder specialized for QR code.
|
||||
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
|
||||
* developed by Phil Karn (KA9Q).
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if HAVE_LIBPTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "rsecc.h"
|
||||
|
||||
#if HAVE_LIBPTHREAD
|
||||
static pthread_mutex_t RSECC_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
#define SYMBOL_SIZE (8)
|
||||
#define symbols ((1U << SYMBOL_SIZE) - 1)
|
||||
static const unsigned int proot = 0x11d; /* stands for x^8+x^4+x^3+x^2+1 (see pp.37 of JIS X0510:2004) */
|
||||
|
||||
/* min/max codeword length of ECC, calculated from the specification. */
|
||||
#define min_length (2)
|
||||
#define max_length (30)
|
||||
#define max_generatorSize (max_length)
|
||||
|
||||
static unsigned char alpha[symbols + 1];
|
||||
static unsigned char aindex[symbols + 1];
|
||||
static unsigned char generator[max_length - min_length + 1][max_generatorSize + 1];
|
||||
static unsigned char generatorInitialized[max_length - min_length + 1];
|
||||
|
||||
static void RSECC_initLookupTable(void)
|
||||
{
|
||||
unsigned int i, b;
|
||||
|
||||
alpha[symbols] = 0;
|
||||
aindex[0] = symbols;
|
||||
|
||||
b = 1;
|
||||
for(i = 0; i < symbols; i++) {
|
||||
alpha[i] = b;
|
||||
aindex[b] = i;
|
||||
b <<= 1;
|
||||
if(b & (symbols + 1)) {
|
||||
b ^= proot;
|
||||
}
|
||||
b &= symbols;
|
||||
}
|
||||
}
|
||||
|
||||
static void RSECC_init(void)
|
||||
{
|
||||
RSECC_initLookupTable();
|
||||
memset(generatorInitialized, 0, (max_length - min_length + 1));
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
static void generator_init(size_t length)
|
||||
{
|
||||
size_t i, j;
|
||||
int g[max_generatorSize + 1];
|
||||
|
||||
g[0] = 1;
|
||||
for(i = 0; i < length; i++) {
|
||||
g[i + 1] = 1;
|
||||
/* Because g[0] never be zero, skipped some conditional checks. */
|
||||
for(j = i; j > 0; j--) {
|
||||
g[j] = g[j - 1] ^ alpha[(aindex[g[j]] + i) % symbols];
|
||||
}
|
||||
g[0] = alpha[(aindex[g[0]] + i) % symbols];
|
||||
}
|
||||
|
||||
for(i = 0; i <= length; i++) {
|
||||
generator[length - min_length][i] = aindex[g[i]];
|
||||
}
|
||||
|
||||
generatorInitialized[length - min_length] = 1;
|
||||
}
|
||||
|
||||
int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc)
|
||||
{
|
||||
size_t i, j;
|
||||
unsigned char feedback;
|
||||
unsigned char *gen;
|
||||
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&RSECC_mutex);
|
||||
#endif
|
||||
if(!initialized) {
|
||||
RSECC_init();
|
||||
}
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&RSECC_mutex);
|
||||
#endif
|
||||
|
||||
if(ecc_length > max_length) return -1;
|
||||
|
||||
memset(ecc, 0, ecc_length);
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&RSECC_mutex);
|
||||
#endif
|
||||
if(!generatorInitialized[ecc_length - min_length]) generator_init(ecc_length);
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&RSECC_mutex);
|
||||
#endif
|
||||
gen = generator[ecc_length - min_length];
|
||||
|
||||
for(i = 0; i < data_length; i++) {
|
||||
feedback = aindex[data[i] ^ ecc[0]];
|
||||
if(feedback != symbols) {
|
||||
for(j = 1; j < ecc_length; j++) {
|
||||
ecc[j] ^= alpha[(unsigned int)(feedback + gen[ecc_length - j]) % symbols];
|
||||
}
|
||||
}
|
||||
memmove(&ecc[0], &ecc[1], ecc_length - 1);
|
||||
if(feedback != symbols) {
|
||||
ecc[ecc_length - 1] = alpha[(unsigned int)(feedback + gen[0]) % symbols];
|
||||
} else {
|
||||
ecc[ecc_length - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon error correction code encoder specialized for QR code.
|
||||
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
|
||||
* developed by Phil Karn (KA9Q).
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if HAVE_LIBPTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "rsecc.h"
|
||||
|
||||
#if HAVE_LIBPTHREAD
|
||||
static pthread_mutex_t RSECC_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
#define SYMBOL_SIZE (8)
|
||||
#define symbols ((1U << SYMBOL_SIZE) - 1)
|
||||
static const unsigned int proot = 0x11d; /* stands for x^8+x^4+x^3+x^2+1 (see pp.37 of JIS X0510:2004) */
|
||||
|
||||
/* min/max codeword length of ECC, calculated from the specification. */
|
||||
#define min_length (2)
|
||||
#define max_length (30)
|
||||
#define max_generatorSize (max_length)
|
||||
|
||||
static unsigned char alpha[symbols + 1];
|
||||
static unsigned char aindex[symbols + 1];
|
||||
static unsigned char generator[max_length - min_length + 1][max_generatorSize + 1];
|
||||
static unsigned char generatorInitialized[max_length - min_length + 1];
|
||||
|
||||
static void RSECC_initLookupTable(void)
|
||||
{
|
||||
unsigned int i, b;
|
||||
|
||||
alpha[symbols] = 0;
|
||||
aindex[0] = symbols;
|
||||
|
||||
b = 1;
|
||||
for(i = 0; i < symbols; i++) {
|
||||
alpha[i] = b;
|
||||
aindex[b] = i;
|
||||
b <<= 1;
|
||||
if(b & (symbols + 1)) {
|
||||
b ^= proot;
|
||||
}
|
||||
b &= symbols;
|
||||
}
|
||||
}
|
||||
|
||||
static void RSECC_init(void)
|
||||
{
|
||||
RSECC_initLookupTable();
|
||||
memset(generatorInitialized, 0, (max_length - min_length + 1));
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
static void generator_init(size_t length)
|
||||
{
|
||||
size_t i, j;
|
||||
int g[max_generatorSize + 1];
|
||||
|
||||
g[0] = 1;
|
||||
for(i = 0; i < length; i++) {
|
||||
g[i + 1] = 1;
|
||||
/* Because g[0] never be zero, skipped some conditional checks. */
|
||||
for(j = i; j > 0; j--) {
|
||||
g[j] = g[j - 1] ^ alpha[(aindex[g[j]] + i) % symbols];
|
||||
}
|
||||
g[0] = alpha[(aindex[g[0]] + i) % symbols];
|
||||
}
|
||||
|
||||
for(i = 0; i <= length; i++) {
|
||||
generator[length - min_length][i] = aindex[g[i]];
|
||||
}
|
||||
|
||||
generatorInitialized[length - min_length] = 1;
|
||||
}
|
||||
|
||||
int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc)
|
||||
{
|
||||
size_t i, j;
|
||||
unsigned char feedback;
|
||||
unsigned char *gen;
|
||||
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&RSECC_mutex);
|
||||
#endif
|
||||
if(!initialized) {
|
||||
RSECC_init();
|
||||
}
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&RSECC_mutex);
|
||||
#endif
|
||||
|
||||
if(ecc_length > max_length) return -1;
|
||||
|
||||
memset(ecc, 0, ecc_length);
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&RSECC_mutex);
|
||||
#endif
|
||||
if(!generatorInitialized[ecc_length - min_length]) generator_init(ecc_length);
|
||||
#if HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&RSECC_mutex);
|
||||
#endif
|
||||
gen = generator[ecc_length - min_length];
|
||||
|
||||
for(i = 0; i < data_length; i++) {
|
||||
feedback = aindex[data[i] ^ ecc[0]];
|
||||
if(feedback != symbols) {
|
||||
for(j = 1; j < ecc_length; j++) {
|
||||
ecc[j] ^= alpha[(unsigned int)(feedback + gen[ecc_length - j]) % symbols];
|
||||
}
|
||||
}
|
||||
memmove(&ecc[0], &ecc[1], ecc_length - 1);
|
||||
if(feedback != symbols) {
|
||||
ecc[ecc_length - 1] = alpha[(unsigned int)(feedback + gen[0]) % symbols];
|
||||
} else {
|
||||
ecc[ecc_length - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+31
-31
@@ -1,31 +1,31 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon error correction code encoder specialized for QR code.
|
||||
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
|
||||
* developed by Phil Karn (KA9Q).
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RSECC_H
|
||||
#define RSECC_H
|
||||
|
||||
extern int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc);
|
||||
|
||||
#endif /* RSECC_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Reed solomon error correction code encoder specialized for QR code.
|
||||
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
|
||||
* developed by Phil Karn (KA9Q).
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RSECC_H
|
||||
#define RSECC_H
|
||||
|
||||
extern int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc);
|
||||
|
||||
#endif /* RSECC_H */
|
||||
|
||||
+323
-323
@@ -1,323 +1,323 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "qrencode.h"
|
||||
#include "qrinput.h"
|
||||
#include "qrspec.h"
|
||||
#include "split.h"
|
||||
|
||||
#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
|
||||
#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
|
||||
|
||||
#if !HAVE_STRDUP
|
||||
#undef strdup
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
size_t len = strlen(s) + 1;
|
||||
void *newstring = malloc(len);
|
||||
if(newstring == NULL) return NULL;
|
||||
return (char *)memcpy(newstring, s, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint)
|
||||
{
|
||||
unsigned char c, d;
|
||||
unsigned int word;
|
||||
|
||||
c = (unsigned char)string[0];
|
||||
|
||||
if(c == '\0') return QR_MODE_NUL;
|
||||
if(isdigit(c)) {
|
||||
return QR_MODE_NUM;
|
||||
} else if(isalnum(c)) {
|
||||
return QR_MODE_AN;
|
||||
} else if(hint == QR_MODE_KANJI) {
|
||||
d = (unsigned char)string[1];
|
||||
if(d != '\0') {
|
||||
word = ((unsigned int)c << 8) | d;
|
||||
if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) {
|
||||
return QR_MODE_KANJI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QR_MODE_8;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint);
|
||||
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint);
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint)
|
||||
{
|
||||
const char *p;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int ln;
|
||||
QRencodeMode mode;
|
||||
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
|
||||
p = string;
|
||||
while(isdigit(*p)) {
|
||||
p++;
|
||||
}
|
||||
run = (int)(p - string);
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_8) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, hint);
|
||||
}
|
||||
}
|
||||
if(mode == QR_MODE_AN) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsModeAn(1) /* + 4 + la */
|
||||
- QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
|
||||
if(dif > 0) {
|
||||
return Split_eatAn(string, input, hint);
|
||||
}
|
||||
}
|
||||
|
||||
ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p, *q;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
|
||||
p = string;
|
||||
while(isalnum(*p)) {
|
||||
if(isdigit(*p)) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsModeAn((int)(p - string)) /* + 4 + la */
|
||||
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
|
||||
+ (isalnum(*q)?(4 + ln):0)
|
||||
- QRinput_estimateBitsModeAn((int)(q - string)) /* - 4 - la */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = (int)(p - string);
|
||||
|
||||
if(*p && !isalnum(*p)) {
|
||||
dif = QRinput_estimateBitsModeAn(run) + 4 + la
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, hint);
|
||||
}
|
||||
}
|
||||
|
||||
ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p;
|
||||
int ret;
|
||||
int run;
|
||||
|
||||
p = string;
|
||||
while(Split_identifyMode(p, hint) == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
}
|
||||
run = (int)(p - string);
|
||||
ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p, *q;
|
||||
QRencodeMode mode;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln, l8;
|
||||
int swcost;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
l8 = QRspec_lengthIndicator(QR_MODE_8, input->version);
|
||||
|
||||
p = string + 1;
|
||||
while(*p != '\0') {
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
break;
|
||||
}
|
||||
if(mode == QR_MODE_NUM) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
if(Split_identifyMode(q, hint) == QR_MODE_8) {
|
||||
swcost = 4 + l8;
|
||||
} else {
|
||||
swcost = 0;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
|
||||
+ swcost
|
||||
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else if(mode == QR_MODE_AN) {
|
||||
q = p;
|
||||
while(isalnum(*q)) {
|
||||
q++;
|
||||
}
|
||||
if(Split_identifyMode(q, hint) == QR_MODE_8) {
|
||||
swcost = 4 + l8;
|
||||
} else {
|
||||
swcost = 0;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeAn((int)(q - p)) + 4 + la
|
||||
+ swcost
|
||||
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = (int)(p - string);
|
||||
ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_splitString(const char *string, QRinput *input,
|
||||
QRencodeMode hint)
|
||||
{
|
||||
int length;
|
||||
QRencodeMode mode;
|
||||
|
||||
while(*string != '\0') {
|
||||
mode = Split_identifyMode(string, hint);
|
||||
if(mode == QR_MODE_NUM) {
|
||||
length = Split_eatNum(string, input, hint);
|
||||
} else if(mode == QR_MODE_AN) {
|
||||
length = Split_eatAn(string, input, hint);
|
||||
} else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
|
||||
length = Split_eatKanji(string, input, hint);
|
||||
} else {
|
||||
length = Split_eat8(string, input, hint);
|
||||
}
|
||||
if(length == 0) break;
|
||||
if(length < 0) return -1;
|
||||
string += length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *dupAndToUpper(const char *str, QRencodeMode hint)
|
||||
{
|
||||
char *newstr, *p;
|
||||
QRencodeMode mode;
|
||||
|
||||
newstr = strdup(str);
|
||||
if(newstr == NULL) return NULL;
|
||||
|
||||
p = newstr;
|
||||
while(*p != '\0') {
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
} else {
|
||||
if (*p >= 'a' && *p <= 'z') {
|
||||
*p = (char)((int)*p - 32);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return newstr;
|
||||
}
|
||||
|
||||
int Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
char *newstr;
|
||||
int ret;
|
||||
|
||||
if(string == NULL || *string == '\0') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if(!casesensitive) {
|
||||
newstr = dupAndToUpper(string, hint);
|
||||
if(newstr == NULL) return -1;
|
||||
ret = Split_splitString(newstr, input, hint);
|
||||
free(newstr);
|
||||
} else {
|
||||
ret = Split_splitString(string, input, hint);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "qrencode.h"
|
||||
#include "qrinput.h"
|
||||
#include "qrspec.h"
|
||||
#include "split.h"
|
||||
|
||||
#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
|
||||
#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
|
||||
|
||||
#if !HAVE_STRDUP
|
||||
#undef strdup
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
size_t len = strlen(s) + 1;
|
||||
void *newstring = malloc(len);
|
||||
if(newstring == NULL) return NULL;
|
||||
return (char *)memcpy(newstring, s, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint)
|
||||
{
|
||||
unsigned char c, d;
|
||||
unsigned int word;
|
||||
|
||||
c = (unsigned char)string[0];
|
||||
|
||||
if(c == '\0') return QR_MODE_NUL;
|
||||
if(isdigit(c)) {
|
||||
return QR_MODE_NUM;
|
||||
} else if(isalnum(c)) {
|
||||
return QR_MODE_AN;
|
||||
} else if(hint == QR_MODE_KANJI) {
|
||||
d = (unsigned char)string[1];
|
||||
if(d != '\0') {
|
||||
word = ((unsigned int)c << 8) | d;
|
||||
if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) {
|
||||
return QR_MODE_KANJI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QR_MODE_8;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint);
|
||||
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint);
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint)
|
||||
{
|
||||
const char *p;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int ln;
|
||||
QRencodeMode mode;
|
||||
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
|
||||
p = string;
|
||||
while(isdigit(*p)) {
|
||||
p++;
|
||||
}
|
||||
run = (int)(p - string);
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_8) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, hint);
|
||||
}
|
||||
}
|
||||
if(mode == QR_MODE_AN) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsModeAn(1) /* + 4 + la */
|
||||
- QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
|
||||
if(dif > 0) {
|
||||
return Split_eatAn(string, input, hint);
|
||||
}
|
||||
}
|
||||
|
||||
ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p, *q;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
|
||||
p = string;
|
||||
while(isalnum(*p)) {
|
||||
if(isdigit(*p)) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsModeAn((int)(p - string)) /* + 4 + la */
|
||||
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
|
||||
+ (isalnum(*q)?(4 + ln):0)
|
||||
- QRinput_estimateBitsModeAn((int)(q - string)) /* - 4 - la */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = (int)(p - string);
|
||||
|
||||
if(*p && !isalnum(*p)) {
|
||||
dif = QRinput_estimateBitsModeAn(run) + 4 + la
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, hint);
|
||||
}
|
||||
}
|
||||
|
||||
ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p;
|
||||
int ret;
|
||||
int run;
|
||||
|
||||
p = string;
|
||||
while(Split_identifyMode(p, hint) == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
}
|
||||
run = (int)(p - string);
|
||||
ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint)
|
||||
{
|
||||
const char *p, *q;
|
||||
QRencodeMode mode;
|
||||
int ret;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln, l8;
|
||||
int swcost;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
|
||||
l8 = QRspec_lengthIndicator(QR_MODE_8, input->version);
|
||||
|
||||
p = string + 1;
|
||||
while(*p != '\0') {
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
break;
|
||||
}
|
||||
if(mode == QR_MODE_NUM) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
if(Split_identifyMode(q, hint) == QR_MODE_8) {
|
||||
swcost = 4 + l8;
|
||||
} else {
|
||||
swcost = 0;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
|
||||
+ swcost
|
||||
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else if(mode == QR_MODE_AN) {
|
||||
q = p;
|
||||
while(isalnum(*q)) {
|
||||
q++;
|
||||
}
|
||||
if(Split_identifyMode(q, hint) == QR_MODE_8) {
|
||||
swcost = 4 + l8;
|
||||
} else {
|
||||
swcost = 0;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeAn((int)(q - p)) + 4 + la
|
||||
+ swcost
|
||||
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
}
|
||||
p = q;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = (int)(p - string);
|
||||
ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string);
|
||||
if(ret < 0) return -1;
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_splitString(const char *string, QRinput *input,
|
||||
QRencodeMode hint)
|
||||
{
|
||||
int length;
|
||||
QRencodeMode mode;
|
||||
|
||||
while(*string != '\0') {
|
||||
mode = Split_identifyMode(string, hint);
|
||||
if(mode == QR_MODE_NUM) {
|
||||
length = Split_eatNum(string, input, hint);
|
||||
} else if(mode == QR_MODE_AN) {
|
||||
length = Split_eatAn(string, input, hint);
|
||||
} else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
|
||||
length = Split_eatKanji(string, input, hint);
|
||||
} else {
|
||||
length = Split_eat8(string, input, hint);
|
||||
}
|
||||
if(length == 0) break;
|
||||
if(length < 0) return -1;
|
||||
string += length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *dupAndToUpper(const char *str, QRencodeMode hint)
|
||||
{
|
||||
char *newstr, *p;
|
||||
QRencodeMode mode;
|
||||
|
||||
newstr = strdup(str);
|
||||
if(newstr == NULL) return NULL;
|
||||
|
||||
p = newstr;
|
||||
while(*p != '\0') {
|
||||
mode = Split_identifyMode(p, hint);
|
||||
if(mode == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
} else {
|
||||
if (*p >= 'a' && *p <= 'z') {
|
||||
*p = (char)((int)*p - 32);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return newstr;
|
||||
}
|
||||
|
||||
int Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
char *newstr;
|
||||
int ret;
|
||||
|
||||
if(string == NULL || *string == '\0') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if(!casesensitive) {
|
||||
newstr = dupAndToUpper(string, hint);
|
||||
if(newstr == NULL) return -1;
|
||||
ret = Split_splitString(newstr, input, hint);
|
||||
free(newstr);
|
||||
} else {
|
||||
ret = Split_splitString(string, input, hint);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+213
-213
@@ -1,213 +1,213 @@
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrinput.h"
|
||||
#include "qrspec.h"
|
||||
#include "split.h"
|
||||
|
||||
#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
|
||||
#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eatAn(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eat8(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eatKanji(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p;
|
||||
int run;
|
||||
int dif;
|
||||
int ln;
|
||||
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(isdigit(*p)) {
|
||||
p++;
|
||||
}
|
||||
run = p - string;
|
||||
if(*p & 0x80) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
if(isalnum(*p) && !casesensitive) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsModeAn(1) /* + 4 + la */
|
||||
- QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
|
||||
if(dif > 0) {
|
||||
return Split_eatAn(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p, *q;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
if(casesensitive) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(isalnum(*p)) {
|
||||
if(isdigit(*p)) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsModeAn(p - string) /* + 4 + la */
|
||||
+ QRinput_estimateBitsModeNum(q - p) + 4 + ln
|
||||
- QRinput_estimateBitsModeAn(q - string) /* - 4 - la */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = p - string;
|
||||
|
||||
if(*p & 0x80) {
|
||||
dif = QRinput_estimateBitsModeAn(run) + 4 + la
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatKanji(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = string;
|
||||
while(QRinput_identifyMode(p) == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
}
|
||||
QRinput_append(input, QR_MODE_KANJI, p - string, (unsigned char *)string);
|
||||
return p - string;
|
||||
}
|
||||
|
||||
static int Split_eat8(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p, *q;
|
||||
QRencodeMode mode;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(*p != '\0') {
|
||||
mode = QRinput_identifyMode(p);
|
||||
if(hint == QR_MODE_KANJI && mode == QR_MODE_KANJI) {
|
||||
break;
|
||||
}
|
||||
if(mode != QR_MODE_8 && mode != QR_MODE_KANJI) {
|
||||
if(mode == QR_MODE_NUM) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeNum(q - p) + 4 + ln
|
||||
- QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else if(!casesensitive) {
|
||||
q = p;
|
||||
while(isalnum(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeAn(q - p) + 4 + la
|
||||
- QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_8, p - string, (unsigned char *)string);
|
||||
return p - string;
|
||||
}
|
||||
|
||||
void Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
int length;
|
||||
QRencodeMode mode;
|
||||
|
||||
if(*string == '\0') return;
|
||||
|
||||
mode = QRinput_identifyMode(string);
|
||||
if(mode == QR_MODE_NUM) {
|
||||
length = Split_eatNum(string, input, version, hint, casesensitive);
|
||||
} else if(mode == QR_MODE_AN && !casesensitive) {
|
||||
length = Split_eatAn(string, input, version, hint, casesensitive);
|
||||
} else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
|
||||
length = Split_eatKanji(string, input, version, hint, casesensitive);
|
||||
} else {
|
||||
length = Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
if(length == 0) return;
|
||||
Split_splitStringToQRinput(&string[length], input, hint, mode, casesensitive);
|
||||
}
|
||||
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "qrencode.h"
|
||||
#include "qrinput.h"
|
||||
#include "qrspec.h"
|
||||
#include "split.h"
|
||||
|
||||
#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
|
||||
#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eatAn(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eat8(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
static int Split_eatKanji(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive);
|
||||
|
||||
static int Split_eatNum(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p;
|
||||
int run;
|
||||
int dif;
|
||||
int ln;
|
||||
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(isdigit(*p)) {
|
||||
p++;
|
||||
}
|
||||
run = p - string;
|
||||
if(*p & 0x80) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
if(isalnum(*p) && !casesensitive) {
|
||||
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
|
||||
+ QRinput_estimateBitsModeAn(1) /* + 4 + la */
|
||||
- QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
|
||||
if(dif > 0) {
|
||||
return Split_eatAn(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatAn(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p, *q;
|
||||
int run;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
if(casesensitive) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(isalnum(*p)) {
|
||||
if(isdigit(*p)) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsModeAn(p - string) /* + 4 + la */
|
||||
+ QRinput_estimateBitsModeNum(q - p) + 4 + ln
|
||||
- QRinput_estimateBitsModeAn(q - string) /* - 4 - la */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
run = p - string;
|
||||
|
||||
if(*p & 0x80) {
|
||||
dif = QRinput_estimateBitsModeAn(run) + 4 + la
|
||||
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
|
||||
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
|
||||
if(dif > 0) {
|
||||
return Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
|
||||
return run;
|
||||
}
|
||||
|
||||
static int Split_eatKanji(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = string;
|
||||
while(QRinput_identifyMode(p) == QR_MODE_KANJI) {
|
||||
p += 2;
|
||||
}
|
||||
QRinput_append(input, QR_MODE_KANJI, p - string, (unsigned char *)string);
|
||||
return p - string;
|
||||
}
|
||||
|
||||
static int Split_eat8(const char *string, QRinput *input, int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
const char *p, *q;
|
||||
QRencodeMode mode;
|
||||
int dif;
|
||||
int la, ln;
|
||||
|
||||
la = QRspec_lengthIndicator(QR_MODE_AN, version);
|
||||
ln = QRspec_lengthIndicator(QR_MODE_NUM, version);
|
||||
|
||||
p = string;
|
||||
while(*p != '\0') {
|
||||
mode = QRinput_identifyMode(p);
|
||||
if(hint == QR_MODE_KANJI && mode == QR_MODE_KANJI) {
|
||||
break;
|
||||
}
|
||||
if(mode != QR_MODE_8 && mode != QR_MODE_KANJI) {
|
||||
if(mode == QR_MODE_NUM) {
|
||||
q = p;
|
||||
while(isdigit(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeNum(q - p) + 4 + ln
|
||||
- QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else if(!casesensitive) {
|
||||
q = p;
|
||||
while(isalnum(*q)) {
|
||||
q++;
|
||||
}
|
||||
dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */
|
||||
+ QRinput_estimateBitsModeAn(q - p) + 4 + la
|
||||
- QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */;
|
||||
if(dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
p = q;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
QRinput_append(input, QR_MODE_8, p - string, (unsigned char *)string);
|
||||
return p - string;
|
||||
}
|
||||
|
||||
void Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
int version, QRencodeMode hint, int casesensitive)
|
||||
{
|
||||
int length;
|
||||
QRencodeMode mode;
|
||||
|
||||
if(*string == '\0') return;
|
||||
|
||||
mode = QRinput_identifyMode(string);
|
||||
if(mode == QR_MODE_NUM) {
|
||||
length = Split_eatNum(string, input, version, hint, casesensitive);
|
||||
} else if(mode == QR_MODE_AN && !casesensitive) {
|
||||
length = Split_eatAn(string, input, version, hint, casesensitive);
|
||||
} else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
|
||||
length = Split_eatKanji(string, input, version, hint, casesensitive);
|
||||
} else {
|
||||
length = Split_eat8(string, input, version, hint, casesensitive);
|
||||
}
|
||||
if(length == 0) return;
|
||||
Split_splitStringToQRinput(&string[length], input, hint, mode, casesensitive);
|
||||
}
|
||||
|
||||
+47
-47
@@ -1,47 +1,47 @@
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef SPLIT_H
|
||||
#define SPLIT_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/**
|
||||
* Split the input string (null terminated) into QRinput.
|
||||
* @param string input string
|
||||
* @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8.
|
||||
* @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS.
|
||||
* @retval 0 success.
|
||||
* @retval -1 an error occurred. errno is set to indicate the error. See
|
||||
* Exceptions for the details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
*/
|
||||
extern int Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
QRencodeMode hint, int casesensitive);
|
||||
|
||||
#endif /* SPLIT_H */
|
||||
/*
|
||||
* qrencode - QR Code encoder
|
||||
*
|
||||
* Input data splitter.
|
||||
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef SPLIT_H
|
||||
#define SPLIT_H
|
||||
|
||||
#include "qrencode.h"
|
||||
|
||||
/**
|
||||
* Split the input string (null terminated) into QRinput.
|
||||
* @param string input string
|
||||
* @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8.
|
||||
* @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS.
|
||||
* @retval 0 success.
|
||||
* @retval -1 an error occurred. errno is set to indicate the error. See
|
||||
* Exceptions for the details.
|
||||
* @throw EINVAL invalid input object.
|
||||
* @throw ENOMEM unable to allocate memory for input objects.
|
||||
*/
|
||||
extern int Split_splitStringToQRinput(const char *string, QRinput *input,
|
||||
QRencodeMode hint, int casesensitive);
|
||||
|
||||
#endif /* SPLIT_H */
|
||||
|
||||
Reference in New Issue
Block a user