zopfli 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitmodules +1 -1
- data/.travis.yml +24 -0
- data/Gemfile +2 -0
- data/Rakefile +8 -10
- data/ext/extconf.rb +1 -0
- data/ext/zopfli.c +37 -17
- data/lib/zopfli/version.rb +1 -1
- data/smoke.sh +9 -0
- data/{test → spec}/fixtures/alice29.txt +0 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/zopfli_spec.rb +68 -0
- data/vendor/zopfli/src/zopfli/blocksplitter.c +34 -44
- data/vendor/zopfli/src/zopfli/blocksplitter.h +2 -6
- data/vendor/zopfli/src/zopfli/cache.c +3 -1
- data/vendor/zopfli/src/zopfli/deflate.c +351 -287
- data/vendor/zopfli/src/zopfli/deflate.h +8 -2
- data/vendor/zopfli/src/zopfli/gzip_container.c +54 -47
- data/vendor/zopfli/src/zopfli/hash.c +18 -10
- data/vendor/zopfli/src/zopfli/hash.h +6 -3
- data/vendor/zopfli/src/zopfli/katajainen.c +73 -62
- data/vendor/zopfli/src/zopfli/lz77.c +190 -42
- data/vendor/zopfli/src/zopfli/lz77.h +32 -19
- data/vendor/zopfli/src/zopfli/squeeze.c +75 -61
- data/vendor/zopfli/src/zopfli/squeeze.h +1 -0
- data/vendor/zopfli/src/zopfli/symbols.h +239 -0
- data/vendor/zopfli/src/zopfli/util.c +0 -178
- data/vendor/zopfli/src/zopfli/util.h +6 -23
- data/vendor/zopfli/src/zopfli/zlib_container.c +1 -1
- data/vendor/zopfli/src/zopfli/zopfli.h +1 -4
- data/vendor/zopfli/src/zopfli/zopfli_bin.c +11 -8
- data/zopfli.gemspec +8 -27
- metadata +13 -20
- data/test/test_zopfli_deflate.rb +0 -45
- data/vendor/zopfli/CONTRIBUTING.md +0 -24
- data/vendor/zopfli/CONTRIBUTORS +0 -8
- data/vendor/zopfli/Makefile +0 -42
- data/vendor/zopfli/README +0 -32
- data/vendor/zopfli/README.zopflipng +0 -35
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng.cpp +0 -6252
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng.h +0 -1716
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.cpp +0 -656
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.h +0 -151
- data/vendor/zopfli/src/zopflipng/zopflipng_bin.cc +0 -408
- data/vendor/zopfli/src/zopflipng/zopflipng_lib.cc +0 -492
- data/vendor/zopfli/src/zopflipng/zopflipng_lib.h +0 -134
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 842bc62060c0806e32e47d1458f725e9a518dd22
|
4
|
+
data.tar.gz: b902c2adbfd79ac9fb5c8bf0a4db743575c4e26e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cd8b6cf2c124a0e755061daef0ff8cb20b4f3d670fa93bf0a60dc0ac1de9aaa25ec823bda35b855bb3becf51aed684c1b8f52481d8b89345bc36445c0807104
|
7
|
+
data.tar.gz: 3ed7ebb30c8198ecdb3c0d269a3c341e998f8941236ae354e1ceda415c6d1ca28b1d8dee310e89ae8412cd2b981bc827c5e06c9681c1d68bc13e74fba955c3ba
|
data/.gitmodules
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
language: ruby
|
2
|
+
sudo: false
|
3
|
+
cache:
|
4
|
+
bundler: true
|
5
|
+
directories:
|
6
|
+
- "$HOME/.ccache"
|
7
|
+
rvm:
|
8
|
+
- 2.2.0
|
9
|
+
- 2.3.3
|
10
|
+
- 2.4.0
|
11
|
+
env:
|
12
|
+
global:
|
13
|
+
- PATH="/usr/lib/ccache:$PATH"
|
14
|
+
before_install:
|
15
|
+
- gem install bundler
|
16
|
+
deploy:
|
17
|
+
provider: rubygems
|
18
|
+
api_key:
|
19
|
+
secure: Ix2H4oY1Ypo5mdYj9JTXufY/E7H/TWjAM54dtG2i/94yV8wMVINl+rhjnFso87LN6y0Tpt7rWy1OG1y3YPbwhBUPLbRXZ+xGjnsLA8/sUpEFODFk/QaYgOkCk2g3+xCgzzNvctd2u9fii/q9eIUts8BznegxtAYbat5a8dGvoVEkYAvHUX4lMRcEZVgMMpjT+xz3IGRe9rnW4umLd8P2mE6CEXAtrwFNSsjL1SVfKVOwwJ/UyiJfUnK6U/mDWdCDYWiPEE/CTz7PbrGGo4nAGoShLmkMUDsOamgECObT2rsNo42XzzrB4GAP+4PPQnias34BtJQLI9x2IEAUkM8vnKhSrtshp43S+ikU01W6rj4NMAvER4s9WNmRjsWgZQ/vEIHIwZXmdnkGvlYSiwRru+17YL2HCbrVp/YXi7X5HgBczuGOt3TZLB0xAKJG21qz+HdtP1nZTZe3EONDvWx9bM3XF2YjJ5gt3UNno8GsefTl71PFDubs1/LrVbkGgGwO6VTb4OgS2bEzntk17488BLTBo3l7bke5FTu8xQUbCawX2dqtOiukP45Ke8hRmgwWSMK+EH8YYcRcuZSbOXYJtGfpfC6nHtlArW+EjJ2Og+nWX68n7NFOIfGfCSX+V7cNgnKsqMjaesF+jEP+53CfVa2xnYxkZx7TgGrFyQEKr9s=
|
20
|
+
gem: zopfli
|
21
|
+
on:
|
22
|
+
tags: true
|
23
|
+
repo: miyucy/zopfli
|
24
|
+
script: bundle exec rake && ./smoke.sh
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,25 +1,23 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require "
|
2
|
+
require "rspec/core/rake_task"
|
3
3
|
require "rbconfig"
|
4
4
|
|
5
5
|
DLEXT = RbConfig::CONFIG["DLEXT"]
|
6
6
|
|
7
|
-
file "ext/zopfli.#{DLEXT}" => Dir.glob("ext/*{.rb,.c}") do
|
7
|
+
file "ext/zopfli.#{DLEXT}" => Dir.glob("ext/*{.rb,.c,.h}") do
|
8
8
|
Dir.chdir("ext") do
|
9
|
-
|
10
|
-
|
9
|
+
ruby "extconf.rb"
|
10
|
+
sh "make"
|
11
11
|
end
|
12
12
|
cp "ext/zopfli.#{DLEXT}", "lib"
|
13
13
|
end
|
14
14
|
|
15
15
|
task :clean do
|
16
16
|
files = Dir["ext/*"] - ["ext/extconf.rb", "ext/zopfli.c"]
|
17
|
-
files+= ["ext/zopfli.#{DLEXT}", "lib/zopfli.#{DLEXT}"]
|
17
|
+
files += ["ext/zopfli.#{DLEXT}", "lib/zopfli.#{DLEXT}"]
|
18
18
|
rm_rf(files) unless files.empty?
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
task :test => "ext/zopfli.#{DLEXT}"
|
21
|
+
RSpec::Core::RakeTask.new(:spec)
|
22
|
+
task :spec => "ext/zopfli.#{DLEXT}"
|
23
|
+
task :default => :spec
|
data/ext/extconf.rb
CHANGED
data/ext/zopfli.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
static VALUE rb_mZopfli;
|
8
8
|
|
9
|
-
ZopfliFormat
|
9
|
+
static ZopfliFormat
|
10
10
|
zopfli_deflate_parse_options(ZopfliOptions *options, VALUE opts)
|
11
11
|
{
|
12
12
|
ZopfliFormat format;
|
@@ -50,35 +50,56 @@ zopfli_deflate_parse_options(ZopfliOptions *options, VALUE opts)
|
|
50
50
|
return format;
|
51
51
|
}
|
52
52
|
|
53
|
-
|
54
|
-
zopfli_deflate(int argc, VALUE *argv, VALUE self)
|
55
|
-
{
|
56
|
-
VALUE in, out, opts;
|
53
|
+
typedef struct {
|
57
54
|
ZopfliOptions options;
|
58
55
|
ZopfliFormat format;
|
59
|
-
unsigned char
|
60
|
-
size_t
|
56
|
+
unsigned char *in;
|
57
|
+
size_t insize;
|
58
|
+
unsigned char *out;
|
59
|
+
size_t outsize;
|
60
|
+
} zopfli_deflate_args_t;
|
61
|
+
|
62
|
+
static void*
|
63
|
+
zopfli_deflate_no_gvl(void* arg)
|
64
|
+
{
|
65
|
+
zopfli_deflate_args_t *args = (zopfli_deflate_args_t*)arg;
|
66
|
+
|
67
|
+
ZopfliCompress(&args->options, args->format,
|
68
|
+
args->in, args->insize,
|
69
|
+
&args->out, &args->outsize);
|
70
|
+
|
71
|
+
return arg;
|
72
|
+
}
|
61
73
|
|
62
|
-
|
74
|
+
static VALUE
|
75
|
+
zopfli_deflate(int argc, VALUE *argv, VALUE self)
|
76
|
+
{
|
77
|
+
zopfli_deflate_args_t args;
|
78
|
+
VALUE in, out, opts;
|
79
|
+
|
80
|
+
ZopfliInitOptions(&args.options);
|
63
81
|
|
64
82
|
rb_scan_args(argc, argv, "11", &in, &opts);
|
65
83
|
|
66
84
|
if (!NIL_P(opts)) {
|
67
|
-
format = zopfli_deflate_parse_options(&options, opts);
|
85
|
+
args.format = zopfli_deflate_parse_options(&args.options, opts);
|
68
86
|
} else {
|
69
|
-
format = DEFAULT_FORMAT;
|
87
|
+
args.format = DEFAULT_FORMAT;
|
70
88
|
}
|
71
89
|
|
72
90
|
StringValue(in);
|
73
91
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
92
|
+
args.in = (unsigned char*)RSTRING_PTR(in);
|
93
|
+
args.insize = RSTRING_LEN(in);
|
94
|
+
|
95
|
+
args.out = NULL;
|
96
|
+
args.outsize = 0;
|
97
|
+
|
98
|
+
rb_thread_call_without_gvl(zopfli_deflate_no_gvl, (void *)&args, NULL, NULL);
|
78
99
|
|
79
|
-
out = rb_str_new(
|
100
|
+
out = rb_str_new((const char*)args.out, args.outsize);
|
80
101
|
|
81
|
-
free(
|
102
|
+
free(args.out);
|
82
103
|
|
83
104
|
return out;
|
84
105
|
}
|
@@ -88,5 +109,4 @@ Init_zopfli()
|
|
88
109
|
{
|
89
110
|
rb_mZopfli = rb_define_module("Zopfli");
|
90
111
|
rb_define_singleton_method(rb_mZopfli, "deflate", zopfli_deflate, -1);
|
91
|
-
rb_require("zopfli/version");
|
92
112
|
}
|
data/lib/zopfli/version.rb
CHANGED
data/smoke.sh
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
gem list | grep zopfli && gem uninstall --force zopfli
|
3
|
+
bundle exec rake clean build
|
4
|
+
gem install --force --local --no-ri --no-rdoc "$(ls pkg/zopfli-*.gem)"
|
5
|
+
cat <<EOF | ruby
|
6
|
+
require 'zopfli'
|
7
|
+
require 'zlib'
|
8
|
+
abort if Zlib::Inflate.inflate(Zopfli.deflate(File.read('smoke.sh'))) != File.read('smoke.sh')
|
9
|
+
EOF
|
File without changes
|
data/spec/spec_helper.rb
ADDED
data/spec/zopfli_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'zlib'
|
3
|
+
require 'stringio'
|
4
|
+
require 'benchmark'
|
5
|
+
require 'thread'
|
6
|
+
|
7
|
+
RSpec.describe Zopfli do
|
8
|
+
let(:fixture) { File.read(File.expand_path('fixtures/alice29.txt', File.dirname(__FILE__))) }
|
9
|
+
|
10
|
+
it 'works' do
|
11
|
+
expect(Zopfli.deflate(fixture)).to eq Zopfli.deflate(fixture, format: :zlib)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'works (zlib format)' do
|
15
|
+
deflated = Zopfli.deflate fixture, format: :zlib
|
16
|
+
|
17
|
+
uncompressed = Zlib::Inflate.inflate deflated
|
18
|
+
|
19
|
+
expect(uncompressed).to eq fixture
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'works (gzip format)' do
|
23
|
+
deflated = Zopfli.deflate fixture, format: :gzip
|
24
|
+
|
25
|
+
uncompressed = Zlib::GzipReader.wrap(StringIO.new(deflated), &:read)
|
26
|
+
|
27
|
+
expect(uncompressed).to eq fixture
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'works (deflate format)' do
|
31
|
+
deflated = Zopfli.deflate fixture, format: :deflate
|
32
|
+
p fixture.bytesize, deflated.bytesize
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'benchmark' do
|
36
|
+
it 'seq' do
|
37
|
+
data = 10.times.map { fixture.dup }
|
38
|
+
deflates = nil
|
39
|
+
t = Benchmark.realtime { deflates = data.map { |datum| Zopfli.deflate datum } }
|
40
|
+
deflates.each { |deflate| expect(Zlib::Inflate.inflate(deflate)).to eq fixture }
|
41
|
+
puts t
|
42
|
+
# => 4.483513999963179
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'thread' do
|
46
|
+
q = Queue.new
|
47
|
+
10.times { q.push fixture.dup }
|
48
|
+
10.times { q.push nil }
|
49
|
+
w = 10.times.map do
|
50
|
+
Thread.new do
|
51
|
+
deflates = []
|
52
|
+
loop do
|
53
|
+
datum = q.pop
|
54
|
+
break if datum.nil?
|
55
|
+
deflates << Zopfli.deflate(datum)
|
56
|
+
end
|
57
|
+
deflates
|
58
|
+
end
|
59
|
+
end
|
60
|
+
deflates = nil
|
61
|
+
t = Benchmark.realtime { deflates = w.map(&:value) }
|
62
|
+
deflates.flatten.each { |deflate| expect(Zlib::Inflate.inflate(deflate)).to eq fixture }
|
63
|
+
puts t
|
64
|
+
# => 2.6099140000296757
|
65
|
+
# => 0.9405940000433475 (w/o gvl)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -24,7 +24,6 @@ Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
|
24
24
|
#include <stdlib.h>
|
25
25
|
|
26
26
|
#include "deflate.h"
|
27
|
-
#include "lz77.h"
|
28
27
|
#include "squeeze.h"
|
29
28
|
#include "tree.h"
|
30
29
|
#include "util.h"
|
@@ -39,9 +38,10 @@ typedef double FindMinimumFun(size_t i, void* context);
|
|
39
38
|
/*
|
40
39
|
Finds minimum of function f(i) where is is of type size_t, f(i) is of type
|
41
40
|
double, i is in range start-end (excluding end).
|
41
|
+
Outputs the minimum value in *smallest and returns the index of this value.
|
42
42
|
*/
|
43
43
|
static size_t FindMinimum(FindMinimumFun f, void* context,
|
44
|
-
size_t start, size_t end) {
|
44
|
+
size_t start, size_t end, double* smallest) {
|
45
45
|
if (end - start < 1024) {
|
46
46
|
double best = ZOPFLI_LARGE_FLOAT;
|
47
47
|
size_t result = start;
|
@@ -53,6 +53,7 @@ static size_t FindMinimum(FindMinimumFun f, void* context,
|
|
53
53
|
result = i;
|
54
54
|
}
|
55
55
|
}
|
56
|
+
*smallest = best;
|
56
57
|
return result;
|
57
58
|
} else {
|
58
59
|
/* Try to find minimum faster by recursively checking multiple points. */
|
@@ -88,6 +89,7 @@ static size_t FindMinimum(FindMinimumFun f, void* context,
|
|
88
89
|
pos = p[besti];
|
89
90
|
lastbest = best;
|
90
91
|
}
|
92
|
+
*smallest = lastbest;
|
91
93
|
return pos;
|
92
94
|
#undef NUM
|
93
95
|
}
|
@@ -103,16 +105,13 @@ dists: ll77 distances
|
|
103
105
|
lstart: start of block
|
104
106
|
lend: end of block (not inclusive)
|
105
107
|
*/
|
106
|
-
static double EstimateCost(const
|
107
|
-
const unsigned short* dists,
|
108
|
+
static double EstimateCost(const ZopfliLZ77Store* lz77,
|
108
109
|
size_t lstart, size_t lend) {
|
109
|
-
return
|
110
|
+
return ZopfliCalculateBlockSizeAutoType(lz77, lstart, lend);
|
110
111
|
}
|
111
112
|
|
112
113
|
typedef struct SplitCostContext {
|
113
|
-
const
|
114
|
-
const unsigned short* dists;
|
115
|
-
size_t llsize;
|
114
|
+
const ZopfliLZ77Store* lz77;
|
116
115
|
size_t start;
|
117
116
|
size_t end;
|
118
117
|
} SplitCostContext;
|
@@ -125,8 +124,7 @@ type: FindMinimumFun
|
|
125
124
|
*/
|
126
125
|
static double SplitCost(size_t i, void* context) {
|
127
126
|
SplitCostContext* c = (SplitCostContext*)context;
|
128
|
-
return EstimateCost(c->
|
129
|
-
EstimateCost(c->litlens, c->dists, i, c->end);
|
127
|
+
return EstimateCost(c->lz77, c->start, i) + EstimateCost(c->lz77, i, c->end);
|
130
128
|
}
|
131
129
|
|
132
130
|
static void AddSorted(size_t value, size_t** out, size_t* outsize) {
|
@@ -147,9 +145,8 @@ static void AddSorted(size_t value, size_t** out, size_t* outsize) {
|
|
147
145
|
/*
|
148
146
|
Prints the block split points as decimal and hex values in the terminal.
|
149
147
|
*/
|
150
|
-
static void PrintBlockSplitPoints(const
|
151
|
-
const
|
152
|
-
size_t llsize, const size_t* lz77splitpoints,
|
148
|
+
static void PrintBlockSplitPoints(const ZopfliLZ77Store* lz77,
|
149
|
+
const size_t* lz77splitpoints,
|
153
150
|
size_t nlz77points) {
|
154
151
|
size_t* splitpoints = 0;
|
155
152
|
size_t npoints = 0;
|
@@ -158,8 +155,8 @@ static void PrintBlockSplitPoints(const unsigned short* litlens,
|
|
158
155
|
index values. */
|
159
156
|
size_t pos = 0;
|
160
157
|
if (nlz77points > 0) {
|
161
|
-
for (i = 0; i <
|
162
|
-
size_t length = dists[i] == 0 ? 1 : litlens[i];
|
158
|
+
for (i = 0; i < lz77->size; i++) {
|
159
|
+
size_t length = lz77->dists[i] == 0 ? 1 : lz77->litlens[i];
|
163
160
|
if (lz77splitpoints[npoints] == i) {
|
164
161
|
ZOPFLI_APPEND_DATA(pos, &splitpoints, &npoints);
|
165
162
|
if (npoints == nlz77points) break;
|
@@ -186,7 +183,7 @@ static void PrintBlockSplitPoints(const unsigned short* litlens,
|
|
186
183
|
Finds next block to try to split, the largest of the available ones.
|
187
184
|
The largest is chosen to make sure that if only a limited amount of blocks is
|
188
185
|
requested, their sizes are spread evenly.
|
189
|
-
|
186
|
+
lz77size: the size of the LL77 data, which is the size of the done array here.
|
190
187
|
done: array indicating which blocks starting at that position are no longer
|
191
188
|
splittable (splitting them increases rather than decreases cost).
|
192
189
|
splitpoints: the splitpoints found so far.
|
@@ -196,7 +193,7 @@ lend: output variable, giving end of block.
|
|
196
193
|
returns 1 if a block was found, 0 if no block found (all are done).
|
197
194
|
*/
|
198
195
|
static int FindLargestSplittableBlock(
|
199
|
-
size_t
|
196
|
+
size_t lz77size, const unsigned char* done,
|
200
197
|
const size_t* splitpoints, size_t npoints,
|
201
198
|
size_t* lstart, size_t* lend) {
|
202
199
|
size_t longest = 0;
|
@@ -204,7 +201,7 @@ static int FindLargestSplittableBlock(
|
|
204
201
|
size_t i;
|
205
202
|
for (i = 0; i <= npoints; i++) {
|
206
203
|
size_t start = i == 0 ? 0 : splitpoints[i - 1];
|
207
|
-
size_t end = i == npoints ?
|
204
|
+
size_t end = i == npoints ? lz77size - 1 : splitpoints[i];
|
208
205
|
if (!done[start] && end - start > longest) {
|
209
206
|
*lstart = start;
|
210
207
|
*lend = end;
|
@@ -216,9 +213,7 @@ static int FindLargestSplittableBlock(
|
|
216
213
|
}
|
217
214
|
|
218
215
|
void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
219
|
-
const
|
220
|
-
const unsigned short* dists,
|
221
|
-
size_t llsize, size_t maxblocks,
|
216
|
+
const ZopfliLZ77Store* lz77, size_t maxblocks,
|
222
217
|
size_t** splitpoints, size_t* npoints) {
|
223
218
|
size_t lstart, lend;
|
224
219
|
size_t i;
|
@@ -227,14 +222,14 @@ void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
|
227
222
|
unsigned char* done;
|
228
223
|
double splitcost, origcost;
|
229
224
|
|
230
|
-
if (
|
225
|
+
if (lz77->size < 10) return; /* This code fails on tiny files. */
|
231
226
|
|
232
|
-
done = (unsigned char*)malloc(
|
227
|
+
done = (unsigned char*)malloc(lz77->size);
|
233
228
|
if (!done) exit(-1); /* Allocation failed. */
|
234
|
-
for (i = 0; i <
|
229
|
+
for (i = 0; i < lz77->size; i++) done[i] = 0;
|
235
230
|
|
236
231
|
lstart = 0;
|
237
|
-
lend =
|
232
|
+
lend = lz77->size;
|
238
233
|
for (;;) {
|
239
234
|
SplitCostContext c;
|
240
235
|
|
@@ -242,20 +237,16 @@ void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
|
242
237
|
break;
|
243
238
|
}
|
244
239
|
|
245
|
-
c.
|
246
|
-
c.dists = dists;
|
247
|
-
c.llsize = llsize;
|
240
|
+
c.lz77 = lz77;
|
248
241
|
c.start = lstart;
|
249
242
|
c.end = lend;
|
250
243
|
assert(lstart < lend);
|
251
|
-
llpos = FindMinimum(SplitCost, &c, lstart + 1, lend);
|
244
|
+
llpos = FindMinimum(SplitCost, &c, lstart + 1, lend, &splitcost);
|
252
245
|
|
253
246
|
assert(llpos > lstart);
|
254
247
|
assert(llpos < lend);
|
255
248
|
|
256
|
-
|
257
|
-
EstimateCost(litlens, dists, llpos, lend);
|
258
|
-
origcost = EstimateCost(litlens, dists, lstart, lend);
|
249
|
+
origcost = EstimateCost(lz77, lstart, lend);
|
259
250
|
|
260
251
|
if (splitcost > origcost || llpos == lstart + 1 || llpos == lend) {
|
261
252
|
done[lstart] = 1;
|
@@ -265,7 +256,7 @@ void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
|
265
256
|
}
|
266
257
|
|
267
258
|
if (!FindLargestSplittableBlock(
|
268
|
-
|
259
|
+
lz77->size, done, *splitpoints, *npoints, &lstart, &lend)) {
|
269
260
|
break; /* No further split will probably reduce compression. */
|
270
261
|
}
|
271
262
|
|
@@ -275,7 +266,7 @@ void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
|
275
266
|
}
|
276
267
|
|
277
268
|
if (options->verbose) {
|
278
|
-
PrintBlockSplitPoints(
|
269
|
+
PrintBlockSplitPoints(lz77, *splitpoints, *npoints);
|
279
270
|
}
|
280
271
|
|
281
272
|
free(done);
|
@@ -290,25 +281,22 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
|
|
290
281
|
size_t* lz77splitpoints = 0;
|
291
282
|
size_t nlz77points = 0;
|
292
283
|
ZopfliLZ77Store store;
|
284
|
+
ZopfliHash hash;
|
285
|
+
ZopfliHash* h = &hash;
|
293
286
|
|
294
|
-
ZopfliInitLZ77Store(&store);
|
295
|
-
|
296
|
-
|
297
|
-
s.blockstart = instart;
|
298
|
-
s.blockend = inend;
|
299
|
-
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
300
|
-
s.lmc = 0;
|
301
|
-
#endif
|
287
|
+
ZopfliInitLZ77Store(in, &store);
|
288
|
+
ZopfliInitBlockState(options, instart, inend, 0, &s);
|
289
|
+
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);
|
302
290
|
|
303
291
|
*npoints = 0;
|
304
292
|
*splitpoints = 0;
|
305
293
|
|
306
294
|
/* Unintuitively, Using a simple LZ77 method here instead of ZopfliLZ77Optimal
|
307
295
|
results in better blocks. */
|
308
|
-
ZopfliLZ77Greedy(&s, in, instart, inend, &store);
|
296
|
+
ZopfliLZ77Greedy(&s, in, instart, inend, &store, h);
|
309
297
|
|
310
298
|
ZopfliBlockSplitLZ77(options,
|
311
|
-
store
|
299
|
+
&store, maxblocks,
|
312
300
|
&lz77splitpoints, &nlz77points);
|
313
301
|
|
314
302
|
/* Convert LZ77 positions to positions in the uncompressed input. */
|
@@ -326,7 +314,9 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
|
|
326
314
|
assert(*npoints == nlz77points);
|
327
315
|
|
328
316
|
free(lz77splitpoints);
|
317
|
+
ZopfliCleanBlockState(&s);
|
329
318
|
ZopfliCleanLZ77Store(&store);
|
319
|
+
ZopfliCleanHash(h);
|
330
320
|
}
|
331
321
|
|
332
322
|
void ZopfliBlockSplitSimple(const unsigned char* in,
|