Skip to content

Commit

Permalink
add Lib::PDF support for packing
Browse files Browse the repository at this point in the history
  • Loading branch information
dwarring committed Apr 19, 2017
1 parent 9fcb95c commit 1399a04
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,6 +1,7 @@
Release 0.2.2
- Experimental use of Lib::PDF
Speed up the slowest test xt/filter-predictos_bulk.t
-- Speed up the slowest test xt/filter-predictors_bulk.t
-- Fast packing alternative for PDF::IO::Util
For regression purposes, at this stage. Probably wont
persue seriously until Rakudo has better JIT.

Expand Down
34 changes: 21 additions & 13 deletions lib/PDF/IO/Util.pm
Expand Up @@ -14,19 +14,27 @@ module PDF::IO::Util {
$haveit;
}

#| loads a faster alternative
our sub xs(Str $module-name, Str $sub-name) {
(require ::($module-name)).so;
::($module-name)::('&'~$sub-name);
}
#= network ordered byte packing and unpacking
proto sub unpack( $, $ --> Buf) is export(:pack) {*};
proto sub pack( $, $ --> Buf) is export(:pack) {*};
proto sub pack-le( $, $ --> Buf) is export(:pack) {*};
multi sub unpack( $nums!, 4) { buf8.new: flat $nums.list.map: { ($_ +> 4, $_ +& 15) } }
multi sub unpack( $nums!, 16) { buf16.new: flat $nums.list.map: -> \hi, \lo { hi +< 8 + lo } }
multi sub unpack( $nums!, 32) { buf32.new: flat $nums.list.map: -> \b1, \b2, \b3, \b4 { b1 +< 24 + b2 +< 16 + b3 +< 8 + b4 } }
multi sub unpack( $nums!, $n) { resample( $nums, 8, $n); }
multi sub pack( $nums!, 4) { buf8.new: flat $nums.list.map: -> \hi, \lo { hi +< 4 + lo } }
multi sub pack( $nums!, 16) { buf8.new: flat $nums.list.map: { ($_ +> 8, $_) } }
multi sub pack( $nums!, 32) { buf8.new: flat $nums.list.map: { ($_ +> 24, $_ +> 16, $_ +> 8, $_) } }
proto sub unpack-pp( $, $ --> Buf) is export(:pack-pp) {*};
proto sub pack-pp( $, $ --> Buf) is export(:pack-pp) {*};
proto sub pack-le( $, $ --> Buf) is export(:pack,:pack-pp) {*};
my constant Packer = 'Lib::PDF::Buf';
our &pack is export(:pack) = libpdf-available() ?? xs(Packer, 'pack') !! &pack-pp;
our &unpack is export(:pack) = libpdf-available() ?? xs(Packer, 'unpack') !! &unpack-pp;
multi sub unpack-pp( $nums!, 4) { buf8.new: flat $nums.list.map: { ($_ +> 4, $_ +& 15) } }
multi sub unpack-pp( $nums!, 16) { buf16.new: flat $nums.list.map: -> \hi, \lo { hi +< 8 + lo } }
multi sub unpack-pp( $nums!, 32) { buf32.new: flat $nums.list.map: -> \b1, \b2, \b3, \b4 { b1 +< 24 + b2 +< 16 + b3 +< 8 + b4 } }
multi sub unpack-pp( $nums!, $n) { resample( $nums, 8, $n); }
multi sub pack-pp( $nums!, 4) { buf8.new: flat $nums.list.map: -> \hi, \lo { hi +< 4 + lo } }
multi sub pack-pp( $nums!, 16) { buf8.new: flat $nums.list.map: { ($_ +> 8, $_) } }
multi sub pack-pp( $nums!, 32) { buf8.new: flat $nums.list.map: { ($_ +> 24, $_ +> 16, $_ +> 8, $_) } }
multi sub pack-le( $nums!, 32) { buf8.new: flat $nums.list.map: { ($_, $_ +> 8, $_ +> 16, $_ +> 24) } }
multi sub pack( $nums!, $n) { resample( $nums, $n, 8); }
multi sub pack-pp( $nums!, $n) { resample( $nums, $n, 8); }
sub container(UInt $bits) {
$bits <= 8 ?? uint8 !! ($bits > 16 ?? uint32 !! uint16)
}
Expand Down Expand Up @@ -63,7 +71,7 @@ module PDF::IO::Util {
}
#| variable resampling, e.g. to decode/encode:
#| obj 123 0 << /Type /XRef /W [1, 3, 1]
multi sub unpack( $nums!, Array $W!) {
multi sub unpack-pp( $nums!, Array $W!) {
my uint $i = 0;
my uint $j = 0;
my uint32 @out;
Expand All @@ -86,7 +94,7 @@ module PDF::IO::Util {
@shaped;
}

multi sub pack($shaped, Array $W!) {
multi sub pack-pp($shaped, Array $W!) {
my uint8 @out;
@out[$W.sum * +$shaped - 1] = 0
if +$shaped;
Expand Down
5 changes: 3 additions & 2 deletions t/io-util.t
Expand Up @@ -21,8 +21,9 @@ is-deeply ($buf = pack([1415192289,], 32)), buf8.new(84, 90, 30, 225), '32 bit p
is-deeply ($buf = pack([2 ** 32 - 1415192289 - 1,], 32)), buf8.new(255-84, 255-90, 255-30, 255-225), '32 bit packing (twos comp)';

quietly {
is-deeply ($buf = unpack(@bytes, 6)), buf8.new(2, 33, 16, 30, 10, 3, 8, 60), '6 bit unpack';
is-deeply pack($buf, 6), $bytes, 'resample round-trip: 8 => 6 => 8';
use PDF::IO::Util :pack-pp;
is-deeply ($buf = unpack-pp(@bytes, 6)), buf8.new(2, 33, 16, 30, 10, 3, 8, 60), '6 bit unpack';
is-deeply pack-pp($buf, 6), $bytes, 'resample round-trip: 8 => 6 => 8';

is-deeply ($buf = unpack([109], 1)), buf8.new(0, 1, 1, 0, 1, 1, 0, 1), '1 bit unpack';
is-deeply ($buf = pack($buf, 1)), buf8.new(109), '8 => 1 => 8 round trip';
Expand Down

0 comments on commit 1399a04

Please sign in to comment.