package Data::QRCode::XS;
use strict;
use warnings;
use Alien::QREncode;
use Data::QRCode::XS::Inline C => ( );
my %levels = (
L => ECLEVEL_L,
M => ECLEVEL_M,
Q => ECLEVEL_Q,
H => ECLEVEL_H,
);
sub new {
my ($class, $data, $level, $version) = @_;
$version ||= 0;
$level = $levels{uc $level} || ECLEVEL_M;
return _build($class,$data,$level,$version);
}
sub data_at {
my ($self,$x,$y) = @_;
my $width = $self->width;
if ($x < 0 or $x >= $width or $y < 0 or $y >= $width) {
return;
}
my $value = _data_at($self,$x,$y);
return {
color => $value & 0x01,
in_data => $value & 0x02,
in_format => $value & 0x04,
in_version => $value & 0x08,
in_timing => $value & 0x10,
in_alignment => $value & 0x20,
in_finder => $value & 0x40,
in_misc => $value & 0x80,
};
}
1;
__DATA__
__C__
int ECLEVEL_L() { return QR_ECLEVEL_L; }
int ECLEVEL_M() { return QR_ECLEVEL_M; }
int ECLEVEL_Q() { return QR_ECLEVEL_Q; }
int ECLEVEL_H() { return QR_ECLEVEL_H; }
SV* _build(const char* class, const SV* data, int level, int version ) {
unsigned char * str;
STRLEN len;
SV * qrsv; SV* self;
QRcode* qr_code;
str = SvPVutf8(data,len);
qr_code = QRcode_encodeData(len,data,version,(QRecLevel)level);
qrsv = newSViv((IV)qr_code);
self = newRV_noinc(qrsv);
sv_bless(self, gv_stashpv(class, GV_ADD));
SvREADONLY_on(qrsv);
return self;
}
int version(SV* self) {
return ((QRcode*)SvIV(SvRV(self)))->version;
}
int width(SV* self) {
return ((QRcode*)SvIV(SvRV(self)))->width;
}
void DESTROY(SV* self) {
QRcode* qr_code = (QRcode*)SvIV(SvRV(self));
QRcode_free(qr_code);
}
int _data_at(SV* self, int x, int y) {
QRcode* qr_code = (QRcode*)SvIV(SvRV(self));
return qr_code->data[x+y*width];
}