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.
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,