zopfli 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +1 -1
  3. data/.travis.yml +24 -0
  4. data/Gemfile +2 -0
  5. data/Rakefile +8 -10
  6. data/ext/extconf.rb +1 -0
  7. data/ext/zopfli.c +37 -17
  8. data/lib/zopfli/version.rb +1 -1
  9. data/smoke.sh +9 -0
  10. data/{test → spec}/fixtures/alice29.txt +0 -0
  11. data/spec/spec_helper.rb +2 -0
  12. data/spec/zopfli_spec.rb +68 -0
  13. data/vendor/zopfli/src/zopfli/blocksplitter.c +34 -44
  14. data/vendor/zopfli/src/zopfli/blocksplitter.h +2 -6
  15. data/vendor/zopfli/src/zopfli/cache.c +3 -1
  16. data/vendor/zopfli/src/zopfli/deflate.c +351 -287
  17. data/vendor/zopfli/src/zopfli/deflate.h +8 -2
  18. data/vendor/zopfli/src/zopfli/gzip_container.c +54 -47
  19. data/vendor/zopfli/src/zopfli/hash.c +18 -10
  20. data/vendor/zopfli/src/zopfli/hash.h +6 -3
  21. data/vendor/zopfli/src/zopfli/katajainen.c +73 -62
  22. data/vendor/zopfli/src/zopfli/lz77.c +190 -42
  23. data/vendor/zopfli/src/zopfli/lz77.h +32 -19
  24. data/vendor/zopfli/src/zopfli/squeeze.c +75 -61
  25. data/vendor/zopfli/src/zopfli/squeeze.h +1 -0
  26. data/vendor/zopfli/src/zopfli/symbols.h +239 -0
  27. data/vendor/zopfli/src/zopfli/util.c +0 -178
  28. data/vendor/zopfli/src/zopfli/util.h +6 -23
  29. data/vendor/zopfli/src/zopfli/zlib_container.c +1 -1
  30. data/vendor/zopfli/src/zopfli/zopfli.h +1 -4
  31. data/vendor/zopfli/src/zopfli/zopfli_bin.c +11 -8
  32. data/zopfli.gemspec +8 -27
  33. metadata +13 -20
  34. data/test/test_zopfli_deflate.rb +0 -45
  35. data/vendor/zopfli/CONTRIBUTING.md +0 -24
  36. data/vendor/zopfli/CONTRIBUTORS +0 -8
  37. data/vendor/zopfli/Makefile +0 -42
  38. data/vendor/zopfli/README +0 -32
  39. data/vendor/zopfli/README.zopflipng +0 -35
  40. data/vendor/zopfli/src/zopflipng/lodepng/lodepng.cpp +0 -6252
  41. data/vendor/zopfli/src/zopflipng/lodepng/lodepng.h +0 -1716
  42. data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.cpp +0 -656
  43. data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.h +0 -151
  44. data/vendor/zopfli/src/zopflipng/zopflipng_bin.cc +0 -408
  45. data/vendor/zopfli/src/zopflipng/zopflipng_lib.cc +0 -492
  46. 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: 4ed0d8eec767ad3ac6d89fef3b9acb09e2cc1091
4
- data.tar.gz: 9c9c5a832bcebf030c9e7950cf4c1165dd74f7e3
3
+ metadata.gz: 842bc62060c0806e32e47d1458f725e9a518dd22
4
+ data.tar.gz: b902c2adbfd79ac9fb5c8bf0a4db743575c4e26e
5
5
  SHA512:
