summaryrefslogtreecommitdiff
path: root/lib/Data/QRCode/XS.pm
blob: f42940fa5452680fe8a9f0c9a9fbc6d8d6fb6a29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package Data::QRCode::XS; 
use strict;
use warnings;
# VERSION 
use Alien::QREncode;
use Data::QRCode::XS::Inline => ( );
 
my %levels = (
    => ECLEVEL_L,
    => ECLEVEL_M,
    => ECLEVEL_Q,
    => 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];
}