#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#ifdef __cplusplus
}
#endif
#include "qrencode.h"
#ifdef UNDER_LIBQRENCODE_1_0_2
QRcode *encode(const char *text,
int version,
QRecLevel level,
QRencodeMode mode,
int casesensitive)
{
QRcode *code;
if(casesensitive) {
code = QRcode_encodeStringCase(text, version, level);
} else {
code = QRcode_encodeString(text, version, level, mode);
}
return code;
}
#else
QRcode *encode(const char *text,
int version,
QRecLevel level,
QRencodeMode mode,
int casesensitive)
{
QRcode *code = QRcode_encodeString(text, version, level, mode, casesensitive);
return code;
}
QRcode *encode_8bit(const char *text,
int version,
QRecLevel level)
{
QRcode *code = QRcode_encodeString8bit(text, version, level);
return code;
}
#endif
void generate(AV *map_av,
QRcode *qrcode)
{
unsigned char *p, *q;
int x, y;
AV *line_av;
/* data */
p = qrcode->data;
q = p;
for(y=0; y<qrcode->width; y++) {
line_av = (AV*)sv_2mortal((SV*)newAV());
for(x=0; x<qrcode->width; x++) {
av_store(line_av, x, (*q & 1) ? newSVpv("*", 1) : newSVpv(" ", 1));
q++;
}
av_store(map_av, y, newRV((SV*)line_av));
}
}
AV *_plot(char *text, HV *hv)
{
AV *map_av = newAV();
QRcode *qrcode;
SV **svp;
STRLEN len;
char *ptr;
int version = 0;
int casesensitive = 0;
QRencodeMode mode = QR_MODE_8;
QRecLevel level = QR_ECLEVEL_L;
if ((svp = hv_fetch(hv, "level", 5, 0)) && *svp && SvOK(*svp)) {
ptr = SvPV(*svp, len);
switch (*ptr) {
case 'l':
case 'L':
level = QR_ECLEVEL_L;
break;
case 'm':
case 'M':
level = QR_ECLEVEL_M;
break;
case 'q':
case 'Q':
level = QR_ECLEVEL_Q;
break;
case 'h':
case 'H':
level = QR_ECLEVEL_H;
break;
default:
level = QR_ECLEVEL_L;
}
}
if ((svp = hv_fetch(hv, "version", 7, 0)) && *svp && SvOK(*svp)) {
ptr = SvPV(*svp, len);
if (ptr >= 0)
version = atoi(ptr);
}
if ((svp = hv_fetch(hv, "mode", 4, 0)) && *svp && SvOK(*svp)) {
ptr = SvPV(*svp, len);
if (strcmp(ptr, "numerical") == 0) {
mode = QR_MODE_NUM;
}
else if (strcmp(ptr, "alpha-numerical") == 0) {
mode = QR_MODE_AN;
}
else if (strcmp(ptr, "8-bit") == 0) {
mode = QR_MODE_8;
}
else if (strcmp(ptr, "kanji") == 0) {
mode = QR_MODE_KANJI;
}
else {
croak("Invalid mode: XS error");
}
}
if ((svp = hv_fetch(hv, "casesensitive", 13, 0)) && *svp) {
casesensitive = SvTRUE(*svp);
}
#ifdef UNDER_LIBQRENCODE_1_0_2
qrcode = encode(text, version, level, mode, casesensitive);
#else
if (mode == QR_MODE_8)
qrcode = encode_8bit(text, version, level);
else
qrcode = encode(text, version, level, mode, casesensitive);
#endif
if (qrcode == NULL)
croak("Failed to encode the input data: XS error");
generate(map_av, qrcode);
QRcode_free(qrcode);
return map_av;
}
MODULE = Text::QRCode PACKAGE = Text::QRCode
PROTOTYPES: ENABLE
AV *
_plot(text, hv)
char *text
HV *hv
CODE:
RETVAL = _plot(text, hv);
OUTPUT:
RETVAL