Skip to content

Commit

Permalink
QRencode_encodeStringMQR() and its 8bit version are added.
Browse files Browse the repository at this point in the history
QRcode_encodeMaskMQR() has been added.
  • Loading branch information
fukuchi committed Jun 3, 2009
1 parent db35a2e commit f832f44
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 36 deletions.
171 changes: 135 additions & 36 deletions qrencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "rscode.h"
#include "split.h"
#include "mask.h"
#include "mmask.h"

/******************************************************************************
* Raw code
Expand Down Expand Up @@ -200,6 +201,7 @@ typedef struct {
unsigned char *datacode;
unsigned char *ecccode;
RSblock *rsblock;
int oddbits;
int count;
} MQRRawCode;

Expand All @@ -208,14 +210,14 @@ __STATIC MQRRawCode *MQRraw_new(QRinput *input)
{
MQRRawCode *raw;
RS *rs;
int dl;

raw = (MQRRawCode *)malloc(sizeof(MQRRawCode));
if(raw == NULL) return NULL;

raw->version = input->version;
raw->dataLength = MQRspec_getDataLength(input->version, input->level);
raw->eccLength = MQRspec_getECCLength(input->version, input->level);
raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level);
raw->datacode = QRinput_getByteStream(input);
if(raw->datacode == NULL) {
free(raw);
Expand All @@ -228,14 +230,19 @@ __STATIC MQRRawCode *MQRraw_new(QRinput *input)
return NULL;
}

dl = (raw->dataLength + 4)/ 8; // M1 and M3 has 4 bit length data code.
rs = init_rs(8, 0x11d, 0, 1, raw->eccLength, 255 - dl - raw->eccLength);
raw->rsblock = (RSblock *)calloc(sizeof(RSblock), 1);
if(raw->rsblock == NULL) {
MQRraw_free(raw);
return NULL;
}

rs = init_rs(8, 0x11d, 0, 1, raw->eccLength, 255 - raw->dataLength - raw->eccLength);
if(rs == NULL) {
MQRraw_free(raw);
return NULL;
}

RSblock_initBlock(raw->rsblock, dl, raw->datacode, raw->eccLength, raw->ecccode, rs);
RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode, rs);

raw->count = 0;

Expand All @@ -247,7 +254,6 @@ __STATIC MQRRawCode *MQRraw_new(QRinput *input)
* This function can be called iteratively.
* @param raw raw code.
* @return code
* FIXME: M1 and M3 has 4bit-length data code!
*/
__STATIC unsigned char MQRraw_getCode(MQRRawCode *raw)
{
Expand Down Expand Up @@ -332,20 +338,21 @@ static unsigned char *FrameFiller_next(FrameFiller *filler)
y = 0;
x -= 2;
filler->dir = 1;
if(x == 6) {
x--;
y = 9;
}
// FIXME: _nextMQR is needed?
// 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 == 6) {
// x--;
// y -= 8;
// }
}
}
if(x < 0 || y < 0) return NULL;
Expand All @@ -357,6 +364,7 @@ static unsigned char *FrameFiller_next(FrameFiller *filler)
// This tail recursion could be optimized.
return FrameFiller_next(filler);
}
printf("%d,%d\n", x, y);
return &p[y * w + x];
}

Expand Down Expand Up @@ -438,6 +446,10 @@ __STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask)
int i, j;
QRcode *qrcode;

if(input->mqr) {
errno = EINVAL;
return NULL;
}
if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) {
errno = EINVAL;
return NULL;
Expand Down Expand Up @@ -499,62 +511,149 @@ __STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask)
return qrcode;
}

QRcode *QRcode_encodeInput(QRinput *input)
{
return QRcode_encodeMask(input, -1);
}

QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
__STATIC QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask)
{
QRinput *input;
QRcode *code;
int ret;
int width, version;
MQRRawCode *raw;
unsigned char *frame, *masked, *p, code, bit;
FrameFiller *filler;
int i, j;
QRcode *qrcode;

if(string == NULL) {
if(!input->mqr) {
errno = EINVAL;
return NULL;
}
if(input->version < 0 || input->version > MQRSPEC_VERSION_MAX) {
errno = EINVAL;
return NULL;
}
if(input->level > QR_ECLEVEL_Q) {
errno = EINVAL;
return NULL;
}

input = QRinput_new2(version, level);
if(input == NULL) return NULL;
raw = MQRraw_new(input);
if(raw == NULL) return NULL;

ret = QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
if(ret < 0) {
QRinput_free(input);
version = raw->version;
width = MQRspec_getWidth(version);
frame = MQRspec_newFrame(version);
if(frame == NULL) {
MQRraw_free(raw);
return NULL;
}
filler = FrameFiller_new(width, frame);
if(filler == NULL) {
MQRraw_free(raw);
free(frame);
return NULL;
}
code = QRcode_encodeInput(input);
QRinput_free(input);

return code;
/* inteleaved data and ecc codes */
for(i=0; i<raw->dataLength + raw->eccLength; i++) {
code = MQRraw_getCode(raw);
if(raw->oddbits && i == raw->dataLength - 1) {
bit = 1 << raw->oddbits;
for(j=0; j<raw->oddbits; j++) {
p = FrameFiller_next(filler);
*p = 0x02 | ((bit & code) != 0);
bit = bit >> 1;
}
} else {
bit = 0x80;
for(j=0; j<8; j++) {
p = FrameFiller_next(filler);
*p = 0x02 | ((bit & code) != 0);
bit = bit >> 1;
}
}
}
MQRraw_free(raw);
free(filler);
/* masking */
if(mask < 0) {
masked = MMask_mask(version, frame, input->level);
} else {
masked = MMask_makeMask(version, frame, mask, input->level);
}
if(masked == NULL) {
free(frame);
return NULL;
}
qrcode = QRcode_new(version, width, masked);

free(frame);

return qrcode;
}

QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
QRcode *QRcode_encodeInput(QRinput *input)
{
if(input->mqr) {
return QRcode_encodeMaskMQR(input, -1);
} else {
return QRcode_encodeMask(input, -1);
}
}

static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int eightbit, int mqr, QRencodeMode hint, int casesensitive)
{
QRinput *input;
QRcode *code;
int ret;

if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
if(string == NULL) {
errno = EINVAL;
return NULL;
}
if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) {
errno = EINVAL;
return NULL;
}

input = QRinput_new2(version, level);
if(mqr) {
input = QRinput_newMQR(version, level);
} else {
input = QRinput_new2(version, level);
}
if(input == NULL) return NULL;

ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
if(eightbit) {
ret = QRinput_append(input, QR_MODE_8, strlen(string), (unsigned char *)string);
} else {
ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
}
if(ret < 0) {
QRinput_free(input);
return NULL;
}

code = QRcode_encodeInput(input);
QRinput_free(input);

return code;
}

QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
{
return QRcode_encodeStringReal(string, version, level, 1, 0, QR_MODE_NUL, 0);
}

QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
{
return QRcode_encodeStringReal(string, version, level, 0, 0, hint, casesensitive);
}

QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level)
{
return QRcode_encodeStringReal(string, version, level, 1, 1, QR_MODE_NUL, 0);
}

QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
{
return QRcode_encodeStringReal(string, version, level, 0, 1, hint, casesensitive);
}

/******************************************************************************
* Structured QR-code encoding
*****************************************************************************/
Expand Down
12 changes: 12 additions & 0 deletions qrencode.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,18 @@ extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel le
*/
extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level);

/**
* Micro QR Code version of QRcode_encodeString().
* @warning This function is THREAD UNSAFE.
*/
extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);

/**
* Micro QR Code version of QRcode_encodeString8bit().
* @warning This function is THREAD UNSAFE.
*/
extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level);

/**
* Free the instance of QRcode class.
* @param qrcode an instance of QRcode class.
Expand Down
1 change: 1 addition & 0 deletions qrencode_inner.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ extern unsigned char *FrameFiller_fillerTest(int version);
* QR-code encoding
*****************************************************************************/
extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);

/******************************************************************************
* Mask
Expand Down

0 comments on commit f832f44

Please sign in to comment.