#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; ywidth; y++) { line_av = (AV*)sv_2mortal((SV*)newAV()); for(x=0; xwidth; 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