6
- metadata.gz: d7f5decb3aec6b12d4a868071fc92cc4156d80253eaed923296b7d14aa302398cccbc155c27b94c76f2af394d2c5949cedca2f856a99d1fb6c06e58db4567022
7
- data.tar.gz: 980e462293ea31247405e54a9614d9948570bfb4936bd2179160b19d2b156879cc0a2dba5153c0b3151afbc12e949a375e558b8efe0e38a4a5484fe166d6b4d6
6
+ metadata.gz: 4cd8b6cf2c124a0e755061daef0ff8cb20b4f3d670fa93bf0a60dc0ac1de9aaa25ec823bda35b855bb3becf51aed684c1b8f52481d8b89345bc36445c0807104
7
+ data.tar.gz: 3ed7ebb30c8198ecdb3c0d269a3c341e998f8941236ae354e1ceda415c6d1ca28b1d8dee310e89ae8412cd2b981bc827c5e06c9681c1d68bc13e74fba955c3ba
data/.gitmodules CHANGED
@@ -1,3 +1,3 @@
1
1
  [submodule "vendor/zopfli"]
2
2
  path = vendor/zopfli
3
- url = https://code.google.com/p/zopfli/
3
+ url = https://github.com/google/zopfli.git
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
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in zopfli.gemspec
4
4
  gemspec
5
+
6
+ gem 'travis'
data/Rakefile CHANGED
@@ -1,25 +1,23 @@
1
1
  require "bundler/gem_tasks"
2
- require "rake/testtask"
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
- ruby "extconf.rb"
10
- sh "make"
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
- Rake::TestTask.new do |t|
22
- t.warning = true
23
- t.verbose = true
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
@@ -28,6 +28,7 @@ lz77.c
28
28
  lz77.h
29
29
  squeeze.c
30
30
  squeeze.h
31
+ symbols.h
31
32
  tree.c
32
33
  tree.h
33
34
  util.c
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
- VALUE
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 *tmp = NULL;
60
- size_t tmpsize = 0;
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
- ZopfliInitOptions(&options);
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
- ZopfliCompress(&options,
75
- format,
76
- RSTRING_PTR(in), RSTRING_LEN(in),
77
- &tmp, &tmpsize);
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(tmp, tmpsize);
100
+ out = rb_str_new((const char*)args.out, args.outsize);
80
101
 
81
- free(tmp);
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
  }
@@ -1,3 +1,3 @@
1
1
  module Zopfli
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.7"
3
3
  end
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
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'zopfli'
@@ -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 unsigned short* litlens,
107
- const unsigned short* dists,
108
+ static double EstimateCost(const ZopfliLZ77Store* lz77,
108
109
  size_t lstart, size_t lend) {
109
- return ZopfliCalculateBlockSize(litlens, dists, lstart, lend, 2);
110
+ return ZopfliCalculateBlockSizeAutoType(lz77, lstart, lend);
110
111
  }
111
112
 
112
113
  typedef struct SplitCostContext {
113
- const unsigned short* litlens;
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->litlens, c->dists, c->start, i) +
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 unsigned short* litlens,
151
- const unsigned short* dists,
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 < llsize; 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
- llsize: the size of the LL77 data, which is the size of the done array here.
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 llsize, const unsigned char* done,
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 ? llsize - 1 : splitpoints[i];
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 unsigned short* litlens,
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 (llsize < 10) return; /* This code fails on tiny files. */
225
+ if (lz77->size < 10) return; /* This code fails on tiny files. */
231
226
 
232
- done = (unsigned char*)malloc(llsize);
227
+ done = (unsigned char*)malloc(lz77->size);
233
228
  if (!done) exit(-1); /* Allocation failed. */
234
- for (i = 0; i < llsize; i++) done[i] = 0;
229
+ for (i = 0; i < lz77->size; i++) done[i] = 0;
235
230
 
236
231
  lstart = 0;
237
- lend = llsize;
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.litlens = litlens;
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
- splitcost = EstimateCost(litlens, dists, lstart, llpos) +
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
- llsize, done, *splitpoints, *npoints, &lstart, &lend)) {
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(litlens, dists, llsize, *splitpoints, *npoints);
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
- s.options = options;
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.litlens, store.dists, store.size, maxblocks,
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,