package Data::QRCode::XS; use strict; use warnings; # VERSION 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]; }