root/lang/cplusplus/range_coder/build_table.pl

Revision 7178, 1.1 kB (checked in by kazuho, 11 months ago)

elementsof(freq) should be 257 including total freq. at the end
use a safer method for rounding the frequency table

  • Property svn:executable set to *
Line 
1#! /usr/bin/perl
2
3use strict;
4use warnings;
5
6use Getopt::Long;
7use List::Util qw/sum max/;
8
9my ($do_ordered);
10
11GetOptions(
12    'ordered' => \$do_ordered,
13);
14
15
16my @cnt = map { 0 } 0..255;
17
18while (<>) {
19    foreach my $c (split '', $_) {
20        $cnt[ord $c]++;
21    }
22}
23
24if ($do_ordered) {
25    my @order = sort { $cnt[$b] <=> $cnt[$a] } 0..255;
26    print "#define USE_ORDERED_TABLE 1\n";
27    print "static unsigned char from_ordered[] = {", join(',', @order), "};\n";
28    my %r = map { $order[$_] => $_ } @order;
29    print "static unsigned char to_ordered[] = {", join(',', map { $r{$_} } 0..255), "};\n";
30    @cnt = map { $cnt[$order[$_]] } 0..255;
31}
32
33my @freq;
34my $cc = sum @cnt;
35my $mult = 0x8000;
36while (1) {
37    print STDERR "$mult\n";
38    my $acc = 0;
39    for (my $i = 0; $i < 256; $i++) {
40        push @freq, $acc;
41        $acc += $cnt[$i] != 0 ? max(int($cnt[$i] / $cc * $mult + 0.5), 1) : 0;
42    }
43    last if $acc <= 0x8000;
44    @freq = ();
45    $mult--;
46}
47push @freq, 0x8000;
48
49print "#define MAX_FREQ 0x8000\n";
50print "static short freq[] __attribute__((aligned(16))) = {", join(',', map { $_ - 0x8000 } @freq), "};\n";
Note: See TracBrowser for help on using the browser.