first commit
This commit is contained in:
16
build/node_modules/node-zopfli/History.md
generated
vendored
Normal file
16
build/node_modules/node-zopfli/History.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
## v2.0.2
|
||||
|
||||
* Support Node.js v7
|
||||
|
||||
## v2.0.1
|
||||
|
||||
* Fix cli [#78](https://github.com/pierreinglebert/node-zopfli/pull/78)
|
||||
|
||||
|
||||
## v2.0.0
|
||||
|
||||
* Drop 0.10 support [#74](https://github.com/pierreinglebert/node-zopfli/pull/74)
|
||||
|
||||
* Swap extension for deflate and zlib [#62](https://github.com/pierreinglebert/node-zopfli/pull/62)
|
||||
|
||||
* Update to latest zopfli (6818a08) [#70](https://github.com/pierreinglebert/node-zopfli/pull/70)
|
||||
21
build/node_modules/node-zopfli/LICENSE
generated
vendored
Normal file
21
build/node_modules/node-zopfli/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Pierre Inglebert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
158
build/node_modules/node-zopfli/README.md
generated
vendored
Normal file
158
build/node_modules/node-zopfli/README.md
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
# node-zopfli
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![Linux Build Status][travis-image]][travis-url]
|
||||
[![Windows Build Status][appveyor-image]][appveyor-url]
|
||||
[![Coverage Status][coveralls-image]][coveralls-url]
|
||||
[![Dependency Status][dep-image]][dep-url]
|
||||
[![devDependency Status][devDep-image]][devDep-url]
|
||||
[![Stories in Ready][waffle-image]][waffle-url]
|
||||
|
||||
Node.js bindings for [Zopfli](https://en.wikipedia.org/wiki/Zopfli) compressing library.
|
||||
Compress gzip files 5% better compared to gzip.
|
||||
|
||||
It is considerably slower than gzip (~100x) so you may want to use it only for static content and cached resources.
|
||||
|
||||
|
||||
## Prerequisites for building
|
||||
|
||||
* Python 2.7
|
||||
* GCC (Unix) or Visual Studio Express (Windows), see [Node Building tools](https://github.com/TooTallNate/node-gyp#installation)
|
||||
|
||||
## Usage
|
||||
|
||||
### Install
|
||||
|
||||
```shell
|
||||
npm install node-zopfli
|
||||
```
|
||||
|
||||
or if you want zopfli binary globally
|
||||
|
||||
```shell
|
||||
npm install -g node-zopfli
|
||||
```
|
||||
|
||||
### Binary (from command line)
|
||||
To gzip a file
|
||||
|
||||
```shell
|
||||
zopfli file.txt
|
||||
```
|
||||
|
||||
To compress a png file
|
||||
|
||||
```shell
|
||||
zopflipng file.png out.png
|
||||
```
|
||||
|
||||
### Usage examples
|
||||
#### Stream (async):
|
||||
|
||||
```js
|
||||
var zopfli = require('node-zopfli');
|
||||
fs.createReadStream('file.js')
|
||||
.pipe(zopfli.createGzip(options))
|
||||
.pipe(fs.createWriteStream('file.js.gz'));
|
||||
```
|
||||
|
||||
Instead of `zopfli.createGzip`, you can also use
|
||||
|
||||
```js
|
||||
new Zopfli('gzip', options);
|
||||
```
|
||||
|
||||
#### Buffer (async):
|
||||
|
||||
```js
|
||||
var zopfli = require('node-zopfli');
|
||||
var input = new Buffer('I want to be compressed');
|
||||
zopfli.deflate(input, options, function(err, deflated) {});
|
||||
zopfli.zlib(input, options, function(err, zlibed) {});
|
||||
zopfli.gzip(input, options, function(err, gziped) {});
|
||||
```
|
||||
|
||||
#### Buffer (sync):
|
||||
|
||||
```js
|
||||
var zopfli = require('node-zopfli');
|
||||
var input = new Buffer('I want to be compressed');
|
||||
var deflated = zopfli.deflateSync(input, options);
|
||||
var zlibed = zopfli.zlibSync(input, options);
|
||||
var gziped = zopfli.gzipSync(input, options);
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
#### compress(input, format, [options, callback])
|
||||
|
||||
`input` is the input buffer
|
||||
|
||||
`format` can be one of `deflate`, `zlib` and `gzip`
|
||||
|
||||
`callback`, if present, gets two arguments `(err, buffer)` where `err` is an error object, if any, and `buffer` is the resultant compressed data.
|
||||
|
||||
If no callback is provided, it returns an A+ Promise.
|
||||
|
||||
##### aliases
|
||||
|
||||
`deflate`, `zlib` and `gzip` methods are aliases on `compress` without `format` argument.
|
||||
|
||||
#### Options
|
||||
|
||||
Here are the options with defaults values you can pass to zopfli:
|
||||
|
||||
```js
|
||||
{
|
||||
verbose: false,
|
||||
verbose_more: false,
|
||||
numiterations: 15,
|
||||
blocksplitting: true,
|
||||
blocksplittinglast: false,
|
||||
blocksplittingmax: 15
|
||||
}
|
||||
```
|
||||
|
||||
##### numiterations
|
||||
Maximum amount of times to rerun forward and backward pass to optimize LZ77 compression cost. Good values: 10, 15 for small files, 5 for files over several MB in size or it will be too slow.
|
||||
|
||||
##### blocksplitting
|
||||
If true, splits the data in multiple deflate blocks with optimal choice for the block boundaries. Block splitting gives better compression.
|
||||
|
||||
##### blocksplittinglast
|
||||
If true, chooses the optimal block split points only after doing the iterative LZ77 compression. If false, chooses the block split points first, then does iterative LZ77 on each individual block. Depending on the file, either first or last gives the best compression.
|
||||
|
||||
##### blocksplittingmax
|
||||
Maximum amount of blocks to split into (0 for unlimited, but this can give extreme results that hurt compression on some files).
|
||||
|
||||
|
||||
## Build from sources
|
||||
|
||||
```shell
|
||||
git clone https://github.com/pierreinglebert/node-zopfli --recursive
|
||||
cd node-zopfli
|
||||
npm install
|
||||
```
|
||||
|
||||
## Tests
|
||||
mocha is used for tests, you can run them with:
|
||||
|
||||
```shell
|
||||
npm test
|
||||
```
|
||||
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/node-zopfli.svg
|
||||
[npm-url]: https://www.npmjs.com/package/node-zopfli
|
||||
[waffle-image]: https://badge.waffle.io/pierreinglebert/node-zopfli.svg
|
||||
[waffle-url]: https://waffle.io/pierreinglebert/node-zopfli
|
||||
[travis-image]: https://img.shields.io/travis/pierreinglebert/node-zopfli/master.svg?label=Linux%20build
|
||||
[travis-url]: https://travis-ci.org/pierreinglebert/node-zopfli
|
||||
[appveyor-image]: https://img.shields.io/appveyor/ci/pierreinglebert/node-zopfli/master.svg?label=Windows%20build
|
||||
[appveyor-url]: https://ci.appveyor.com/project/pierreinglebert/node-zopfli/branch/master
|
||||
[coveralls-image]: https://img.shields.io/coveralls/pierreinglebert/node-zopfli.svg
|
||||
[coveralls-url]: https://coveralls.io/r/pierreinglebert/node-zopfli?branch=master
|
||||
[dep-image]: https://img.shields.io/david/pierreinglebert/node-zopfli.svg
|
||||
[dep-url]: https://david-dm.org/pierreinglebert/node-zopfli
|
||||
[devDep-image]: https://img.shields.io/david/dev/pierreinglebert/node-zopfli.svg
|
||||
[devDep-url]: https://david-dm.org/pierreinglebert/node-zopfli#info=devDependencies
|
||||
64
build/node_modules/node-zopfli/bin/zopfli
generated
vendored
Executable file
64
build/node_modules/node-zopfli/bin/zopfli
generated
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
var program = require('commander');
|
||||
var fs = require('fs');
|
||||
var zopfli = require('../lib/zopfli');
|
||||
|
||||
program
|
||||
.version(require('../package.json').version)
|
||||
.usage('[options] [files...]')
|
||||
.option('--deflate', 'raw deflate (without container)')
|
||||
.option('--zlib', 'deflate using zlib container')
|
||||
.option('--gzip', 'deflate using gzip container')
|
||||
.option('-e, --ext <s>', 'overwrite default file extension')
|
||||
.option('-i, --iterations <n>', 'number of iterations (higher = smaller = slower)', parseInt)
|
||||
.option('-v, --verbose', 'Verbose')
|
||||
.parse(process.argv);
|
||||
|
||||
var options = {
|
||||
verbose: false,
|
||||
verbose_more: false,
|
||||
numiterations: 15,
|
||||
blocksplitting: true,
|
||||
blocksplittinglast: false,
|
||||
blocksplittingmax: 15
|
||||
};
|
||||
|
||||
if (program.iterations) options.numiterations = parseInt(program.iterations, 10);
|
||||
if (program.verbose) options.verbose = program.verbose;
|
||||
|
||||
var method = zopfli.createGzip;
|
||||
var extension = 'gz';
|
||||
|
||||
if (program.deflate) {
|
||||
method = zopfli.createDeflate;
|
||||
extension = 'deflate';
|
||||
}
|
||||
if (program.zlib) {
|
||||
method = zopfli.createZlib;
|
||||
extension = 'zlib';
|
||||
}
|
||||
if (program.ext) {
|
||||
extension = program.ext;
|
||||
}
|
||||
|
||||
if (program.args.length === 0) {
|
||||
program.outputHelp();
|
||||
process.exit(1);
|
||||
} else {
|
||||
Promise.all(
|
||||
program.args.map(function(item) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.createReadStream(item)
|
||||
.on('error', reject)
|
||||
.pipe(new method(options))
|
||||
.on('error', reject)
|
||||
.pipe(fs.createWriteStream(item + '.' + extension))
|
||||
.on('error', reject)
|
||||
.on('finish', resolve);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
56
build/node_modules/node-zopfli/bin/zopflipng
generated
vendored
Executable file
56
build/node_modules/node-zopfli/bin/zopflipng
generated
vendored
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
var program = require('commander');
|
||||
var fs = require('fs');
|
||||
var binary = require('node-pre-gyp');
|
||||
var path = require('path');
|
||||
var binding_path = binary.find(path.join(__dirname, '../package.json'));
|
||||
var zopfli = require(binding_path);
|
||||
|
||||
program
|
||||
.version(require('../package.json').version)
|
||||
.usage('[options] file destfile')
|
||||
.option('--lossy_transparent', 'Allow altering hidden colors of fully transparent pixels')
|
||||
.option('--lossy', 'Convert 16-bit per channel images to 8-bit per channel')
|
||||
.option('--filter_strategies', 'Filter strategies to try : "zero", "one", "two", "three", "four", "minimum", "entropy", "predefined", "brute", if none, it will be guessed automatically')
|
||||
.option('--keepchunks', 'Chunks to keep')
|
||||
.option('--iterations=<n>', 'Number of iterations for small images < 200 KiB', parseInt)
|
||||
.option('--iterations_large=<n>', 'Number of iterations for large images > 200 KiB', parseInt)
|
||||
.parse(process.argv);
|
||||
|
||||
var options = {
|
||||
lossy_transparent: false,
|
||||
lossy_8bit: false,
|
||||
filter_strategies: [],
|
||||
auto_filter_strategy: true,
|
||||
keepchunks: [],
|
||||
use_zopfli: true,
|
||||
num_iterations: 15,
|
||||
num_iterations_large: 5,
|
||||
block_split_strategy: 'both' // Split chunk strategy none, first, last, both
|
||||
};
|
||||
|
||||
options.lossy_transparent = !!program.lossy_transparent;
|
||||
options.lossy_8bit = !!program.lossy;
|
||||
// if (program.filter_strategies) options.filter_strategies = []; //TODO
|
||||
// if (program.keepchunks) options.keepchunks = []; //TODO
|
||||
options.num_iterations = program.iterations || options.num_iterations;
|
||||
options.num_iterations_large = program.iterations_large || options.num_iterations_large;
|
||||
|
||||
if (typeof program.args[0] !== 'string') {
|
||||
console.log('You must provide a file to compress');
|
||||
process.exit(1);
|
||||
}
|
||||
if (typeof program.args[1] !== 'string') {
|
||||
console.log('You must provide a destination file');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (fs.existsSync(program.args[0])) {
|
||||
zopfli.pngcompress(program.args[0], program.args[1], options);
|
||||
} else {
|
||||
console.log('File ' + program.args[0] + ' doesn\'t exist');
|
||||
process.exit(1);
|
||||
}
|
||||
93
build/node_modules/node-zopfli/binding.gyp
generated
vendored
Normal file
93
build/node_modules/node-zopfli/binding.gyp
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
{
|
||||
'target_defaults': {
|
||||
'default_configuration': 'Release'
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'cflags': ['-g3', '-O0'],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'BasicRuntimeChecks': 3, # /RTC1
|
||||
'ExceptionHandling': 1, # /EHsc
|
||||
'Optimization': '0', # /Od, no optimization
|
||||
'WarningLevel': 4
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'GenerateDebugInformation': 'true',
|
||||
'LinkIncremental': 2 # enable incremental linking
|
||||
}
|
||||
}
|
||||
},
|
||||
'Release': {
|
||||
'cflags': ['-O2', '-W', '-Wall', '-Wextra', '-ansi'],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'AdditionalOptions': ['/Zc:inline', '/MP'],
|
||||
'BufferSecurityCheck': 'true',
|
||||
'ExceptionHandling': 1, # /EHsc
|
||||
'FavorSizeOrSpeed': '1',
|
||||
'OmitFramePointers': 'false', # Ideally, we should only disable for x64
|
||||
'Optimization': '2',
|
||||
'StringPooling': 'true',
|
||||
'WarningLevel': 3,
|
||||
'WholeProgramOptimization': 'true'
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'DataExecutionPrevention': 2, # enable DEP
|
||||
'EnableCOMDATFolding': 2, # /OPT:ICF
|
||||
'LinkIncremental': 1, # disable incremental linking
|
||||
'LinkTimeCodeGeneration': 1, # link-time code generation
|
||||
'OptimizeReferences': 2, # /OPT:REF
|
||||
'RandomizedBaseAddress': 2, # enable ASLR
|
||||
'SetChecksum': 'true'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"target_name": "<(module_name)",
|
||||
'lflags': ['-lm'],
|
||||
"include_dirs": [
|
||||
"zopfli/src/zopfli",
|
||||
"zopfli/src/zopflipng",
|
||||
"<!(node -e \"require('nan')\")"
|
||||
],
|
||||
"sources": [
|
||||
"src/zopfli-binding.cc",
|
||||
"src/png/zopflipng.cc",
|
||||
"zopfli/src/zopfli/blocksplitter.c",
|
||||
"zopfli/src/zopfli/cache.c",
|
||||
"zopfli/src/zopfli/deflate.c",
|
||||
"zopfli/src/zopfli/gzip_container.c",
|
||||
"zopfli/src/zopfli/hash.c",
|
||||
"zopfli/src/zopfli/katajainen.c",
|
||||
"zopfli/src/zopfli/lz77.c",
|
||||
"zopfli/src/zopfli/squeeze.c",
|
||||
"zopfli/src/zopfli/tree.c",
|
||||
"zopfli/src/zopfli/util.c",
|
||||
"zopfli/src/zopfli/zlib_container.c",
|
||||
"zopfli/src/zopfli/zopfli_lib.c",
|
||||
"zopfli/src/zopflipng/zopflipng_lib.cc",
|
||||
"zopfli/src/zopflipng/lodepng/lodepng.cpp",
|
||||
"zopfli/src/zopflipng/lodepng/lodepng_util.cpp"
|
||||
],
|
||||
"cflags": [
|
||||
"-Wall",
|
||||
"-O3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_name": "action_after_build",
|
||||
"type": "none",
|
||||
"dependencies": ["<(module_name)"],
|
||||
"copies": [
|
||||
{
|
||||
"files": ["<(PRODUCT_DIR)/<(module_name).node"],
|
||||
"destination": "<(module_path)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
347
build/node_modules/node-zopfli/build/Makefile
generated
vendored
Normal file
347
build/node_modules/node-zopfli/build/Makefile
generated
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
# We borrow heavily from the kernel build setup, though we are simpler since
|
||||
# we don't have Kconfig tweaking settings on us.
|
||||
|
||||
# The implicit make rules have it looking for RCS files, among other things.
|
||||
# We instead explicitly write all the rules we care about.
|
||||
# It's even quicker (saves ~200ms) to pass -r on the command line.
|
||||
MAKEFLAGS=-r
|
||||
|
||||
# The source directory tree.
|
||||
srcdir := ..
|
||||
abs_srcdir := $(abspath $(srcdir))
|
||||
|
||||
# The name of the builddir.
|
||||
builddir_name ?= .
|
||||
|
||||
# The V=1 flag on command line makes us verbosely print command lines.
|
||||
ifdef V
|
||||
quiet=
|
||||
else
|
||||
quiet=quiet_
|
||||
endif
|
||||
|
||||
# Specify BUILDTYPE=Release on the command line for a release build.
|
||||
BUILDTYPE ?= Release
|
||||
|
||||
# Directory all our build output goes into.
|
||||
# Note that this must be two directories beneath src/ for unit tests to pass,
|
||||
# as they reach into the src/ directory for data with relative paths.
|
||||
builddir ?= $(builddir_name)/$(BUILDTYPE)
|
||||
abs_builddir := $(abspath $(builddir))
|
||||
depsdir := $(builddir)/.deps
|
||||
|
||||
# Object output directory.
|
||||
obj := $(builddir)/obj
|
||||
abs_obj := $(abspath $(obj))
|
||||
|
||||
# We build up a list of every single one of the targets so we can slurp in the
|
||||
# generated dependency rule Makefiles in one pass.
|
||||
all_deps :=
|
||||
|
||||
|
||||
|
||||
CC.target ?= $(CC)
|
||||
CFLAGS.target ?= $(CPPFLAGS) $(CFLAGS)
|
||||
CXX.target ?= $(CXX)
|
||||
CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS)
|
||||
LINK.target ?= $(LINK)
|
||||
LDFLAGS.target ?= $(LDFLAGS)
|
||||
AR.target ?= $(AR)
|
||||
|
||||
# C++ apps need to be linked with g++.
|
||||
LINK ?= $(CXX.target)
|
||||
|
||||
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
|
||||
# to replicate this environment fallback in make as well.
|
||||
CC.host ?= gcc
|
||||
CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host)
|
||||
CXX.host ?= g++
|
||||
CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host)
|
||||
LINK.host ?= $(CXX.host)
|
||||
LDFLAGS.host ?=
|
||||
AR.host ?= ar
|
||||
|
||||
# Define a dir function that can handle spaces.
|
||||
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
|
||||
# "leading spaces cannot appear in the text of the first argument as written.
|
||||
# These characters can be put into the argument value by variable substitution."
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
|
||||
# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
|
||||
replace_spaces = $(subst $(space),?,$1)
|
||||
unreplace_spaces = $(subst ?,$(space),$1)
|
||||
dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
|
||||
|
||||
# Flags to make gcc output dependency info. Note that you need to be
|
||||
# careful here to use the flags that ccache and distcc can understand.
|
||||
# We write to a dep file on the side first and then rename at the end
|
||||
# so we can't end up with a broken dep file.
|
||||
depfile = $(depsdir)/$(call replace_spaces,$@).d
|
||||
DEPFLAGS = -MMD -MF $(depfile).raw
|
||||
|
||||
# We have to fixup the deps output in a few ways.
|
||||
# (1) the file output should mention the proper .o file.
|
||||
# ccache or distcc lose the path to the target, so we convert a rule of
|
||||
# the form:
|
||||
# foobar.o: DEP1 DEP2
|
||||
# into
|
||||
# path/to/foobar.o: DEP1 DEP2
|
||||
# (2) we want missing files not to cause us to fail to build.
|
||||
# We want to rewrite
|
||||
# foobar.o: DEP1 DEP2 \
|
||||
# DEP3
|
||||
# to
|
||||
# DEP1:
|
||||
# DEP2:
|
||||
# DEP3:
|
||||
# so if the files are missing, they're just considered phony rules.
|
||||
# We have to do some pretty insane escaping to get those backslashes
|
||||
# and dollar signs past make, the shell, and sed at the same time.
|
||||
# Doesn't work with spaces, but that's fine: .d files have spaces in
|
||||
# their names replaced with other characters.
|
||||
define fixup_dep
|
||||
# The depfile may not exist if the input file didn't have any #includes.
|
||||
touch $(depfile).raw
|
||||
# Fixup path as in (1).
|
||||
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
|
||||
# Add extra rules as in (2).
|
||||
# We remove slashes and replace spaces with new lines;
|
||||
# remove blank lines;
|
||||
# delete the first line and append a colon to the remaining lines.
|
||||
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
|
||||
grep -v '^$$' |\
|
||||
sed -e 1d -e 's|$$|:|' \
|
||||
>> $(depfile)
|
||||
rm $(depfile).raw
|
||||
endef
|
||||
|
||||
# Command definitions:
|
||||
# - cmd_foo is the actual command to run;
|
||||
# - quiet_cmd_foo is the brief-output summary of the command.
|
||||
|
||||
quiet_cmd_cc = CC($(TOOLSET)) $@
|
||||
cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
|
||||
|
||||
quiet_cmd_cxx = CXX($(TOOLSET)) $@
|
||||
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
|
||||
|
||||
quiet_cmd_objc = CXX($(TOOLSET)) $@
|
||||
cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
|
||||
|
||||
quiet_cmd_objcxx = CXX($(TOOLSET)) $@
|
||||
cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
|
||||
|
||||
# Commands for precompiled header files.
|
||||
quiet_cmd_pch_c = CXX($(TOOLSET)) $@
|
||||
cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
|
||||
quiet_cmd_pch_cc = CXX($(TOOLSET)) $@
|
||||
cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
|
||||
quiet_cmd_pch_m = CXX($(TOOLSET)) $@
|
||||
cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
|
||||
quiet_cmd_pch_mm = CXX($(TOOLSET)) $@
|
||||
cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
|
||||
|
||||
# gyp-mac-tool is written next to the root Makefile by gyp.
|
||||
# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd
|
||||
# already.
|
||||
quiet_cmd_mac_tool = MACTOOL $(4) $<
|
||||
cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@"
|
||||
|
||||
quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@
|
||||
cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4)
|
||||
|
||||
quiet_cmd_infoplist = INFOPLIST $@
|
||||
cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@"
|
||||
|
||||
quiet_cmd_touch = TOUCH $@
|
||||
cmd_touch = touch $@
|
||||
|
||||
quiet_cmd_copy = COPY $@
|
||||
# send stderr to /dev/null to ignore messages when linking directories.
|
||||
cmd_copy = rm -rf "$@" && cp -af "$<" "$@"
|
||||
|
||||
quiet_cmd_alink = LIBTOOL-STATIC $@
|
||||
cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^)
|
||||
|
||||
quiet_cmd_link = LINK($(TOOLSET)) $@
|
||||
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
|
||||
|
||||
quiet_cmd_solink = SOLINK($(TOOLSET)) $@
|
||||
cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
|
||||
|
||||
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
|
||||
cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
|
||||
|
||||
|
||||
# Define an escape_quotes function to escape single quotes.
|
||||
# This allows us to handle quotes properly as long as we always use
|
||||
# use single quotes and escape_quotes.
|
||||
escape_quotes = $(subst ','\'',$(1))
|
||||
# This comment is here just to include a ' to unconfuse syntax highlighting.
|
||||
# Define an escape_vars function to escape '$' variable syntax.
|
||||
# This allows us to read/write command lines with shell variables (e.g.
|
||||
# $LD_LIBRARY_PATH), without triggering make substitution.
|
||||
escape_vars = $(subst $$,$$$$,$(1))
|
||||
# Helper that expands to a shell command to echo a string exactly as it is in
|
||||
# make. This uses printf instead of echo because printf's behaviour with respect
|
||||
# to escape sequences is more portable than echo's across different shells
|
||||
# (e.g., dash, bash).
|
||||
exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
|
||||
|
||||
# Helper to compare the command we're about to run against the command
|
||||
# we logged the last time we ran the command. Produces an empty
|
||||
# string (false) when the commands match.
|
||||
# Tricky point: Make has no string-equality test function.
|
||||
# The kernel uses the following, but it seems like it would have false
|
||||
# positives, where one string reordered its arguments.
|
||||
# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
|
||||
# $(filter-out $(cmd_$@), $(cmd_$(1))))
|
||||
# We instead substitute each for the empty string into the other, and
|
||||
# say they're equal if both substitutions produce the empty string.
|
||||
# .d files contain ? instead of spaces, take that into account.
|
||||
command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
|
||||
$(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
|
||||
|
||||
# Helper that is non-empty when a prerequisite changes.
|
||||
# Normally make does this implicitly, but we force rules to always run
|
||||
# so we can check their command lines.
|
||||
# $? -- new prerequisites
|
||||
# $| -- order-only dependencies
|
||||
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
|
||||
|
||||
# Helper that executes all postbuilds until one fails.
|
||||
define do_postbuilds
|
||||
@E=0;\
|
||||
for p in $(POSTBUILDS); do\
|
||||
eval $$p;\
|
||||
E=$$?;\
|
||||
if [ $$E -ne 0 ]; then\
|
||||
break;\
|
||||
fi;\
|
||||
done;\
|
||||
if [ $$E -ne 0 ]; then\
|
||||
rm -rf "$@";\
|
||||
exit $$E;\
|
||||
fi
|
||||
endef
|
||||
|
||||
# do_cmd: run a command via the above cmd_foo names, if necessary.
|
||||
# Should always run for a given target to handle command-line changes.
|
||||
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
|
||||
# Third argument, if non-zero, makes it do POSTBUILDS processing.
|
||||
# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
|
||||
# spaces already and dirx strips the ? characters.
|
||||
define do_cmd
|
||||
$(if $(or $(command_changed),$(prereq_changed)),
|
||||
@$(call exact_echo, $($(quiet)cmd_$(1)))
|
||||
@mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
|
||||
$(if $(findstring flock,$(word 2,$(cmd_$1))),
|
||||
@$(cmd_$(1))
|
||||
@echo " $(quiet_cmd_$(1)): Finished",
|
||||
@$(cmd_$(1))
|
||||
)
|
||||
@$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
|
||||
@$(if $(2),$(fixup_dep))
|
||||
$(if $(and $(3), $(POSTBUILDS)),
|
||||
$(call do_postbuilds)
|
||||
)
|
||||
)
|
||||
endef
|
||||
|
||||
# Declare the "all" target first so it is the default,
|
||||
# even though we don't have the deps yet.
|
||||
.PHONY: all
|
||||
all:
|
||||
|
||||
# make looks for ways to re-generate included makefiles, but in our case, we
|
||||
# don't have a direct way. Explicitly telling make that it has nothing to do
|
||||
# for them makes it go faster.
|
||||
%.d: ;
|
||||
|
||||
# Use FORCE_DO_CMD to force a target to run. Should be coupled with
|
||||
# do_cmd.
|
||||
.PHONY: FORCE_DO_CMD
|
||||
FORCE_DO_CMD:
|
||||
|
||||
TOOLSET := target
|
||||
# Suffix rules, putting all outputs into $(obj).
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD
|
||||
@$(call do_cmd,objc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD
|
||||
@$(call do_cmd,objcxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
# Try building from generated source, too.
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD
|
||||
@$(call do_cmd,objc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD
|
||||
@$(call do_cmd,objcxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD
|
||||
@$(call do_cmd,objc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD
|
||||
@$(call do_cmd,objcxx,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
|
||||
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
|
||||
$(findstring $(join ^,$(prefix)),\
|
||||
$(join ^,action_after_build.target.mk)))),)
|
||||
include action_after_build.target.mk
|
||||
endif
|
||||
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
|
||||
$(findstring $(join ^,$(prefix)),\
|
||||
$(join ^,zopfli.target.mk)))),)
|
||||
include zopfli.target.mk
|
||||
endif
|
||||
|
||||
quiet_cmd_regen_makefile = ACTION Regenerating $@
|
||||
cmd_regen_makefile = cd $(srcdir); /Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/build/config.gypi -I/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-gyp/addon.gypi -I/Users/asciidisco/.node-gyp/9.3.0/include/node/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/asciidisco/.node-gyp/9.3.0" "-Dnode_gyp_dir=/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-gyp" "-Dnode_lib_file=/Users/asciidisco/.node-gyp/9.3.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli" "-Dnode_engine=v8" binding.gyp
|
||||
Makefile: $(srcdir)/../../../../../.node-gyp/9.3.0/include/node/common.gypi $(srcdir)/../node-gyp/addon.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp
|
||||
$(call do_cmd,regen_makefile)
|
||||
|
||||
# "all" is a concatenation of the "all" targets from all the included
|
||||
# sub-makefiles. This is just here to clarify.
|
||||
all:
|
||||
|
||||
# Add in dependency-tracking rules. $(all_deps) is the list of every single
|
||||
# target in our tree. Only consider the ones with .d (dependency) info:
|
||||
d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
|
||||
ifneq ($(d_files),)
|
||||
include $(d_files)
|
||||
endif
|
||||
1
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/action_after_build.stamp.d
generated
vendored
Normal file
1
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/action_after_build.stamp.d
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
cmd_Release/obj.target/action_after_build.stamp := touch Release/obj.target/action_after_build.stamp
|
||||
58
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/src/png/zopflipng.o.d
generated
vendored
Normal file
58
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/src/png/zopflipng.o.d
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
cmd_Release/obj.target/zopfli/src/png/zopflipng.o := c++ '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/src/png/zopflipng.o.d.raw -c -o Release/obj.target/zopfli/src/png/zopflipng.o ../src/png/zopflipng.cc
|
||||
Release/obj.target/zopfli/src/png/zopflipng.o: ../src/png/zopflipng.cc \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-version.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8config.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-platform.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_version.h \
|
||||
../../nan/nan.h /Users/asciidisco/.node-gyp/9.3.0/include/node/uv.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-errno.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-version.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-unix.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-threadpool.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-darwin.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/pthread-barrier.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_buffer.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_object_wrap.h \
|
||||
../../nan/nan_callbacks.h ../../nan/nan_callbacks_12_inl.h \
|
||||
../../nan/nan_maybe_43_inl.h ../../nan/nan_converters.h \
|
||||
../../nan/nan_converters_43_inl.h ../../nan/nan_new.h \
|
||||
../../nan/nan_implementation_12_inl.h \
|
||||
../../nan/nan_persistent_12_inl.h ../../nan/nan_weak.h \
|
||||
../../nan/nan_object_wrap.h ../../nan/nan_private.h \
|
||||
../../nan/nan_typedarray_contents.h ../../nan/nan_json.h \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h \
|
||||
../zopfli/src/zopflipng/zopflipng_lib.h
|
||||
../src/png/zopflipng.cc:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-version.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8config.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-platform.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_version.h:
|
||||
../../nan/nan.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-errno.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-version.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-unix.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-threadpool.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-darwin.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/pthread-barrier.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_buffer.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_object_wrap.h:
|
||||
../../nan/nan_callbacks.h:
|
||||
../../nan/nan_callbacks_12_inl.h:
|
||||
../../nan/nan_maybe_43_inl.h:
|
||||
../../nan/nan_converters.h:
|
||||
../../nan/nan_converters_43_inl.h:
|
||||
../../nan/nan_new.h:
|
||||
../../nan/nan_implementation_12_inl.h:
|
||||
../../nan/nan_persistent_12_inl.h:
|
||||
../../nan/nan_weak.h:
|
||||
../../nan/nan_object_wrap.h:
|
||||
../../nan/nan_private.h:
|
||||
../../nan/nan_typedarray_contents.h:
|
||||
../../nan/nan_json.h:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h:
|
||||
../zopfli/src/zopflipng/zopflipng_lib.h:
|
||||
59
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/src/zopfli-binding.o.d
generated
vendored
Normal file
59
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/src/zopfli-binding.o.d
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
cmd_Release/obj.target/zopfli/src/zopfli-binding.o := c++ '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/src/zopfli-binding.o.d.raw -c -o Release/obj.target/zopfli/src/zopfli-binding.o ../src/zopfli-binding.cc
|
||||
Release/obj.target/zopfli/src/zopfli-binding.o: ../src/zopfli-binding.cc \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-version.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8config.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-platform.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_version.h \
|
||||
../zopfli/src/zopfli/zopfli.h ../src/zopfli-binding.h ../../nan/nan.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-errno.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-version.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-unix.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-threadpool.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-darwin.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/pthread-barrier.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_buffer.h \
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_object_wrap.h \
|
||||
../../nan/nan_callbacks.h ../../nan/nan_callbacks_12_inl.h \
|
||||
../../nan/nan_maybe_43_inl.h ../../nan/nan_converters.h \
|
||||
../../nan/nan_converters_43_inl.h ../../nan/nan_new.h \
|
||||
../../nan/nan_implementation_12_inl.h \
|
||||
../../nan/nan_persistent_12_inl.h ../../nan/nan_weak.h \
|
||||
../../nan/nan_object_wrap.h ../../nan/nan_private.h \
|
||||
../../nan/nan_typedarray_contents.h ../../nan/nan_json.h \
|
||||
../src/png/zopflipng.h
|
||||
../src/zopfli-binding.cc:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-version.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8config.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/v8-platform.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_version.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../src/zopfli-binding.h:
|
||||
../../nan/nan.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-errno.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-version.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-unix.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-threadpool.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/uv-darwin.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/pthread-barrier.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_buffer.h:
|
||||
/Users/asciidisco/.node-gyp/9.3.0/include/node/node_object_wrap.h:
|
||||
../../nan/nan_callbacks.h:
|
||||
../../nan/nan_callbacks_12_inl.h:
|
||||
../../nan/nan_maybe_43_inl.h:
|
||||
../../nan/nan_converters.h:
|
||||
../../nan/nan_converters_43_inl.h:
|
||||
../../nan/nan_new.h:
|
||||
../../nan/nan_implementation_12_inl.h:
|
||||
../../nan/nan_persistent_12_inl.h:
|
||||
../../nan/nan_weak.h:
|
||||
../../nan/nan_object_wrap.h:
|
||||
../../nan/nan_private.h:
|
||||
../../nan/nan_typedarray_contents.h:
|
||||
../../nan/nan_json.h:
|
||||
../src/png/zopflipng.h:
|
||||
18
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o.d
generated
vendored
Normal file
18
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o.d
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o ../zopfli/src/zopfli/blocksplitter.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o: \
|
||||
../zopfli/src/zopfli/blocksplitter.c \
|
||||
../zopfli/src/zopfli/blocksplitter.h ../zopfli/src/zopfli/lz77.h \
|
||||
../zopfli/src/zopfli/cache.h ../zopfli/src/zopfli/util.h \
|
||||
../zopfli/src/zopfli/hash.h ../zopfli/src/zopfli/zopfli.h \
|
||||
../zopfli/src/zopfli/deflate.h ../zopfli/src/zopfli/squeeze.h \
|
||||
../zopfli/src/zopfli/tree.h
|
||||
../zopfli/src/zopfli/blocksplitter.c:
|
||||
../zopfli/src/zopfli/blocksplitter.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/squeeze.h:
|
||||
../zopfli/src/zopfli/tree.h:
|
||||
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/cache.o.d
generated
vendored
Normal file
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/cache.o.d
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/cache.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/cache.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/cache.o ../zopfli/src/zopfli/cache.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/cache.o: \
|
||||
../zopfli/src/zopfli/cache.c ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/util.h
|
||||
../zopfli/src/zopfli/cache.c:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
19
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o.d
generated
vendored
Normal file
19
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o.d
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o ../zopfli/src/zopfli/deflate.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o: \
|
||||
../zopfli/src/zopfli/deflate.c ../zopfli/src/zopfli/deflate.h \
|
||||
../zopfli/src/zopfli/lz77.h ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/util.h ../zopfli/src/zopfli/hash.h \
|
||||
../zopfli/src/zopfli/zopfli.h ../zopfli/src/zopfli/blocksplitter.h \
|
||||
../zopfli/src/zopfli/squeeze.h ../zopfli/src/zopfli/symbols.h \
|
||||
../zopfli/src/zopfli/tree.h
|
||||
../zopfli/src/zopfli/deflate.c:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/blocksplitter.h:
|
||||
../zopfli/src/zopfli/squeeze.h:
|
||||
../zopfli/src/zopfli/symbols.h:
|
||||
../zopfli/src/zopfli/tree.h:
|
||||
15
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o.d
generated
vendored
Normal file
15
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o.d
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o ../zopfli/src/zopfli/gzip_container.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o: \
|
||||
../zopfli/src/zopfli/gzip_container.c \
|
||||
../zopfli/src/zopfli/gzip_container.h ../zopfli/src/zopfli/zopfli.h \
|
||||
../zopfli/src/zopfli/util.h ../zopfli/src/zopfli/deflate.h \
|
||||
../zopfli/src/zopfli/lz77.h ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/hash.h
|
||||
../zopfli/src/zopfli/gzip_container.c:
|
||||
../zopfli/src/zopfli/gzip_container.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/hash.o.d
generated
vendored
Normal file
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/hash.o.d
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/hash.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/hash.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/hash.o ../zopfli/src/zopfli/hash.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/hash.o: \
|
||||
../zopfli/src/zopfli/hash.c ../zopfli/src/zopfli/hash.h \
|
||||
../zopfli/src/zopfli/util.h
|
||||
../zopfli/src/zopfli/hash.c:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
5
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o.d
generated
vendored
Normal file
5
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o.d
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o ../zopfli/src/zopfli/katajainen.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o: \
|
||||
../zopfli/src/zopfli/katajainen.c ../zopfli/src/zopfli/katajainen.h
|
||||
../zopfli/src/zopfli/katajainen.c:
|
||||
../zopfli/src/zopfli/katajainen.h:
|
||||
13
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o.d
generated
vendored
Normal file
13
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o.d
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o ../zopfli/src/zopfli/lz77.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o: \
|
||||
../zopfli/src/zopfli/lz77.c ../zopfli/src/zopfli/lz77.h \
|
||||
../zopfli/src/zopfli/cache.h ../zopfli/src/zopfli/util.h \
|
||||
../zopfli/src/zopfli/hash.h ../zopfli/src/zopfli/zopfli.h \
|
||||
../zopfli/src/zopfli/symbols.h
|
||||
../zopfli/src/zopfli/lz77.c:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/symbols.h:
|
||||
19
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o.d
generated
vendored
Normal file
19
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o.d
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o ../zopfli/src/zopfli/squeeze.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o: \
|
||||
../zopfli/src/zopfli/squeeze.c ../zopfli/src/zopfli/squeeze.h \
|
||||
../zopfli/src/zopfli/lz77.h ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/util.h ../zopfli/src/zopfli/hash.h \
|
||||
../zopfli/src/zopfli/zopfli.h ../zopfli/src/zopfli/blocksplitter.h \
|
||||
../zopfli/src/zopfli/deflate.h ../zopfli/src/zopfli/symbols.h \
|
||||
../zopfli/src/zopfli/tree.h
|
||||
../zopfli/src/zopfli/squeeze.c:
|
||||
../zopfli/src/zopfli/squeeze.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/blocksplitter.h:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/symbols.h:
|
||||
../zopfli/src/zopfli/tree.h:
|
||||
8
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/tree.o.d
generated
vendored
Normal file
8
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/tree.o.d
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/tree.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/tree.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/tree.o ../zopfli/src/zopfli/tree.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/tree.o: \
|
||||
../zopfli/src/zopfli/tree.c ../zopfli/src/zopfli/tree.h \
|
||||
../zopfli/src/zopfli/katajainen.h ../zopfli/src/zopfli/util.h
|
||||
../zopfli/src/zopfli/tree.c:
|
||||
../zopfli/src/zopfli/tree.h:
|
||||
../zopfli/src/zopfli/katajainen.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/util.o.d
generated
vendored
Normal file
7
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/util.o.d
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/util.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/util.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/util.o ../zopfli/src/zopfli/util.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/util.o: \
|
||||
../zopfli/src/zopfli/util.c ../zopfli/src/zopfli/util.h \
|
||||
../zopfli/src/zopfli/zopfli.h
|
||||
../zopfli/src/zopfli/util.c:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
15
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o.d
generated
vendored
Normal file
15
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o.d
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o ../zopfli/src/zopfli/zlib_container.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o: \
|
||||
../zopfli/src/zopfli/zlib_container.c \
|
||||
../zopfli/src/zopfli/zlib_container.h ../zopfli/src/zopfli/zopfli.h \
|
||||
../zopfli/src/zopfli/util.h ../zopfli/src/zopfli/deflate.h \
|
||||
../zopfli/src/zopfli/lz77.h ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/hash.h
|
||||
../zopfli/src/zopfli/zlib_container.c:
|
||||
../zopfli/src/zopfli/zlib_container.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
16
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o.d
generated
vendored
Normal file
16
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o.d
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o := cc '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o ../zopfli/src/zopfli/zopfli_lib.c
|
||||
Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o: \
|
||||
../zopfli/src/zopfli/zopfli_lib.c ../zopfli/src/zopfli/zopfli.h \
|
||||
../zopfli/src/zopfli/deflate.h ../zopfli/src/zopfli/lz77.h \
|
||||
../zopfli/src/zopfli/cache.h ../zopfli/src/zopfli/util.h \
|
||||
../zopfli/src/zopfli/hash.h ../zopfli/src/zopfli/gzip_container.h \
|
||||
../zopfli/src/zopfli/zlib_container.h
|
||||
../zopfli/src/zopfli/zopfli_lib.c:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
../zopfli/src/zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/gzip_container.h:
|
||||
../zopfli/src/zopfli/zlib_container.h:
|
||||
6
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o.d
generated
vendored
Normal file
6
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o.d
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o := c++ '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o ../zopfli/src/zopflipng/lodepng/lodepng.cpp
|
||||
Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o: \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.cpp \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.cpp:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h:
|
||||
8
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o.d
generated
vendored
Normal file
8
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o.d
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o := c++ '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o ../zopfli/src/zopflipng/lodepng/lodepng_util.cpp
|
||||
Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o: \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.cpp \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.h \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.cpp:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.h:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h:
|
||||
20
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o.d
generated
vendored
Normal file
20
build/node_modules/node-zopfli/build/Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o.d
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
cmd_Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o := c++ '-DNODE_GYP_MODULE_NAME=zopfli' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/asciidisco/.node-gyp/9.3.0/include/node -I/Users/asciidisco/.node-gyp/9.3.0/src -I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include -I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include -I../zopfli/src/zopfli -I../zopfli/src/zopflipng -I../../nan -Os -gdwarf-2 -mmacosx-version-min=10.7 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++0x -stdlib=libc++ -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o.d.raw -c -o Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o ../zopfli/src/zopflipng/zopflipng_lib.cc
|
||||
Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o: \
|
||||
../zopfli/src/zopflipng/zopflipng_lib.cc \
|
||||
../zopfli/src/zopflipng/zopflipng_lib.h \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h \
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.h \
|
||||
../zopfli/src/zopflipng/../zopfli/deflate.h \
|
||||
../zopfli/src/zopfli/lz77.h ../zopfli/src/zopfli/cache.h \
|
||||
../zopfli/src/zopfli/util.h ../zopfli/src/zopfli/hash.h \
|
||||
../zopfli/src/zopfli/zopfli.h
|
||||
../zopfli/src/zopflipng/zopflipng_lib.cc:
|
||||
../zopfli/src/zopflipng/zopflipng_lib.h:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng.h:
|
||||
../zopfli/src/zopflipng/lodepng/lodepng_util.h:
|
||||
../zopfli/src/zopflipng/../zopfli/deflate.h:
|
||||
../zopfli/src/zopfli/lz77.h:
|
||||
../zopfli/src/zopfli/cache.h:
|
||||
../zopfli/src/zopfli/util.h:
|
||||
../zopfli/src/zopfli/hash.h:
|
||||
../zopfli/src/zopfli/zopfli.h:
|
||||
1
build/node_modules/node-zopfli/build/Release/.deps/Release/zopfli.node.d
generated
vendored
Normal file
1
build/node_modules/node-zopfli/build/Release/.deps/Release/zopfli.node.d
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
cmd_Release/zopfli.node := c++ -bundle -undefined dynamic_lookup -Wl,-no_pie -Wl,-search_paths_first -mmacosx-version-min=10.7 -arch x86_64 -L./Release -stdlib=libc++ -o Release/zopfli.node Release/obj.target/zopfli/src/zopfli-binding.o Release/obj.target/zopfli/src/png/zopflipng.o Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o Release/obj.target/zopfli/zopfli/src/zopfli/cache.o Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o Release/obj.target/zopfli/zopfli/src/zopfli/hash.o Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o Release/obj.target/zopfli/zopfli/src/zopfli/tree.o Release/obj.target/zopfli/zopfli/src/zopfli/util.o Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o
|
||||
@@ -0,0 +1 @@
|
||||
cmd_/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node := rm -rf "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node" && cp -af "Release/zopfli.node" "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node"
|
||||
0
build/node_modules/node-zopfli/build/Release/obj.target/action_after_build.stamp
generated
vendored
Normal file
0
build/node_modules/node-zopfli/build/Release/obj.target/action_after_build.stamp
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/src/png/zopflipng.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/src/png/zopflipng.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/src/zopfli-binding.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/src/zopfli-binding.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/blocksplitter.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/cache.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/cache.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/deflate.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/gzip_container.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/hash.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/hash.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/katajainen.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/lz77.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/squeeze.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/tree.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/tree.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/util.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/util.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/zlib_container.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopfli/zopfli_lib.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o
generated
vendored
Normal file
BIN
build/node_modules/node-zopfli/build/Release/obj.target/zopfli/zopfli/src/zopflipng/zopflipng_lib.o
generated
vendored
Normal file
Binary file not shown.
BIN
build/node_modules/node-zopfli/build/Release/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/build/Release/zopfli.node
generated
vendored
Executable file
Binary file not shown.
32
build/node_modules/node-zopfli/build/action_after_build.target.mk
generated
vendored
Normal file
32
build/node_modules/node-zopfli/build/action_after_build.target.mk
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# This file is generated by gyp; do not edit.
|
||||
|
||||
TOOLSET := target
|
||||
TARGET := action_after_build
|
||||
### Generated for copy rule.
|
||||
/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node: TOOLSET := $(TOOLSET)
|
||||
/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node: $(builddir)/zopfli.node FORCE_DO_CMD
|
||||
$(call do_cmd,copy)
|
||||
|
||||
all_deps += /Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node
|
||||
binding_gyp_action_after_build_target_copies = /Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node
|
||||
|
||||
### Rules for final target.
|
||||
# Build our special outputs first.
|
||||
$(obj).target/action_after_build.stamp: | $(binding_gyp_action_after_build_target_copies)
|
||||
|
||||
# Preserve order dependency of special output on deps.
|
||||
$(binding_gyp_action_after_build_target_copies): | $(builddir)/zopfli.node
|
||||
|
||||
$(obj).target/action_after_build.stamp: TOOLSET := $(TOOLSET)
|
||||
$(obj).target/action_after_build.stamp: $(builddir)/zopfli.node FORCE_DO_CMD
|
||||
$(call do_cmd,touch)
|
||||
|
||||
all_deps += $(obj).target/action_after_build.stamp
|
||||
# Add target alias
|
||||
.PHONY: action_after_build
|
||||
action_after_build: $(obj).target/action_after_build.stamp
|
||||
|
||||
# Add target alias to "all" target.
|
||||
.PHONY: all
|
||||
all: action_after_build
|
||||
|
||||
6
build/node_modules/node-zopfli/build/binding.Makefile
generated
vendored
Normal file
6
build/node_modules/node-zopfli/build/binding.Makefile
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# This file is generated by gyp; do not edit.
|
||||
|
||||
export builddir_name ?= ./build/.
|
||||
.PHONY: all
|
||||
all:
|
||||
$(MAKE) zopfli action_after_build
|
||||
187
build/node_modules/node-zopfli/build/config.gypi
generated
vendored
Normal file
187
build/node_modules/node-zopfli/build/config.gypi
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
# Do not edit. File was generated by node-gyp's "configure" step
|
||||
{
|
||||
"target_defaults": {
|
||||
"cflags": [],
|
||||
"default_configuration": "Release",
|
||||
"defines": [],
|
||||
"include_dirs": [],
|
||||
"libraries": []
|
||||
},
|
||||
"variables": {
|
||||
"asan": 0,
|
||||
"coverage": "false",
|
||||
"debug_devtools": "node",
|
||||
"debug_http2": "false",
|
||||
"debug_nghttp2": "false",
|
||||
"force_dynamic_crt": 0,
|
||||
"host_arch": "x64",
|
||||
"icu_data_file": "icudt60l.dat",
|
||||
"icu_data_in": "../../deps/icu-small/source/data/in/icudt60l.dat",
|
||||
"icu_endianness": "l",
|
||||
"icu_gyp_path": "tools/icu/icu-generic.gyp",
|
||||
"icu_locales": "en,root",
|
||||
"icu_path": "deps/icu-small",
|
||||
"icu_small": "true",
|
||||
"icu_ver_major": "60",
|
||||
"llvm_version": 0,
|
||||
"node_byteorder": "little",
|
||||
"node_enable_d8": "false",
|
||||
"node_enable_v8_vtunejit": "false",
|
||||
"node_install_npm": "true",
|
||||
"node_module_version": 59,
|
||||
"node_no_browser_globals": "false",
|
||||
"node_prefix": "/",
|
||||
"node_release_urlbase": "https://nodejs.org/download/release/",
|
||||
"node_shared": "false",
|
||||
"node_shared_cares": "false",
|
||||
"node_shared_http_parser": "false",
|
||||
"node_shared_libuv": "false",
|
||||
"node_shared_nghttp2": "false",
|
||||
"node_shared_openssl": "false",
|
||||
"node_shared_zlib": "false",
|
||||
"node_tag": "",
|
||||
"node_use_bundled_v8": "true",
|
||||
"node_use_dtrace": "true",
|
||||
"node_use_etw": "false",
|
||||
"node_use_lttng": "false",
|
||||
"node_use_openssl": "true",
|
||||
"node_use_perfctr": "false",
|
||||
"node_use_v8_platform": "true",
|
||||
"node_without_node_options": "false",
|
||||
"openssl_fips": "",
|
||||
"openssl_no_asm": 0,
|
||||
"shlib_suffix": "59.dylib",
|
||||
"target_arch": "x64",
|
||||
"uv_parent_path": "/deps/uv/",
|
||||
"uv_use_dtrace": "true",
|
||||
"v8_enable_gdbjit": 0,
|
||||
"v8_enable_i18n_support": 1,
|
||||
"v8_enable_inspector": 1,
|
||||
"v8_no_strict_aliasing": 1,
|
||||
"v8_optimized_debug": 0,
|
||||
"v8_promise_internal_field_count": 1,
|
||||
"v8_random_seed": 0,
|
||||
"v8_trace_maps": 0,
|
||||
"v8_use_snapshot": "true",
|
||||
"want_separate_host_toolset": 0,
|
||||
"xcode_version": "7.0",
|
||||
"nodedir": "/Users/asciidisco/.node-gyp/9.3.0",
|
||||
"standalone_static_library": 1,
|
||||
"fallback_to_build": "true",
|
||||
"module": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node",
|
||||
"module_name": "zopfli",
|
||||
"module_path": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64",
|
||||
"save_dev": "",
|
||||
"legacy_bundling": "",
|
||||
"dry_run": "",
|
||||
"viewer": "man",
|
||||
"only": "",
|
||||
"commit_hooks": "true",
|
||||
"browser": "",
|
||||
"also": "",
|
||||
"rollback": "true",
|
||||
"usage": "",
|
||||
"globalignorefile": "/usr/local/etc/npmignore",
|
||||
"shell": "/bin/zsh",
|
||||
"maxsockets": "50",
|
||||
"init_author_url": "https://asciidisco.com/",
|
||||
"shrinkwrap": "true",
|
||||
"parseable": "",
|
||||
"metrics_registry": "https://registry.npmjs.org/",
|
||||
"timing": "",
|
||||
"init_license": "MIT",
|
||||
"email": "public@asciidisco.com",
|
||||
"if_present": "",
|
||||
"sign_git_tag": "",
|
||||
"cache_max": "Infinity",
|
||||
"init_author_email": "public@asciidisco.com",
|
||||
"long": "",
|
||||
"local_address": "",
|
||||
"git_tag_version": "true",
|
||||
"cert": "",
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"fetch_retries": "2",
|
||||
"versions": "",
|
||||
"message": "%s",
|
||||
"key": "",
|
||||
"globalconfig": "/usr/local/etc/npmrc",
|
||||
"prefer_online": "",
|
||||
"logs_max": "10",
|
||||
"always_auth": "",
|
||||
"global_style": "",
|
||||
"cache_lock_retries": "10",
|
||||
"heading": "npm",
|
||||
"searchlimit": "20",
|
||||
"read_only": "",
|
||||
"offline": "",
|
||||
"fetch_retry_mintimeout": "10000",
|
||||
"json": "",
|
||||
"access": "",
|
||||
"allow_same_version": "",
|
||||
"https_proxy": "",
|
||||
"engine_strict": "",
|
||||
"description": "true",
|
||||
"userconfig": "/Users/asciidisco/.npmrc",
|
||||
"init_module": "/Users/asciidisco/.npm-init.js",
|
||||
"cidr": "",
|
||||
"user": "",
|
||||
"node_version": "9.3.0",
|
||||
"save": "true",
|
||||
"ignore_prepublish": "",
|
||||
"editor": "vi",
|
||||
"auth_type": "legacy",
|
||||
"tag": "latest",
|
||||
"script_shell": "",
|
||||
"global": "",
|
||||
"progress": "true",
|
||||
"searchstaleness": "900",
|
||||
"optional": "true",
|
||||
"ham_it_up": "",
|
||||
"username": "asciidisco",
|
||||
"save_prod": "",
|
||||
"force": "",
|
||||
"bin_links": "true",
|
||||
"searchopts": "",
|
||||
"depth": "Infinity",
|
||||
"sso_poll_frequency": "500",
|
||||
"rebuild_bundle": "true",
|
||||
"unicode": "true",
|
||||
"fetch_retry_maxtimeout": "60000",
|
||||
"tag_version_prefix": "v",
|
||||
"strict_ssl": "true",
|
||||
"sso_type": "oauth",
|
||||
"scripts_prepend_node_path": "warn-only",
|
||||
"save_prefix": "^",
|
||||
"ca": "",
|
||||
"group": "20",
|
||||
"fetch_retry_factor": "10",
|
||||
"dev": "",
|
||||
"save_exact": "true",
|
||||
"version": "",
|
||||
"prefer_offline": "",
|
||||
"cache_lock_stale": "60000",
|
||||
"otp": "",
|
||||
"cache_min": "10",
|
||||
"searchexclude": "",
|
||||
"cache": "/Users/asciidisco/.npm",
|
||||
"color": "true",
|
||||
"package_lock": "true",
|
||||
"save_optional": "",
|
||||
"ignore_scripts": "",
|
||||
"user_agent": "npm/5.5.1 node/v9.3.0 darwin x64",
|
||||
"cache_lock_wait": "10000",
|
||||
"production": "",
|
||||
"send_metrics": "",
|
||||
"save_bundle": "",
|
||||
"umask": "0022",
|
||||
"init_version": "1.0.0",
|
||||
"git": "git",
|
||||
"init_author_name": "Sebastian Golasch",
|
||||
"scope": "",
|
||||
"unsafe_perm": "true",
|
||||
"tmp": "/var/folders/s2/bnwr2pf51vzfbv8fb0jy99sh0000gn/T",
|
||||
"onload_script": "",
|
||||
"link": "",
|
||||
"prefix": "/usr/local"
|
||||
}
|
||||
}
|
||||
611
build/node_modules/node-zopfli/build/gyp-mac-tool
generated
vendored
Executable file
611
build/node_modules/node-zopfli/build/gyp-mac-tool
generated
vendored
Executable file
@@ -0,0 +1,611 @@
|
||||
#!/usr/bin/env python
|
||||
# Generated by gyp. Do not edit.
|
||||
# Copyright (c) 2012 Google Inc. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Utility functions to perform Xcode-style build steps.
|
||||
|
||||
These functions are executed via gyp-mac-tool when using the Makefile generator.
|
||||
"""
|
||||
|
||||
import fcntl
|
||||
import fnmatch
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import plistlib
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
def main(args):
|
||||
executor = MacTool()
|
||||
exit_code = executor.Dispatch(args)
|
||||
if exit_code is not None:
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
class MacTool(object):
|
||||
"""This class performs all the Mac tooling steps. The methods can either be
|
||||
executed directly, or dispatched from an argument list."""
|
||||
|
||||
def Dispatch(self, args):
|
||||
"""Dispatches a string command to a method."""
|
||||
if len(args) < 1:
|
||||
raise Exception("Not enough arguments")
|
||||
|
||||
method = "Exec%s" % self._CommandifyName(args[0])
|
||||
return getattr(self, method)(*args[1:])
|
||||
|
||||
def _CommandifyName(self, name_string):
|
||||
"""Transforms a tool name like copy-info-plist to CopyInfoPlist"""
|
||||
return name_string.title().replace('-', '')
|
||||
|
||||
def ExecCopyBundleResource(self, source, dest, convert_to_binary):
|
||||
"""Copies a resource file to the bundle/Resources directory, performing any
|
||||
necessary compilation on each resource."""
|
||||
extension = os.path.splitext(source)[1].lower()
|
||||
if os.path.isdir(source):
|
||||
# Copy tree.
|
||||
# TODO(thakis): This copies file attributes like mtime, while the
|
||||
# single-file branch below doesn't. This should probably be changed to
|
||||
# be consistent with the single-file branch.
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(source, dest)
|
||||
elif extension == '.xib':
|
||||
return self._CopyXIBFile(source, dest)
|
||||
elif extension == '.storyboard':
|
||||
return self._CopyXIBFile(source, dest)
|
||||
elif extension == '.strings':
|
||||
self._CopyStringsFile(source, dest, convert_to_binary)
|
||||
else:
|
||||
shutil.copy(source, dest)
|
||||
|
||||
def _CopyXIBFile(self, source, dest):
|
||||
"""Compiles a XIB file with ibtool into a binary plist in the bundle."""
|
||||
|
||||
# ibtool sometimes crashes with relative paths. See crbug.com/314728.
|
||||
base = os.path.dirname(os.path.realpath(__file__))
|
||||
if os.path.relpath(source):
|
||||
source = os.path.join(base, source)
|
||||
if os.path.relpath(dest):
|
||||
dest = os.path.join(base, dest)
|
||||
|
||||
args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices',
|
||||
'--output-format', 'human-readable-text', '--compile', dest, source]
|
||||
ibtool_section_re = re.compile(r'/\*.*\*/')
|
||||
ibtool_re = re.compile(r'.*note:.*is clipping its content')
|
||||
ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
current_section_header = None
|
||||
for line in ibtoolout.stdout:
|
||||
if ibtool_section_re.match(line):
|
||||
current_section_header = line
|
||||
elif not ibtool_re.match(line):
|
||||
if current_section_header:
|
||||
sys.stdout.write(current_section_header)
|
||||
current_section_header = None
|
||||
sys.stdout.write(line)
|
||||
return ibtoolout.returncode
|
||||
|
||||
def _ConvertToBinary(self, dest):
|
||||
subprocess.check_call([
|
||||
'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest])
|
||||
|
||||
def _CopyStringsFile(self, source, dest, convert_to_binary):
|
||||
"""Copies a .strings file using iconv to reconvert the input into UTF-16."""
|
||||
input_code = self._DetectInputEncoding(source) or "UTF-8"
|
||||
|
||||
# Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call
|
||||
# CFPropertyListCreateFromXMLData() behind the scenes; at least it prints
|
||||
# CFPropertyListCreateFromXMLData(): Old-style plist parser: missing
|
||||
# semicolon in dictionary.
|
||||
# on invalid files. Do the same kind of validation.
|
||||
import CoreFoundation
|
||||
s = open(source, 'rb').read()
|
||||
d = CoreFoundation.CFDataCreate(None, s, len(s))
|
||||
_, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None)
|
||||
if error:
|
||||
return
|
||||
|
||||
fp = open(dest, 'wb')
|
||||
fp.write(s.decode(input_code).encode('UTF-16'))
|
||||
fp.close()
|
||||
|
||||
if convert_to_binary == 'True':
|
||||
self._ConvertToBinary(dest)
|
||||
|
||||
def _DetectInputEncoding(self, file_name):
|
||||
"""Reads the first few bytes from file_name and tries to guess the text
|
||||
encoding. Returns None as a guess if it can't detect it."""
|
||||
fp = open(file_name, 'rb')
|
||||
try:
|
||||
header = fp.read(3)
|
||||
except e:
|
||||
fp.close()
|
||||
return None
|
||||
fp.close()
|
||||
if header.startswith("\xFE\xFF"):
|
||||
return "UTF-16"
|
||||
elif header.startswith("\xFF\xFE"):
|
||||
return "UTF-16"
|
||||
elif header.startswith("\xEF\xBB\xBF"):
|
||||
return "UTF-8"
|
||||
else:
|
||||
return None
|
||||
|
||||
def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys):
|
||||
"""Copies the |source| Info.plist to the destination directory |dest|."""
|
||||
# Read the source Info.plist into memory.
|
||||
fd = open(source, 'r')
|
||||
lines = fd.read()
|
||||
fd.close()
|
||||
|
||||
# Insert synthesized key/value pairs (e.g. BuildMachineOSBuild).
|
||||
plist = plistlib.readPlistFromString(lines)
|
||||
if keys:
|
||||
plist = dict(plist.items() + json.loads(keys[0]).items())
|
||||
lines = plistlib.writePlistToString(plist)
|
||||
|
||||
# Go through all the environment variables and replace them as variables in
|
||||
# the file.
|
||||
IDENT_RE = re.compile(r'[/\s]')
|
||||
for key in os.environ:
|
||||
if key.startswith('_'):
|
||||
continue
|
||||
evar = '${%s}' % key
|
||||
evalue = os.environ[key]
|
||||
lines = string.replace(lines, evar, evalue)
|
||||
|
||||
# Xcode supports various suffices on environment variables, which are
|
||||
# all undocumented. :rfc1034identifier is used in the standard project
|
||||
# template these days, and :identifier was used earlier. They are used to
|
||||
# convert non-url characters into things that look like valid urls --
|
||||
# except that the replacement character for :identifier, '_' isn't valid
|
||||
# in a URL either -- oops, hence :rfc1034identifier was born.
|
||||
evar = '${%s:identifier}' % key
|
||||
evalue = IDENT_RE.sub('_', os.environ[key])
|
||||
lines = string.replace(lines, evar, evalue)
|
||||
|
||||
evar = '${%s:rfc1034identifier}' % key
|
||||
evalue = IDENT_RE.sub('-', os.environ[key])
|
||||
lines = string.replace(lines, evar, evalue)
|
||||
|
||||
# Remove any keys with values that haven't been replaced.
|
||||
lines = lines.split('\n')
|
||||
for i in range(len(lines)):
|
||||
if lines[i].strip().startswith("<string>${"):
|
||||
lines[i] = None
|
||||
lines[i - 1] = None
|
||||
lines = '\n'.join(filter(lambda x: x is not None, lines))
|
||||
|
||||
# Write out the file with variables replaced.
|
||||
fd = open(dest, 'w')
|
||||
fd.write(lines)
|
||||
fd.close()
|
||||
|
||||
# Now write out PkgInfo file now that the Info.plist file has been
|
||||
# "compiled".
|
||||
self._WritePkgInfo(dest)
|
||||
|
||||
if convert_to_binary == 'True':
|
||||
self._ConvertToBinary(dest)
|
||||
|
||||
def _WritePkgInfo(self, info_plist):
|
||||
"""This writes the PkgInfo file from the data stored in Info.plist."""
|
||||
plist = plistlib.readPlist(info_plist)
|
||||
if not plist:
|
||||
return
|
||||
|
||||
# Only create PkgInfo for executable types.
|
||||
package_type = plist['CFBundlePackageType']
|
||||
if package_type != 'APPL':
|
||||
return
|
||||
|
||||
# The format of PkgInfo is eight characters, representing the bundle type
|
||||
# and bundle signature, each four characters. If that is missing, four
|
||||
# '?' characters are used instead.
|
||||
signature_code = plist.get('CFBundleSignature', '????')
|
||||
if len(signature_code) != 4: # Wrong length resets everything, too.
|
||||
signature_code = '?' * 4
|
||||
|
||||
dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo')
|
||||
fp = open(dest, 'w')
|
||||
fp.write('%s%s' % (package_type, signature_code))
|
||||
fp.close()
|
||||
|
||||
def ExecFlock(self, lockfile, *cmd_list):
|
||||
"""Emulates the most basic behavior of Linux's flock(1)."""
|
||||
# Rely on exception handling to report errors.
|
||||
fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666)
|
||||
fcntl.flock(fd, fcntl.LOCK_EX)
|
||||
return subprocess.call(cmd_list)
|
||||
|
||||
def ExecFilterLibtool(self, *cmd_list):
|
||||
"""Calls libtool and filters out '/path/to/libtool: file: foo.o has no
|
||||
symbols'."""
|
||||
libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$')
|
||||
libtool_re5 = re.compile(
|
||||
r'^.*libtool: warning for library: ' +
|
||||
r'.* the table of contents is empty ' +
|
||||
r'\(no object file members in the library define global symbols\)$')
|
||||
env = os.environ.copy()
|
||||
# Ref:
|
||||
# http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c
|
||||
# The problem with this flag is that it resets the file mtime on the file to
|
||||
# epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone.
|
||||
env['ZERO_AR_DATE'] = '1'
|
||||
libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env)
|
||||
_, err = libtoolout.communicate()
|
||||
for line in err.splitlines():
|
||||
if not libtool_re.match(line) and not libtool_re5.match(line):
|
||||
print >>sys.stderr, line
|
||||
# Unconditionally touch the output .a file on the command line if present
|
||||
# and the command succeeded. A bit hacky.
|
||||
if not libtoolout.returncode:
|
||||
for i in range(len(cmd_list) - 1):
|
||||
if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'):
|
||||
os.utime(cmd_list[i+1], None)
|
||||
break
|
||||
return libtoolout.returncode
|
||||
|
||||
def ExecPackageFramework(self, framework, version):
|
||||
"""Takes a path to Something.framework and the Current version of that and
|
||||
sets up all the symlinks."""
|
||||
# Find the name of the binary based on the part before the ".framework".
|
||||
binary = os.path.basename(framework).split('.')[0]
|
||||
|
||||
CURRENT = 'Current'
|
||||
RESOURCES = 'Resources'
|
||||
VERSIONS = 'Versions'
|
||||
|
||||
if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)):
|
||||
# Binary-less frameworks don't seem to contain symlinks (see e.g.
|
||||
# chromium's out/Debug/org.chromium.Chromium.manifest/ bundle).
|
||||
return
|
||||
|
||||
# Move into the framework directory to set the symlinks correctly.
|
||||
pwd = os.getcwd()
|
||||
os.chdir(framework)
|
||||
|
||||
# Set up the Current version.
|
||||
self._Relink(version, os.path.join(VERSIONS, CURRENT))
|
||||
|
||||
# Set up the root symlinks.
|
||||
self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary)
|
||||
self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES)
|
||||
|
||||
# Back to where we were before!
|
||||
os.chdir(pwd)
|
||||
|
||||
def _Relink(self, dest, link):
|
||||
"""Creates a symlink to |dest| named |link|. If |link| already exists,
|
||||
it is overwritten."""
|
||||
if os.path.lexists(link):
|
||||
os.remove(link)
|
||||
os.symlink(dest, link)
|
||||
|
||||
def ExecCompileXcassets(self, keys, *inputs):
|
||||
"""Compiles multiple .xcassets files into a single .car file.
|
||||
|
||||
This invokes 'actool' to compile all the inputs .xcassets files. The
|
||||
|keys| arguments is a json-encoded dictionary of extra arguments to
|
||||
pass to 'actool' when the asset catalogs contains an application icon
|
||||
or a launch image.
|
||||
|
||||
Note that 'actool' does not create the Assets.car file if the asset
|
||||
catalogs does not contains imageset.
|
||||
"""
|
||||
command_line = [
|
||||
'xcrun', 'actool', '--output-format', 'human-readable-text',
|
||||
'--compress-pngs', '--notices', '--warnings', '--errors',
|
||||
]
|
||||
is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ
|
||||
if is_iphone_target:
|
||||
platform = os.environ['CONFIGURATION'].split('-')[-1]
|
||||
if platform not in ('iphoneos', 'iphonesimulator'):
|
||||
platform = 'iphonesimulator'
|
||||
command_line.extend([
|
||||
'--platform', platform, '--target-device', 'iphone',
|
||||
'--target-device', 'ipad', '--minimum-deployment-target',
|
||||
os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile',
|
||||
os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']),
|
||||
])
|
||||
else:
|
||||
command_line.extend([
|
||||
'--platform', 'macosx', '--target-device', 'mac',
|
||||
'--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'],
|
||||
'--compile',
|
||||
os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']),
|
||||
])
|
||||
if keys:
|
||||
keys = json.loads(keys)
|
||||
for key, value in keys.iteritems():
|
||||
arg_name = '--' + key
|
||||
if isinstance(value, bool):
|
||||
if value:
|
||||
command_line.append(arg_name)
|
||||
elif isinstance(value, list):
|
||||
for v in value:
|
||||
command_line.append(arg_name)
|
||||
command_line.append(str(v))
|
||||
else:
|
||||
command_line.append(arg_name)
|
||||
command_line.append(str(value))
|
||||
# Note: actool crashes if inputs path are relative, so use os.path.abspath
|
||||
# to get absolute path name for inputs.
|
||||
command_line.extend(map(os.path.abspath, inputs))
|
||||
subprocess.check_call(command_line)
|
||||
|
||||
def ExecMergeInfoPlist(self, output, *inputs):
|
||||
"""Merge multiple .plist files into a single .plist file."""
|
||||
merged_plist = {}
|
||||
for path in inputs:
|
||||
plist = self._LoadPlistMaybeBinary(path)
|
||||
self._MergePlist(merged_plist, plist)
|
||||
plistlib.writePlist(merged_plist, output)
|
||||
|
||||
def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning):
|
||||
"""Code sign a bundle.
|
||||
|
||||
This function tries to code sign an iOS bundle, following the same
|
||||
algorithm as Xcode:
|
||||
1. copy ResourceRules.plist from the user or the SDK into the bundle,
|
||||
2. pick the provisioning profile that best match the bundle identifier,
|
||||
and copy it into the bundle as embedded.mobileprovision,
|
||||
3. copy Entitlements.plist from user or SDK next to the bundle,
|
||||
4. code sign the bundle.
|
||||
"""
|
||||
resource_rules_path = self._InstallResourceRules(resource_rules)
|
||||
substitutions, overrides = self._InstallProvisioningProfile(
|
||||
provisioning, self._GetCFBundleIdentifier())
|
||||
entitlements_path = self._InstallEntitlements(
|
||||
entitlements, substitutions, overrides)
|
||||
subprocess.check_call([
|
||||
'codesign', '--force', '--sign', key, '--resource-rules',
|
||||
resource_rules_path, '--entitlements', entitlements_path,
|
||||
os.path.join(
|
||||
os.environ['TARGET_BUILD_DIR'],
|
||||
os.environ['FULL_PRODUCT_NAME'])])
|
||||
|
||||
def _InstallResourceRules(self, resource_rules):
|
||||
"""Installs ResourceRules.plist from user or SDK into the bundle.
|
||||
|
||||
Args:
|
||||
resource_rules: string, optional, path to the ResourceRules.plist file
|
||||
to use, default to "${SDKROOT}/ResourceRules.plist"
|
||||
|
||||
Returns:
|
||||
Path to the copy of ResourceRules.plist into the bundle.
|
||||
"""
|
||||
source_path = resource_rules
|
||||
target_path = os.path.join(
|
||||
os.environ['BUILT_PRODUCTS_DIR'],
|
||||
os.environ['CONTENTS_FOLDER_PATH'],
|
||||
'ResourceRules.plist')
|
||||
if not source_path:
|
||||
source_path = os.path.join(
|
||||
os.environ['SDKROOT'], 'ResourceRules.plist')
|
||||
shutil.copy2(source_path, target_path)
|
||||
return target_path
|
||||
|
||||
def _InstallProvisioningProfile(self, profile, bundle_identifier):
|
||||
"""Installs embedded.mobileprovision into the bundle.
|
||||
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
|
||||
Returns:
|
||||
A tuple containing two dictionary: variables substitutions and values
|
||||
to overrides when generating the entitlements file.
|
||||
"""
|
||||
source_path, provisioning_data, team_id = self._FindProvisioningProfile(
|
||||
profile, bundle_identifier)
|
||||
target_path = os.path.join(
|
||||
os.environ['BUILT_PRODUCTS_DIR'],
|
||||
os.environ['CONTENTS_FOLDER_PATH'],
|
||||
'embedded.mobileprovision')
|
||||
shutil.copy2(source_path, target_path)
|
||||
substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.')
|
||||
return substitutions, provisioning_data['Entitlements']
|
||||
|
||||
def _FindProvisioningProfile(self, profile, bundle_identifier):
|
||||
"""Finds the .mobileprovision file to use for signing the bundle.
|
||||
|
||||
Checks all the installed provisioning profiles (or if the user specified
|
||||
the PROVISIONING_PROFILE variable, only consult it) and select the most
|
||||
specific that correspond to the bundle identifier.
|
||||
|
||||
Args:
|
||||
profile: string, optional, short name of the .mobileprovision file
|
||||
to use, if empty or the file is missing, the best file installed
|
||||
will be used
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
|
||||
Returns:
|
||||
A tuple of the path to the selected provisioning profile, the data of
|
||||
the embedded plist in the provisioning profile and the team identifier
|
||||
to use for code signing.
|
||||
|
||||
Raises:
|
||||
SystemExit: if no .mobileprovision can be used to sign the bundle.
|
||||
"""
|
||||
profiles_dir = os.path.join(
|
||||
os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')
|
||||
if not os.path.isdir(profiles_dir):
|
||||
print >>sys.stderr, (
|
||||
'cannot find mobile provisioning for %s' % bundle_identifier)
|
||||
sys.exit(1)
|
||||
provisioning_profiles = None
|
||||
if profile:
|
||||
profile_path = os.path.join(profiles_dir, profile + '.mobileprovision')
|
||||
if os.path.exists(profile_path):
|
||||
provisioning_profiles = [profile_path]
|
||||
if not provisioning_profiles:
|
||||
provisioning_profiles = glob.glob(
|
||||
os.path.join(profiles_dir, '*.mobileprovision'))
|
||||
valid_provisioning_profiles = {}
|
||||
for profile_path in provisioning_profiles:
|
||||
profile_data = self._LoadProvisioningProfile(profile_path)
|
||||
app_id_pattern = profile_data.get(
|
||||
'Entitlements', {}).get('application-identifier', '')
|
||||
for team_identifier in profile_data.get('TeamIdentifier', []):
|
||||
app_id = '%s.%s' % (team_identifier, bundle_identifier)
|
||||
if fnmatch.fnmatch(app_id, app_id_pattern):
|
||||
valid_provisioning_profiles[app_id_pattern] = (
|
||||
profile_path, profile_data, team_identifier)
|
||||
if not valid_provisioning_profiles:
|
||||
print >>sys.stderr, (
|
||||
'cannot find mobile provisioning for %s' % bundle_identifier)
|
||||
sys.exit(1)
|
||||
# If the user has multiple provisioning profiles installed that can be
|
||||
# used for ${bundle_identifier}, pick the most specific one (ie. the
|
||||
# provisioning profile whose pattern is the longest).
|
||||
selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
|
||||
return valid_provisioning_profiles[selected_key]
|
||||
|
||||
def _LoadProvisioningProfile(self, profile_path):
|
||||
"""Extracts the plist embedded in a provisioning profile.
|
||||
|
||||
Args:
|
||||
profile_path: string, path to the .mobileprovision file
|
||||
|
||||
Returns:
|
||||
Content of the plist embedded in the provisioning profile as a dictionary.
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile() as temp:
|
||||
subprocess.check_call([
|
||||
'security', 'cms', '-D', '-i', profile_path, '-o', temp.name])
|
||||
return self._LoadPlistMaybeBinary(temp.name)
|
||||
|
||||
def _MergePlist(self, merged_plist, plist):
|
||||
"""Merge |plist| into |merged_plist|."""
|
||||
for key, value in plist.iteritems():
|
||||
if isinstance(value, dict):
|
||||
merged_value = merged_plist.get(key, {})
|
||||
if isinstance(merged_value, dict):
|
||||
self._MergePlist(merged_value, value)
|
||||
merged_plist[key] = merged_value
|
||||
else:
|
||||
merged_plist[key] = value
|
||||
else:
|
||||
merged_plist[key] = value
|
||||
|
||||
def _LoadPlistMaybeBinary(self, plist_path):
|
||||
"""Loads into a memory a plist possibly encoded in binary format.
|
||||
|
||||
This is a wrapper around plistlib.readPlist that tries to convert the
|
||||
plist to the XML format if it can't be parsed (assuming that it is in
|
||||
the binary format).
|
||||
|
||||
Args:
|
||||
plist_path: string, path to a plist file, in XML or binary format
|
||||
|
||||
Returns:
|
||||
Content of the plist as a dictionary.
|
||||
"""
|
||||
try:
|
||||
# First, try to read the file using plistlib that only supports XML,
|
||||
# and if an exception is raised, convert a temporary copy to XML and
|
||||
# load that copy.
|
||||
return plistlib.readPlist(plist_path)
|
||||
except:
|
||||
pass
|
||||
with tempfile.NamedTemporaryFile() as temp:
|
||||
shutil.copy2(plist_path, temp.name)
|
||||
subprocess.check_call(['plutil', '-convert', 'xml1', temp.name])
|
||||
return plistlib.readPlist(temp.name)
|
||||
|
||||
def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix):
|
||||
"""Constructs a dictionary of variable substitutions for Entitlements.plist.
|
||||
|
||||
Args:
|
||||
bundle_identifier: string, value of CFBundleIdentifier from Info.plist
|
||||
app_identifier_prefix: string, value for AppIdentifierPrefix
|
||||
|
||||
Returns:
|
||||
Dictionary of substitutions to apply when generating Entitlements.plist.
|
||||
"""
|
||||
return {
|
||||
'CFBundleIdentifier': bundle_identifier,
|
||||
'AppIdentifierPrefix': app_identifier_prefix,
|
||||
}
|
||||
|
||||
def _GetCFBundleIdentifier(self):
|
||||
"""Extracts CFBundleIdentifier value from Info.plist in the bundle.
|
||||
|
||||
Returns:
|
||||
Value of CFBundleIdentifier in the Info.plist located in the bundle.
|
||||
"""
|
||||
info_plist_path = os.path.join(
|
||||
os.environ['TARGET_BUILD_DIR'],
|
||||
os.environ['INFOPLIST_PATH'])
|
||||
info_plist_data = self._LoadPlistMaybeBinary(info_plist_path)
|
||||
return info_plist_data['CFBundleIdentifier']
|
||||
|
||||
def _InstallEntitlements(self, entitlements, substitutions, overrides):
|
||||
"""Generates and install the ${BundleName}.xcent entitlements file.
|
||||
|
||||
Expands variables "$(variable)" pattern in the source entitlements file,
|
||||
add extra entitlements defined in the .mobileprovision file and the copy
|
||||
the generated plist to "${BundlePath}.xcent".
|
||||
|
||||
Args:
|
||||
entitlements: string, optional, path to the Entitlements.plist template
|
||||
to use, defaults to "${SDKROOT}/Entitlements.plist"
|
||||
substitutions: dictionary, variable substitutions
|
||||
overrides: dictionary, values to add to the entitlements
|
||||
|
||||
Returns:
|
||||
Path to the generated entitlements file.
|
||||
"""
|
||||
source_path = entitlements
|
||||
target_path = os.path.join(
|
||||
os.environ['BUILT_PRODUCTS_DIR'],
|
||||
os.environ['PRODUCT_NAME'] + '.xcent')
|
||||
if not source_path:
|
||||
source_path = os.path.join(
|
||||
os.environ['SDKROOT'],
|
||||
'Entitlements.plist')
|
||||
shutil.copy2(source_path, target_path)
|
||||
data = self._LoadPlistMaybeBinary(target_path)
|
||||
data = self._ExpandVariables(data, substitutions)
|
||||
if overrides:
|
||||
for key in overrides:
|
||||
if key not in data:
|
||||
data[key] = overrides[key]
|
||||
plistlib.writePlist(data, target_path)
|
||||
return target_path
|
||||
|
||||
def _ExpandVariables(self, data, substitutions):
|
||||
"""Expands variables "$(variable)" in data.
|
||||
|
||||
Args:
|
||||
data: object, can be either string, list or dictionary
|
||||
substitutions: dictionary, variable substitutions to perform
|
||||
|
||||
Returns:
|
||||
Copy of data where each references to "$(variable)" has been replaced
|
||||
by the corresponding value found in substitutions, or left intact if
|
||||
the key was not found.
|
||||
"""
|
||||
if isinstance(data, str):
|
||||
for key, value in substitutions.iteritems():
|
||||
data = data.replace('$(%s)' % key, value)
|
||||
return data
|
||||
if isinstance(data, list):
|
||||
return [self._ExpandVariables(v, substitutions) for v in data]
|
||||
if isinstance(data, dict):
|
||||
return {k: self._ExpandVariables(data[k], substitutions) for k in data}
|
||||
return data
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
218
build/node_modules/node-zopfli/build/zopfli.target.mk
generated
vendored
Normal file
218
build/node_modules/node-zopfli/build/zopfli.target.mk
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
# This file is generated by gyp; do not edit.
|
||||
|
||||
TOOLSET := target
|
||||
TARGET := zopfli
|
||||
DEFS_Debug := \
|
||||
'-DNODE_GYP_MODULE_NAME=zopfli' \
|
||||
'-DUSING_UV_SHARED=1' \
|
||||
'-DUSING_V8_SHARED=1' \
|
||||
'-DV8_DEPRECATION_WARNINGS=1' \
|
||||
'-D_DARWIN_USE_64_BIT_INODE=1' \
|
||||
'-D_LARGEFILE_SOURCE' \
|
||||
'-D_FILE_OFFSET_BITS=64' \
|
||||
'-DBUILDING_NODE_EXTENSION' \
|
||||
'-DDEBUG' \
|
||||
'-D_DEBUG' \
|
||||
'-DV8_ENABLE_CHECKS'
|
||||
|
||||
# Flags passed to all source files.
|
||||
CFLAGS_Debug := \
|
||||
-O0 \
|
||||
-gdwarf-2 \
|
||||
-mmacosx-version-min=10.7 \
|
||||
-arch x86_64 \
|
||||
-Wall \
|
||||
-Wendif-labels \
|
||||
-W \
|
||||
-Wno-unused-parameter
|
||||
|
||||
# Flags passed to only C files.
|
||||
CFLAGS_C_Debug := \
|
||||
-fno-strict-aliasing
|
||||
|
||||
# Flags passed to only C++ files.
|
||||
CFLAGS_CC_Debug := \
|
||||
-std=gnu++0x \
|
||||
-stdlib=libc++ \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
-fno-threadsafe-statics \
|
||||
-fno-strict-aliasing
|
||||
|
||||
# Flags passed to only ObjC files.
|
||||
CFLAGS_OBJC_Debug :=
|
||||
|
||||
# Flags passed to only ObjC++ files.
|
||||
CFLAGS_OBJCC_Debug :=
|
||||
|
||||
INCS_Debug := \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/include/node \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/src \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include \
|
||||
-I$(srcdir)/zopfli/src/zopfli \
|
||||
-I$(srcdir)/zopfli/src/zopflipng \
|
||||
-I$(srcdir)/../nan
|
||||
|
||||
DEFS_Release := \
|
||||
'-DNODE_GYP_MODULE_NAME=zopfli' \
|
||||
'-DUSING_UV_SHARED=1' \
|
||||
'-DUSING_V8_SHARED=1' \
|
||||
'-DV8_DEPRECATION_WARNINGS=1' \
|
||||
'-D_DARWIN_USE_64_BIT_INODE=1' \
|
||||
'-D_LARGEFILE_SOURCE' \
|
||||
'-D_FILE_OFFSET_BITS=64' \
|
||||
'-DBUILDING_NODE_EXTENSION'
|
||||
|
||||
# Flags passed to all source files.
|
||||
CFLAGS_Release := \
|
||||
-Os \
|
||||
-gdwarf-2 \
|
||||
-mmacosx-version-min=10.7 \
|
||||
-arch x86_64 \
|
||||
-Wall \
|
||||
-Wendif-labels \
|
||||
-W \
|
||||
-Wno-unused-parameter
|
||||
|
||||
# Flags passed to only C files.
|
||||
CFLAGS_C_Release := \
|
||||
-fno-strict-aliasing
|
||||
|
||||
# Flags passed to only C++ files.
|
||||
CFLAGS_CC_Release := \
|
||||
-std=gnu++0x \
|
||||
-stdlib=libc++ \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
-fno-threadsafe-statics \
|
||||
-fno-strict-aliasing
|
||||
|
||||
# Flags passed to only ObjC files.
|
||||
CFLAGS_OBJC_Release :=
|
||||
|
||||
# Flags passed to only ObjC++ files.
|
||||
CFLAGS_OBJCC_Release :=
|
||||
|
||||
INCS_Release := \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/include/node \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/src \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/deps/uv/include \
|
||||
-I/Users/asciidisco/.node-gyp/9.3.0/deps/v8/include \
|
||||
-I$(srcdir)/zopfli/src/zopfli \
|
||||
-I$(srcdir)/zopfli/src/zopflipng \
|
||||
-I$(srcdir)/../nan
|
||||
|
||||
OBJS := \
|
||||
$(obj).target/$(TARGET)/src/zopfli-binding.o \
|
||||
$(obj).target/$(TARGET)/src/png/zopflipng.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/blocksplitter.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/cache.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/deflate.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/gzip_container.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/hash.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/katajainen.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/lz77.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/squeeze.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/tree.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/util.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/zlib_container.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopfli/zopfli_lib.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopflipng/zopflipng_lib.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopflipng/lodepng/lodepng.o \
|
||||
$(obj).target/$(TARGET)/zopfli/src/zopflipng/lodepng/lodepng_util.o
|
||||
|
||||
# Add to the list of files we specially track dependencies for.
|
||||
all_deps += $(OBJS)
|
||||
|
||||
# CFLAGS et al overrides must be target-local.
|
||||
# See "Target-specific Variable Values" in the GNU Make manual.
|
||||
$(OBJS): TOOLSET := $(TOOLSET)
|
||||
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
|
||||
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
|
||||
$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))
|
||||
$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))
|
||||
|
||||
# Suffix rules, putting all outputs into $(obj).
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
# Try building from generated source, too.
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
|
||||
@$(call do_cmd,cc,1)
|
||||
|
||||
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
|
||||
@$(call do_cmd,cxx,1)
|
||||
|
||||
# End of this set of suffix rules
|
||||
### Rules for final target.
|
||||
LDFLAGS_Debug := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-no_pie \
|
||||
-Wl,-search_paths_first \
|
||||
-mmacosx-version-min=10.7 \
|
||||
-arch x86_64 \
|
||||
-L$(builddir) \
|
||||
-stdlib=libc++
|
||||
|
||||
LIBTOOLFLAGS_Debug := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-no_pie \
|
||||
-Wl,-search_paths_first
|
||||
|
||||
LDFLAGS_Release := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-no_pie \
|
||||
-Wl,-search_paths_first \
|
||||
-mmacosx-version-min=10.7 \
|
||||
-arch x86_64 \
|
||||
-L$(builddir) \
|
||||
-stdlib=libc++
|
||||
|
||||
LIBTOOLFLAGS_Release := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-no_pie \
|
||||
-Wl,-search_paths_first
|
||||
|
||||
LIBS :=
|
||||
|
||||
$(builddir)/zopfli.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
|
||||
$(builddir)/zopfli.node: LIBS := $(LIBS)
|
||||
$(builddir)/zopfli.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE))
|
||||
$(builddir)/zopfli.node: TOOLSET := $(TOOLSET)
|
||||
$(builddir)/zopfli.node: $(OBJS) FORCE_DO_CMD
|
||||
$(call do_cmd,solink_module)
|
||||
|
||||
all_deps += $(builddir)/zopfli.node
|
||||
# Add target alias
|
||||
.PHONY: zopfli
|
||||
zopfli: $(builddir)/zopfli.node
|
||||
|
||||
# Short alias for building this executable.
|
||||
.PHONY: zopfli.node
|
||||
zopfli.node: $(builddir)/zopfli.node
|
||||
|
||||
# Add executable to "all" target.
|
||||
.PHONY: all
|
||||
all: $(builddir)/zopfli.node
|
||||
|
||||
BIN
build/node_modules/node-zopfli/lib/binding/node-v42-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v42-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
BIN
build/node_modules/node-zopfli/lib/binding/node-v45-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v45-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
BIN
build/node_modules/node-zopfli/lib/binding/node-v46-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v46-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
BIN
build/node_modules/node-zopfli/lib/binding/node-v48-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v48-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
BIN
build/node_modules/node-zopfli/lib/binding/node-v57-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v57-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
BIN
build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node
generated
vendored
Executable file
BIN
build/node_modules/node-zopfli/lib/binding/node-v59-darwin-x64/zopfli.node
generated
vendored
Executable file
Binary file not shown.
112
build/node_modules/node-zopfli/lib/zopfli.js
generated
vendored
Normal file
112
build/node_modules/node-zopfli/lib/zopfli.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
var binary = require('node-pre-gyp');
|
||||
var path = require('path');
|
||||
var defaults = require('defaults');
|
||||
var binding_path = binary.find(path.join(__dirname, '../package.json'));
|
||||
var zopfli = require(binding_path);
|
||||
|
||||
var util = require('util');
|
||||
var Transform = require('stream').Transform;
|
||||
|
||||
/* Streaming part */
|
||||
var defaultOptions = {
|
||||
verbose: false,
|
||||
verbose_more: false,
|
||||
numiterations: 15,
|
||||
blocksplitting: true,
|
||||
blocksplittinglast: false,
|
||||
blocksplittingmax: 15
|
||||
};
|
||||
|
||||
function Zopfli(format, options) {
|
||||
this.first = true;
|
||||
this.adler = 0x01;
|
||||
this.crc = null;
|
||||
this.format = format || 'deflate';
|
||||
this.options = defaults(options, defaultOptions);
|
||||
this.in = new Buffer(0);
|
||||
Transform.prototype.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
util.inherits(Zopfli, Transform);
|
||||
|
||||
Zopfli.prototype._transform = function(chunk, encoding, done) {
|
||||
this.in = Buffer.concat([this.in, chunk]);
|
||||
done();
|
||||
};
|
||||
|
||||
Zopfli.prototype._flush = function(done) {
|
||||
var transform = this;
|
||||
var inBuffer = new Buffer(this.in);
|
||||
zopfli.deflate(inBuffer, this.format, this.options, function(err, outbuf) {
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
transform.push(outbuf);
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* Stream */
|
||||
Zopfli.createGzip = function(options) {
|
||||
return new Zopfli('gzip', options);
|
||||
};
|
||||
|
||||
Zopfli.createZlib = function(options) {
|
||||
return new Zopfli('zlib', options);
|
||||
};
|
||||
|
||||
Zopfli.createDeflate = function(options) {
|
||||
return new Zopfli('deflate', options);
|
||||
};
|
||||
|
||||
/* Buffer */
|
||||
Zopfli.compress = function(buffer, type, options, callback) {
|
||||
if (typeof callback === 'undefined' && typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
options = options || {};
|
||||
if (typeof callback === 'function') {
|
||||
zopfli.deflate(buffer, type, options, callback);
|
||||
} else {
|
||||
return new Promise(function(resolve, reject) {
|
||||
zopfli.deflate(buffer, type, options, function(err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Zopfli.gzip = function(buffer, options, callback) {
|
||||
return Zopfli.compress(buffer, 'gzip', options, callback);
|
||||
};
|
||||
|
||||
Zopfli.zlib = function(buffer, options, callback) {
|
||||
return Zopfli.compress(buffer, 'zlib', options, callback);
|
||||
};
|
||||
|
||||
Zopfli.deflate = function(buffer, options, callback) {
|
||||
return Zopfli.compress(buffer, 'deflate', options, callback);
|
||||
};
|
||||
|
||||
/* Sync buffer */
|
||||
Zopfli.gzipSync = function(buffer, options) {
|
||||
return zopfli.deflateSync(buffer, 'gzip', options);
|
||||
};
|
||||
|
||||
Zopfli.zlibSync = function(buffer, options) {
|
||||
return zopfli.deflateSync(buffer, 'zlib', options);
|
||||
};
|
||||
|
||||
Zopfli.deflateSync = function(buffer, options) {
|
||||
return zopfli.deflateSync(buffer, 'deflate', options);
|
||||
};
|
||||
|
||||
module.exports = Zopfli;
|
||||
114
build/node_modules/node-zopfli/package.json
generated
vendored
Normal file
114
build/node_modules/node-zopfli/package.json
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"node-zopfli@2.0.2",
|
||||
"/Users/asciidisco/Desktop/asciidisco.com/build"
|
||||
]
|
||||
],
|
||||
"_from": "node-zopfli@2.0.2",
|
||||
"_id": "node-zopfli@2.0.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-p6RzrpKq6oXUxo1Fu/LJRMRhFrg=",
|
||||
"_location": "/node-zopfli",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "node-zopfli@2.0.2",
|
||||
"name": "node-zopfli",
|
||||
"escapedName": "node-zopfli",
|
||||
"rawSpec": "2.0.2",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.0.2"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/node-zopfli/-/node-zopfli-2.0.2.tgz",
|
||||
"_spec": "2.0.2",
|
||||
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build",
|
||||
"author": {
|
||||
"name": "Pierre Inglebert",
|
||||
"email": "pierre.inglebert@gmail.com"
|
||||
},
|
||||
"bin": {
|
||||
"zopfli": "bin/zopfli",
|
||||
"zopflipng": "bin/zopflipng"
|
||||
},
|
||||
"binary": {
|
||||
"module_name": "zopfli",
|
||||
"module_path": "./lib/binding/{node_abi}-{platform}-{arch}",
|
||||
"remote_path": "./{configuration}",
|
||||
"package_name": "{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz",
|
||||
"host": "https://node-zopfli.s3.amazonaws.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/pierreinglebert/node-zopfli/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "duralog",
|
||||
"email": "funisher@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "MayhemYDG",
|
||||
"email": "stepien.nicolas@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "XhmikosR",
|
||||
"email": "xhmikosr@gmail.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.8.1",
|
||||
"defaults": "^1.0.2",
|
||||
"nan": "^2.0.0",
|
||||
"node-pre-gyp": "^0.6.4"
|
||||
},
|
||||
"description": "Bindings for Zopfli compressing lib. Compress gzip files 5% better than gzip.",
|
||||
"devDependencies": {
|
||||
"async": "^2.0.0",
|
||||
"aws-sdk": "^2.4.8",
|
||||
"chai": "^3.5.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"eslint": "1.0.0",
|
||||
"istanbul": "^0.4.4",
|
||||
"mocha": "^2.2.4",
|
||||
"randomstring": "^1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib",
|
||||
"src",
|
||||
"zopfli",
|
||||
"binding.gyp"
|
||||
],
|
||||
"gypfile": true,
|
||||
"homepage": "https://github.com/pierreinglebert/node-zopfli",
|
||||
"keywords": [
|
||||
"zopfli",
|
||||
"zlib",
|
||||
"compress",
|
||||
"gzip",
|
||||
"deflate"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/zopfli.js",
|
||||
"name": "node-zopfli",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/pierreinglebert/node-zopfli.git"
|
||||
},
|
||||
"scripts": {
|
||||
"coveralls": "coveralls < ./coverage/lcov.info",
|
||||
"install": "node-pre-gyp install --fallback-to-build",
|
||||
"lint": "eslint .",
|
||||
"mocha": "mocha test",
|
||||
"test": "npm run lint && npm run mocha",
|
||||
"test-cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec test"
|
||||
},
|
||||
"version": "2.0.2"
|
||||
}
|
||||
169
build/node_modules/node-zopfli/src/png/zopflipng.cc
generated
vendored
Normal file
169
build/node_modules/node-zopfli/src/png/zopflipng.cc
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
#include <node.h>
|
||||
#include <v8.h>
|
||||
#include "nan.h"
|
||||
|
||||
#include "lodepng/lodepng.h"
|
||||
#include "zopflipng_lib.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
void parseOptions(const Local<Object>& options, ZopfliPNGOptions& png_options) {
|
||||
Local<String> option_name;
|
||||
Local<Value> option_value;
|
||||
|
||||
if(!options.IsEmpty()) {
|
||||
|
||||
// Allow altering hidden colors of fully transparent pixels
|
||||
option_name = Nan::New<String>("lossy_transparent").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'lossy_transparent'");
|
||||
}
|
||||
png_options.lossy_transparent = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// Convert 16-bit per channel images to 8-bit per channel
|
||||
option_name = Nan::New<String>("lossy_8bit").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'lossy_8bit'");
|
||||
}
|
||||
png_options.lossy_8bit = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// Filter strategies to try
|
||||
//"zero", "one", "two", "three", "four", "minimum", "entropy", "predefined", "brute"
|
||||
option_name = Nan::New<String>("filter_strategies").ToLocalChecked();
|
||||
Local<Value> fieldValue = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!fieldValue->IsUndefined() && !fieldValue->IsNull()) {
|
||||
if(fieldValue->IsArray()) {
|
||||
Handle<Array> filter_strategies = Handle<Array>::Cast(fieldValue);
|
||||
for (uint32_t i = 0; i < filter_strategies->Length(); i++) {
|
||||
std::string strStrategy(*Nan::Utf8String(filter_strategies->Get(i)->ToString()));
|
||||
ZopfliPNGFilterStrategy strategy = kStrategyZero;
|
||||
if(strStrategy.compare("zero") == 0) { strategy = kStrategyZero; }
|
||||
else if(strStrategy.compare("one") == 0) { strategy = kStrategyOne; }
|
||||
else if(strStrategy.compare("two") == 0) { strategy = kStrategyTwo; }
|
||||
else if(strStrategy.compare("three") == 0) { strategy = kStrategyThree; }
|
||||
else if(strStrategy.compare("four") == 0) { strategy = kStrategyFour; }
|
||||
else if(strStrategy.compare("minsum") == 0) { strategy = kStrategyMinSum; }
|
||||
else if(strStrategy.compare("entropy") == 0) { strategy = kStrategyEntropy; }
|
||||
else if(strStrategy.compare("predefined") == 0) { strategy = kStrategyPredefined; }
|
||||
else if(strStrategy.compare("bruteforce") == 0) { strategy = kStrategyBruteForce; }
|
||||
else {
|
||||
Nan::ThrowTypeError((std::string("Wrong strategy : ") + strStrategy).c_str());
|
||||
}
|
||||
png_options.filter_strategies.push_back(strategy);
|
||||
}
|
||||
} else {
|
||||
//Wrong
|
||||
Nan::ThrowTypeError("Wrong type for option 'filter_strategies'");
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically choose filter strategy using less good compression
|
||||
option_name = Nan::New<String>("auto_filter_strategy").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'auto_filter_strategy'");
|
||||
}
|
||||
png_options.auto_filter_strategy = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// PNG chunks to keep
|
||||
// chunks to literally copy over from the original PNG to the resulting one
|
||||
option_name = Nan::New<String>("use_zopfli").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'use_zopfli'");
|
||||
}
|
||||
png_options.use_zopfli = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// Zopfli number of iterations
|
||||
option_name = Nan::New<String>("num_iterations").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'num_iterations'");
|
||||
}
|
||||
png_options.num_iterations = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// Zopfli number of iterations on images > 200 KiB
|
||||
option_name = Nan::New<String>("num_iterations_large").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsNumber()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'num_iterations_large'");
|
||||
}
|
||||
png_options.num_iterations_large = option_value->Int32Value();
|
||||
}
|
||||
|
||||
// Split chunk strategy none, first, last, both
|
||||
std::string strStrategy;
|
||||
option_name = Nan::New<String>("block_split_strategy").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
option_value = Nan::Get(options, option_name).ToLocalChecked();
|
||||
if(!option_value->IsString()) {
|
||||
Nan::ThrowTypeError("Wrong type for option 'block_split_strategy'");
|
||||
}
|
||||
if(strStrategy.compare("none") == 0) { png_options.block_split_strategy = 0; }
|
||||
else if(strStrategy.compare("first") == 0) { png_options.block_split_strategy = 1; }
|
||||
else if(strStrategy.compare("last") == 0) { png_options.block_split_strategy = 2; }
|
||||
else if(strStrategy.compare("both") == 0) { png_options.block_split_strategy = 3; }
|
||||
else {
|
||||
Nan::ThrowTypeError("Wrong value for option 'block_split_strategy'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(PNGDeflate) {
|
||||
if(info.Length() < 1 || !info[0]->IsString()) {
|
||||
Nan::ThrowTypeError("First argument must be a string");
|
||||
}
|
||||
std::string imageName(*Nan::Utf8String(info[0]->ToString()));
|
||||
|
||||
if(info.Length() < 2 || !info[1]->IsString()) {
|
||||
Nan::ThrowTypeError("First argument must be a string");
|
||||
}
|
||||
std::string out_filename(*Nan::Utf8String(info[1]->ToString()));
|
||||
|
||||
ZopfliPNGOptions png_options;
|
||||
|
||||
if(info.Length() >= 2 && info[2]->IsObject()) {
|
||||
Local<Object> options = info[2]->ToObject();
|
||||
parseOptions(options, png_options);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
std::vector<unsigned char> origpng;
|
||||
unsigned error;
|
||||
lodepng::State inputstate;
|
||||
std::vector<unsigned char> resultpng;
|
||||
|
||||
lodepng::load_file(origpng, imageName);
|
||||
|
||||
bool verbose = false;
|
||||
error = ZopfliPNGOptimize(origpng, png_options, verbose, &resultpng);
|
||||
|
||||
if (error) {
|
||||
printf("Decoding error %u: %s\n", error, lodepng_error_text(error));
|
||||
} else {
|
||||
// Verify result, check that the result causes no decoding errors
|
||||
error = lodepng::decode(image, w, h, inputstate, resultpng);
|
||||
if (error) {
|
||||
printf("Error: verification of result failed.\n");
|
||||
} else {
|
||||
lodepng::save_file(resultpng, out_filename);
|
||||
}
|
||||
}
|
||||
info.GetReturnValue().Set(Nan::New<v8::Integer>(error));
|
||||
}
|
||||
8
build/node_modules/node-zopfli/src/png/zopflipng.h
generated
vendored
Normal file
8
build/node_modules/node-zopfli/src/png/zopflipng.h
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "nan.h"
|
||||
|
||||
#ifndef NODE_ZOPFLI_PNG_H_
|
||||
#define NODE_ZOPFLI_PNG_H_
|
||||
|
||||
NAN_METHOD(PNGDeflate);
|
||||
|
||||
#endif
|
||||
227
build/node_modules/node-zopfli/src/zopfli-binding.cc
generated
vendored
Normal file
227
build/node_modules/node-zopfli/src/zopfli-binding.cc
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
#include <node.h>
|
||||
#include "zopfli.h"
|
||||
#include "zopfli-binding.h"
|
||||
#include "png/zopflipng.h"
|
||||
|
||||
namespace nodezopfli {
|
||||
|
||||
using namespace v8;
|
||||
using namespace node;
|
||||
|
||||
NAN_INLINE Nan::NAN_METHOD_RETURN_TYPE ParseArgs(const Nan::FunctionCallbackInfo<v8::Value>& info, ZopfliFormat& format, ZopfliOptions& zopfli_options) {
|
||||
ZopfliInitOptions(&zopfli_options);
|
||||
format = ZOPFLI_FORMAT_GZIP;
|
||||
|
||||
if(info.Length() < 1 || !Buffer::HasInstance(info[0])) {
|
||||
Nan::ThrowTypeError("First argument must be a buffer");
|
||||
}
|
||||
|
||||
if(info.Length() >= 2 && info[1]->IsString()) {
|
||||
std::string given_format(*Nan::Utf8String(info[1]));
|
||||
if(given_format.compare("gzip") == 0) {
|
||||
format = ZOPFLI_FORMAT_GZIP;
|
||||
} else if(given_format.compare("zlib") == 0) {
|
||||
format = ZOPFLI_FORMAT_ZLIB;
|
||||
} else if(given_format.compare("deflate") == 0) {
|
||||
format = ZOPFLI_FORMAT_DEFLATE;
|
||||
} else {
|
||||
Nan::ThrowTypeError("Invalid Zopfli format");
|
||||
}
|
||||
} else {
|
||||
Nan::ThrowTypeError("Second argument must be a string");
|
||||
}
|
||||
|
||||
if(info.Length() >= 3 && info[2]->IsObject()) {
|
||||
Local<Object> options = info[2].As<Object>();
|
||||
|
||||
if (!options.IsEmpty()) {
|
||||
Local<String> option_name;
|
||||
Local<Value> fieldValue;
|
||||
|
||||
// Whether to print output
|
||||
option_name = Nan::New<String>("verbose").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.verbose = Nan::Get(options, option_name).ToLocalChecked()->BooleanValue();
|
||||
}
|
||||
|
||||
// Whether to print more detailed output
|
||||
option_name = Nan::New<String>("verbose_more").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.verbose_more = Nan::Get(options, option_name).ToLocalChecked()->BooleanValue();
|
||||
}
|
||||
|
||||
/*
|
||||
Maximum amount of times to rerun forward and backward pass to optimize LZ77
|
||||
compression cost. Good values: 10, 15 for small files, 5 for files over
|
||||
several MB in size or it will be too slow.
|
||||
*/
|
||||
option_name = Nan::New<String>("numiterations").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.numiterations = Nan::Get(options, option_name).ToLocalChecked()->Int32Value();
|
||||
}
|
||||
|
||||
/*
|
||||
If true, chooses the optimal block split points only after doing the iterative
|
||||
LZ77 compression. If false, chooses the block split points first, then does
|
||||
iterative LZ77 on each individual block. Depending on the file, either first
|
||||
or last gives the best compression. Default: false (0).
|
||||
*/
|
||||
option_name = Nan::New<String>("blocksplitting").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.blocksplitting = Nan::Get(options, option_name).ToLocalChecked()->Int32Value();
|
||||
}
|
||||
|
||||
/*
|
||||
If true, chooses the optimal block split points only after doing the iterative
|
||||
LZ77 compression. If false, chooses the block split points first, then does
|
||||
iterative LZ77 on each individual block. Depending on the file, either first
|
||||
or last gives the best compression. Default: false (0).
|
||||
*/
|
||||
option_name = Nan::New<String>("blocksplittinglast").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.blocksplittinglast = Nan::Get(options, option_name).ToLocalChecked()->Int32Value();
|
||||
}
|
||||
|
||||
/*
|
||||
Maximum amount of blocks to split into (0 for unlimited, but this can give
|
||||
extreme results that hurt compression on some files). Default value: 15.
|
||||
*/
|
||||
option_name = Nan::New<String>("blocksplittingmax").ToLocalChecked();
|
||||
if (Nan::Has(options, option_name).FromJust()) {
|
||||
zopfli_options.blocksplittingmax = Nan::Get(options, option_name).ToLocalChecked()->Int32Value();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Nan::ThrowTypeError("Third argument must be an object");
|
||||
}
|
||||
//info.GetReturnValue().SetUndefined();
|
||||
}
|
||||
|
||||
|
||||
// Base
|
||||
// PROTECTED
|
||||
class CompressWorker : public Nan::AsyncWorker {
|
||||
public:
|
||||
CompressWorker(Nan::Callback *callback, ZopfliFormat& format, ZopfliOptions& zopfli_options, Handle<Object> buffer)
|
||||
: Nan::AsyncWorker(callback), format(format), zopfli_options(zopfli_options) {
|
||||
Nan::HandleScope scope;
|
||||
// Handle<Object> object = args[0]->ToObject();
|
||||
size_t length = node::Buffer::Length(buffer);
|
||||
const char *data = node::Buffer::Data(buffer);
|
||||
input = std::string(data, length);
|
||||
resultdata = 0;
|
||||
resultsize = 0;
|
||||
}
|
||||
~CompressWorker() {}
|
||||
|
||||
// Executed inside the worker-thread.
|
||||
// It is not safe to access V8, or V8 data structures
|
||||
// here, so everything we need for input and output
|
||||
// should go on `this`.
|
||||
void Execute() {
|
||||
std::string* input = &this->input;
|
||||
ZopfliCompress(&zopfli_options, format, (const unsigned char*)input->data(), input->length(), (unsigned char **)&resultdata, &resultsize);
|
||||
}
|
||||
|
||||
// Executed when the async work is complete
|
||||
// this function will be run inside the main event loop
|
||||
// so it is safe to use V8 again
|
||||
void HandleOKCallback() {
|
||||
Nan::HandleScope();
|
||||
|
||||
Local<Value> argv[] = {
|
||||
Nan::Null(),
|
||||
Nan::NewBuffer((char*)resultdata, resultsize).ToLocalChecked()
|
||||
};
|
||||
|
||||
callback->Call(2, argv);
|
||||
}
|
||||
|
||||
private:
|
||||
ZopfliFormat format;
|
||||
ZopfliOptions zopfli_options;
|
||||
std::string input;
|
||||
char* resultdata;
|
||||
size_t resultsize;
|
||||
};
|
||||
|
||||
// CompressBinding
|
||||
// PUBLIC
|
||||
NAN_METHOD(CompressBinding::Async) {
|
||||
ZopfliFormat format;
|
||||
ZopfliOptions zopfli_options;
|
||||
if(info.Length() == 0 || (info.Length() >= 1 && !info[info.Length()-1]->IsFunction())) {
|
||||
Nan::ThrowTypeError("Last argument must be a callback function");
|
||||
}
|
||||
ParseArgs(info, format, zopfli_options);
|
||||
|
||||
Nan::Callback *callback = new Nan::Callback(info[info.Length()-1].As<v8::Function>());
|
||||
Nan::AsyncQueueWorker(new CompressWorker(callback, format, zopfli_options, info[0]->ToObject()));
|
||||
info.GetReturnValue().SetUndefined();
|
||||
}
|
||||
|
||||
NAN_METHOD(CompressBinding::Sync) {
|
||||
ZopfliFormat format;
|
||||
ZopfliOptions zopfli_options;
|
||||
ParseArgs(info, format, zopfli_options);
|
||||
Local<Object> inbuffer = info[0]->ToObject();
|
||||
size_t inbuffersize = Buffer::Length(inbuffer);
|
||||
const unsigned char * inbufferdata = (const unsigned char*)Buffer::Data(inbuffer);
|
||||
unsigned char* out = 0;
|
||||
size_t outsize = 0;
|
||||
ZopfliCompress(&zopfli_options, format,
|
||||
inbufferdata, inbuffersize,
|
||||
&out, &outsize);
|
||||
info.GetReturnValue().Set(Nan::NewBuffer((char*)out, outsize).ToLocalChecked());
|
||||
}
|
||||
|
||||
unsigned updateAdler32(unsigned int adler, const unsigned char* data, size_t size)
|
||||
{
|
||||
unsigned sums_overflow = 5550;
|
||||
unsigned s1 = adler;
|
||||
unsigned s2 = 1 >> 16;
|
||||
|
||||
while (size > 0) {
|
||||
size_t amount = size > sums_overflow ? sums_overflow : size;
|
||||
size -= amount;
|
||||
while (amount > 0) {
|
||||
s1 += (*data++);
|
||||
s2 += s1;
|
||||
amount--;
|
||||
}
|
||||
s1 %= 65521;
|
||||
s2 %= 65521;
|
||||
}
|
||||
return (s2 << 16) | s1;
|
||||
}
|
||||
|
||||
NAN_METHOD(Adler32) {
|
||||
if(info.Length() >= 1 && !info[0]->IsUint32() && !info[0]->IsInt32()) {
|
||||
return Nan::ThrowTypeError("adler must be an unsigned integer");
|
||||
}
|
||||
|
||||
unsigned int adler = info[0]->Uint32Value();
|
||||
|
||||
if(info.Length() < 1 || !Buffer::HasInstance(info[1])) {
|
||||
return Nan::ThrowTypeError("data must be a buffer");
|
||||
}
|
||||
Local<Value> inbuffer = info[1];
|
||||
size_t inbuffersize = Buffer::Length(inbuffer->ToObject());
|
||||
const unsigned char * data = (const unsigned char*)Buffer::Data(inbuffer->ToObject());
|
||||
adler = updateAdler32(adler, data, inbuffersize);
|
||||
info.GetReturnValue().Set(Nan::New<Uint32>(adler));
|
||||
}
|
||||
|
||||
// NAN_MODULE_INIT(Init) {
|
||||
// NAN_EXPORT(target, Foo);
|
||||
// }
|
||||
|
||||
NAN_MODULE_INIT(Init) {
|
||||
Nan::SetMethod(target, "deflate", CompressBinding::Async);
|
||||
Nan::SetMethod(target, "deflateSync", CompressBinding::Sync);
|
||||
Nan::SetMethod(target, "adler32", Adler32);
|
||||
Nan::SetMethod(target, "pngcompress", PNGDeflate);
|
||||
}
|
||||
NODE_MODULE(zopfli, Init)
|
||||
|
||||
}
|
||||
17
build/node_modules/node-zopfli/src/zopfli-binding.h
generated
vendored
Normal file
17
build/node_modules/node-zopfli/src/zopfli-binding.h
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _NODE_ZOPFLI_H_
|
||||
#define _NODE_ZOPFLI_H_
|
||||
#include <node.h>
|
||||
#include <v8.h>
|
||||
#include "nan.h"
|
||||
|
||||
namespace nodezopfli {
|
||||
|
||||
class CompressBinding {
|
||||
public:
|
||||
static NAN_METHOD(Async);
|
||||
static NAN_METHOD(Sync);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
24
build/node_modules/node-zopfli/zopfli/CONTRIBUTING.md
generated
vendored
Normal file
24
build/node_modules/node-zopfli/zopfli/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Want to contribute? Great! First, read this page (including the small print at the end).
|
||||
|
||||
### Before you contribute
|
||||
Before we can use your code, you must sign the
|
||||
[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
|
||||
(CLA), which you can do online. The CLA is necessary mainly because you own the
|
||||
copyright to your changes, even after your contribution becomes part of our
|
||||
codebase, so we need your permission to use and distribute your code. We also
|
||||
need to be sure of various other things—for instance that you'll tell us if you
|
||||
know that your code infringes on other people's patents. You don't have to sign
|
||||
the CLA until after you've submitted your code for review and a member has
|
||||
approved it, but you must do it before we can put your code into our codebase.
|
||||
Before you start working on a larger contribution, you should get in touch with
|
||||
us first through the issue tracker with your idea so that we can help out and
|
||||
possibly guide you. Coordinating up front makes it much easier to avoid
|
||||
frustration later on.
|
||||
|
||||
### Code reviews
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use Github pull requests for this purpose.
|
||||
|
||||
### The small print
|
||||
Contributions made by corporations are covered by a different agreement than
|
||||
the one above, the Software Grant and Corporate Contributor License Agreement.
|
||||
9
build/node_modules/node-zopfli/zopfli/CONTRIBUTORS
generated
vendored
Normal file
9
build/node_modules/node-zopfli/zopfli/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
Mark Adler
|
||||
Jyrki Alakuijala
|
||||
Frédéric Kayser
|
||||
Jeffrey Lim
|
||||
Daniel Reed
|
||||
Huzaifa Sidhpurwala
|
||||
Péter Szabó
|
||||
Lode Vandevenne
|
||||
Derek Buitenhuis
|
||||
201
build/node_modules/node-zopfli/zopfli/COPYING
generated
vendored
Normal file
201
build/node_modules/node-zopfli/zopfli/COPYING
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
42
build/node_modules/node-zopfli/zopfli/Makefile
generated
vendored
Normal file
42
build/node_modules/node-zopfli/zopfli/Makefile
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
||||
CFLAGS = -W -Wall -Wextra -ansi -pedantic -lm -O2 -Wno-unused-function
|
||||
CXXFLAGS = -W -Wall -Wextra -ansi -pedantic -O2
|
||||
|
||||
ZOPFLILIB_SRC = src/zopfli/blocksplitter.c src/zopfli/cache.c\
|
||||
src/zopfli/deflate.c src/zopfli/gzip_container.c\
|
||||
src/zopfli/hash.c src/zopfli/katajainen.c\
|
||||
src/zopfli/lz77.c src/zopfli/squeeze.c\
|
||||
src/zopfli/tree.c src/zopfli/util.c\
|
||||
src/zopfli/zlib_container.c src/zopfli/zopfli_lib.c
|
||||
ZOPFLILIB_OBJ := $(patsubst src/zopfli/%.c,%.o,$(ZOPFLILIB_SRC))
|
||||
ZOPFLIBIN_SRC := src/zopfli/zopfli_bin.c
|
||||
LODEPNG_SRC := src/zopflipng/lodepng/lodepng.cpp src/zopflipng/lodepng/lodepng_util.cpp
|
||||
ZOPFLIPNGLIB_SRC := src/zopflipng/zopflipng_lib.cc
|
||||
ZOPFLIPNGBIN_SRC := src/zopflipng/zopflipng_bin.cc
|
||||
|
||||
.PHONY: zopfli zopflipng
|
||||
|
||||
# Zopfli binary
|
||||
zopfli:
|
||||
$(CC) $(ZOPFLILIB_SRC) $(ZOPFLIBIN_SRC) $(CFLAGS) -o zopfli
|
||||
|
||||
# Zopfli shared library
|
||||
libzopfli:
|
||||
$(CC) $(ZOPFLILIB_SRC) $(CFLAGS) -fPIC -c
|
||||
$(CC) $(ZOPFLILIB_OBJ) $(CFLAGS) -shared -Wl,-soname,libzopfli.so.1 -o libzopfli.so.1.0.1
|
||||
|
||||
# ZopfliPNG binary
|
||||
zopflipng:
|
||||
$(CC) $(ZOPFLILIB_SRC) $(CFLAGS) -c
|
||||
$(CXX) $(ZOPFLILIB_OBJ) $(LODEPNG_SRC) $(ZOPFLIPNGLIB_SRC) $(ZOPFLIPNGBIN_SRC) $(CFLAGS) -o zopflipng
|
||||
|
||||
# ZopfliPNG shared library
|
||||
libzopflipng:
|
||||
$(CC) $(ZOPFLILIB_SRC) $(CFLAGS) -fPIC -c
|
||||
$(CXX) $(ZOPFLILIB_OBJ) $(LODEPNG_SRC) $(ZOPFLIPNGLIB_SRC) $(CFLAGS) -fPIC --shared -Wl,-soname,libzopflipng.so.1 -o libzopflipng.so.1.0.0
|
||||
|
||||
# Remove all libraries and binaries
|
||||
clean:
|
||||
rm -f zopflipng zopfli $(ZOPFLILIB_OBJ) libzopfli*
|
||||
39
build/node_modules/node-zopfli/zopfli/README
generated
vendored
Normal file
39
build/node_modules/node-zopfli/zopfli/README
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
Zopfli Compression Algorithm is a compression library programmed in C to perform
|
||||
very good, but slow, deflate or zlib compression.
|
||||
|
||||
The basic function to compress data is ZopfliCompress in zopfli.h. Use the
|
||||
ZopfliOptions object to set parameters that affect the speed and compression.
|
||||
Use the ZopfliInitOptions function to place the default values in the
|
||||
ZopfliOptions first.
|
||||
|
||||
ZopfliCompress supports deflate, gzip and zlib output format with a parameter.
|
||||
To support only one individual format, you can instead use ZopfliDeflate in
|
||||
deflate.h, ZopfliZlibCompress in zlib_container.h or ZopfliGzipCompress in
|
||||
gzip_container.h.
|
||||
|
||||
ZopfliDeflate creates a valid deflate stream in memory, see:
|
||||
http://www.ietf.org/rfc/rfc1951.txt
|
||||
ZopfliZlibCompress creates a valid zlib stream in memory, see:
|
||||
http://www.ietf.org/rfc/rfc1950.txt
|
||||
ZopfliGzipCompress creates a valid gzip stream in memory, see:
|
||||
http://www.ietf.org/rfc/rfc1952.txt
|
||||
|
||||
This library can only compress, not decompress. Existing zlib or deflate
|
||||
libraries can decompress the data.
|
||||
|
||||
zopfli_bin.c is separate from the library and contains an example program to
|
||||
create very well compressed gzip files. Currently the makefile builds this
|
||||
program with the library statically linked in.
|
||||
|
||||
The source code of Zopfli is under src/zopfli. Build instructions:
|
||||
|
||||
To build zopfli, compile all .c source files under src/zopfli to a single binary
|
||||
with C, and link to the standard C math library, e.g.:
|
||||
gcc src/zopfli/*.c -O2 -W -Wall -Wextra -Wno-unused-function -ansi -pedantic -lm -o zopfli
|
||||
|
||||
A makefile is provided as well, but only for linux. Use "make" to build the
|
||||
binary, "make libzopfli" to build it as a shared library. For other platforms,
|
||||
please use the build instructions above instead.
|
||||
|
||||
Zopfli Compression Algorithm was created by Lode Vandevenne and Jyrki
|
||||
Alakuijala, based on an algorithm by Jyrki Alakuijala.
|
||||
54
build/node_modules/node-zopfli/zopfli/README.zopflipng
generated
vendored
Normal file
54
build/node_modules/node-zopfli/zopfli/README.zopflipng
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
ZopfliPNG is a command line program to optimize the Portable Network Graphics
|
||||
(PNG) images. This version has the following features:
|
||||
- uses Zopfli compression for the Deflate compression,
|
||||
- compares several strategies for choosing scanline filter codes,
|
||||
- chooses a suitable color type to losslessly encode the image,
|
||||
- removes all chunks that are unimportant for the typical web use (metadata,
|
||||
text, etc...),
|
||||
- optionally alters the hidden colors of fully transparent pixels for more
|
||||
compression, and,
|
||||
- optionally converts 16-bit color channels to 8-bit.
|
||||
|
||||
This is an alpha-release for testing while improvements, particularly to add
|
||||
palette selection, are still being made. Feedback and bug reports are welcome.
|
||||
|
||||
Important:
|
||||
|
||||
This PNG optimizer removes ancillary chunks (pieces of metadata) from the
|
||||
PNG image that normally do not affect rendering. However in special
|
||||
circumstances you may wish to keep some. For example for a design using
|
||||
custom gamma correction, keeping it may be desired. Visually check in the
|
||||
target renderer after using ZopfliPNG. Use --keepchunks to keep chunks, e.g.
|
||||
--keepchunks=gAMA,pHYs to keep gamma and DPI information. This will increase
|
||||
file size. The following page contains a list of ancillary PNG chunks:
|
||||
http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
|
||||
|
||||
Build instructions:
|
||||
|
||||
To build ZopfliPNG, compile all .c, .cc and .cpp files from src/zopfli,
|
||||
src/zopflipng and src/zopflipng/lodepng, except src/zopfli/zopfli_bin.c, to a
|
||||
single binary with C++, e.g.:
|
||||
g++ src/zopfli/{blocksplitter,cache,deflate,gzip_container,hash,katajainen,lz77,squeeze,tree,util,zlib_container,zopfli_lib}.c src/zopflipng/*.cc src/zopflipng/lodepng/*.cpp -O2 -W -Wall -Wextra -Wno-unused-function -ansi -pedantic -o zopflipng
|
||||
|
||||
A makefile is provided as well, but only for linux: use "make zopflipng" with
|
||||
the Zopfli makefile. For other platforms, please use the build instructions
|
||||
above instead.
|
||||
|
||||
The main compression algorithm in ZopfliPNG is ported from WebP lossless, but
|
||||
naturally cannot give as much compression gain for PNGs as it does for a more
|
||||
modern compression codec like WebP
|
||||
https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification.
|
||||
|
||||
Compared to libpng -- an often used PNG encoder implementation -- ZopfliPNG uses
|
||||
2-3 orders of magnitude more CPU time for compression. Initial testing using a
|
||||
corpus of 1000 PNGs with translucency, randomly selected from the internet,
|
||||
gives a compression improvement of 12% compared to convert -q 95, but only 0.5%
|
||||
compared to pngout (from better of /f0 and /f5 runs).
|
||||
|
||||
By releasing this software we hope to make images on the web load faster without
|
||||
a new image format, but the opportunities for optimization within PNG are
|
||||
limited. When targeting Android, Chrome, Opera, and Yandex browsers, or by using
|
||||
suitable plugins for other browsers, it is good to note that WebP lossless
|
||||
images are still 26 % smaller than images recompressed with ZopfliPNG.
|
||||
|
||||
2013-05-07, Lode Vandevenne and Jyrki Alakuijala
|
||||
332
build/node_modules/node-zopfli/zopfli/src/zopfli/blocksplitter.c
generated
vendored
Normal file
332
build/node_modules/node-zopfli/zopfli/src/zopfli/blocksplitter.c
generated
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "blocksplitter.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "deflate.h"
|
||||
#include "squeeze.h"
|
||||
#include "tree.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
The "f" for the FindMinimum function below.
|
||||
i: the current parameter of f(i)
|
||||
context: for your implementation
|
||||
*/
|
||||
typedef double FindMinimumFun(size_t i, void* context);
|
||||
|
||||
/*
|
||||
Finds minimum of function f(i) where is is of type size_t, f(i) is of type
|
||||
double, i is in range start-end (excluding end).
|
||||
Outputs the minimum value in *smallest and returns the index of this value.
|
||||
*/
|
||||
static size_t FindMinimum(FindMinimumFun f, void* context,
|
||||
size_t start, size_t end, double* smallest) {
|
||||
if (end - start < 1024) {
|
||||
double best = ZOPFLI_LARGE_FLOAT;
|
||||
size_t result = start;
|
||||
size_t i;
|
||||
for (i = start; i < end; i++) {
|
||||
double v = f(i, context);
|
||||
if (v < best) {
|
||||
best = v;
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
*smallest = best;
|
||||
return result;
|
||||
} else {
|
||||
/* Try to find minimum faster by recursively checking multiple points. */
|
||||
#define NUM 9 /* Good value: 9. */
|
||||
size_t i;
|
||||
size_t p[NUM];
|
||||
double vp[NUM];
|
||||
size_t besti;
|
||||
double best;
|
||||
double lastbest = ZOPFLI_LARGE_FLOAT;
|
||||
size_t pos = start;
|
||||
|
||||
for (;;) {
|
||||
if (end - start <= NUM) break;
|
||||
|
||||
for (i = 0; i < NUM; i++) {
|
||||
p[i] = start + (i + 1) * ((end - start) / (NUM + 1));
|
||||
vp[i] = f(p[i], context);
|
||||
}
|
||||
besti = 0;
|
||||
best = vp[0];
|
||||
for (i = 1; i < NUM; i++) {
|
||||
if (vp[i] < best) {
|
||||
best = vp[i];
|
||||
besti = i;
|
||||
}
|
||||
}
|
||||
if (best > lastbest) break;
|
||||
|
||||
start = besti == 0 ? start : p[besti - 1];
|
||||
end = besti == NUM - 1 ? end : p[besti + 1];
|
||||
|
||||
pos = p[besti];
|
||||
lastbest = best;
|
||||
}
|
||||
*smallest = lastbest;
|
||||
return pos;
|
||||
#undef NUM
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns estimated cost of a block in bits. It includes the size to encode the
|
||||
tree and the size to encode all literal, length and distance symbols and their
|
||||
extra bits.
|
||||
|
||||
litlens: lz77 lit/lengths
|
||||
dists: ll77 distances
|
||||
lstart: start of block
|
||||
lend: end of block (not inclusive)
|
||||
*/
|
||||
static double EstimateCost(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
return ZopfliCalculateBlockSizeAutoType(lz77, lstart, lend);
|
||||
}
|
||||
|
||||
typedef struct SplitCostContext {
|
||||
const ZopfliLZ77Store* lz77;
|
||||
size_t start;
|
||||
size_t end;
|
||||
} SplitCostContext;
|
||||
|
||||
|
||||
/*
|
||||
Gets the cost which is the sum of the cost of the left and the right section
|
||||
of the data.
|
||||
type: FindMinimumFun
|
||||
*/
|
||||
static double SplitCost(size_t i, void* context) {
|
||||
SplitCostContext* c = (SplitCostContext*)context;
|
||||
return EstimateCost(c->lz77, c->start, i) + EstimateCost(c->lz77, i, c->end);
|
||||
}
|
||||
|
||||
static void AddSorted(size_t value, size_t** out, size_t* outsize) {
|
||||
size_t i;
|
||||
ZOPFLI_APPEND_DATA(value, out, outsize);
|
||||
for (i = 0; i + 1 < *outsize; i++) {
|
||||
if ((*out)[i] > value) {
|
||||
size_t j;
|
||||
for (j = *outsize - 1; j > i; j--) {
|
||||
(*out)[j] = (*out)[j - 1];
|
||||
}
|
||||
(*out)[i] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Prints the block split points as decimal and hex values in the terminal.
|
||||
*/
|
||||
static void PrintBlockSplitPoints(const ZopfliLZ77Store* lz77,
|
||||
const size_t* lz77splitpoints,
|
||||
size_t nlz77points) {
|
||||
size_t* splitpoints = 0;
|
||||
size_t npoints = 0;
|
||||
size_t i;
|
||||
/* The input is given as lz77 indices, but we want to see the uncompressed
|
||||
index values. */
|
||||
size_t pos = 0;
|
||||
if (nlz77points > 0) {
|
||||
for (i = 0; i < lz77->size; i++) {
|
||||
size_t length = lz77->dists[i] == 0 ? 1 : lz77->litlens[i];
|
||||
if (lz77splitpoints[npoints] == i) {
|
||||
ZOPFLI_APPEND_DATA(pos, &splitpoints, &npoints);
|
||||
if (npoints == nlz77points) break;
|
||||
}
|
||||
pos += length;
|
||||
}
|
||||
}
|
||||
assert(npoints == nlz77points);
|
||||
|
||||
fprintf(stderr, "block split points: ");
|
||||
for (i = 0; i < npoints; i++) {
|
||||
fprintf(stderr, "%d ", (int)splitpoints[i]);
|
||||
}
|
||||
fprintf(stderr, "(hex:");
|
||||
for (i = 0; i < npoints; i++) {
|
||||
fprintf(stderr, " %x", (int)splitpoints[i]);
|
||||
}
|
||||
fprintf(stderr, ")\n");
|
||||
|
||||
free(splitpoints);
|
||||
}
|
||||
|
||||
/*
|
||||
Finds next block to try to split, the largest of the available ones.
|
||||
The largest is chosen to make sure that if only a limited amount of blocks is
|
||||
requested, their sizes are spread evenly.
|
||||
lz77size: the size of the LL77 data, which is the size of the done array here.
|
||||
done: array indicating which blocks starting at that position are no longer
|
||||
splittable (splitting them increases rather than decreases cost).
|
||||
splitpoints: the splitpoints found so far.
|
||||
npoints: the amount of splitpoints found so far.
|
||||
lstart: output variable, giving start of block.
|
||||
lend: output variable, giving end of block.
|
||||
returns 1 if a block was found, 0 if no block found (all are done).
|
||||
*/
|
||||
static int FindLargestSplittableBlock(
|
||||
size_t lz77size, const unsigned char* done,
|
||||
const size_t* splitpoints, size_t npoints,
|
||||
size_t* lstart, size_t* lend) {
|
||||
size_t longest = 0;
|
||||
int found = 0;
|
||||
size_t i;
|
||||
for (i = 0; i <= npoints; i++) {
|
||||
size_t start = i == 0 ? 0 : splitpoints[i - 1];
|
||||
size_t end = i == npoints ? lz77size - 1 : splitpoints[i];
|
||||
if (!done[start] && end - start > longest) {
|
||||
*lstart = start;
|
||||
*lend = end;
|
||||
found = 1;
|
||||
longest = end - start;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
||||
const ZopfliLZ77Store* lz77, size_t maxblocks,
|
||||
size_t** splitpoints, size_t* npoints) {
|
||||
size_t lstart, lend;
|
||||
size_t i;
|
||||
size_t llpos = 0;
|
||||
size_t numblocks = 1;
|
||||
unsigned char* done;
|
||||
double splitcost, origcost;
|
||||
|
||||
if (lz77->size < 10) return; /* This code fails on tiny files. */
|
||||
|
||||
done = (unsigned char*)malloc(lz77->size);
|
||||
if (!done) exit(-1); /* Allocation failed. */
|
||||
for (i = 0; i < lz77->size; i++) done[i] = 0;
|
||||
|
||||
lstart = 0;
|
||||
lend = lz77->size;
|
||||
for (;;) {
|
||||
SplitCostContext c;
|
||||
|
||||
if (maxblocks > 0 && numblocks >= maxblocks) {
|
||||
break;
|
||||
}
|
||||
|
||||
c.lz77 = lz77;
|
||||
c.start = lstart;
|
||||
c.end = lend;
|
||||
assert(lstart < lend);
|
||||
llpos = FindMinimum(SplitCost, &c, lstart + 1, lend, &splitcost);
|
||||
|
||||
assert(llpos > lstart);
|
||||
assert(llpos < lend);
|
||||
|
||||
origcost = EstimateCost(lz77, lstart, lend);
|
||||
|
||||
if (splitcost > origcost || llpos == lstart + 1 || llpos == lend) {
|
||||
done[lstart] = 1;
|
||||
} else {
|
||||
AddSorted(llpos, splitpoints, npoints);
|
||||
numblocks++;
|
||||
}
|
||||
|
||||
if (!FindLargestSplittableBlock(
|
||||
lz77->size, done, *splitpoints, *npoints, &lstart, &lend)) {
|
||||
break; /* No further split will probably reduce compression. */
|
||||
}
|
||||
|
||||
if (lend - lstart < 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (options->verbose) {
|
||||
PrintBlockSplitPoints(lz77, *splitpoints, *npoints);
|
||||
}
|
||||
|
||||
free(done);
|
||||
}
|
||||
|
||||
void ZopfliBlockSplit(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
size_t maxblocks, size_t** splitpoints, size_t* npoints) {
|
||||
size_t pos = 0;
|
||||
size_t i;
|
||||
ZopfliBlockState s;
|
||||
size_t* lz77splitpoints = 0;
|
||||
size_t nlz77points = 0;
|
||||
ZopfliLZ77Store store;
|
||||
ZopfliHash hash;
|
||||
ZopfliHash* h = &hash;
|
||||
|
||||
ZopfliInitLZ77Store(in, &store);
|
||||
ZopfliInitBlockState(options, instart, inend, 0, &s);
|
||||
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
|
||||
*npoints = 0;
|
||||
*splitpoints = 0;
|
||||
|
||||
/* Unintuitively, Using a simple LZ77 method here instead of ZopfliLZ77Optimal
|
||||
results in better blocks. */
|
||||
ZopfliLZ77Greedy(&s, in, instart, inend, &store, h);
|
||||
|
||||
ZopfliBlockSplitLZ77(options,
|
||||
&store, maxblocks,
|
||||
&lz77splitpoints, &nlz77points);
|
||||
|
||||
/* Convert LZ77 positions to positions in the uncompressed input. */
|
||||
pos = instart;
|
||||
if (nlz77points > 0) {
|
||||
for (i = 0; i < store.size; i++) {
|
||||
size_t length = store.dists[i] == 0 ? 1 : store.litlens[i];
|
||||
if (lz77splitpoints[*npoints] == i) {
|
||||
ZOPFLI_APPEND_DATA(pos, splitpoints, npoints);
|
||||
if (*npoints == nlz77points) break;
|
||||
}
|
||||
pos += length;
|
||||
}
|
||||
}
|
||||
assert(*npoints == nlz77points);
|
||||
|
||||
free(lz77splitpoints);
|
||||
ZopfliCleanBlockState(&s);
|
||||
ZopfliCleanLZ77Store(&store);
|
||||
ZopfliCleanHash(h);
|
||||
}
|
||||
|
||||
void ZopfliBlockSplitSimple(const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
size_t blocksize,
|
||||
size_t** splitpoints, size_t* npoints) {
|
||||
size_t i = instart;
|
||||
while (i < inend) {
|
||||
ZOPFLI_APPEND_DATA(i, splitpoints, npoints);
|
||||
i += blocksize;
|
||||
}
|
||||
(void)in;
|
||||
}
|
||||
73
build/node_modules/node-zopfli/zopfli/src/zopfli/blocksplitter.h
generated
vendored
Normal file
73
build/node_modules/node-zopfli/zopfli/src/zopfli/blocksplitter.h
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions to choose good boundaries for block splitting. Deflate allows encoding
|
||||
the data in multiple blocks, with a separate Huffman tree for each block. The
|
||||
Huffman tree itself requires some bytes to encode, so by choosing certain
|
||||
blocks, you can either hurt, or enhance compression. These functions choose good
|
||||
ones that enhance it.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_BLOCKSPLITTER_H_
|
||||
#define ZOPFLI_BLOCKSPLITTER_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lz77.h"
|
||||
#include "zopfli.h"
|
||||
|
||||
|
||||
/*
|
||||
Does blocksplitting on LZ77 data.
|
||||
The output splitpoints are indices in the LZ77 data.
|
||||
maxblocks: set a limit to the amount of blocks. Set to 0 to mean no limit.
|
||||
*/
|
||||
void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
|
||||
const ZopfliLZ77Store* lz77, size_t maxblocks,
|
||||
size_t** splitpoints, size_t* npoints);
|
||||
|
||||
/*
|
||||
Does blocksplitting on uncompressed data.
|
||||
The output splitpoints are indices in the uncompressed bytes.
|
||||
|
||||
options: general program options.
|
||||
in: uncompressed input data
|
||||
instart: where to start splitting
|
||||
inend: where to end splitting (not inclusive)
|
||||
maxblocks: maximum amount of blocks to split into, or 0 for no limit
|
||||
splitpoints: dynamic array to put the resulting split point coordinates into.
|
||||
The coordinates are indices in the input array.
|
||||
npoints: pointer to amount of splitpoints, for the dynamic array. The amount of
|
||||
blocks is the amount of splitpoitns + 1.
|
||||
*/
|
||||
void ZopfliBlockSplit(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
size_t maxblocks, size_t** splitpoints, size_t* npoints);
|
||||
|
||||
/*
|
||||
Divides the input into equal blocks, does not even take LZ77 lengths into
|
||||
account.
|
||||
*/
|
||||
void ZopfliBlockSplitSimple(const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
size_t blocksize,
|
||||
size_t** splitpoints, size_t* npoints);
|
||||
|
||||
#endif /* ZOPFLI_BLOCKSPLITTER_H_ */
|
||||
125
build/node_modules/node-zopfli/zopfli/src/zopfli/cache.c
generated
vendored
Normal file
125
build/node_modules/node-zopfli/zopfli/src/zopfli/cache.c
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
|
||||
void ZopfliInitCache(size_t blocksize, ZopfliLongestMatchCache* lmc) {
|
||||
size_t i;
|
||||
lmc->length = (unsigned short*)malloc(sizeof(unsigned short) * blocksize);
|
||||
lmc->dist = (unsigned short*)malloc(sizeof(unsigned short) * blocksize);
|
||||
/* Rather large amount of memory. */
|
||||
lmc->sublen = (unsigned char*)malloc(ZOPFLI_CACHE_LENGTH * 3 * blocksize);
|
||||
if(lmc->sublen == NULL) {
|
||||
fprintf(stderr,
|
||||
"Error: Out of memory. Tried allocating %lu bytes of memory.\n",
|
||||
ZOPFLI_CACHE_LENGTH * 3 * blocksize);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* length > 0 and dist 0 is invalid combination, which indicates on purpose
|
||||
that this cache value is not filled in yet. */
|
||||
for (i = 0; i < blocksize; i++) lmc->length[i] = 1;
|
||||
for (i = 0; i < blocksize; i++) lmc->dist[i] = 0;
|
||||
for (i = 0; i < ZOPFLI_CACHE_LENGTH * blocksize * 3; i++) lmc->sublen[i] = 0;
|
||||
}
|
||||
|
||||
void ZopfliCleanCache(ZopfliLongestMatchCache* lmc) {
|
||||
free(lmc->length);
|
||||
free(lmc->dist);
|
||||
free(lmc->sublen);
|
||||
}
|
||||
|
||||
void ZopfliSublenToCache(const unsigned short* sublen,
|
||||
size_t pos, size_t length,
|
||||
ZopfliLongestMatchCache* lmc) {
|
||||
size_t i;
|
||||
size_t j = 0;
|
||||
unsigned bestlength = 0;
|
||||
unsigned char* cache;
|
||||
|
||||
#if ZOPFLI_CACHE_LENGTH == 0
|
||||
return;
|
||||
#endif
|
||||
|
||||
cache = &lmc->sublen[ZOPFLI_CACHE_LENGTH * pos * 3];
|
||||
if (length < 3) return;
|
||||
for (i = 3; i <= length; i++) {
|
||||
if (i == length || sublen[i] != sublen[i + 1]) {
|
||||
cache[j * 3] = i - 3;
|
||||
cache[j * 3 + 1] = sublen[i] % 256;
|
||||
cache[j * 3 + 2] = (sublen[i] >> 8) % 256;
|
||||
bestlength = i;
|
||||
j++;
|
||||
if (j >= ZOPFLI_CACHE_LENGTH) break;
|
||||
}
|
||||
}
|
||||
if (j < ZOPFLI_CACHE_LENGTH) {
|
||||
assert(bestlength == length);
|
||||
cache[(ZOPFLI_CACHE_LENGTH - 1) * 3] = bestlength - 3;
|
||||
} else {
|
||||
assert(bestlength <= length);
|
||||
}
|
||||
assert(bestlength == ZopfliMaxCachedSublen(lmc, pos, length));
|
||||
}
|
||||
|
||||
void ZopfliCacheToSublen(const ZopfliLongestMatchCache* lmc,
|
||||
size_t pos, size_t length,
|
||||
unsigned short* sublen) {
|
||||
size_t i, j;
|
||||
unsigned maxlength = ZopfliMaxCachedSublen(lmc, pos, length);
|
||||
unsigned prevlength = 0;
|
||||
unsigned char* cache;
|
||||
#if ZOPFLI_CACHE_LENGTH == 0
|
||||
return;
|
||||
#endif
|
||||
if (length < 3) return;
|
||||
cache = &lmc->sublen[ZOPFLI_CACHE_LENGTH * pos * 3];
|
||||
for (j = 0; j < ZOPFLI_CACHE_LENGTH; j++) {
|
||||
unsigned length = cache[j * 3] + 3;
|
||||
unsigned dist = cache[j * 3 + 1] + 256 * cache[j * 3 + 2];
|
||||
for (i = prevlength; i <= length; i++) {
|
||||
sublen[i] = dist;
|
||||
}
|
||||
if (length == maxlength) break;
|
||||
prevlength = length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the length up to which could be stored in the cache.
|
||||
*/
|
||||
unsigned ZopfliMaxCachedSublen(const ZopfliLongestMatchCache* lmc,
|
||||
size_t pos, size_t length) {
|
||||
unsigned char* cache;
|
||||
#if ZOPFLI_CACHE_LENGTH == 0
|
||||
return 0;
|
||||
#endif
|
||||
cache = &lmc->sublen[ZOPFLI_CACHE_LENGTH * pos * 3];
|
||||
(void)length;
|
||||
if (cache[1] == 0 && cache[2] == 0) return 0; /* No sublen cached. */
|
||||
return cache[(ZOPFLI_CACHE_LENGTH - 1) * 3] + 3;
|
||||
}
|
||||
|
||||
#endif /* ZOPFLI_LONGEST_MATCH_CACHE */
|
||||
66
build/node_modules/node-zopfli/zopfli/src/zopfli/cache.h
generated
vendored
Normal file
66
build/node_modules/node-zopfli/zopfli/src/zopfli/cache.h
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
The cache that speeds up ZopfliFindLongestMatch of lz77.c.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_CACHE_H_
|
||||
#define ZOPFLI_CACHE_H_
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
|
||||
/*
|
||||
Cache used by ZopfliFindLongestMatch to remember previously found length/dist
|
||||
values.
|
||||
This is needed because the squeeze runs will ask these values multiple times for
|
||||
the same position.
|
||||
Uses large amounts of memory, since it has to remember the distance belonging
|
||||
to every possible shorter-than-the-best length (the so called "sublen" array).
|
||||
*/
|
||||
typedef struct ZopfliLongestMatchCache {
|
||||
unsigned short* length;
|
||||
unsigned short* dist;
|
||||
unsigned char* sublen;
|
||||
} ZopfliLongestMatchCache;
|
||||
|
||||
/* Initializes the ZopfliLongestMatchCache. */
|
||||
void ZopfliInitCache(size_t blocksize, ZopfliLongestMatchCache* lmc);
|
||||
|
||||
/* Frees up the memory of the ZopfliLongestMatchCache. */
|
||||
void ZopfliCleanCache(ZopfliLongestMatchCache* lmc);
|
||||
|
||||
/* Stores sublen array in the cache. */
|
||||
void ZopfliSublenToCache(const unsigned short* sublen,
|
||||
size_t pos, size_t length,
|
||||
ZopfliLongestMatchCache* lmc);
|
||||
|
||||
/* Extracts sublen array from the cache. */
|
||||
void ZopfliCacheToSublen(const ZopfliLongestMatchCache* lmc,
|
||||
size_t pos, size_t length,
|
||||
unsigned short* sublen);
|
||||
/* Returns the length up to which could be stored in the cache. */
|
||||
unsigned ZopfliMaxCachedSublen(const ZopfliLongestMatchCache* lmc,
|
||||
size_t pos, size_t length);
|
||||
|
||||
#endif /* ZOPFLI_LONGEST_MATCH_CACHE */
|
||||
|
||||
#endif /* ZOPFLI_CACHE_H_ */
|
||||
931
build/node_modules/node-zopfli/zopfli/src/zopfli/deflate.c
generated
vendored
Normal file
931
build/node_modules/node-zopfli/zopfli/src/zopfli/deflate.c
generated
vendored
Normal file
@@ -0,0 +1,931 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "blocksplitter.h"
|
||||
#include "squeeze.h"
|
||||
#include "symbols.h"
|
||||
#include "tree.h"
|
||||
|
||||
/*
|
||||
bp = bitpointer, always in range [0, 7].
|
||||
The outsize is number of necessary bytes to encode the bits.
|
||||
Given the value of bp and the amount of bytes, the amount of bits represented
|
||||
is not simply bytesize * 8 + bp because even representing one bit requires a
|
||||
whole byte. It is: (bp == 0) ? (bytesize * 8) : ((bytesize - 1) * 8 + bp)
|
||||
*/
|
||||
static void AddBit(int bit,
|
||||
unsigned char* bp, unsigned char** out, size_t* outsize) {
|
||||
if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
(*out)[*outsize - 1] |= bit << *bp;
|
||||
*bp = (*bp + 1) & 7;
|
||||
}
|
||||
|
||||
static void AddBits(unsigned symbol, unsigned length,
|
||||
unsigned char* bp, unsigned char** out, size_t* outsize) {
|
||||
/* TODO(lode): make more efficient (add more bits at once). */
|
||||
unsigned i;
|
||||
for (i = 0; i < length; i++) {
|
||||
unsigned bit = (symbol >> i) & 1;
|
||||
if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
(*out)[*outsize - 1] |= bit << *bp;
|
||||
*bp = (*bp + 1) & 7;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds bits, like AddBits, but the order is inverted. The deflate specification
|
||||
uses both orders in one standard.
|
||||
*/
|
||||
static void AddHuffmanBits(unsigned symbol, unsigned length,
|
||||
unsigned char* bp, unsigned char** out,
|
||||
size_t* outsize) {
|
||||
/* TODO(lode): make more efficient (add more bits at once). */
|
||||
unsigned i;
|
||||
for (i = 0; i < length; i++) {
|
||||
unsigned bit = (symbol >> (length - i - 1)) & 1;
|
||||
if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
(*out)[*outsize - 1] |= bit << *bp;
|
||||
*bp = (*bp + 1) & 7;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ensures there are at least 2 distance codes to support buggy decoders.
|
||||
Zlib 1.2.1 and below have a bug where it fails if there isn't at least 1
|
||||
distance code (with length > 0), even though it's valid according to the
|
||||
deflate spec to have 0 distance codes. On top of that, some mobile phones
|
||||
require at least two distance codes. To support these decoders too (but
|
||||
potentially at the cost of a few bytes), add dummy code lengths of 1.
|
||||
References to this bug can be found in the changelog of
|
||||
Zlib 1.2.2 and here: http://www.jonof.id.au/forum/index.php?topic=515.0.
|
||||
|
||||
d_lengths: the 32 lengths of the distance codes.
|
||||
*/
|
||||
static void PatchDistanceCodesForBuggyDecoders(unsigned* d_lengths) {
|
||||
int num_dist_codes = 0; /* Amount of non-zero distance codes */
|
||||
int i;
|
||||
for (i = 0; i < 30 /* Ignore the two unused codes from the spec */; i++) {
|
||||
if (d_lengths[i]) num_dist_codes++;
|
||||
if (num_dist_codes >= 2) return; /* Two or more codes is fine. */
|
||||
}
|
||||
|
||||
if (num_dist_codes == 0) {
|
||||
d_lengths[0] = d_lengths[1] = 1;
|
||||
} else if (num_dist_codes == 1) {
|
||||
d_lengths[d_lengths[0] ? 1 : 0] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Encodes the Huffman tree and returns how many bits its encoding takes. If out
|
||||
is a null pointer, only returns the size and runs faster.
|
||||
*/
|
||||
static size_t EncodeTree(const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths,
|
||||
int use_16, int use_17, int use_18,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
unsigned lld_total; /* Total amount of literal, length, distance codes. */
|
||||
/* Runlength encoded version of lengths of litlen and dist trees. */
|
||||
unsigned* rle = 0;
|
||||
unsigned* rle_bits = 0; /* Extra bits for rle values 16, 17 and 18. */
|
||||
size_t rle_size = 0; /* Size of rle array. */
|
||||
size_t rle_bits_size = 0; /* Should have same value as rle_size. */
|
||||
unsigned hlit = 29; /* 286 - 257 */
|
||||
unsigned hdist = 29; /* 32 - 1, but gzip does not like hdist > 29.*/
|
||||
unsigned hclen;
|
||||
unsigned hlit2;
|
||||
size_t i, j;
|
||||
size_t clcounts[19];
|
||||
unsigned clcl[19]; /* Code length code lengths. */
|
||||
unsigned clsymbols[19];
|
||||
/* The order in which code length code lengths are encoded as per deflate. */
|
||||
static const unsigned order[19] = {
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
};
|
||||
int size_only = !out;
|
||||
size_t result_size = 0;
|
||||
|
||||
for(i = 0; i < 19; i++) clcounts[i] = 0;
|
||||
|
||||
/* Trim zeros. */
|
||||
while (hlit > 0 && ll_lengths[257 + hlit - 1] == 0) hlit--;
|
||||
while (hdist > 0 && d_lengths[1 + hdist - 1] == 0) hdist--;
|
||||
hlit2 = hlit + 257;
|
||||
|
||||
lld_total = hlit2 + hdist + 1;
|
||||
|
||||
for (i = 0; i < lld_total; i++) {
|
||||
/* This is an encoding of a huffman tree, so now the length is a symbol */
|
||||
unsigned char symbol = i < hlit2 ? ll_lengths[i] : d_lengths[i - hlit2];
|
||||
unsigned count = 1;
|
||||
if(use_16 || (symbol == 0 && (use_17 || use_18))) {
|
||||
for (j = i + 1; j < lld_total && symbol ==
|
||||
(j < hlit2 ? ll_lengths[j] : d_lengths[j - hlit2]); j++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
i += count - 1;
|
||||
|
||||
/* Repetitions of zeroes */
|
||||
if (symbol == 0 && count >= 3) {
|
||||
if (use_18) {
|
||||
while (count >= 11) {
|
||||
unsigned count2 = count > 138 ? 138 : count;
|
||||
if (!size_only) {
|
||||
ZOPFLI_APPEND_DATA(18, &rle, &rle_size);
|
||||
ZOPFLI_APPEND_DATA(count2 - 11, &rle_bits, &rle_bits_size);
|
||||
}
|
||||
clcounts[18]++;
|
||||
count -= count2;
|
||||
}
|
||||
}
|
||||
if (use_17) {
|
||||
while (count >= 3) {
|
||||
unsigned count2 = count > 10 ? 10 : count;
|
||||
if (!size_only) {
|
||||
ZOPFLI_APPEND_DATA(17, &rle, &rle_size);
|
||||
ZOPFLI_APPEND_DATA(count2 - 3, &rle_bits, &rle_bits_size);
|
||||
}
|
||||
clcounts[17]++;
|
||||
count -= count2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Repetitions of any symbol */
|
||||
if (use_16 && count >= 4) {
|
||||
count--; /* Since the first one is hardcoded. */
|
||||
clcounts[symbol]++;
|
||||
if (!size_only) {
|
||||
ZOPFLI_APPEND_DATA(symbol, &rle, &rle_size);
|
||||
ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
|
||||
}
|
||||
while (count >= 3) {
|
||||
unsigned count2 = count > 6 ? 6 : count;
|
||||
if (!size_only) {
|
||||
ZOPFLI_APPEND_DATA(16, &rle, &rle_size);
|
||||
ZOPFLI_APPEND_DATA(count2 - 3, &rle_bits, &rle_bits_size);
|
||||
}
|
||||
clcounts[16]++;
|
||||
count -= count2;
|
||||
}
|
||||
}
|
||||
|
||||
/* No or insufficient repetition */
|
||||
clcounts[symbol] += count;
|
||||
while (count > 0) {
|
||||
if (!size_only) {
|
||||
ZOPFLI_APPEND_DATA(symbol, &rle, &rle_size);
|
||||
ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
ZopfliCalculateBitLengths(clcounts, 19, 7, clcl);
|
||||
if (!size_only) ZopfliLengthsToSymbols(clcl, 19, 7, clsymbols);
|
||||
|
||||
hclen = 15;
|
||||
/* Trim zeros. */
|
||||
while (hclen > 0 && clcounts[order[hclen + 4 - 1]] == 0) hclen--;
|
||||
|
||||
if (!size_only) {
|
||||
AddBits(hlit, 5, bp, out, outsize);
|
||||
AddBits(hdist, 5, bp, out, outsize);
|
||||
AddBits(hclen, 4, bp, out, outsize);
|
||||
|
||||
for (i = 0; i < hclen + 4; i++) {
|
||||
AddBits(clcl[order[i]], 3, bp, out, outsize);
|
||||
}
|
||||
|
||||
for (i = 0; i < rle_size; i++) {
|
||||
unsigned symbol = clsymbols[rle[i]];
|
||||
AddHuffmanBits(symbol, clcl[rle[i]], bp, out, outsize);
|
||||
/* Extra bits. */
|
||||
if (rle[i] == 16) AddBits(rle_bits[i], 2, bp, out, outsize);
|
||||
else if (rle[i] == 17) AddBits(rle_bits[i], 3, bp, out, outsize);
|
||||
else if (rle[i] == 18) AddBits(rle_bits[i], 7, bp, out, outsize);
|
||||
}
|
||||
}
|
||||
|
||||
result_size += 14; /* hlit, hdist, hclen bits */
|
||||
result_size += (hclen + 4) * 3; /* clcl bits */
|
||||
for(i = 0; i < 19; i++) {
|
||||
result_size += clcl[i] * clcounts[i];
|
||||
}
|
||||
/* Extra bits. */
|
||||
result_size += clcounts[16] * 2;
|
||||
result_size += clcounts[17] * 3;
|
||||
result_size += clcounts[18] * 7;
|
||||
|
||||
/* Note: in case of "size_only" these are null pointers so no effect. */
|
||||
free(rle);
|
||||
free(rle_bits);
|
||||
|
||||
return result_size;
|
||||
}
|
||||
|
||||
static void AddDynamicTree(const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
int i;
|
||||
int best = 0;
|
||||
size_t bestsize = 0;
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
size_t size = EncodeTree(ll_lengths, d_lengths,
|
||||
i & 1, i & 2, i & 4,
|
||||
0, 0, 0);
|
||||
if (bestsize == 0 || size < bestsize) {
|
||||
bestsize = size;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
|
||||
EncodeTree(ll_lengths, d_lengths,
|
||||
best & 1, best & 2, best & 4,
|
||||
bp, out, outsize);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives the exact size of the tree, in bits, as it will be encoded in DEFLATE.
|
||||
*/
|
||||
static size_t CalculateTreeSize(const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths) {
|
||||
size_t result = 0;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
size_t size = EncodeTree(ll_lengths, d_lengths,
|
||||
i & 1, i & 2, i & 4,
|
||||
0, 0, 0);
|
||||
if (result == 0 || size < result) result = size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Adds all lit/len and dist codes from the lists as huffman symbols. Does not add
|
||||
end code 256. expected_data_size is the uncompressed block size, used for
|
||||
assert, but you can set it to 0 to not do the assertion.
|
||||
*/
|
||||
static void AddLZ77Data(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
size_t expected_data_size,
|
||||
const unsigned* ll_symbols, const unsigned* ll_lengths,
|
||||
const unsigned* d_symbols, const unsigned* d_lengths,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
size_t testlength = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = lstart; i < lend; i++) {
|
||||
unsigned dist = lz77->dists[i];
|
||||
unsigned litlen = lz77->litlens[i];
|
||||
if (dist == 0) {
|
||||
assert(litlen < 256);
|
||||
assert(ll_lengths[litlen] > 0);
|
||||
AddHuffmanBits(ll_symbols[litlen], ll_lengths[litlen], bp, out, outsize);
|
||||
testlength++;
|
||||
} else {
|
||||
unsigned lls = ZopfliGetLengthSymbol(litlen);
|
||||
unsigned ds = ZopfliGetDistSymbol(dist);
|
||||
assert(litlen >= 3 && litlen <= 288);
|
||||
assert(ll_lengths[lls] > 0);
|
||||
assert(d_lengths[ds] > 0);
|
||||
AddHuffmanBits(ll_symbols[lls], ll_lengths[lls], bp, out, outsize);
|
||||
AddBits(ZopfliGetLengthExtraBitsValue(litlen),
|
||||
ZopfliGetLengthExtraBits(litlen),
|
||||
bp, out, outsize);
|
||||
AddHuffmanBits(d_symbols[ds], d_lengths[ds], bp, out, outsize);
|
||||
AddBits(ZopfliGetDistExtraBitsValue(dist),
|
||||
ZopfliGetDistExtraBits(dist),
|
||||
bp, out, outsize);
|
||||
testlength += litlen;
|
||||
}
|
||||
}
|
||||
assert(expected_data_size == 0 || testlength == expected_data_size);
|
||||
}
|
||||
|
||||
static void GetFixedTree(unsigned* ll_lengths, unsigned* d_lengths) {
|
||||
size_t i;
|
||||
for (i = 0; i < 144; i++) ll_lengths[i] = 8;
|
||||
for (i = 144; i < 256; i++) ll_lengths[i] = 9;
|
||||
for (i = 256; i < 280; i++) ll_lengths[i] = 7;
|
||||
for (i = 280; i < 288; i++) ll_lengths[i] = 8;
|
||||
for (i = 0; i < 32; i++) d_lengths[i] = 5;
|
||||
}
|
||||
|
||||
/*
|
||||
Same as CalculateBlockSymbolSize, but for block size smaller than histogram
|
||||
size.
|
||||
*/
|
||||
static size_t CalculateBlockSymbolSizeSmall(const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths,
|
||||
const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
size_t result = 0;
|
||||
size_t i;
|
||||
for (i = lstart; i < lend; i++) {
|
||||
assert(i < lz77->size);
|
||||
assert(lz77->litlens[i] < 259);
|
||||
if (lz77->dists[i] == 0) {
|
||||
result += ll_lengths[lz77->litlens[i]];
|
||||
} else {
|
||||
int ll_symbol = ZopfliGetLengthSymbol(lz77->litlens[i]);
|
||||
int d_symbol = ZopfliGetDistSymbol(lz77->dists[i]);
|
||||
result += ll_lengths[ll_symbol];
|
||||
result += d_lengths[d_symbol];
|
||||
result += ZopfliGetLengthSymbolExtraBits(ll_symbol);
|
||||
result += ZopfliGetDistSymbolExtraBits(d_symbol);
|
||||
}
|
||||
}
|
||||
result += ll_lengths[256]; /*end symbol*/
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Same as CalculateBlockSymbolSize, but with the histogram provided by the caller.
|
||||
*/
|
||||
static size_t CalculateBlockSymbolSizeGivenCounts(const size_t* ll_counts,
|
||||
const size_t* d_counts,
|
||||
const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths,
|
||||
const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
size_t result = 0;
|
||||
size_t i;
|
||||
if (lstart + ZOPFLI_NUM_LL * 3 > lend) {
|
||||
return CalculateBlockSymbolSizeSmall(
|
||||
ll_lengths, d_lengths, lz77, lstart, lend);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++) {
|
||||
result += ll_lengths[i] * ll_counts[i];
|
||||
}
|
||||
for (i = 257; i < 286; i++) {
|
||||
result += ll_lengths[i] * ll_counts[i];
|
||||
result += ZopfliGetLengthSymbolExtraBits(i) * ll_counts[i];
|
||||
}
|
||||
for (i = 0; i < 30; i++) {
|
||||
result += d_lengths[i] * d_counts[i];
|
||||
result += ZopfliGetDistSymbolExtraBits(i) * d_counts[i];
|
||||
}
|
||||
result += ll_lengths[256]; /*end symbol*/
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates size of the part after the header and tree of an LZ77 block, in bits.
|
||||
*/
|
||||
static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths,
|
||||
const unsigned* d_lengths,
|
||||
const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
if (lstart + ZOPFLI_NUM_LL * 3 > lend) {
|
||||
return CalculateBlockSymbolSizeSmall(
|
||||
ll_lengths, d_lengths, lz77, lstart, lend);
|
||||
} else {
|
||||
size_t ll_counts[ZOPFLI_NUM_LL];
|
||||
size_t d_counts[ZOPFLI_NUM_D];
|
||||
ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts);
|
||||
return CalculateBlockSymbolSizeGivenCounts(
|
||||
ll_counts, d_counts, ll_lengths, d_lengths, lz77, lstart, lend);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t AbsDiff(size_t x, size_t y) {
|
||||
if (x > y)
|
||||
return x - y;
|
||||
else
|
||||
return y - x;
|
||||
}
|
||||
|
||||
/*
|
||||
Changes the population counts in a way that the consequent Huffman tree
|
||||
compression, especially its rle-part, will be more likely to compress this data
|
||||
more efficiently. length contains the size of the histogram.
|
||||
*/
|
||||
void OptimizeHuffmanForRle(int length, size_t* counts) {
|
||||
int i, k, stride;
|
||||
size_t symbol, sum, limit;
|
||||
int* good_for_rle;
|
||||
|
||||
/* 1) We don't want to touch the trailing zeros. We may break the
|
||||
rules of the format by adding more data in the distance codes. */
|
||||
for (; length >= 0; --length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
if (counts[length - 1] != 0) {
|
||||
/* Now counts[0..length - 1] does not have trailing zeros. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 2) Let's mark all population counts that already can be encoded
|
||||
with an rle code.*/
|
||||
good_for_rle = (int*)malloc(length * sizeof(int));
|
||||
for (i = 0; i < length; ++i) good_for_rle[i] = 0;
|
||||
|
||||
/* Let's not spoil any of the existing good rle codes.
|
||||
Mark any seq of 0's that is longer than 5 as a good_for_rle.
|
||||
Mark any seq of non-0's that is longer than 7 as a good_for_rle.*/
|
||||
symbol = counts[0];
|
||||
stride = 0;
|
||||
for (i = 0; i < length + 1; ++i) {
|
||||
if (i == length || counts[i] != symbol) {
|
||||
if ((symbol == 0 && stride >= 5) || (symbol != 0 && stride >= 7)) {
|
||||
for (k = 0; k < stride; ++k) {
|
||||
good_for_rle[i - k - 1] = 1;
|
||||
}
|
||||
}
|
||||
stride = 1;
|
||||
if (i != length) {
|
||||
symbol = counts[i];
|
||||
}
|
||||
} else {
|
||||
++stride;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3) Let's replace those population counts that lead to more rle codes. */
|
||||
stride = 0;
|
||||
limit = counts[0];
|
||||
sum = 0;
|
||||
for (i = 0; i < length + 1; ++i) {
|
||||
if (i == length || good_for_rle[i]
|
||||
/* Heuristic for selecting the stride ranges to collapse. */
|
||||
|| AbsDiff(counts[i], limit) >= 4) {
|
||||
if (stride >= 4 || (stride >= 3 && sum == 0)) {
|
||||
/* The stride must end, collapse what we have, if we have enough (4). */
|
||||
int count = (sum + stride / 2) / stride;
|
||||
if (count < 1) count = 1;
|
||||
if (sum == 0) {
|
||||
/* Don't make an all zeros stride to be upgraded to ones. */
|
||||
count = 0;
|
||||
}
|
||||
for (k = 0; k < stride; ++k) {
|
||||
/* We don't want to change value at counts[i],
|
||||
that is already belonging to the next stride. Thus - 1. */
|
||||
counts[i - k - 1] = count;
|
||||
}
|
||||
}
|
||||
stride = 0;
|
||||
sum = 0;
|
||||
if (i < length - 3) {
|
||||
/* All interesting strides have a count of at least 4,
|
||||
at least when non-zeros. */
|
||||
limit = (counts[i] + counts[i + 1] +
|
||||
counts[i + 2] + counts[i + 3] + 2) / 4;
|
||||
} else if (i < length) {
|
||||
limit = counts[i];
|
||||
} else {
|
||||
limit = 0;
|
||||
}
|
||||
}
|
||||
++stride;
|
||||
if (i != length) {
|
||||
sum += counts[i];
|
||||
}
|
||||
}
|
||||
|
||||
free(good_for_rle);
|
||||
}
|
||||
|
||||
/*
|
||||
Tries out OptimizeHuffmanForRle for this block, if the result is smaller,
|
||||
uses it, otherwise keeps the original. Returns size of encoded tree and data in
|
||||
bits, not including the 3-bit block header.
|
||||
*/
|
||||
static double TryOptimizeHuffmanForRle(
|
||||
const ZopfliLZ77Store* lz77, size_t lstart, size_t lend,
|
||||
const size_t* ll_counts, const size_t* d_counts,
|
||||
unsigned* ll_lengths, unsigned* d_lengths) {
|
||||
size_t ll_counts2[ZOPFLI_NUM_LL];
|
||||
size_t d_counts2[ZOPFLI_NUM_D];
|
||||
unsigned ll_lengths2[ZOPFLI_NUM_LL];
|
||||
unsigned d_lengths2[ZOPFLI_NUM_D];
|
||||
double treesize;
|
||||
double datasize;
|
||||
double treesize2;
|
||||
double datasize2;
|
||||
|
||||
treesize = CalculateTreeSize(ll_lengths, d_lengths);
|
||||
datasize = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
|
||||
ll_lengths, d_lengths, lz77, lstart, lend);
|
||||
|
||||
memcpy(ll_counts2, ll_counts, sizeof(ll_counts2));
|
||||
memcpy(d_counts2, d_counts, sizeof(d_counts2));
|
||||
OptimizeHuffmanForRle(ZOPFLI_NUM_LL, ll_counts2);
|
||||
OptimizeHuffmanForRle(ZOPFLI_NUM_D, d_counts2);
|
||||
ZopfliCalculateBitLengths(ll_counts2, ZOPFLI_NUM_LL, 15, ll_lengths2);
|
||||
ZopfliCalculateBitLengths(d_counts2, ZOPFLI_NUM_D, 15, d_lengths2);
|
||||
PatchDistanceCodesForBuggyDecoders(d_lengths2);
|
||||
|
||||
treesize2 = CalculateTreeSize(ll_lengths2, d_lengths2);
|
||||
datasize2 = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
|
||||
ll_lengths2, d_lengths2, lz77, lstart, lend);
|
||||
|
||||
if (treesize2 + datasize2 < treesize + datasize) {
|
||||
memcpy(ll_lengths, ll_lengths2, sizeof(ll_lengths2));
|
||||
memcpy(d_lengths, d_lengths2, sizeof(d_lengths2));
|
||||
return treesize2 + datasize2;
|
||||
}
|
||||
return treesize + datasize;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates the bit lengths for the symbols for dynamic blocks. Chooses bit
|
||||
lengths that give the smallest size of tree encoding + encoding of all the
|
||||
symbols to have smallest output size. This are not necessarily the ideal Huffman
|
||||
bit lengths. Returns size of encoded tree and data in bits, not including the
|
||||
3-bit block header.
|
||||
*/
|
||||
static double GetDynamicLengths(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
unsigned* ll_lengths, unsigned* d_lengths) {
|
||||
size_t ll_counts[ZOPFLI_NUM_LL];
|
||||
size_t d_counts[ZOPFLI_NUM_D];
|
||||
|
||||
ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts);
|
||||
ll_counts[256] = 1; /* End symbol. */
|
||||
ZopfliCalculateBitLengths(ll_counts, ZOPFLI_NUM_LL, 15, ll_lengths);
|
||||
ZopfliCalculateBitLengths(d_counts, ZOPFLI_NUM_D, 15, d_lengths);
|
||||
PatchDistanceCodesForBuggyDecoders(d_lengths);
|
||||
return TryOptimizeHuffmanForRle(
|
||||
lz77, lstart, lend, ll_counts, d_counts, ll_lengths, d_lengths);
|
||||
}
|
||||
|
||||
double ZopfliCalculateBlockSize(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend, int btype) {
|
||||
unsigned ll_lengths[ZOPFLI_NUM_LL];
|
||||
unsigned d_lengths[ZOPFLI_NUM_D];
|
||||
|
||||
double result = 3; /* bfinal and btype bits */
|
||||
|
||||
if (btype == 0) {
|
||||
size_t length = ZopfliLZ77GetByteRange(lz77, lstart, lend);
|
||||
size_t rem = length % 65535;
|
||||
size_t blocks = length / 65535 + (rem ? 1 : 0);
|
||||
/* An uncompressed block must actually be split into multiple blocks if it's
|
||||
larger than 65535 bytes long. Eeach block header is 5 bytes: 3 bits,
|
||||
padding, LEN and NLEN (potential less padding for first one ignored). */
|
||||
return blocks * 5 * 8 + length * 8;
|
||||
} if (btype == 1) {
|
||||
GetFixedTree(ll_lengths, d_lengths);
|
||||
result += CalculateBlockSymbolSize(
|
||||
ll_lengths, d_lengths, lz77, lstart, lend);
|
||||
} else {
|
||||
result += GetDynamicLengths(lz77, lstart, lend, ll_lengths, d_lengths);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double ZopfliCalculateBlockSizeAutoType(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
double uncompressedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 0);
|
||||
/* Don't do the expensive fixed cost calculation for larger blocks that are
|
||||
unlikely to use it. */
|
||||
double fixedcost = (lz77->size > 1000) ?
|
||||
uncompressedcost : ZopfliCalculateBlockSize(lz77, lstart, lend, 1);
|
||||
double dyncost = ZopfliCalculateBlockSize(lz77, lstart, lend, 2);
|
||||
return (uncompressedcost < fixedcost && uncompressedcost < dyncost)
|
||||
? uncompressedcost
|
||||
: (fixedcost < dyncost ? fixedcost : dyncost);
|
||||
}
|
||||
|
||||
/* Since an uncompressed block can be max 65535 in size, it actually adds
|
||||
multible blocks if needed. */
|
||||
static void AddNonCompressedBlock(const ZopfliOptions* options, int final,
|
||||
const unsigned char* in, size_t instart,
|
||||
size_t inend,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
size_t pos = instart;
|
||||
(void)options;
|
||||
for (;;) {
|
||||
size_t i;
|
||||
unsigned short blocksize = 65535;
|
||||
unsigned short nlen;
|
||||
int currentfinal;
|
||||
|
||||
if (pos + blocksize > inend) blocksize = inend - pos;
|
||||
currentfinal = pos + blocksize >= inend;
|
||||
|
||||
nlen = ~blocksize;
|
||||
|
||||
AddBit(final && currentfinal, bp, out, outsize);
|
||||
/* BTYPE 00 */
|
||||
AddBit(0, bp, out, outsize);
|
||||
AddBit(0, bp, out, outsize);
|
||||
|
||||
/* Any bits of input up to the next byte boundary are ignored. */
|
||||
*bp = 0;
|
||||
|
||||
ZOPFLI_APPEND_DATA(blocksize % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((blocksize / 256) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(nlen % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((nlen / 256) % 256, out, outsize);
|
||||
|
||||
for (i = 0; i < blocksize; i++) {
|
||||
ZOPFLI_APPEND_DATA(in[pos + i], out, outsize);
|
||||
}
|
||||
|
||||
if (currentfinal) break;
|
||||
pos += blocksize;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Adds a deflate block with the given LZ77 data to the output.
|
||||
options: global program options
|
||||
btype: the block type, must be 1 or 2
|
||||
final: whether to set the "final" bit on this block, must be the last block
|
||||
litlens: literal/length array of the LZ77 data, in the same format as in
|
||||
ZopfliLZ77Store.
|
||||
dists: distance array of the LZ77 data, in the same format as in
|
||||
ZopfliLZ77Store.
|
||||
lstart: where to start in the LZ77 data
|
||||
lend: where to end in the LZ77 data (not inclusive)
|
||||
expected_data_size: the uncompressed block size, used for assert, but you can
|
||||
set it to 0 to not do the assertion.
|
||||
bp: output bit pointer
|
||||
out: dynamic output array to append to
|
||||
outsize: dynamic output array size
|
||||
*/
|
||||
static void AddLZ77Block(const ZopfliOptions* options, int btype, int final,
|
||||
const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
size_t expected_data_size,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
unsigned ll_lengths[ZOPFLI_NUM_LL];
|
||||
unsigned d_lengths[ZOPFLI_NUM_D];
|
||||
unsigned ll_symbols[ZOPFLI_NUM_LL];
|
||||
unsigned d_symbols[ZOPFLI_NUM_D];
|
||||
size_t detect_block_size = *outsize;
|
||||
size_t compressed_size;
|
||||
size_t uncompressed_size = 0;
|
||||
size_t i;
|
||||
if (btype == 0) {
|
||||
size_t length = ZopfliLZ77GetByteRange(lz77, lstart, lend);
|
||||
size_t pos = lstart == lend ? 0 : lz77->pos[lstart];
|
||||
size_t end = pos + length;
|
||||
AddNonCompressedBlock(options, final,
|
||||
lz77->data, pos, end, bp, out, outsize);
|
||||
return;
|
||||
}
|
||||
|
||||
AddBit(final, bp, out, outsize);
|
||||
AddBit(btype & 1, bp, out, outsize);
|
||||
AddBit((btype & 2) >> 1, bp, out, outsize);
|
||||
|
||||
if (btype == 1) {
|
||||
/* Fixed block. */
|
||||
GetFixedTree(ll_lengths, d_lengths);
|
||||
} else {
|
||||
/* Dynamic block. */
|
||||
unsigned detect_tree_size;
|
||||
assert(btype == 2);
|
||||
|
||||
GetDynamicLengths(lz77, lstart, lend, ll_lengths, d_lengths);
|
||||
|
||||
detect_tree_size = *outsize;
|
||||
AddDynamicTree(ll_lengths, d_lengths, bp, out, outsize);
|
||||
if (options->verbose) {
|
||||
fprintf(stderr, "treesize: %d\n", (int)(*outsize - detect_tree_size));
|
||||
}
|
||||
}
|
||||
|
||||
ZopfliLengthsToSymbols(ll_lengths, ZOPFLI_NUM_LL, 15, ll_symbols);
|
||||
ZopfliLengthsToSymbols(d_lengths, ZOPFLI_NUM_D, 15, d_symbols);
|
||||
|
||||
detect_block_size = *outsize;
|
||||
AddLZ77Data(lz77, lstart, lend, expected_data_size,
|
||||
ll_symbols, ll_lengths, d_symbols, d_lengths,
|
||||
bp, out, outsize);
|
||||
/* End symbol. */
|
||||
AddHuffmanBits(ll_symbols[256], ll_lengths[256], bp, out, outsize);
|
||||
|
||||
for (i = lstart; i < lend; i++) {
|
||||
uncompressed_size += lz77->dists[i] == 0 ? 1 : lz77->litlens[i];
|
||||
}
|
||||
compressed_size = *outsize - detect_block_size;
|
||||
if (options->verbose) {
|
||||
fprintf(stderr, "compressed block size: %d (%dk) (unc: %d)\n",
|
||||
(int)compressed_size, (int)(compressed_size / 1024),
|
||||
(int)(uncompressed_size));
|
||||
}
|
||||
}
|
||||
|
||||
static void AddLZ77BlockAutoType(const ZopfliOptions* options, int final,
|
||||
const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
size_t expected_data_size,
|
||||
unsigned char* bp,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
double uncompressedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 0);
|
||||
double fixedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 1);
|
||||
double dyncost = ZopfliCalculateBlockSize(lz77, lstart, lend, 2);
|
||||
|
||||
/* Whether to perform the expensive calculation of creating an optimal block
|
||||
with fixed huffman tree to check if smaller. Only do this for small blocks or
|
||||
blocks which already are pretty good with fixed huffman tree. */
|
||||
int expensivefixed = (lz77->size < 1000) || fixedcost <= dyncost * 1.1;
|
||||
|
||||
ZopfliLZ77Store fixedstore;
|
||||
if (lstart == lend) {
|
||||
/* Smallest empty block is represented by fixed block */
|
||||
AddBits(final, 1, bp, out, outsize);
|
||||
AddBits(1, 2, bp, out, outsize); /* btype 01 */
|
||||
AddBits(0, 7, bp, out, outsize); /* end symbol has code 0000000 */
|
||||
return;
|
||||
}
|
||||
ZopfliInitLZ77Store(lz77->data, &fixedstore);
|
||||
if (expensivefixed) {
|
||||
/* Recalculate the LZ77 with ZopfliLZ77OptimalFixed */
|
||||
size_t instart = lz77->pos[lstart];
|
||||
size_t inend = instart + ZopfliLZ77GetByteRange(lz77, lstart, lend);
|
||||
|
||||
ZopfliBlockState s;
|
||||
ZopfliInitBlockState(options, instart, inend, 1, &s);
|
||||
ZopfliLZ77OptimalFixed(&s, lz77->data, instart, inend, &fixedstore);
|
||||
fixedcost = ZopfliCalculateBlockSize(&fixedstore, 0, fixedstore.size, 1);
|
||||
ZopfliCleanBlockState(&s);
|
||||
}
|
||||
|
||||
if (uncompressedcost < fixedcost && uncompressedcost < dyncost) {
|
||||
AddLZ77Block(options, 0, final, lz77, lstart, lend,
|
||||
expected_data_size, bp, out, outsize);
|
||||
} else if (fixedcost < dyncost) {
|
||||
if (expensivefixed) {
|
||||
AddLZ77Block(options, 1, final, &fixedstore, 0, fixedstore.size,
|
||||
expected_data_size, bp, out, outsize);
|
||||
} else {
|
||||
AddLZ77Block(options, 1, final, lz77, lstart, lend,
|
||||
expected_data_size, bp, out, outsize);
|
||||
}
|
||||
} else {
|
||||
AddLZ77Block(options, 2, final, lz77, lstart, lend,
|
||||
expected_data_size, bp, out, outsize);
|
||||
}
|
||||
|
||||
ZopfliCleanLZ77Store(&fixedstore);
|
||||
}
|
||||
|
||||
/*
|
||||
Deflate a part, to allow ZopfliDeflate() to use multiple master blocks if
|
||||
needed.
|
||||
It is possible to call this function multiple times in a row, shifting
|
||||
instart and inend to next bytes of the data. If instart is larger than 0, then
|
||||
previous bytes are used as the initial dictionary for LZ77.
|
||||
This function will usually output multiple deflate blocks. If final is 1, then
|
||||
the final bit will be set on the last block.
|
||||
*/
|
||||
void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
unsigned char* bp, unsigned char** out,
|
||||
size_t* outsize) {
|
||||
size_t i;
|
||||
/* byte coordinates rather than lz77 index */
|
||||
size_t* splitpoints_uncompressed = 0;
|
||||
size_t npoints = 0;
|
||||
size_t* splitpoints = 0;
|
||||
double totalcost = 0;
|
||||
ZopfliLZ77Store lz77;
|
||||
|
||||
/* If btype=2 is specified, it tries all block types. If a lesser btype is
|
||||
given, then however it forces that one. Neither of the lesser types needs
|
||||
block splitting as they have no dynamic huffman trees. */
|
||||
if (btype == 0) {
|
||||
AddNonCompressedBlock(options, final, in, instart, inend, bp, out, outsize);
|
||||
return;
|
||||
} else if (btype == 1) {
|
||||
ZopfliLZ77Store store;
|
||||
ZopfliBlockState s;
|
||||
ZopfliInitLZ77Store(in, &store);
|
||||
ZopfliInitBlockState(options, instart, inend, 1, &s);
|
||||
|
||||
ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
|
||||
AddLZ77Block(options, btype, final, &store, 0, store.size, 0,
|
||||
bp, out, outsize);
|
||||
|
||||
ZopfliCleanBlockState(&s);
|
||||
ZopfliCleanLZ77Store(&store);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (options->blocksplitting) {
|
||||
ZopfliBlockSplit(options, in, instart, inend,
|
||||
options->blocksplittingmax,
|
||||
&splitpoints_uncompressed, &npoints);
|
||||
splitpoints = (size_t*)malloc(sizeof(*splitpoints) * npoints);
|
||||
}
|
||||
|
||||
ZopfliInitLZ77Store(in, &lz77);
|
||||
|
||||
for (i = 0; i <= npoints; i++) {
|
||||
size_t start = i == 0 ? instart : splitpoints_uncompressed[i - 1];
|
||||
size_t end = i == npoints ? inend : splitpoints_uncompressed[i];
|
||||
ZopfliBlockState s;
|
||||
ZopfliLZ77Store store;
|
||||
ZopfliInitLZ77Store(in, &store);
|
||||
ZopfliInitBlockState(options, start, end, 1, &s);
|
||||
ZopfliLZ77Optimal(&s, in, start, end, options->numiterations, &store);
|
||||
totalcost += ZopfliCalculateBlockSizeAutoType(&store, 0, store.size);
|
||||
|
||||
ZopfliAppendLZ77Store(&store, &lz77);
|
||||
if (i < npoints) splitpoints[i] = lz77.size;
|
||||
|
||||
ZopfliCleanBlockState(&s);
|
||||
ZopfliCleanLZ77Store(&store);
|
||||
}
|
||||
|
||||
/* Second block splitting attempt */
|
||||
if (options->blocksplitting && npoints > 1) {
|
||||
size_t* splitpoints2 = 0;
|
||||
size_t npoints2 = 0;
|
||||
double totalcost2 = 0;
|
||||
|
||||
ZopfliBlockSplitLZ77(options, &lz77,
|
||||
options->blocksplittingmax, &splitpoints2, &npoints2);
|
||||
|
||||
for (i = 0; i <= npoints2; i++) {
|
||||
size_t start = i == 0 ? 0 : splitpoints2[i - 1];
|
||||
size_t end = i == npoints2 ? lz77.size : splitpoints2[i];
|
||||
totalcost2 += ZopfliCalculateBlockSizeAutoType(&lz77, start, end);
|
||||
}
|
||||
|
||||
if (totalcost2 < totalcost) {
|
||||
free(splitpoints);
|
||||
splitpoints = splitpoints2;
|
||||
npoints = npoints2;
|
||||
} else {
|
||||
free(splitpoints2);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= npoints; i++) {
|
||||
size_t start = i == 0 ? 0 : splitpoints[i - 1];
|
||||
size_t end = i == npoints ? lz77.size : splitpoints[i];
|
||||
AddLZ77BlockAutoType(options, i == npoints && final,
|
||||
&lz77, start, end, 0,
|
||||
bp, out, outsize);
|
||||
}
|
||||
|
||||
ZopfliCleanLZ77Store(&lz77);
|
||||
free(splitpoints);
|
||||
free(splitpoints_uncompressed);
|
||||
}
|
||||
|
||||
void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char* bp, unsigned char** out, size_t* outsize) {
|
||||
size_t offset = *outsize;
|
||||
#if ZOPFLI_MASTER_BLOCK_SIZE == 0
|
||||
ZopfliDeflatePart(options, btype, final, in, 0, insize, bp, out, outsize);
|
||||
#else
|
||||
size_t i = 0;
|
||||
do {
|
||||
int masterfinal = (i + ZOPFLI_MASTER_BLOCK_SIZE >= insize);
|
||||
int final2 = final && masterfinal;
|
||||
size_t size = masterfinal ? insize - i : ZOPFLI_MASTER_BLOCK_SIZE;
|
||||
ZopfliDeflatePart(options, btype, final2,
|
||||
in, i, i + size, bp, out, outsize);
|
||||
i += size;
|
||||
} while (i < insize);
|
||||
#endif
|
||||
if (options->verbose) {
|
||||
fprintf(stderr,
|
||||
"Original Size: %lu, Deflate: %lu, Compression: %f%% Removed\n",
|
||||
(unsigned long)insize, (unsigned long)(*outsize - offset),
|
||||
100.0 * (double)(insize - (*outsize - offset)) / (double)insize);
|
||||
}
|
||||
}
|
||||
92
build/node_modules/node-zopfli/zopfli/src/zopfli/deflate.h
generated
vendored
Normal file
92
build/node_modules/node-zopfli/zopfli/src/zopfli/deflate.h
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_DEFLATE_H_
|
||||
#define ZOPFLI_DEFLATE_H_
|
||||
|
||||
/*
|
||||
Functions to compress according to the DEFLATE specification, using the
|
||||
"squeeze" LZ77 compression backend.
|
||||
*/
|
||||
|
||||
#include "lz77.h"
|
||||
#include "zopfli.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Compresses according to the deflate specification and append the compressed
|
||||
result to the output.
|
||||
This function will usually output multiple deflate blocks. If final is 1, then
|
||||
the final bit will be set on the last block.
|
||||
|
||||
options: global program options
|
||||
btype: the deflate block type. Use 2 for best compression.
|
||||
-0: non compressed blocks (00)
|
||||
-1: blocks with fixed tree (01)
|
||||
-2: blocks with dynamic tree (10)
|
||||
final: whether this is the last section of the input, sets the final bit to the
|
||||
last deflate block.
|
||||
in: the input bytes
|
||||
insize: number of input bytes
|
||||
bp: bit pointer for the output array. This must initially be 0, and for
|
||||
consecutive calls must be reused (it can have values from 0-7). This is
|
||||
because deflate appends blocks as bit-based data, rather than on byte
|
||||
boundaries.
|
||||
out: pointer to the dynamic output array to which the result is appended. Must
|
||||
be freed after use.
|
||||
outsize: pointer to the dynamic output array size.
|
||||
*/
|
||||
void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char* bp, unsigned char** out, size_t* outsize);
|
||||
|
||||
/*
|
||||
Like ZopfliDeflate, but allows to specify start and end byte with instart and
|
||||
inend. Only that part is compressed, but earlier bytes are still used for the
|
||||
back window.
|
||||
*/
|
||||
void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
unsigned char* bp, unsigned char** out,
|
||||
size_t* outsize);
|
||||
|
||||
/*
|
||||
Calculates block size in bits.
|
||||
litlens: lz77 lit/lengths
|
||||
dists: ll77 distances
|
||||
lstart: start of block
|
||||
lend: end of block (not inclusive)
|
||||
*/
|
||||
double ZopfliCalculateBlockSize(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend, int btype);
|
||||
|
||||
/*
|
||||
Calculates block size in bits, automatically using the best btype.
|
||||
*/
|
||||
double ZopfliCalculateBlockSizeAutoType(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* ZOPFLI_DEFLATE_H_ */
|
||||
124
build/node_modules/node-zopfli/zopfli/src/zopfli/gzip_container.c
generated
vendored
Normal file
124
build/node_modules/node-zopfli/zopfli/src/zopfli/gzip_container.c
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "gzip_container.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
/* CRC polynomial: 0xedb88320 */
|
||||
static const unsigned long crc32_table[256] = {
|
||||
0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u,
|
||||
3915621685u, 2657392035u, 249268274u, 2044508324u, 3772115230u, 2547177864u,
|
||||
162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u,
|
||||
4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u,
|
||||
325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u,
|
||||
4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u,
|
||||
1006888145u, 1258607687u, 3524101629u, 2768942443u, 901097722u, 1119000684u,
|
||||
3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u,
|
||||
651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u,
|
||||
3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u,
|
||||
795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u,
|
||||
2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u,
|
||||
2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u,
|
||||
2439277719u, 3865271297u, 1802195444u, 476864866u, 2238001368u, 4066508878u,
|
||||
1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u,
|
||||
2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u,
|
||||
1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u,
|
||||
2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u,
|
||||
1141124467u, 855842277u, 2852801631u, 3708648649u, 1342533948u, 654459306u,
|
||||
3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
|
||||
1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u,
|
||||
3082640443u, 3233442989u, 3988292384u, 2596254646u, 62317068u, 1957810842u,
|
||||
3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u,
|
||||
225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u,
|
||||
4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u,
|
||||
426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u,
|
||||
4189708143u, 2394877945u, 397917763u, 1622183637u, 3604390888u, 2714866558u,
|
||||
953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u,
|
||||
3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u,
|
||||
829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u,
|
||||
3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u,
|
||||
733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u,
|
||||
2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u,
|
||||
1913087877u, 83908371u, 2512341634u, 3803740692u, 2075208622u, 213261112u,
|
||||
2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u,
|
||||
1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u,
|
||||
2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u,
|
||||
1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u,
|
||||
2808555105u, 3495958263u, 1231636301u, 1047427035u, 2932959818u, 3654703836u,
|
||||
1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
|
||||
3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u,
|
||||
1423857449u, 601450431u, 3009837614u, 3294710456u, 1567103746u, 711928724u,
|
||||
3020668471u, 3272380065u, 1510334235u, 755167117u
|
||||
};
|
||||
|
||||
/* Returns the CRC32 */
|
||||
static unsigned long CRC(const unsigned char* data, size_t size) {
|
||||
unsigned long result = 0xffffffffu;
|
||||
for (; size > 0; size--) {
|
||||
result = crc32_table[(result ^ *(data++)) & 0xff] ^ (result >> 8);
|
||||
}
|
||||
return result ^ 0xffffffffu;
|
||||
}
|
||||
|
||||
/* Compresses the data according to the gzip specification, RFC 1952. */
|
||||
void ZopfliGzipCompress(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
unsigned long crcvalue = CRC(in, insize);
|
||||
unsigned char bp = 0;
|
||||
|
||||
ZOPFLI_APPEND_DATA(31, out, outsize); /* ID1 */
|
||||
ZOPFLI_APPEND_DATA(139, out, outsize); /* ID2 */
|
||||
ZOPFLI_APPEND_DATA(8, out, outsize); /* CM */
|
||||
ZOPFLI_APPEND_DATA(0, out, outsize); /* FLG */
|
||||
/* MTIME */
|
||||
ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(0, out, outsize);
|
||||
|
||||
ZOPFLI_APPEND_DATA(2, out, outsize); /* XFL, 2 indicates best compression. */
|
||||
ZOPFLI_APPEND_DATA(3, out, outsize); /* OS follows Unix conventions. */
|
||||
|
||||
ZopfliDeflate(options, 2 /* Dynamic block */, 1,
|
||||
in, insize, &bp, out, outsize);
|
||||
|
||||
/* CRC */
|
||||
ZOPFLI_APPEND_DATA(crcvalue % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((crcvalue >> 8) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((crcvalue >> 16) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((crcvalue >> 24) % 256, out, outsize);
|
||||
|
||||
/* ISIZE */
|
||||
ZOPFLI_APPEND_DATA(insize % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((insize >> 8) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((insize >> 16) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((insize >> 24) % 256, out, outsize);
|
||||
|
||||
if (options->verbose) {
|
||||
fprintf(stderr,
|
||||
"Original Size: %d, Gzip: %d, Compression: %f%% Removed\n",
|
||||
(int)insize, (int)*outsize,
|
||||
100.0 * (double)(insize - *outsize) / (double)insize);
|
||||
}
|
||||
}
|
||||
50
build/node_modules/node-zopfli/zopfli/src/zopfli/gzip_container.h
generated
vendored
Normal file
50
build/node_modules/node-zopfli/zopfli/src/zopfli/gzip_container.h
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_GZIP_H_
|
||||
#define ZOPFLI_GZIP_H_
|
||||
|
||||
/*
|
||||
Functions to compress according to the Gzip specification.
|
||||
*/
|
||||
|
||||
#include "zopfli.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Compresses according to the gzip specification and append the compressed
|
||||
result to the output.
|
||||
|
||||
options: global program options
|
||||
out: pointer to the dynamic output array to which the result is appended. Must
|
||||
be freed after use.
|
||||
outsize: pointer to the dynamic output array size.
|
||||
*/
|
||||
void ZopfliGzipCompress(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* ZOPFLI_GZIP_H_ */
|
||||
143
build/node_modules/node-zopfli/zopfli/src/zopfli/hash.c
generated
vendored
Normal file
143
build/node_modules/node-zopfli/zopfli/src/zopfli/hash.c
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HASH_SHIFT 5
|
||||
#define HASH_MASK 32767
|
||||
|
||||
void ZopfliAllocHash(size_t window_size, ZopfliHash* h) {
|
||||
h->head = (int*)malloc(sizeof(*h->head) * 65536);
|
||||
h->prev = (unsigned short*)malloc(sizeof(*h->prev) * window_size);
|
||||
h->hashval = (int*)malloc(sizeof(*h->hashval) * window_size);
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
|
||||
#endif
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
|
||||
h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
|
||||
h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZopfliResetHash(size_t window_size, ZopfliHash* h) {
|
||||
size_t i;
|
||||
|
||||
h->val = 0;
|
||||
for (i = 0; i < 65536; i++) {
|
||||
h->head[i] = -1; /* -1 indicates no head so far. */
|
||||
}
|
||||
for (i = 0; i < window_size; i++) {
|
||||
h->prev[i] = i; /* If prev[j] == j, then prev[j] is uninitialized. */
|
||||
h->hashval[i] = -1;
|
||||
}
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
for (i = 0; i < window_size; i++) {
|
||||
h->same[i] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
h->val2 = 0;
|
||||
for (i = 0; i < 65536; i++) {
|
||||
h->head2[i] = -1;
|
||||
}
|
||||
for (i = 0; i < window_size; i++) {
|
||||
h->prev2[i] = i;
|
||||
h->hashval2[i] = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZopfliCleanHash(ZopfliHash* h) {
|
||||
free(h->head);
|
||||
free(h->prev);
|
||||
free(h->hashval);
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
free(h->head2);
|
||||
free(h->prev2);
|
||||
free(h->hashval2);
|
||||
#endif
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
free(h->same);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Update the sliding hash value with the given byte. All calls to this function
|
||||
must be made on consecutive input characters. Since the hash value exists out
|
||||
of multiple input bytes, a few warmups with this function are needed initially.
|
||||
*/
|
||||
static void UpdateHashValue(ZopfliHash* h, unsigned char c) {
|
||||
h->val = (((h->val) << HASH_SHIFT) ^ (c)) & HASH_MASK;
|
||||
}
|
||||
|
||||
void ZopfliUpdateHash(const unsigned char* array, size_t pos, size_t end,
|
||||
ZopfliHash* h) {
|
||||
unsigned short hpos = pos & ZOPFLI_WINDOW_MASK;
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
size_t amount = 0;
|
||||
#endif
|
||||
|
||||
UpdateHashValue(h, pos + ZOPFLI_MIN_MATCH <= end ?
|
||||
array[pos + ZOPFLI_MIN_MATCH - 1] : 0);
|
||||
h->hashval[hpos] = h->val;
|
||||
if (h->head[h->val] != -1 && h->hashval[h->head[h->val]] == h->val) {
|
||||
h->prev[hpos] = h->head[h->val];
|
||||
}
|
||||
else h->prev[hpos] = hpos;
|
||||
h->head[h->val] = hpos;
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
/* Update "same". */
|
||||
if (h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] > 1) {
|
||||
amount = h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] - 1;
|
||||
}
|
||||
while (pos + amount + 1 < end &&
|
||||
array[pos] == array[pos + amount + 1] && amount < (unsigned short)(-1)) {
|
||||
amount++;
|
||||
}
|
||||
h->same[hpos] = amount;
|
||||
#endif
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
h->val2 = ((h->same[hpos] - ZOPFLI_MIN_MATCH) & 255) ^ h->val;
|
||||
h->hashval2[hpos] = h->val2;
|
||||
if (h->head2[h->val2] != -1 && h->hashval2[h->head2[h->val2]] == h->val2) {
|
||||
h->prev2[hpos] = h->head2[h->val2];
|
||||
}
|
||||
else h->prev2[hpos] = hpos;
|
||||
h->head2[h->val2] = hpos;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZopfliWarmupHash(const unsigned char* array, size_t pos, size_t end,
|
||||
ZopfliHash* h) {
|
||||
UpdateHashValue(h, array[pos + 0]);
|
||||
if (pos + 1 < end) UpdateHashValue(h, array[pos + 1]);
|
||||
}
|
||||
73
build/node_modules/node-zopfli/zopfli/src/zopfli/hash.h
generated
vendored
Normal file
73
build/node_modules/node-zopfli/zopfli/src/zopfli/hash.h
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
The hash for ZopfliFindLongestMatch of lz77.c.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_HASH_H_
|
||||
#define ZOPFLI_HASH_H_
|
||||
|
||||
#include "util.h"
|
||||
|
||||
typedef struct ZopfliHash {
|
||||
int* head; /* Hash value to index of its most recent occurrence. */
|
||||
unsigned short* prev; /* Index to index of prev. occurrence of same hash. */
|
||||
int* hashval; /* Index to hash value at this index. */
|
||||
int val; /* Current hash value. */
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
/* Fields with similar purpose as the above hash, but for the second hash with
|
||||
a value that is calculated differently. */
|
||||
int* head2; /* Hash value to index of its most recent occurrence. */
|
||||
unsigned short* prev2; /* Index to index of prev. occurrence of same hash. */
|
||||
int* hashval2; /* Index to hash value at this index. */
|
||||
int val2; /* Current hash value. */
|
||||
#endif
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
unsigned short* same; /* Amount of repetitions of same byte after this .*/
|
||||
#endif
|
||||
} ZopfliHash;
|
||||
|
||||
/* Allocates ZopfliHash memory. */
|
||||
void ZopfliAllocHash(size_t window_size, ZopfliHash* h);
|
||||
|
||||
/* Resets all fields of ZopfliHash. */
|
||||
void ZopfliResetHash(size_t window_size, ZopfliHash* h);
|
||||
|
||||
/* Frees ZopfliHash memory. */
|
||||
void ZopfliCleanHash(ZopfliHash* h);
|
||||
|
||||
/*
|
||||
Updates the hash values based on the current position in the array. All calls
|
||||
to this must be made for consecutive bytes.
|
||||
*/
|
||||
void ZopfliUpdateHash(const unsigned char* array, size_t pos, size_t end,
|
||||
ZopfliHash* h);
|
||||
|
||||
/*
|
||||
Prepopulates hash:
|
||||
Fills in the initial values in the hash, before ZopfliUpdateHash can be used
|
||||
correctly.
|
||||
*/
|
||||
void ZopfliWarmupHash(const unsigned char* array, size_t pos, size_t end,
|
||||
ZopfliHash* h);
|
||||
|
||||
#endif /* ZOPFLI_HASH_H_ */
|
||||
262
build/node_modules/node-zopfli/zopfli/src/zopfli/katajainen.c
generated
vendored
Executable file
262
build/node_modules/node-zopfli/zopfli/src/zopfli/katajainen.c
generated
vendored
Executable file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Bounded package merge algorithm, based on the paper
|
||||
"A Fast and Space-Economical Algorithm for Length-Limited Coding
|
||||
Jyrki Katajainen, Alistair Moffat, Andrew Turpin".
|
||||
*/
|
||||
|
||||
#include "katajainen.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
typedef struct Node Node;
|
||||
|
||||
/*
|
||||
Nodes forming chains. Also used to represent leaves.
|
||||
*/
|
||||
struct Node {
|
||||
size_t weight; /* Total weight (symbol count) of this chain. */
|
||||
Node* tail; /* Previous node(s) of this chain, or 0 if none. */
|
||||
int count; /* Leaf symbol index, or number of leaves before this chain. */
|
||||
};
|
||||
|
||||
/*
|
||||
Memory pool for nodes.
|
||||
*/
|
||||
typedef struct NodePool {
|
||||
Node* next; /* Pointer to a free node in the pool. */
|
||||
} NodePool;
|
||||
|
||||
/*
|
||||
Initializes a chain node with the given values and marks it as in use.
|
||||
*/
|
||||
static void InitNode(size_t weight, int count, Node* tail, Node* node) {
|
||||
node->weight = weight;
|
||||
node->count = count;
|
||||
node->tail = tail;
|
||||
}
|
||||
|
||||
/*
|
||||
Performs a Boundary Package-Merge step. Puts a new chain in the given list. The
|
||||
new chain is, depending on the weights, a leaf or a combination of two chains
|
||||
from the previous list.
|
||||
lists: The lists of chains.
|
||||
maxbits: Number of lists.
|
||||
leaves: The leaves, one per symbol.
|
||||
numsymbols: Number of leaves.
|
||||
pool: the node memory pool.
|
||||
index: The index of the list in which a new chain or leaf is required.
|
||||
*/
|
||||
static void BoundaryPM(Node* (*lists)[2], Node* leaves, int numsymbols,
|
||||
NodePool* pool, int index) {
|
||||
Node* newchain;
|
||||
Node* oldchain;
|
||||
int lastcount = lists[index][1]->count; /* Count of last chain of list. */
|
||||
|
||||
if (index == 0 && lastcount >= numsymbols) return;
|
||||
|
||||
newchain = pool->next++;
|
||||
oldchain = lists[index][1];
|
||||
|
||||
/* These are set up before the recursive calls below, so that there is a list
|
||||
pointing to the new node, to let the garbage collection know it's in use. */
|
||||
lists[index][0] = oldchain;
|
||||
lists[index][1] = newchain;
|
||||
|
||||
if (index == 0) {
|
||||
/* New leaf node in list 0. */
|
||||
InitNode(leaves[lastcount].weight, lastcount + 1, 0, newchain);
|
||||
} else {
|
||||
size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;
|
||||
if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
|
||||
/* New leaf inserted in list, so count is incremented. */
|
||||
InitNode(leaves[lastcount].weight, lastcount + 1, oldchain->tail,
|
||||
newchain);
|
||||
} else {
|
||||
InitNode(sum, lastcount, lists[index - 1][1], newchain);
|
||||
/* Two lookahead chains of previous list used up, create new ones. */
|
||||
BoundaryPM(lists, leaves, numsymbols, pool, index - 1);
|
||||
BoundaryPM(lists, leaves, numsymbols, pool, index - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void BoundaryPMFinal(Node* (*lists)[2],
|
||||
Node* leaves, int numsymbols, NodePool* pool, int index) {
|
||||
int lastcount = lists[index][1]->count; /* Count of last chain of list. */
|
||||
|
||||
size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;
|
||||
|
||||
if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
|
||||
Node* newchain = pool->next;
|
||||
Node* oldchain = lists[index][1]->tail;
|
||||
|
||||
lists[index][1] = newchain;
|
||||
newchain->count = lastcount + 1;
|
||||
newchain->tail = oldchain;
|
||||
} else {
|
||||
lists[index][1]->tail = lists[index - 1][1];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Initializes each list with as lookahead chains the two leaves with lowest
|
||||
weights.
|
||||
*/
|
||||
static void InitLists(
|
||||
NodePool* pool, const Node* leaves, int maxbits, Node* (*lists)[2]) {
|
||||
int i;
|
||||
Node* node0 = pool->next++;
|
||||
Node* node1 = pool->next++;
|
||||
InitNode(leaves[0].weight, 1, 0, node0);
|
||||
InitNode(leaves[1].weight, 2, 0, node1);
|
||||
for (i = 0; i < maxbits; i++) {
|
||||
lists[i][0] = node0;
|
||||
lists[i][1] = node1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Converts result of boundary package-merge to the bitlengths. The result in the
|
||||
last chain of the last list contains the amount of active leaves in each list.
|
||||
chain: Chain to extract the bit length from (last chain from last list).
|
||||
*/
|
||||
static void ExtractBitLengths(Node* chain, Node* leaves, unsigned* bitlengths) {
|
||||
int counts[16] = {0};
|
||||
unsigned end = 16;
|
||||
unsigned ptr = 15;
|
||||
unsigned value = 1;
|
||||
Node* node;
|
||||
int val;
|
||||
|
||||
for (node = chain; node; node = node->tail) {
|
||||
counts[--end] = node->count;
|
||||
}
|
||||
|
||||
val = counts[15];
|
||||
while (ptr >= end) {
|
||||
for (; val > counts[ptr - 1]; val--) {
|
||||
bitlengths[leaves[val - 1].count] = value;
|
||||
}
|
||||
ptr--;
|
||||
value++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Comparator for sorting the leaves. Has the function signature for qsort.
|
||||
*/
|
||||
static int LeafComparator(const void* a, const void* b) {
|
||||
return ((const Node*)a)->weight - ((const Node*)b)->weight;
|
||||
}
|
||||
|
||||
int ZopfliLengthLimitedCodeLengths(
|
||||
const size_t* frequencies, int n, int maxbits, unsigned* bitlengths) {
|
||||
NodePool pool;
|
||||
int i;
|
||||
int numsymbols = 0; /* Amount of symbols with frequency > 0. */
|
||||
int numBoundaryPMRuns;
|
||||
Node* nodes;
|
||||
|
||||
/* Array of lists of chains. Each list requires only two lookahead chains at
|
||||
a time, so each list is a array of two Node*'s. */
|
||||
Node* (*lists)[2];
|
||||
|
||||
/* One leaf per symbol. Only numsymbols leaves will be used. */
|
||||
Node* leaves = (Node*)malloc(n * sizeof(*leaves));
|
||||
|
||||
/* Initialize all bitlengths at 0. */
|
||||
for (i = 0; i < n; i++) {
|
||||
bitlengths[i] = 0;
|
||||
}
|
||||
|
||||
/* Count used symbols and place them in the leaves. */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frequencies[i]) {
|
||||
leaves[numsymbols].weight = frequencies[i];
|
||||
leaves[numsymbols].count = i; /* Index of symbol this leaf represents. */
|
||||
numsymbols++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check special cases and error conditions. */
|
||||
if ((1 << maxbits) < numsymbols) {
|
||||
free(leaves);
|
||||
return 1; /* Error, too few maxbits to represent symbols. */
|
||||
}
|
||||
if (numsymbols == 0) {
|
||||
free(leaves);
|
||||
return 0; /* No symbols at all. OK. */
|
||||
}
|
||||
if (numsymbols == 1) {
|
||||
bitlengths[leaves[0].count] = 1;
|
||||
free(leaves);
|
||||
return 0; /* Only one symbol, give it bitlength 1, not 0. OK. */
|
||||
}
|
||||
if (numsymbols == 2) {
|
||||
bitlengths[leaves[0].count]++;
|
||||
bitlengths[leaves[1].count]++;
|
||||
free(leaves);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sort the leaves from lightest to heaviest. Add count into the same
|
||||
variable for stable sorting. */
|
||||
for (i = 0; i < numsymbols; i++) {
|
||||
if (leaves[i].weight >=
|
||||
((size_t)1 << (sizeof(leaves[0].weight) * CHAR_BIT - 9))) {
|
||||
free(leaves);
|
||||
return 1; /* Error, we need 9 bits for the count. */
|
||||
}
|
||||
leaves[i].weight = (leaves[i].weight << 9) | leaves[i].count;
|
||||
}
|
||||
qsort(leaves, numsymbols, sizeof(Node), LeafComparator);
|
||||
for (i = 0; i < numsymbols; i++) {
|
||||
leaves[i].weight >>= 9;
|
||||
}
|
||||
|
||||
if (numsymbols - 1 < maxbits) {
|
||||
maxbits = numsymbols - 1;
|
||||
}
|
||||
|
||||
/* Initialize node memory pool. */
|
||||
nodes = (Node*)malloc(maxbits * 2 * numsymbols * sizeof(Node));
|
||||
pool.next = nodes;
|
||||
|
||||
lists = (Node* (*)[2])malloc(maxbits * sizeof(*lists));
|
||||
InitLists(&pool, leaves, maxbits, lists);
|
||||
|
||||
/* In the last list, 2 * numsymbols - 2 active chains need to be created. Two
|
||||
are already created in the initialization. Each BoundaryPM run creates one. */
|
||||
numBoundaryPMRuns = 2 * numsymbols - 4;
|
||||
for (i = 0; i < numBoundaryPMRuns - 1; i++) {
|
||||
BoundaryPM(lists, leaves, numsymbols, &pool, maxbits - 1);
|
||||
}
|
||||
BoundaryPMFinal(lists, leaves, numsymbols, &pool, maxbits - 1);
|
||||
|
||||
ExtractBitLengths(lists[maxbits - 1][1], leaves, bitlengths);
|
||||
|
||||
free(lists);
|
||||
free(leaves);
|
||||
free(nodes);
|
||||
return 0; /* OK. */
|
||||
}
|
||||
42
build/node_modules/node-zopfli/zopfli/src/zopfli/katajainen.h
generated
vendored
Normal file
42
build/node_modules/node-zopfli/zopfli/src/zopfli/katajainen.h
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_KATAJAINEN_H_
|
||||
#define ZOPFLI_KATAJAINEN_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
Outputs minimum-redundancy length-limited code bitlengths for symbols with the
|
||||
given counts. The bitlengths are limited by maxbits.
|
||||
|
||||
The output is tailored for DEFLATE: symbols that never occur, get a bit length
|
||||
of 0, and if only a single symbol occurs at least once, its bitlength will be 1,
|
||||
and not 0 as would theoretically be needed for a single symbol.
|
||||
|
||||
frequencies: The amount of occurrences of each symbol.
|
||||
n: The amount of symbols.
|
||||
maxbits: Maximum bit length, inclusive.
|
||||
bitlengths: Output, the bitlengths for the symbol prefix codes.
|
||||
return: 0 for OK, non-0 for error.
|
||||
*/
|
||||
int ZopfliLengthLimitedCodeLengths(
|
||||
const size_t* frequencies, int n, int maxbits, unsigned* bitlengths);
|
||||
|
||||
#endif /* ZOPFLI_KATAJAINEN_H_ */
|
||||
630
build/node_modules/node-zopfli/zopfli/src/zopfli/lz77.c
generated
vendored
Normal file
630
build/node_modules/node-zopfli/zopfli/src/zopfli/lz77.c
generated
vendored
Normal file
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "lz77.h"
|
||||
#include "symbols.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void ZopfliInitLZ77Store(const unsigned char* data, ZopfliLZ77Store* store) {
|
||||
store->size = 0;
|
||||
store->litlens = 0;
|
||||
store->dists = 0;
|
||||
store->pos = 0;
|
||||
store->data = data;
|
||||
store->ll_symbol = 0;
|
||||
store->d_symbol = 0;
|
||||
store->ll_counts = 0;
|
||||
store->d_counts = 0;
|
||||
}
|
||||
|
||||
void ZopfliCleanLZ77Store(ZopfliLZ77Store* store) {
|
||||
free(store->litlens);
|
||||
free(store->dists);
|
||||
free(store->pos);
|
||||
free(store->ll_symbol);
|
||||
free(store->d_symbol);
|
||||
free(store->ll_counts);
|
||||
free(store->d_counts);
|
||||
}
|
||||
|
||||
static size_t CeilDiv(size_t a, size_t b) {
|
||||
return (a + b - 1) / b;
|
||||
}
|
||||
|
||||
void ZopfliCopyLZ77Store(
|
||||
const ZopfliLZ77Store* source, ZopfliLZ77Store* dest) {
|
||||
size_t i;
|
||||
size_t llsize = ZOPFLI_NUM_LL * CeilDiv(source->size, ZOPFLI_NUM_LL);
|
||||
size_t dsize = ZOPFLI_NUM_D * CeilDiv(source->size, ZOPFLI_NUM_D);
|
||||
ZopfliCleanLZ77Store(dest);
|
||||
ZopfliInitLZ77Store(source->data, dest);
|
||||
dest->litlens =
|
||||
(unsigned short*)malloc(sizeof(*dest->litlens) * source->size);
|
||||
dest->dists = (unsigned short*)malloc(sizeof(*dest->dists) * source->size);
|
||||
dest->pos = (size_t*)malloc(sizeof(*dest->pos) * source->size);
|
||||
dest->ll_symbol =
|
||||
(unsigned short*)malloc(sizeof(*dest->ll_symbol) * source->size);
|
||||
dest->d_symbol =
|
||||
(unsigned short*)malloc(sizeof(*dest->d_symbol) * source->size);
|
||||
dest->ll_counts = (size_t*)malloc(sizeof(*dest->ll_counts) * llsize);
|
||||
dest->d_counts = (size_t*)malloc(sizeof(*dest->d_counts) * dsize);
|
||||
|
||||
/* Allocation failed. */
|
||||
if (!dest->litlens || !dest->dists) exit(-1);
|
||||
if (!dest->pos) exit(-1);
|
||||
if (!dest->ll_symbol || !dest->d_symbol) exit(-1);
|
||||
if (!dest->ll_counts || !dest->d_counts) exit(-1);
|
||||
|
||||
dest->size = source->size;
|
||||
for (i = 0; i < source->size; i++) {
|
||||
dest->litlens[i] = source->litlens[i];
|
||||
dest->dists[i] = source->dists[i];
|
||||
dest->pos[i] = source->pos[i];
|
||||
dest->ll_symbol[i] = source->ll_symbol[i];
|
||||
dest->d_symbol[i] = source->d_symbol[i];
|
||||
}
|
||||
for (i = 0; i < llsize; i++) {
|
||||
dest->ll_counts[i] = source->ll_counts[i];
|
||||
}
|
||||
for (i = 0; i < dsize; i++) {
|
||||
dest->d_counts[i] = source->d_counts[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Appends the length and distance to the LZ77 arrays of the ZopfliLZ77Store.
|
||||
context must be a ZopfliLZ77Store*.
|
||||
*/
|
||||
void ZopfliStoreLitLenDist(unsigned short length, unsigned short dist,
|
||||
size_t pos, ZopfliLZ77Store* store) {
|
||||
size_t i;
|
||||
/* Needed for using ZOPFLI_APPEND_DATA multiple times. */
|
||||
size_t origsize = store->size;
|
||||
size_t llstart = ZOPFLI_NUM_LL * (origsize / ZOPFLI_NUM_LL);
|
||||
size_t dstart = ZOPFLI_NUM_D * (origsize / ZOPFLI_NUM_D);
|
||||
|
||||
/* Everytime the index wraps around, a new cumulative histogram is made: we're
|
||||
keeping one histogram value per LZ77 symbol rather than a full histogram for
|
||||
each to save memory. */
|
||||
if (origsize % ZOPFLI_NUM_LL == 0) {
|
||||
size_t llsize = origsize;
|
||||
for (i = 0; i < ZOPFLI_NUM_LL; i++) {
|
||||
ZOPFLI_APPEND_DATA(
|
||||
origsize == 0 ? 0 : store->ll_counts[origsize - ZOPFLI_NUM_LL + i],
|
||||
&store->ll_counts, &llsize);
|
||||
}
|
||||
}
|
||||
if (origsize % ZOPFLI_NUM_D == 0) {
|
||||
size_t dsize = origsize;
|
||||
for (i = 0; i < ZOPFLI_NUM_D; i++) {
|
||||
ZOPFLI_APPEND_DATA(
|
||||
origsize == 0 ? 0 : store->d_counts[origsize - ZOPFLI_NUM_D + i],
|
||||
&store->d_counts, &dsize);
|
||||
}
|
||||
}
|
||||
|
||||
ZOPFLI_APPEND_DATA(length, &store->litlens, &store->size);
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(dist, &store->dists, &store->size);
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(pos, &store->pos, &store->size);
|
||||
assert(length < 259);
|
||||
|
||||
if (dist == 0) {
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(length, &store->ll_symbol, &store->size);
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(0, &store->d_symbol, &store->size);
|
||||
store->ll_counts[llstart + length]++;
|
||||
} else {
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(ZopfliGetLengthSymbol(length),
|
||||
&store->ll_symbol, &store->size);
|
||||
store->size = origsize;
|
||||
ZOPFLI_APPEND_DATA(ZopfliGetDistSymbol(dist),
|
||||
&store->d_symbol, &store->size);
|
||||
store->ll_counts[llstart + ZopfliGetLengthSymbol(length)]++;
|
||||
store->d_counts[dstart + ZopfliGetDistSymbol(dist)]++;
|
||||
}
|
||||
}
|
||||
|
||||
void ZopfliAppendLZ77Store(const ZopfliLZ77Store* store,
|
||||
ZopfliLZ77Store* target) {
|
||||
size_t i;
|
||||
for (i = 0; i < store->size; i++) {
|
||||
ZopfliStoreLitLenDist(store->litlens[i], store->dists[i],
|
||||
store->pos[i], target);
|
||||
}
|
||||
}
|
||||
|
||||
size_t ZopfliLZ77GetByteRange(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend) {
|
||||
size_t l = lend - 1;
|
||||
if (lstart == lend) return 0;
|
||||
return lz77->pos[l] + ((lz77->dists[l] == 0) ?
|
||||
1 : lz77->litlens[l]) - lz77->pos[lstart];
|
||||
}
|
||||
|
||||
static void ZopfliLZ77GetHistogramAt(const ZopfliLZ77Store* lz77, size_t lpos,
|
||||
size_t* ll_counts, size_t* d_counts) {
|
||||
/* The real histogram is created by using the histogram for this chunk, but
|
||||
all superfluous values of this chunk subtracted. */
|
||||
size_t llpos = ZOPFLI_NUM_LL * (lpos / ZOPFLI_NUM_LL);
|
||||
size_t dpos = ZOPFLI_NUM_D * (lpos / ZOPFLI_NUM_D);
|
||||
size_t i;
|
||||
for (i = 0; i < ZOPFLI_NUM_LL; i++) {
|
||||
ll_counts[i] = lz77->ll_counts[llpos + i];
|
||||
}
|
||||
for (i = lpos + 1; i < llpos + ZOPFLI_NUM_LL && i < lz77->size; i++) {
|
||||
ll_counts[lz77->ll_symbol[i]]--;
|
||||
}
|
||||
for (i = 0; i < ZOPFLI_NUM_D; i++) {
|
||||
d_counts[i] = lz77->d_counts[dpos + i];
|
||||
}
|
||||
for (i = lpos + 1; i < dpos + ZOPFLI_NUM_D && i < lz77->size; i++) {
|
||||
if (lz77->dists[i] != 0) d_counts[lz77->d_symbol[i]]--;
|
||||
}
|
||||
}
|
||||
|
||||
void ZopfliLZ77GetHistogram(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
size_t* ll_counts, size_t* d_counts) {
|
||||
size_t i;
|
||||
if (lstart + ZOPFLI_NUM_LL * 3 > lend) {
|
||||
memset(ll_counts, 0, sizeof(*ll_counts) * ZOPFLI_NUM_LL);
|
||||
memset(d_counts, 0, sizeof(*d_counts) * ZOPFLI_NUM_D);
|
||||
for (i = lstart; i < lend; i++) {
|
||||
ll_counts[lz77->ll_symbol[i]]++;
|
||||
if (lz77->dists[i] != 0) d_counts[lz77->d_symbol[i]]++;
|
||||
}
|
||||
} else {
|
||||
/* Subtract the cumulative histograms at the end and the start to get the
|
||||
histogram for this range. */
|
||||
ZopfliLZ77GetHistogramAt(lz77, lend - 1, ll_counts, d_counts);
|
||||
if (lstart > 0) {
|
||||
size_t ll_counts2[ZOPFLI_NUM_LL];
|
||||
size_t d_counts2[ZOPFLI_NUM_D];
|
||||
ZopfliLZ77GetHistogramAt(lz77, lstart - 1, ll_counts2, d_counts2);
|
||||
|
||||
for (i = 0; i < ZOPFLI_NUM_LL; i++) {
|
||||
ll_counts[i] -= ll_counts2[i];
|
||||
}
|
||||
for (i = 0; i < ZOPFLI_NUM_D; i++) {
|
||||
d_counts[i] -= d_counts2[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZopfliInitBlockState(const ZopfliOptions* options,
|
||||
size_t blockstart, size_t blockend, int add_lmc,
|
||||
ZopfliBlockState* s) {
|
||||
s->options = options;
|
||||
s->blockstart = blockstart;
|
||||
s->blockend = blockend;
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
if (add_lmc) {
|
||||
s->lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
|
||||
ZopfliInitCache(blockend - blockstart, s->lmc);
|
||||
} else {
|
||||
s->lmc = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ZopfliCleanBlockState(ZopfliBlockState* s) {
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
if (s->lmc) {
|
||||
ZopfliCleanCache(s->lmc);
|
||||
free(s->lmc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Gets a score of the length given the distance. Typically, the score of the
|
||||
length is the length itself, but if the distance is very long, decrease the
|
||||
score of the length a bit to make up for the fact that long distances use large
|
||||
amounts of extra bits.
|
||||
|
||||
This is not an accurate score, it is a heuristic only for the greedy LZ77
|
||||
implementation. More accurate cost models are employed later. Making this
|
||||
heuristic more accurate may hurt rather than improve compression.
|
||||
|
||||
The two direct uses of this heuristic are:
|
||||
-avoid using a length of 3 in combination with a long distance. This only has
|
||||
an effect if length == 3.
|
||||
-make a slightly better choice between the two options of the lazy matching.
|
||||
|
||||
Indirectly, this affects:
|
||||
-the block split points if the default of block splitting first is used, in a
|
||||
rather unpredictable way
|
||||
-the first zopfli run, so it affects the chance of the first run being closer
|
||||
to the optimal output
|
||||
*/
|
||||
static int GetLengthScore(int length, int distance) {
|
||||
/*
|
||||
At 1024, the distance uses 9+ extra bits and this seems to be the sweet spot
|
||||
on tested files.
|
||||
*/
|
||||
return distance > 1024 ? length - 1 : length;
|
||||
}
|
||||
|
||||
void ZopfliVerifyLenDist(const unsigned char* data, size_t datasize, size_t pos,
|
||||
unsigned short dist, unsigned short length) {
|
||||
|
||||
/* TODO(lode): make this only run in a debug compile, it's for assert only. */
|
||||
size_t i;
|
||||
|
||||
assert(pos + length <= datasize);
|
||||
for (i = 0; i < length; i++) {
|
||||
if (data[pos - dist + i] != data[pos + i]) {
|
||||
assert(data[pos - dist + i] == data[pos + i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Finds how long the match of scan and match is. Can be used to find how many
|
||||
bytes starting from scan, and from match, are equal. Returns the last byte
|
||||
after scan, which is still equal to the correspondinb byte after match.
|
||||
scan is the position to compare
|
||||
match is the earlier position to compare.
|
||||
end is the last possible byte, beyond which to stop looking.
|
||||
safe_end is a few (8) bytes before end, for comparing multiple bytes at once.
|
||||
*/
|
||||
static const unsigned char* GetMatch(const unsigned char* scan,
|
||||
const unsigned char* match,
|
||||
const unsigned char* end,
|
||||
const unsigned char* safe_end) {
|
||||
|
||||
if (sizeof(size_t) == 8) {
|
||||
/* 8 checks at once per array bounds check (size_t is 64-bit). */
|
||||
while (scan < safe_end && *((size_t*)scan) == *((size_t*)match)) {
|
||||
scan += 8;
|
||||
match += 8;
|
||||
}
|
||||
} else if (sizeof(unsigned int) == 4) {
|
||||
/* 4 checks at once per array bounds check (unsigned int is 32-bit). */
|
||||
while (scan < safe_end
|
||||
&& *((unsigned int*)scan) == *((unsigned int*)match)) {
|
||||
scan += 4;
|
||||
match += 4;
|
||||
}
|
||||
} else {
|
||||
/* do 8 checks at once per array bounds check. */
|
||||
while (scan < safe_end && *scan == *match && *++scan == *++match
|
||||
&& *++scan == *++match && *++scan == *++match
|
||||
&& *++scan == *++match && *++scan == *++match
|
||||
&& *++scan == *++match && *++scan == *++match) {
|
||||
scan++; match++;
|
||||
}
|
||||
}
|
||||
|
||||
/* The remaining few bytes. */
|
||||
while (scan != end && *scan == *match) {
|
||||
scan++; match++;
|
||||
}
|
||||
|
||||
return scan;
|
||||
}
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
/*
|
||||
Gets distance, length and sublen values from the cache if possible.
|
||||
Returns 1 if it got the values from the cache, 0 if not.
|
||||
Updates the limit value to a smaller one if possible with more limited
|
||||
information from the cache.
|
||||
*/
|
||||
static int TryGetFromLongestMatchCache(ZopfliBlockState* s,
|
||||
size_t pos, size_t* limit,
|
||||
unsigned short* sublen, unsigned short* distance, unsigned short* length) {
|
||||
/* The LMC cache starts at the beginning of the block rather than the
|
||||
beginning of the whole array. */
|
||||
size_t lmcpos = pos - s->blockstart;
|
||||
|
||||
/* Length > 0 and dist 0 is invalid combination, which indicates on purpose
|
||||
that this cache value is not filled in yet. */
|
||||
unsigned char cache_available = s->lmc && (s->lmc->length[lmcpos] == 0 ||
|
||||
s->lmc->dist[lmcpos] != 0);
|
||||
unsigned char limit_ok_for_cache = cache_available &&
|
||||
(*limit == ZOPFLI_MAX_MATCH || s->lmc->length[lmcpos] <= *limit ||
|
||||
(sublen && ZopfliMaxCachedSublen(s->lmc,
|
||||
lmcpos, s->lmc->length[lmcpos]) >= *limit));
|
||||
|
||||
if (s->lmc && limit_ok_for_cache && cache_available) {
|
||||
if (!sublen || s->lmc->length[lmcpos]
|
||||
<= ZopfliMaxCachedSublen(s->lmc, lmcpos, s->lmc->length[lmcpos])) {
|
||||
*length = s->lmc->length[lmcpos];
|
||||
if (*length > *limit) *length = *limit;
|
||||
if (sublen) {
|
||||
ZopfliCacheToSublen(s->lmc, lmcpos, *length, sublen);
|
||||
*distance = sublen[*length];
|
||||
if (*limit == ZOPFLI_MAX_MATCH && *length >= ZOPFLI_MIN_MATCH) {
|
||||
assert(sublen[*length] == s->lmc->dist[lmcpos]);
|
||||
}
|
||||
} else {
|
||||
*distance = s->lmc->dist[lmcpos];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Can't use much of the cache, since the "sublens" need to be calculated,
|
||||
but at least we already know when to stop. */
|
||||
*limit = s->lmc->length[lmcpos];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Stores the found sublen, distance and length in the longest match cache, if
|
||||
possible.
|
||||
*/
|
||||
static void StoreInLongestMatchCache(ZopfliBlockState* s,
|
||||
size_t pos, size_t limit,
|
||||
const unsigned short* sublen,
|
||||
unsigned short distance, unsigned short length) {
|
||||
/* The LMC cache starts at the beginning of the block rather than the
|
||||
beginning of the whole array. */
|
||||
size_t lmcpos = pos - s->blockstart;
|
||||
|
||||
/* Length > 0 and dist 0 is invalid combination, which indicates on purpose
|
||||
that this cache value is not filled in yet. */
|
||||
unsigned char cache_available = s->lmc && (s->lmc->length[lmcpos] == 0 ||
|
||||
s->lmc->dist[lmcpos] != 0);
|
||||
|
||||
if (s->lmc && limit == ZOPFLI_MAX_MATCH && sublen && !cache_available) {
|
||||
assert(s->lmc->length[lmcpos] == 1 && s->lmc->dist[lmcpos] == 0);
|
||||
s->lmc->dist[lmcpos] = length < ZOPFLI_MIN_MATCH ? 0 : distance;
|
||||
s->lmc->length[lmcpos] = length < ZOPFLI_MIN_MATCH ? 0 : length;
|
||||
assert(!(s->lmc->length[lmcpos] == 1 && s->lmc->dist[lmcpos] == 0));
|
||||
ZopfliSublenToCache(sublen, lmcpos, length, s->lmc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h,
|
||||
const unsigned char* array,
|
||||
size_t pos, size_t size, size_t limit,
|
||||
unsigned short* sublen, unsigned short* distance, unsigned short* length) {
|
||||
unsigned short hpos = pos & ZOPFLI_WINDOW_MASK, p, pp;
|
||||
unsigned short bestdist = 0;
|
||||
unsigned short bestlength = 1;
|
||||
const unsigned char* scan;
|
||||
const unsigned char* match;
|
||||
const unsigned char* arrayend;
|
||||
const unsigned char* arrayend_safe;
|
||||
#if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE
|
||||
int chain_counter = ZOPFLI_MAX_CHAIN_HITS; /* For quitting early. */
|
||||
#endif
|
||||
|
||||
unsigned dist = 0; /* Not unsigned short on purpose. */
|
||||
|
||||
int* hhead = h->head;
|
||||
unsigned short* hprev = h->prev;
|
||||
int* hhashval = h->hashval;
|
||||
int hval = h->val;
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
if (TryGetFromLongestMatchCache(s, pos, &limit, sublen, distance, length)) {
|
||||
assert(pos + *length <= size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(limit <= ZOPFLI_MAX_MATCH);
|
||||
assert(limit >= ZOPFLI_MIN_MATCH);
|
||||
assert(pos < size);
|
||||
|
||||
if (size - pos < ZOPFLI_MIN_MATCH) {
|
||||
/* The rest of the code assumes there are at least ZOPFLI_MIN_MATCH bytes to
|
||||
try. */
|
||||
*length = 0;
|
||||
*distance = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pos + limit > size) {
|
||||
limit = size - pos;
|
||||
}
|
||||
arrayend = &array[pos] + limit;
|
||||
arrayend_safe = arrayend - 8;
|
||||
|
||||
assert(hval < 65536);
|
||||
|
||||
pp = hhead[hval]; /* During the whole loop, p == hprev[pp]. */
|
||||
p = hprev[pp];
|
||||
|
||||
assert(pp == hpos);
|
||||
|
||||
dist = p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp);
|
||||
|
||||
/* Go through all distances. */
|
||||
while (dist < ZOPFLI_WINDOW_SIZE) {
|
||||
unsigned short currentlength = 0;
|
||||
|
||||
assert(p < ZOPFLI_WINDOW_SIZE);
|
||||
assert(p == hprev[pp]);
|
||||
assert(hhashval[p] == hval);
|
||||
|
||||
if (dist > 0) {
|
||||
assert(pos < size);
|
||||
assert(dist <= pos);
|
||||
scan = &array[pos];
|
||||
match = &array[pos - dist];
|
||||
|
||||
/* Testing the byte at position bestlength first, goes slightly faster. */
|
||||
if (pos + bestlength >= size
|
||||
|| *(scan + bestlength) == *(match + bestlength)) {
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME
|
||||
unsigned short same0 = h->same[pos & ZOPFLI_WINDOW_MASK];
|
||||
if (same0 > 2 && *scan == *match) {
|
||||
unsigned short same1 = h->same[(pos - dist) & ZOPFLI_WINDOW_MASK];
|
||||
unsigned short same = same0 < same1 ? same0 : same1;
|
||||
if (same > limit) same = limit;
|
||||
scan += same;
|
||||
match += same;
|
||||
}
|
||||
#endif
|
||||
scan = GetMatch(scan, match, arrayend, arrayend_safe);
|
||||
currentlength = scan - &array[pos]; /* The found length. */
|
||||
}
|
||||
|
||||
if (currentlength > bestlength) {
|
||||
if (sublen) {
|
||||
unsigned short j;
|
||||
for (j = bestlength + 1; j <= currentlength; j++) {
|
||||
sublen[j] = dist;
|
||||
}
|
||||
}
|
||||
bestdist = dist;
|
||||
bestlength = currentlength;
|
||||
if (currentlength >= limit) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZOPFLI_HASH_SAME_HASH
|
||||
/* Switch to the other hash once this will be more efficient. */
|
||||
if (hhead != h->head2 && bestlength >= h->same[hpos] &&
|
||||
h->val2 == h->hashval2[p]) {
|
||||
/* Now use the hash that encodes the length and first byte. */
|
||||
hhead = h->head2;
|
||||
hprev = h->prev2;
|
||||
hhashval = h->hashval2;
|
||||
hval = h->val2;
|
||||
}
|
||||
#endif
|
||||
|
||||
pp = p;
|
||||
p = hprev[p];
|
||||
if (p == pp) break; /* Uninited prev value. */
|
||||
|
||||
dist += p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp);
|
||||
|
||||
#if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE
|
||||
chain_counter--;
|
||||
if (chain_counter <= 0) break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
StoreInLongestMatchCache(s, pos, limit, sublen, bestdist, bestlength);
|
||||
#endif
|
||||
|
||||
assert(bestlength <= limit);
|
||||
|
||||
*distance = bestdist;
|
||||
*length = bestlength;
|
||||
assert(pos + *length <= size);
|
||||
}
|
||||
|
||||
void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
ZopfliLZ77Store* store, ZopfliHash* h) {
|
||||
size_t i = 0, j;
|
||||
unsigned short leng;
|
||||
unsigned short dist;
|
||||
int lengthscore;
|
||||
size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
|
||||
? instart - ZOPFLI_WINDOW_SIZE : 0;
|
||||
unsigned short dummysublen[259];
|
||||
|
||||
#ifdef ZOPFLI_LAZY_MATCHING
|
||||
/* Lazy matching. */
|
||||
unsigned prev_length = 0;
|
||||
unsigned prev_match = 0;
|
||||
int prevlengthscore;
|
||||
int match_available = 0;
|
||||
#endif
|
||||
|
||||
if (instart == inend) return;
|
||||
|
||||
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
ZopfliWarmupHash(in, windowstart, inend, h);
|
||||
for (i = windowstart; i < instart; i++) {
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
|
||||
for (i = instart; i < inend; i++) {
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
|
||||
ZopfliFindLongestMatch(s, h, in, i, inend, ZOPFLI_MAX_MATCH, dummysublen,
|
||||
&dist, &leng);
|
||||
lengthscore = GetLengthScore(leng, dist);
|
||||
|
||||
#ifdef ZOPFLI_LAZY_MATCHING
|
||||
/* Lazy matching. */
|
||||
prevlengthscore = GetLengthScore(prev_length, prev_match);
|
||||
if (match_available) {
|
||||
match_available = 0;
|
||||
if (lengthscore > prevlengthscore + 1) {
|
||||
ZopfliStoreLitLenDist(in[i - 1], 0, i - 1, store);
|
||||
if (lengthscore >= ZOPFLI_MIN_MATCH && leng < ZOPFLI_MAX_MATCH) {
|
||||
match_available = 1;
|
||||
prev_length = leng;
|
||||
prev_match = dist;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* Add previous to output. */
|
||||
leng = prev_length;
|
||||
dist = prev_match;
|
||||
lengthscore = prevlengthscore;
|
||||
/* Add to output. */
|
||||
ZopfliVerifyLenDist(in, inend, i - 1, dist, leng);
|
||||
ZopfliStoreLitLenDist(leng, dist, i - 1, store);
|
||||
for (j = 2; j < leng; j++) {
|
||||
assert(i < inend);
|
||||
i++;
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (lengthscore >= ZOPFLI_MIN_MATCH && leng < ZOPFLI_MAX_MATCH) {
|
||||
match_available = 1;
|
||||
prev_length = leng;
|
||||
prev_match = dist;
|
||||
continue;
|
||||
}
|
||||
/* End of lazy matching. */
|
||||
#endif
|
||||
|
||||
/* Add to output. */
|
||||
if (lengthscore >= ZOPFLI_MIN_MATCH) {
|
||||
ZopfliVerifyLenDist(in, inend, i, dist, leng);
|
||||
ZopfliStoreLitLenDist(leng, dist, i, store);
|
||||
} else {
|
||||
leng = 1;
|
||||
ZopfliStoreLitLenDist(in[i], 0, i, store);
|
||||
}
|
||||
for (j = 1; j < leng; j++) {
|
||||
assert(i < inend);
|
||||
i++;
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
142
build/node_modules/node-zopfli/zopfli/src/zopfli/lz77.h
generated
vendored
Normal file
142
build/node_modules/node-zopfli/zopfli/src/zopfli/lz77.h
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions for basic LZ77 compression and utilities for the "squeeze" LZ77
|
||||
compression.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_LZ77_H_
|
||||
#define ZOPFLI_LZ77_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cache.h"
|
||||
#include "hash.h"
|
||||
#include "zopfli.h"
|
||||
|
||||
/*
|
||||
Stores lit/length and dist pairs for LZ77.
|
||||
Parameter litlens: Contains the literal symbols or length values.
|
||||
Parameter dists: Contains the distances. A value is 0 to indicate that there is
|
||||
no dist and the corresponding litlens value is a literal instead of a length.
|
||||
Parameter size: The size of both the litlens and dists arrays.
|
||||
The memory can best be managed by using ZopfliInitLZ77Store to initialize it,
|
||||
ZopfliCleanLZ77Store to destroy it, and ZopfliStoreLitLenDist to append values.
|
||||
|
||||
*/
|
||||
typedef struct ZopfliLZ77Store {
|
||||
unsigned short* litlens; /* Lit or len. */
|
||||
unsigned short* dists; /* If 0: indicates literal in corresponding litlens,
|
||||
if > 0: length in corresponding litlens, this is the distance. */
|
||||
size_t size;
|
||||
|
||||
const unsigned char* data; /* original data */
|
||||
size_t* pos; /* position in data where this LZ77 command begins */
|
||||
|
||||
unsigned short* ll_symbol;
|
||||
unsigned short* d_symbol;
|
||||
|
||||
/* Cumulative histograms wrapping around per chunk. Each chunk has the amount
|
||||
of distinct symbols as length, so using 1 value per LZ77 symbol, we have a
|
||||
precise histogram at every N symbols, and the rest can be calculated by
|
||||
looping through the actual symbols of this chunk. */
|
||||
size_t* ll_counts;
|
||||
size_t* d_counts;
|
||||
} ZopfliLZ77Store;
|
||||
|
||||
void ZopfliInitLZ77Store(const unsigned char* data, ZopfliLZ77Store* store);
|
||||
void ZopfliCleanLZ77Store(ZopfliLZ77Store* store);
|
||||
void ZopfliCopyLZ77Store(const ZopfliLZ77Store* source, ZopfliLZ77Store* dest);
|
||||
void ZopfliStoreLitLenDist(unsigned short length, unsigned short dist,
|
||||
size_t pos, ZopfliLZ77Store* store);
|
||||
void ZopfliAppendLZ77Store(const ZopfliLZ77Store* store,
|
||||
ZopfliLZ77Store* target);
|
||||
/* Gets the amount of raw bytes that this range of LZ77 symbols spans. */
|
||||
size_t ZopfliLZ77GetByteRange(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend);
|
||||
/* Gets the histogram of lit/len and dist symbols in the given range, using the
|
||||
cumulative histograms, so faster than adding one by one for large range. Does
|
||||
not add the one end symbol of value 256. */
|
||||
void ZopfliLZ77GetHistogram(const ZopfliLZ77Store* lz77,
|
||||
size_t lstart, size_t lend,
|
||||
size_t* ll_counts, size_t* d_counts);
|
||||
|
||||
/*
|
||||
Some state information for compressing a block.
|
||||
This is currently a bit under-used (with mainly only the longest match cache),
|
||||
but is kept for easy future expansion.
|
||||
*/
|
||||
typedef struct ZopfliBlockState {
|
||||
const ZopfliOptions* options;
|
||||
|
||||
#ifdef ZOPFLI_LONGEST_MATCH_CACHE
|
||||
/* Cache for length/distance pairs found so far. */
|
||||
ZopfliLongestMatchCache* lmc;
|
||||
#endif
|
||||
|
||||
/* The start (inclusive) and end (not inclusive) of the current block. */
|
||||
size_t blockstart;
|
||||
size_t blockend;
|
||||
} ZopfliBlockState;
|
||||
|
||||
void ZopfliInitBlockState(const ZopfliOptions* options,
|
||||
size_t blockstart, size_t blockend, int add_lmc,
|
||||
ZopfliBlockState* s);
|
||||
void ZopfliCleanBlockState(ZopfliBlockState* s);
|
||||
|
||||
/*
|
||||
Finds the longest match (length and corresponding distance) for LZ77
|
||||
compression.
|
||||
Even when not using "sublen", it can be more efficient to provide an array,
|
||||
because only then the caching is used.
|
||||
array: the data
|
||||
pos: position in the data to find the match for
|
||||
size: size of the data
|
||||
limit: limit length to maximum this value (default should be 258). This allows
|
||||
finding a shorter dist for that length (= less extra bits). Must be
|
||||
in the range [ZOPFLI_MIN_MATCH, ZOPFLI_MAX_MATCH].
|
||||
sublen: output array of 259 elements, or null. Has, for each length, the
|
||||
smallest distance required to reach this length. Only 256 of its 259 values
|
||||
are used, the first 3 are ignored (the shortest length is 3. It is purely
|
||||
for convenience that the array is made 3 longer).
|
||||
*/
|
||||
void ZopfliFindLongestMatch(
|
||||
ZopfliBlockState *s, const ZopfliHash* h, const unsigned char* array,
|
||||
size_t pos, size_t size, size_t limit,
|
||||
unsigned short* sublen, unsigned short* distance, unsigned short* length);
|
||||
|
||||
/*
|
||||
Verifies if length and dist are indeed valid, only used for assertion.
|
||||
*/
|
||||
void ZopfliVerifyLenDist(const unsigned char* data, size_t datasize, size_t pos,
|
||||
unsigned short dist, unsigned short length);
|
||||
|
||||
/*
|
||||
Does LZ77 using an algorithm similar to gzip, with lazy matching, rather than
|
||||
with the slow but better "squeeze" implementation.
|
||||
The result is placed in the ZopfliLZ77Store.
|
||||
If instart is larger than 0, it uses values before instart as starting
|
||||
dictionary.
|
||||
*/
|
||||
void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
ZopfliLZ77Store* store, ZopfliHash* h);
|
||||
|
||||
#endif /* ZOPFLI_LZ77_H_ */
|
||||
560
build/node_modules/node-zopfli/zopfli/src/zopfli/squeeze.c
generated
vendored
Normal file
560
build/node_modules/node-zopfli/zopfli/src/zopfli/squeeze.c
generated
vendored
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "squeeze.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blocksplitter.h"
|
||||
#include "deflate.h"
|
||||
#include "symbols.h"
|
||||
#include "tree.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct SymbolStats {
|
||||
/* The literal and length symbols. */
|
||||
size_t litlens[ZOPFLI_NUM_LL];
|
||||
/* The 32 unique dist symbols, not the 32768 possible dists. */
|
||||
size_t dists[ZOPFLI_NUM_D];
|
||||
|
||||
/* Length of each lit/len symbol in bits. */
|
||||
double ll_symbols[ZOPFLI_NUM_LL];
|
||||
/* Length of each dist symbol in bits. */
|
||||
double d_symbols[ZOPFLI_NUM_D];
|
||||
} SymbolStats;
|
||||
|
||||
/* Sets everything to 0. */
|
||||
static void InitStats(SymbolStats* stats) {
|
||||
memset(stats->litlens, 0, ZOPFLI_NUM_LL * sizeof(stats->litlens[0]));
|
||||
memset(stats->dists, 0, ZOPFLI_NUM_D * sizeof(stats->dists[0]));
|
||||
|
||||
memset(stats->ll_symbols, 0, ZOPFLI_NUM_LL * sizeof(stats->ll_symbols[0]));
|
||||
memset(stats->d_symbols, 0, ZOPFLI_NUM_D * sizeof(stats->d_symbols[0]));
|
||||
}
|
||||
|
||||
static void CopyStats(SymbolStats* source, SymbolStats* dest) {
|
||||
memcpy(dest->litlens, source->litlens,
|
||||
ZOPFLI_NUM_LL * sizeof(dest->litlens[0]));
|
||||
memcpy(dest->dists, source->dists, ZOPFLI_NUM_D * sizeof(dest->dists[0]));
|
||||
|
||||
memcpy(dest->ll_symbols, source->ll_symbols,
|
||||
ZOPFLI_NUM_LL * sizeof(dest->ll_symbols[0]));
|
||||
memcpy(dest->d_symbols, source->d_symbols,
|
||||
ZOPFLI_NUM_D * sizeof(dest->d_symbols[0]));
|
||||
}
|
||||
|
||||
/* Adds the bit lengths. */
|
||||
static void AddWeighedStatFreqs(const SymbolStats* stats1, double w1,
|
||||
const SymbolStats* stats2, double w2,
|
||||
SymbolStats* result) {
|
||||
size_t i;
|
||||
for (i = 0; i < ZOPFLI_NUM_LL; i++) {
|
||||
result->litlens[i] =
|
||||
(size_t) (stats1->litlens[i] * w1 + stats2->litlens[i] * w2);
|
||||
}
|
||||
for (i = 0; i < ZOPFLI_NUM_D; i++) {
|
||||
result->dists[i] =
|
||||
(size_t) (stats1->dists[i] * w1 + stats2->dists[i] * w2);
|
||||
}
|
||||
result->litlens[256] = 1; /* End symbol. */
|
||||
}
|
||||
|
||||
typedef struct RanState {
|
||||
unsigned int m_w, m_z;
|
||||
} RanState;
|
||||
|
||||
static void InitRanState(RanState* state) {
|
||||
state->m_w = 1;
|
||||
state->m_z = 2;
|
||||
}
|
||||
|
||||
/* Get random number: "Multiply-With-Carry" generator of G. Marsaglia */
|
||||
static unsigned int Ran(RanState* state) {
|
||||
state->m_z = 36969 * (state->m_z & 65535) + (state->m_z >> 16);
|
||||
state->m_w = 18000 * (state->m_w & 65535) + (state->m_w >> 16);
|
||||
return (state->m_z << 16) + state->m_w; /* 32-bit result. */
|
||||
}
|
||||
|
||||
static void RandomizeFreqs(RanState* state, size_t* freqs, int n) {
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((Ran(state) >> 4) % 3 == 0) freqs[i] = freqs[Ran(state) % n];
|
||||
}
|
||||
}
|
||||
|
||||
static void RandomizeStatFreqs(RanState* state, SymbolStats* stats) {
|
||||
RandomizeFreqs(state, stats->litlens, ZOPFLI_NUM_LL);
|
||||
RandomizeFreqs(state, stats->dists, ZOPFLI_NUM_D);
|
||||
stats->litlens[256] = 1; /* End symbol. */
|
||||
}
|
||||
|
||||
static void ClearStatFreqs(SymbolStats* stats) {
|
||||
size_t i;
|
||||
for (i = 0; i < ZOPFLI_NUM_LL; i++) stats->litlens[i] = 0;
|
||||
for (i = 0; i < ZOPFLI_NUM_D; i++) stats->dists[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Function that calculates a cost based on a model for the given LZ77 symbol.
|
||||
litlen: means literal symbol if dist is 0, length otherwise.
|
||||
*/
|
||||
typedef double CostModelFun(unsigned litlen, unsigned dist, void* context);
|
||||
|
||||
/*
|
||||
Cost model which should exactly match fixed tree.
|
||||
type: CostModelFun
|
||||
*/
|
||||
static double GetCostFixed(unsigned litlen, unsigned dist, void* unused) {
|
||||
(void)unused;
|
||||
if (dist == 0) {
|
||||
if (litlen <= 143) return 8;
|
||||
else return 9;
|
||||
} else {
|
||||
int dbits = ZopfliGetDistExtraBits(dist);
|
||||
int lbits = ZopfliGetLengthExtraBits(litlen);
|
||||
int lsym = ZopfliGetLengthSymbol(litlen);
|
||||
int cost = 0;
|
||||
if (lsym <= 279) cost += 7;
|
||||
else cost += 8;
|
||||
cost += 5; /* Every dist symbol has length 5. */
|
||||
return cost + dbits + lbits;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Cost model based on symbol statistics.
|
||||
type: CostModelFun
|
||||
*/
|
||||
static double GetCostStat(unsigned litlen, unsigned dist, void* context) {
|
||||
SymbolStats* stats = (SymbolStats*)context;
|
||||
if (dist == 0) {
|
||||
return stats->ll_symbols[litlen];
|
||||
} else {
|
||||
int lsym = ZopfliGetLengthSymbol(litlen);
|
||||
int lbits = ZopfliGetLengthExtraBits(litlen);
|
||||
int dsym = ZopfliGetDistSymbol(dist);
|
||||
int dbits = ZopfliGetDistExtraBits(dist);
|
||||
return lbits + dbits + stats->ll_symbols[lsym] + stats->d_symbols[dsym];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Finds the minimum possible cost this cost model can return for valid length and
|
||||
distance symbols.
|
||||
*/
|
||||
static double GetCostModelMinCost(CostModelFun* costmodel, void* costcontext) {
|
||||
double mincost;
|
||||
int bestlength = 0; /* length that has lowest cost in the cost model */
|
||||
int bestdist = 0; /* distance that has lowest cost in the cost model */
|
||||
int i;
|
||||
/*
|
||||
Table of distances that have a different distance symbol in the deflate
|
||||
specification. Each value is the first distance that has a new symbol. Only
|
||||
different symbols affect the cost model so only these need to be checked.
|
||||
See RFC 1951 section 3.2.5. Compressed blocks (length and distance codes).
|
||||
*/
|
||||
static const int dsymbols[30] = {
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
|
||||
769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
|
||||
};
|
||||
|
||||
mincost = ZOPFLI_LARGE_FLOAT;
|
||||
for (i = 3; i < 259; i++) {
|
||||
double c = costmodel(i, 1, costcontext);
|
||||
if (c < mincost) {
|
||||
bestlength = i;
|
||||
mincost = c;
|
||||
}
|
||||
}
|
||||
|
||||
mincost = ZOPFLI_LARGE_FLOAT;
|
||||
for (i = 0; i < 30; i++) {
|
||||
double c = costmodel(3, dsymbols[i], costcontext);
|
||||
if (c < mincost) {
|
||||
bestdist = dsymbols[i];
|
||||
mincost = c;
|
||||
}
|
||||
}
|
||||
|
||||
return costmodel(bestlength, bestdist, costcontext);
|
||||
}
|
||||
|
||||
static size_t zopfli_min(size_t a, size_t b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/*
|
||||
Performs the forward pass for "squeeze". Gets the most optimal length to reach
|
||||
every byte from a previous byte, using cost calculations.
|
||||
s: the ZopfliBlockState
|
||||
in: the input data array
|
||||
instart: where to start
|
||||
inend: where to stop (not inclusive)
|
||||
costmodel: function to calculate the cost of some lit/len/dist pair.
|
||||
costcontext: abstract context for the costmodel function
|
||||
length_array: output array of size (inend - instart) which will receive the best
|
||||
length to reach this byte from a previous byte.
|
||||
returns the cost that was, according to the costmodel, needed to get to the end.
|
||||
*/
|
||||
static double GetBestLengths(ZopfliBlockState *s,
|
||||
const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
CostModelFun* costmodel, void* costcontext,
|
||||
unsigned short* length_array,
|
||||
ZopfliHash* h, float* costs) {
|
||||
/* Best cost to get here so far. */
|
||||
size_t blocksize = inend - instart;
|
||||
size_t i = 0, k, kend;
|
||||
unsigned short leng;
|
||||
unsigned short dist;
|
||||
unsigned short sublen[259];
|
||||
size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
|
||||
? instart - ZOPFLI_WINDOW_SIZE : 0;
|
||||
double result;
|
||||
double mincost = GetCostModelMinCost(costmodel, costcontext);
|
||||
double mincostaddcostj;
|
||||
|
||||
if (instart == inend) return 0;
|
||||
|
||||
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
ZopfliWarmupHash(in, windowstart, inend, h);
|
||||
for (i = windowstart; i < instart; i++) {
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
|
||||
for (i = 1; i < blocksize + 1; i++) costs[i] = ZOPFLI_LARGE_FLOAT;
|
||||
costs[0] = 0; /* Because it's the start. */
|
||||
length_array[0] = 0;
|
||||
|
||||
for (i = instart; i < inend; i++) {
|
||||
size_t j = i - instart; /* Index in the costs array and length_array. */
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
|
||||
#ifdef ZOPFLI_SHORTCUT_LONG_REPETITIONS
|
||||
/* If we're in a long repetition of the same character and have more than
|
||||
ZOPFLI_MAX_MATCH characters before and after our position. */
|
||||
if (h->same[i & ZOPFLI_WINDOW_MASK] > ZOPFLI_MAX_MATCH * 2
|
||||
&& i > instart + ZOPFLI_MAX_MATCH + 1
|
||||
&& i + ZOPFLI_MAX_MATCH * 2 + 1 < inend
|
||||
&& h->same[(i - ZOPFLI_MAX_MATCH) & ZOPFLI_WINDOW_MASK]
|
||||
> ZOPFLI_MAX_MATCH) {
|
||||
double symbolcost = costmodel(ZOPFLI_MAX_MATCH, 1, costcontext);
|
||||
/* Set the length to reach each one to ZOPFLI_MAX_MATCH, and the cost to
|
||||
the cost corresponding to that length. Doing this, we skip
|
||||
ZOPFLI_MAX_MATCH values to avoid calling ZopfliFindLongestMatch. */
|
||||
for (k = 0; k < ZOPFLI_MAX_MATCH; k++) {
|
||||
costs[j + ZOPFLI_MAX_MATCH] = costs[j] + symbolcost;
|
||||
length_array[j + ZOPFLI_MAX_MATCH] = ZOPFLI_MAX_MATCH;
|
||||
i++;
|
||||
j++;
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ZopfliFindLongestMatch(s, h, in, i, inend, ZOPFLI_MAX_MATCH, sublen,
|
||||
&dist, &leng);
|
||||
|
||||
/* Literal. */
|
||||
if (i + 1 <= inend) {
|
||||
double newCost = costmodel(in[i], 0, costcontext) + costs[j];
|
||||
assert(newCost >= 0);
|
||||
if (newCost < costs[j + 1]) {
|
||||
costs[j + 1] = newCost;
|
||||
length_array[j + 1] = 1;
|
||||
}
|
||||
}
|
||||
/* Lengths. */
|
||||
kend = zopfli_min(leng, inend-i);
|
||||
mincostaddcostj = mincost + costs[j];
|
||||
for (k = 3; k <= kend; k++) {
|
||||
double newCost;
|
||||
|
||||
/* Calling the cost model is expensive, avoid this if we are already at
|
||||
the minimum possible cost that it can return. */
|
||||
if (costs[j + k] <= mincostaddcostj) continue;
|
||||
|
||||
newCost = costmodel(k, sublen[k], costcontext) + costs[j];
|
||||
assert(newCost >= 0);
|
||||
if (newCost < costs[j + k]) {
|
||||
assert(k <= ZOPFLI_MAX_MATCH);
|
||||
costs[j + k] = newCost;
|
||||
length_array[j + k] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(costs[blocksize] >= 0);
|
||||
result = costs[blocksize];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates the optimal path of lz77 lengths to use, from the calculated
|
||||
length_array. The length_array must contain the optimal length to reach that
|
||||
byte. The path will be filled with the lengths to use, so its data size will be
|
||||
the amount of lz77 symbols.
|
||||
*/
|
||||
static void TraceBackwards(size_t size, const unsigned short* length_array,
|
||||
unsigned short** path, size_t* pathsize) {
|
||||
size_t index = size;
|
||||
if (size == 0) return;
|
||||
for (;;) {
|
||||
ZOPFLI_APPEND_DATA(length_array[index], path, pathsize);
|
||||
assert(length_array[index] <= index);
|
||||
assert(length_array[index] <= ZOPFLI_MAX_MATCH);
|
||||
assert(length_array[index] != 0);
|
||||
index -= length_array[index];
|
||||
if (index == 0) break;
|
||||
}
|
||||
|
||||
/* Mirror result. */
|
||||
for (index = 0; index < *pathsize / 2; index++) {
|
||||
unsigned short temp = (*path)[index];
|
||||
(*path)[index] = (*path)[*pathsize - index - 1];
|
||||
(*path)[*pathsize - index - 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static void FollowPath(ZopfliBlockState* s,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
unsigned short* path, size_t pathsize,
|
||||
ZopfliLZ77Store* store, ZopfliHash *h) {
|
||||
size_t i, j, pos = 0;
|
||||
size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
|
||||
? instart - ZOPFLI_WINDOW_SIZE : 0;
|
||||
|
||||
size_t total_length_test = 0;
|
||||
|
||||
if (instart == inend) return;
|
||||
|
||||
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
ZopfliWarmupHash(in, windowstart, inend, h);
|
||||
for (i = windowstart; i < instart; i++) {
|
||||
ZopfliUpdateHash(in, i, inend, h);
|
||||
}
|
||||
|
||||
pos = instart;
|
||||
for (i = 0; i < pathsize; i++) {
|
||||
unsigned short length = path[i];
|
||||
unsigned short dummy_length;
|
||||
unsigned short dist;
|
||||
assert(pos < inend);
|
||||
|
||||
ZopfliUpdateHash(in, pos, inend, h);
|
||||
|
||||
/* Add to output. */
|
||||
if (length >= ZOPFLI_MIN_MATCH) {
|
||||
/* Get the distance by recalculating longest match. The found length
|
||||
should match the length from the path. */
|
||||
ZopfliFindLongestMatch(s, h, in, pos, inend, length, 0,
|
||||
&dist, &dummy_length);
|
||||
assert(!(dummy_length != length && length > 2 && dummy_length > 2));
|
||||
ZopfliVerifyLenDist(in, inend, pos, dist, length);
|
||||
ZopfliStoreLitLenDist(length, dist, pos, store);
|
||||
total_length_test += length;
|
||||
} else {
|
||||
length = 1;
|
||||
ZopfliStoreLitLenDist(in[pos], 0, pos, store);
|
||||
total_length_test++;
|
||||
}
|
||||
|
||||
|
||||
assert(pos + length <= inend);
|
||||
for (j = 1; j < length; j++) {
|
||||
ZopfliUpdateHash(in, pos + j, inend, h);
|
||||
}
|
||||
|
||||
pos += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates the entropy of the statistics */
|
||||
static void CalculateStatistics(SymbolStats* stats) {
|
||||
ZopfliCalculateEntropy(stats->litlens, ZOPFLI_NUM_LL, stats->ll_symbols);
|
||||
ZopfliCalculateEntropy(stats->dists, ZOPFLI_NUM_D, stats->d_symbols);
|
||||
}
|
||||
|
||||
/* Appends the symbol statistics from the store. */
|
||||
static void GetStatistics(const ZopfliLZ77Store* store, SymbolStats* stats) {
|
||||
size_t i;
|
||||
for (i = 0; i < store->size; i++) {
|
||||
if (store->dists[i] == 0) {
|
||||
stats->litlens[store->litlens[i]]++;
|
||||
} else {
|
||||
stats->litlens[ZopfliGetLengthSymbol(store->litlens[i])]++;
|
||||
stats->dists[ZopfliGetDistSymbol(store->dists[i])]++;
|
||||
}
|
||||
}
|
||||
stats->litlens[256] = 1; /* End symbol. */
|
||||
|
||||
CalculateStatistics(stats);
|
||||
}
|
||||
|
||||
/*
|
||||
Does a single run for ZopfliLZ77Optimal. For good compression, repeated runs
|
||||
with updated statistics should be performed.
|
||||
s: the block state
|
||||
in: the input data array
|
||||
instart: where to start
|
||||
inend: where to stop (not inclusive)
|
||||
path: pointer to dynamically allocated memory to store the path
|
||||
pathsize: pointer to the size of the dynamic path array
|
||||
length_array: array of size (inend - instart) used to store lengths
|
||||
costmodel: function to use as the cost model for this squeeze run
|
||||
costcontext: abstract context for the costmodel function
|
||||
store: place to output the LZ77 data
|
||||
returns the cost that was, according to the costmodel, needed to get to the end.
|
||||
This is not the actual cost.
|
||||
*/
|
||||
static double LZ77OptimalRun(ZopfliBlockState* s,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
unsigned short** path, size_t* pathsize,
|
||||
unsigned short* length_array, CostModelFun* costmodel,
|
||||
void* costcontext, ZopfliLZ77Store* store,
|
||||
ZopfliHash* h, float* costs) {
|
||||
double cost = GetBestLengths(s, in, instart, inend, costmodel,
|
||||
costcontext, length_array, h, costs);
|
||||
free(*path);
|
||||
*path = 0;
|
||||
*pathsize = 0;
|
||||
TraceBackwards(inend - instart, length_array, path, pathsize);
|
||||
FollowPath(s, in, instart, inend, *path, *pathsize, store, h);
|
||||
assert(cost < ZOPFLI_LARGE_FLOAT);
|
||||
return cost;
|
||||
}
|
||||
|
||||
void ZopfliLZ77Optimal(ZopfliBlockState *s,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
int numiterations,
|
||||
ZopfliLZ77Store* store) {
|
||||
/* Dist to get to here with smallest cost. */
|
||||
size_t blocksize = inend - instart;
|
||||
unsigned short* length_array =
|
||||
(unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
|
||||
unsigned short* path = 0;
|
||||
size_t pathsize = 0;
|
||||
ZopfliLZ77Store currentstore;
|
||||
ZopfliHash hash;
|
||||
ZopfliHash* h = &hash;
|
||||
SymbolStats stats, beststats, laststats;
|
||||
int i;
|
||||
float* costs = (float*)malloc(sizeof(float) * (blocksize + 1));
|
||||
double cost;
|
||||
double bestcost = ZOPFLI_LARGE_FLOAT;
|
||||
double lastcost = 0;
|
||||
/* Try randomizing the costs a bit once the size stabilizes. */
|
||||
RanState ran_state;
|
||||
int lastrandomstep = -1;
|
||||
|
||||
if (!costs) exit(-1); /* Allocation failed. */
|
||||
if (!length_array) exit(-1); /* Allocation failed. */
|
||||
|
||||
InitRanState(&ran_state);
|
||||
InitStats(&stats);
|
||||
ZopfliInitLZ77Store(in, ¤tstore);
|
||||
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
|
||||
/* Do regular deflate, then loop multiple shortest path runs, each time using
|
||||
the statistics of the previous run. */
|
||||
|
||||
/* Initial run. */
|
||||
ZopfliLZ77Greedy(s, in, instart, inend, ¤tstore, h);
|
||||
GetStatistics(¤tstore, &stats);
|
||||
|
||||
/* Repeat statistics with each time the cost model from the previous stat
|
||||
run. */
|
||||
for (i = 0; i < numiterations; i++) {
|
||||
ZopfliCleanLZ77Store(¤tstore);
|
||||
ZopfliInitLZ77Store(in, ¤tstore);
|
||||
LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
|
||||
length_array, GetCostStat, (void*)&stats,
|
||||
¤tstore, h, costs);
|
||||
cost = ZopfliCalculateBlockSize(¤tstore, 0, currentstore.size, 2);
|
||||
if (s->options->verbose_more || (s->options->verbose && cost < bestcost)) {
|
||||
fprintf(stderr, "Iteration %d: %d bit\n", i, (int) cost);
|
||||
}
|
||||
if (cost < bestcost) {
|
||||
/* Copy to the output store. */
|
||||
ZopfliCopyLZ77Store(¤tstore, store);
|
||||
CopyStats(&stats, &beststats);
|
||||
bestcost = cost;
|
||||
}
|
||||
CopyStats(&stats, &laststats);
|
||||
ClearStatFreqs(&stats);
|
||||
GetStatistics(¤tstore, &stats);
|
||||
if (lastrandomstep != -1) {
|
||||
/* This makes it converge slower but better. Do it only once the
|
||||
randomness kicks in so that if the user does few iterations, it gives a
|
||||
better result sooner. */
|
||||
AddWeighedStatFreqs(&stats, 1.0, &laststats, 0.5, &stats);
|
||||
CalculateStatistics(&stats);
|
||||
}
|
||||
if (i > 5 && cost == lastcost) {
|
||||
CopyStats(&beststats, &stats);
|
||||
RandomizeStatFreqs(&ran_state, &stats);
|
||||
CalculateStatistics(&stats);
|
||||
lastrandomstep = i;
|
||||
}
|
||||
lastcost = cost;
|
||||
}
|
||||
|
||||
free(length_array);
|
||||
free(path);
|
||||
free(costs);
|
||||
ZopfliCleanLZ77Store(¤tstore);
|
||||
ZopfliCleanHash(h);
|
||||
}
|
||||
|
||||
void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
|
||||
const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
ZopfliLZ77Store* store)
|
||||
{
|
||||
/* Dist to get to here with smallest cost. */
|
||||
size_t blocksize = inend - instart;
|
||||
unsigned short* length_array =
|
||||
(unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
|
||||
unsigned short* path = 0;
|
||||
size_t pathsize = 0;
|
||||
ZopfliHash hash;
|
||||
ZopfliHash* h = &hash;
|
||||
float* costs = (float*)malloc(sizeof(float) * (blocksize + 1));
|
||||
|
||||
if (!costs) exit(-1); /* Allocation failed. */
|
||||
if (!length_array) exit(-1); /* Allocation failed. */
|
||||
|
||||
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);
|
||||
|
||||
s->blockstart = instart;
|
||||
s->blockend = inend;
|
||||
|
||||
/* Shortest path for fixed tree This one should give the shortest possible
|
||||
result for fixed tree, no repeated runs are needed since the tree is known. */
|
||||
LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
|
||||
length_array, GetCostFixed, 0, store, h, costs);
|
||||
|
||||
free(length_array);
|
||||
free(path);
|
||||
free(costs);
|
||||
ZopfliCleanHash(h);
|
||||
}
|
||||
61
build/node_modules/node-zopfli/zopfli/src/zopfli/squeeze.h
generated
vendored
Normal file
61
build/node_modules/node-zopfli/zopfli/src/zopfli/squeeze.h
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
The squeeze functions do enhanced LZ77 compression by optimal parsing with a
|
||||
cost model, rather than greedily choosing the longest length or using a single
|
||||
step of lazy matching like regular implementations.
|
||||
|
||||
Since the cost model is based on the Huffman tree that can only be calculated
|
||||
after the LZ77 data is generated, there is a chicken and egg problem, and
|
||||
multiple runs are done with updated cost models to converge to a better
|
||||
solution.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_SQUEEZE_H_
|
||||
#define ZOPFLI_SQUEEZE_H_
|
||||
|
||||
#include "lz77.h"
|
||||
|
||||
/*
|
||||
Calculates lit/len and dist pairs for given data.
|
||||
If instart is larger than 0, it uses values before instart as starting
|
||||
dictionary.
|
||||
*/
|
||||
void ZopfliLZ77Optimal(ZopfliBlockState *s,
|
||||
const unsigned char* in, size_t instart, size_t inend,
|
||||
int numiterations,
|
||||
ZopfliLZ77Store* store);
|
||||
|
||||
/*
|
||||
Does the same as ZopfliLZ77Optimal, but optimized for the fixed tree of the
|
||||
deflate standard.
|
||||
The fixed tree never gives the best compression. But this gives the best
|
||||
possible LZ77 encoding possible with the fixed tree.
|
||||
This does not create or output any fixed tree, only LZ77 data optimized for
|
||||
using with a fixed tree.
|
||||
If instart is larger than 0, it uses values before instart as starting
|
||||
dictionary.
|
||||
*/
|
||||
void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
|
||||
const unsigned char* in,
|
||||
size_t instart, size_t inend,
|
||||
ZopfliLZ77Store* store);
|
||||
|
||||
#endif /* ZOPFLI_SQUEEZE_H_ */
|
||||
239
build/node_modules/node-zopfli/zopfli/src/zopfli/symbols.h
generated
vendored
Normal file
239
build/node_modules/node-zopfli/zopfli/src/zopfli/symbols.h
generated
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Utilities for using the lz77 symbols of the deflate spec.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_SYMBOLS_H_
|
||||
#define ZOPFLI_SYMBOLS_H_
|
||||
|
||||
/* __has_builtin available in clang */
|
||||
#ifdef __has_builtin
|
||||
# if __has_builtin(__builtin_clz)
|
||||
# define ZOPFLI_HAS_BUILTIN_CLZ
|
||||
# endif
|
||||
/* __builtin_clz available beginning with GCC 3.4 */
|
||||
#elif __GNUC__ * 100 + __GNUC_MINOR__ >= 304
|
||||
# define ZOPFLI_HAS_BUILTIN_CLZ
|
||||
#endif
|
||||
|
||||
/* Gets the amount of extra bits for the given dist, cfr. the DEFLATE spec. */
|
||||
static int ZopfliGetDistExtraBits(int dist) {
|
||||
#ifdef ZOPFLI_HAS_BUILTIN_CLZ
|
||||
if (dist < 5) return 0;
|
||||
return (31 ^ __builtin_clz(dist - 1)) - 1; /* log2(dist - 1) - 1 */
|
||||
#else
|
||||
if (dist < 5) return 0;
|
||||
else if (dist < 9) return 1;
|
||||
else if (dist < 17) return 2;
|
||||
else if (dist < 33) return 3;
|
||||
else if (dist < 65) return 4;
|
||||
else if (dist < 129) return 5;
|
||||
else if (dist < 257) return 6;
|
||||
else if (dist < 513) return 7;
|
||||
else if (dist < 1025) return 8;
|
||||
else if (dist < 2049) return 9;
|
||||
else if (dist < 4097) return 10;
|
||||
else if (dist < 8193) return 11;
|
||||
else if (dist < 16385) return 12;
|
||||
else return 13;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Gets value of the extra bits for the given dist, cfr. the DEFLATE spec. */
|
||||
static int ZopfliGetDistExtraBitsValue(int dist) {
|
||||
#ifdef ZOPFLI_HAS_BUILTIN_CLZ
|
||||
if (dist < 5) {
|
||||
return 0;
|
||||
} else {
|
||||
int l = 31 ^ __builtin_clz(dist - 1); /* log2(dist - 1) */
|
||||
return (dist - (1 + (1 << l))) & ((1 << (l - 1)) - 1);
|
||||
}
|
||||
#else
|
||||
if (dist < 5) return 0;
|
||||
else if (dist < 9) return (dist - 5) & 1;
|
||||
else if (dist < 17) return (dist - 9) & 3;
|
||||
else if (dist < 33) return (dist - 17) & 7;
|
||||
else if (dist < 65) return (dist - 33) & 15;
|
||||
else if (dist < 129) return (dist - 65) & 31;
|
||||
else if (dist < 257) return (dist - 129) & 63;
|
||||
else if (dist < 513) return (dist - 257) & 127;
|
||||
else if (dist < 1025) return (dist - 513) & 255;
|
||||
else if (dist < 2049) return (dist - 1025) & 511;
|
||||
else if (dist < 4097) return (dist - 2049) & 1023;
|
||||
else if (dist < 8193) return (dist - 4097) & 2047;
|
||||
else if (dist < 16385) return (dist - 8193) & 4095;
|
||||
else return (dist - 16385) & 8191;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Gets the symbol for the given dist, cfr. the DEFLATE spec. */
|
||||
static int ZopfliGetDistSymbol(int dist) {
|
||||
#ifdef ZOPFLI_HAS_BUILTIN_CLZ
|
||||
if (dist < 5) {
|
||||
return dist - 1;
|
||||
} else {
|
||||
int l = (31 ^ __builtin_clz(dist - 1)); /* log2(dist - 1) */
|
||||
int r = ((dist - 1) >> (l - 1)) & 1;
|
||||
return l * 2 + r;
|
||||
}
|
||||
#else
|
||||
if (dist < 193) {
|
||||
if (dist < 13) { /* dist 0..13. */
|
||||
if (dist < 5) return dist - 1;
|
||||
else if (dist < 7) return 4;
|
||||
else if (dist < 9) return 5;
|
||||
else return 6;
|
||||
} else { /* dist 13..193. */
|
||||
if (dist < 17) return 7;
|
||||
else if (dist < 25) return 8;
|
||||
else if (dist < 33) return 9;
|
||||
else if (dist < 49) return 10;
|
||||
else if (dist < 65) return 11;
|
||||
else if (dist < 97) return 12;
|
||||
else if (dist < 129) return 13;
|
||||
else return 14;
|
||||
}
|
||||
} else {
|
||||
if (dist < 2049) { /* dist 193..2049. */
|
||||
if (dist < 257) return 15;
|
||||
else if (dist < 385) return 16;
|
||||
else if (dist < 513) return 17;
|
||||
else if (dist < 769) return 18;
|
||||
else if (dist < 1025) return 19;
|
||||
else if (dist < 1537) return 20;
|
||||
else return 21;
|
||||
} else { /* dist 2049..32768. */
|
||||
if (dist < 3073) return 22;
|
||||
else if (dist < 4097) return 23;
|
||||
else if (dist < 6145) return 24;
|
||||
else if (dist < 8193) return 25;
|
||||
else if (dist < 12289) return 26;
|
||||
else if (dist < 16385) return 27;
|
||||
else if (dist < 24577) return 28;
|
||||
else return 29;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Gets the amount of extra bits for the given length, cfr. the DEFLATE spec. */
|
||||
static int ZopfliGetLengthExtraBits(int l) {
|
||||
static const int table[259] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
|
||||
};
|
||||
return table[l];
|
||||
}
|
||||
|
||||
/* Gets value of the extra bits for the given length, cfr. the DEFLATE spec. */
|
||||
static int ZopfliGetLengthExtraBitsValue(int l) {
|
||||
static const int table[259] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 0,
|
||||
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,
|
||||
6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2,
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
||||
27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0
|
||||
};
|
||||
return table[l];
|
||||
}
|
||||
|
||||
/*
|
||||
Gets the symbol for the given length, cfr. the DEFLATE spec.
|
||||
Returns the symbol in the range [257-285] (inclusive)
|
||||
*/
|
||||
static int ZopfliGetLengthSymbol(int l) {
|
||||
static const int table[259] = {
|
||||
0, 0, 0, 257, 258, 259, 260, 261, 262, 263, 264,
|
||||
265, 265, 266, 266, 267, 267, 268, 268,
|
||||
269, 269, 269, 269, 270, 270, 270, 270,
|
||||
271, 271, 271, 271, 272, 272, 272, 272,
|
||||
273, 273, 273, 273, 273, 273, 273, 273,
|
||||
274, 274, 274, 274, 274, 274, 274, 274,
|
||||
275, 275, 275, 275, 275, 275, 275, 275,
|
||||
276, 276, 276, 276, 276, 276, 276, 276,
|
||||
277, 277, 277, 277, 277, 277, 277, 277,
|
||||
277, 277, 277, 277, 277, 277, 277, 277,
|
||||
278, 278, 278, 278, 278, 278, 278, 278,
|
||||
278, 278, 278, 278, 278, 278, 278, 278,
|
||||
279, 279, 279, 279, 279, 279, 279, 279,
|
||||
279, 279, 279, 279, 279, 279, 279, 279,
|
||||
280, 280, 280, 280, 280, 280, 280, 280,
|
||||
280, 280, 280, 280, 280, 280, 280, 280,
|
||||
281, 281, 281, 281, 281, 281, 281, 281,
|
||||
281, 281, 281, 281, 281, 281, 281, 281,
|
||||
281, 281, 281, 281, 281, 281, 281, 281,
|
||||
281, 281, 281, 281, 281, 281, 281, 281,
|
||||
282, 282, 282, 282, 282, 282, 282, 282,
|
||||
282, 282, 282, 282, 282, 282, 282, 282,
|
||||
282, 282, 282, 282, 282, 282, 282, 282,
|
||||
282, 282, 282, 282, 282, 282, 282, 282,
|
||||
283, 283, 283, 283, 283, 283, 283, 283,
|
||||
283, 283, 283, 283, 283, 283, 283, 283,
|
||||
283, 283, 283, 283, 283, 283, 283, 283,
|
||||
283, 283, 283, 283, 283, 283, 283, 283,
|
||||
284, 284, 284, 284, 284, 284, 284, 284,
|
||||
284, 284, 284, 284, 284, 284, 284, 284,
|
||||
284, 284, 284, 284, 284, 284, 284, 284,
|
||||
284, 284, 284, 284, 284, 284, 284, 285
|
||||
};
|
||||
return table[l];
|
||||
}
|
||||
|
||||
/* Gets the amount of extra bits for the given length symbol. */
|
||||
static int ZopfliGetLengthSymbolExtraBits(int s) {
|
||||
static const int table[29] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
|
||||
};
|
||||
return table[s - 257];
|
||||
}
|
||||
|
||||
/* Gets the amount of extra bits for the given distance symbol. */
|
||||
static int ZopfliGetDistSymbolExtraBits(int s) {
|
||||
static const int table[30] = {
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||
9, 9, 10, 10, 11, 11, 12, 12, 13, 13
|
||||
};
|
||||
return table[s];
|
||||
}
|
||||
|
||||
#endif /* ZOPFLI_SYMBOLS_H_ */
|
||||
101
build/node_modules/node-zopfli/zopfli/src/zopfli/tree.c
generated
vendored
Normal file
101
build/node_modules/node-zopfli/zopfli/src/zopfli/tree.c
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "katajainen.h"
|
||||
#include "util.h"
|
||||
|
||||
void ZopfliLengthsToSymbols(const unsigned* lengths, size_t n, unsigned maxbits,
|
||||
unsigned* symbols) {
|
||||
size_t* bl_count = (size_t*)malloc(sizeof(size_t) * (maxbits + 1));
|
||||
size_t* next_code = (size_t*)malloc(sizeof(size_t) * (maxbits + 1));
|
||||
unsigned bits, i;
|
||||
unsigned code;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
symbols[i] = 0;
|
||||
}
|
||||
|
||||
/* 1) Count the number of codes for each code length. Let bl_count[N] be the
|
||||
number of codes of length N, N >= 1. */
|
||||
for (bits = 0; bits <= maxbits; bits++) {
|
||||
bl_count[bits] = 0;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
assert(lengths[i] <= maxbits);
|
||||
bl_count[lengths[i]]++;
|
||||
}
|
||||
/* 2) Find the numerical value of the smallest code for each code length. */
|
||||
code = 0;
|
||||
bl_count[0] = 0;
|
||||
for (bits = 1; bits <= maxbits; bits++) {
|
||||
code = (code + bl_count[bits-1]) << 1;
|
||||
next_code[bits] = code;
|
||||
}
|
||||
/* 3) Assign numerical values to all codes, using consecutive values for all
|
||||
codes of the same length with the base values determined at step 2. */
|
||||
for (i = 0; i < n; i++) {
|
||||
unsigned len = lengths[i];
|
||||
if (len != 0) {
|
||||
symbols[i] = next_code[len];
|
||||
next_code[len]++;
|
||||
}
|
||||
}
|
||||
|
||||
free(bl_count);
|
||||
free(next_code);
|
||||
}
|
||||
|
||||
void ZopfliCalculateEntropy(const size_t* count, size_t n, double* bitlengths) {
|
||||
static const double kInvLog2 = 1.4426950408889; /* 1.0 / log(2.0) */
|
||||
unsigned sum = 0;
|
||||
unsigned i;
|
||||
double log2sum;
|
||||
for (i = 0; i < n; ++i) {
|
||||
sum += count[i];
|
||||
}
|
||||
log2sum = (sum == 0 ? log(n) : log(sum)) * kInvLog2;
|
||||
for (i = 0; i < n; ++i) {
|
||||
/* When the count of the symbol is 0, but its cost is requested anyway, it
|
||||
means the symbol will appear at least once anyway, so give it the cost as if
|
||||
its count is 1.*/
|
||||
if (count[i] == 0) bitlengths[i] = log2sum;
|
||||
else bitlengths[i] = log2sum - log(count[i]) * kInvLog2;
|
||||
/* Depending on compiler and architecture, the above subtraction of two
|
||||
floating point numbers may give a negative result very close to zero
|
||||
instead of zero (e.g. -5.973954e-17 with gcc 4.1.2 on Ubuntu 11.4). Clamp
|
||||
it to zero. These floating point imprecisions do not affect the cost model
|
||||
significantly so this is ok. */
|
||||
if (bitlengths[i] < 0 && bitlengths[i] > -1e-5) bitlengths[i] = 0;
|
||||
assert(bitlengths[i] >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ZopfliCalculateBitLengths(const size_t* count, size_t n, int maxbits,
|
||||
unsigned* bitlengths) {
|
||||
int error = ZopfliLengthLimitedCodeLengths(count, n, maxbits, bitlengths);
|
||||
(void) error;
|
||||
assert(!error);
|
||||
}
|
||||
51
build/node_modules/node-zopfli/zopfli/src/zopfli/tree.h
generated
vendored
Normal file
51
build/node_modules/node-zopfli/zopfli/src/zopfli/tree.h
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Utilities for creating and using Huffman trees.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_TREE_H_
|
||||
#define ZOPFLI_TREE_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
Calculates the bitlengths for the Huffman tree, based on the counts of each
|
||||
symbol.
|
||||
*/
|
||||
void ZopfliCalculateBitLengths(const size_t* count, size_t n, int maxbits,
|
||||
unsigned *bitlengths);
|
||||
|
||||
/*
|
||||
Converts a series of Huffman tree bitlengths, to the bit values of the symbols.
|
||||
*/
|
||||
void ZopfliLengthsToSymbols(const unsigned* lengths, size_t n, unsigned maxbits,
|
||||
unsigned* symbols);
|
||||
|
||||
/*
|
||||
Calculates the entropy of each symbol, based on the counts of each symbol. The
|
||||
result is similar to the result of ZopfliCalculateBitLengths, but with the
|
||||
actual theoritical bit lengths according to the entropy. Since the resulting
|
||||
values are fractional, they cannot be used to encode the tree specified by
|
||||
DEFLATE.
|
||||
*/
|
||||
void ZopfliCalculateEntropy(const size_t* count, size_t n, double* bitlengths);
|
||||
|
||||
#endif /* ZOPFLI_TREE_H_ */
|
||||
35
build/node_modules/node-zopfli/zopfli/src/zopfli/util.c
generated
vendored
Normal file
35
build/node_modules/node-zopfli/zopfli/src/zopfli/util.c
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "zopfli.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void ZopfliInitOptions(ZopfliOptions* options) {
|
||||
options->verbose = 0;
|
||||
options->verbose_more = 0;
|
||||
options->numiterations = 15;
|
||||
options->blocksplitting = 1;
|
||||
options->blocksplittinglast = 0;
|
||||
options->blocksplittingmax = 15;
|
||||
}
|
||||
158
build/node_modules/node-zopfli/zopfli/src/zopfli/util.h
generated
vendored
Normal file
158
build/node_modules/node-zopfli/zopfli/src/zopfli/util.h
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Several utilities, including: #defines to try different compression results,
|
||||
basic deflate specification values and generic program options.
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_UTIL_H_
|
||||
#define ZOPFLI_UTIL_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Minimum and maximum length that can be encoded in deflate. */
|
||||
#define ZOPFLI_MAX_MATCH 258
|
||||
#define ZOPFLI_MIN_MATCH 3
|
||||
|
||||
/* Number of distinct literal/length and distance symbols in DEFLATE */
|
||||
#define ZOPFLI_NUM_LL 288
|
||||
#define ZOPFLI_NUM_D 32
|
||||
|
||||
/*
|
||||
The window size for deflate. Must be a power of two. This should be 32768, the
|
||||
maximum possible by the deflate spec. Anything less hurts compression more than
|
||||
speed.
|
||||
*/
|
||||
#define ZOPFLI_WINDOW_SIZE 32768
|
||||
|
||||
/*
|
||||
The window mask used to wrap indices into the window. This is why the
|
||||
window size must be a power of two.
|
||||
*/
|
||||
#define ZOPFLI_WINDOW_MASK (ZOPFLI_WINDOW_SIZE - 1)
|
||||
|
||||
/*
|
||||
A block structure of huge, non-smart, blocks to divide the input into, to allow
|
||||
operating on huge files without exceeding memory, such as the 1GB wiki9 corpus.
|
||||
The whole compression algorithm, including the smarter block splitting, will
|
||||
be executed independently on each huge block.
|
||||
Dividing into huge blocks hurts compression, but not much relative to the size.
|
||||
Set it to 0 to disable master blocks.
|
||||
*/
|
||||
#define ZOPFLI_MASTER_BLOCK_SIZE 1000000
|
||||
|
||||
/*
|
||||
Used to initialize costs for example
|
||||
*/
|
||||
#define ZOPFLI_LARGE_FLOAT 1e30
|
||||
|
||||
/*
|
||||
For longest match cache. max 256. Uses huge amounts of memory but makes it
|
||||
faster. Uses this many times three bytes per single byte of the input data.
|
||||
This is so because longest match finding has to find the exact distance
|
||||
that belongs to each length for the best lz77 strategy.
|
||||
Good values: e.g. 5, 8.
|
||||
*/
|
||||
#define ZOPFLI_CACHE_LENGTH 8
|
||||
|
||||
/*
|
||||
limit the max hash chain hits for this hash value. This has an effect only
|
||||
on files where the hash value is the same very often. On these files, this
|
||||
gives worse compression (the value should ideally be 32768, which is the
|
||||
ZOPFLI_WINDOW_SIZE, while zlib uses 4096 even for best level), but makes it
|
||||
faster on some specific files.
|
||||
Good value: e.g. 8192.
|
||||
*/
|
||||
#define ZOPFLI_MAX_CHAIN_HITS 8192
|
||||
|
||||
/*
|
||||
Whether to use the longest match cache for ZopfliFindLongestMatch. This cache
|
||||
consumes a lot of memory but speeds it up. No effect on compression size.
|
||||
*/
|
||||
#define ZOPFLI_LONGEST_MATCH_CACHE
|
||||
|
||||
/*
|
||||
Enable to remember amount of successive identical bytes in the hash chain for
|
||||
finding longest match
|
||||
required for ZOPFLI_HASH_SAME_HASH and ZOPFLI_SHORTCUT_LONG_REPETITIONS
|
||||
This has no effect on the compression result, and enabling it increases speed.
|
||||
*/
|
||||
#define ZOPFLI_HASH_SAME
|
||||
|
||||
/*
|
||||
Switch to a faster hash based on the info from ZOPFLI_HASH_SAME once the
|
||||
best length so far is long enough. This is way faster for files with lots of
|
||||
identical bytes, on which the compressor is otherwise too slow. Regular files
|
||||
are unaffected or maybe a tiny bit slower.
|
||||
This has no effect on the compression result, only on speed.
|
||||
*/
|
||||
#define ZOPFLI_HASH_SAME_HASH
|
||||
|
||||
/*
|
||||
Enable this, to avoid slowness for files which are a repetition of the same
|
||||
character more than a multiple of ZOPFLI_MAX_MATCH times. This should not affect
|
||||
the compression result.
|
||||
*/
|
||||
#define ZOPFLI_SHORTCUT_LONG_REPETITIONS
|
||||
|
||||
/*
|
||||
Whether to use lazy matching in the greedy LZ77 implementation. This gives a
|
||||
better result of ZopfliLZ77Greedy, but the effect this has on the optimal LZ77
|
||||
varies from file to file.
|
||||
*/
|
||||
#define ZOPFLI_LAZY_MATCHING
|
||||
|
||||
/*
|
||||
Appends value to dynamically allocated memory, doubling its allocation size
|
||||
whenever needed.
|
||||
|
||||
value: the value to append, type T
|
||||
data: pointer to the dynamic array to append to, type T**
|
||||
size: pointer to the size of the array to append to, type size_t*. This is the
|
||||
size that you consider the array to be, not the internal allocation size.
|
||||
Precondition: allocated size of data is at least a power of two greater than or
|
||||
equal than *size.
|
||||
*/
|
||||
#ifdef __cplusplus /* C++ cannot assign void* from malloc to *data */
|
||||
#define ZOPFLI_APPEND_DATA(/* T */ value, /* T** */ data, /* size_t* */ size) {\
|
||||
if (!((*size) & ((*size) - 1))) {\
|
||||
/*double alloc size if it's a power of two*/\
|
||||
void** data_void = reinterpret_cast<void**>(data);\
|
||||
*data_void = (*size) == 0 ? malloc(sizeof(**data))\
|
||||
: realloc((*data), (*size) * 2 * sizeof(**data));\
|
||||
}\
|
||||
(*data)[(*size)] = (value);\
|
||||
(*size)++;\
|
||||
}
|
||||
#else /* C gives problems with strict-aliasing rules for (void**) cast */
|
||||
#define ZOPFLI_APPEND_DATA(/* T */ value, /* T** */ data, /* size_t* */ size) {\
|
||||
if (!((*size) & ((*size) - 1))) {\
|
||||
/*double alloc size if it's a power of two*/\
|
||||
(*data) = (*size) == 0 ? malloc(sizeof(**data))\
|
||||
: realloc((*data), (*size) * 2 * sizeof(**data));\
|
||||
}\
|
||||
(*data)[(*size)] = (value);\
|
||||
(*size)++;\
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* ZOPFLI_UTIL_H_ */
|
||||
79
build/node_modules/node-zopfli/zopfli/src/zopfli/zlib_container.c
generated
vendored
Normal file
79
build/node_modules/node-zopfli/zopfli/src/zopfli/zlib_container.c
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "zlib_container.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
|
||||
/* Calculates the adler32 checksum of the data */
|
||||
static unsigned adler32(const unsigned char* data, size_t size)
|
||||
{
|
||||
static const unsigned sums_overflow = 5550;
|
||||
unsigned s1 = 1;
|
||||
unsigned s2 = 1 >> 16;
|
||||
|
||||
while (size > 0) {
|
||||
size_t amount = size > sums_overflow ? sums_overflow : size;
|
||||
size -= amount;
|
||||
while (amount > 0) {
|
||||
s1 += (*data++);
|
||||
s2 += s1;
|
||||
amount--;
|
||||
}
|
||||
s1 %= 65521;
|
||||
s2 %= 65521;
|
||||
}
|
||||
|
||||
return (s2 << 16) | s1;
|
||||
}
|
||||
|
||||
void ZopfliZlibCompress(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
unsigned char bitpointer = 0;
|
||||
unsigned checksum = adler32(in, (unsigned)insize);
|
||||
unsigned cmf = 120; /* CM 8, CINFO 7. See zlib spec.*/
|
||||
unsigned flevel = 3;
|
||||
unsigned fdict = 0;
|
||||
unsigned cmfflg = 256 * cmf + fdict * 32 + flevel * 64;
|
||||
unsigned fcheck = 31 - cmfflg % 31;
|
||||
cmfflg += fcheck;
|
||||
|
||||
ZOPFLI_APPEND_DATA(cmfflg / 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(cmfflg % 256, out, outsize);
|
||||
|
||||
ZopfliDeflate(options, 2 /* dynamic block */, 1 /* final */,
|
||||
in, insize, &bitpointer, out, outsize);
|
||||
|
||||
ZOPFLI_APPEND_DATA((checksum >> 24) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((checksum >> 16) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA((checksum >> 8) % 256, out, outsize);
|
||||
ZOPFLI_APPEND_DATA(checksum % 256, out, outsize);
|
||||
|
||||
if (options->verbose) {
|
||||
fprintf(stderr,
|
||||
"Original Size: %d, Zlib: %d, Compression: %f%% Removed\n",
|
||||
(int)insize, (int)*outsize,
|
||||
100.0 * (double)(insize - *outsize) / (double)insize);
|
||||
}
|
||||
}
|
||||
50
build/node_modules/node-zopfli/zopfli/src/zopfli/zlib_container.h
generated
vendored
Normal file
50
build/node_modules/node-zopfli/zopfli/src/zopfli/zlib_container.h
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_ZLIB_H_
|
||||
#define ZOPFLI_ZLIB_H_
|
||||
|
||||
/*
|
||||
Functions to compress according to the Zlib specification.
|
||||
*/
|
||||
|
||||
#include "zopfli.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Compresses according to the zlib specification and append the compressed
|
||||
result to the output.
|
||||
|
||||
options: global program options
|
||||
out: pointer to the dynamic output array to which the result is appended. Must
|
||||
be freed after use.
|
||||
outsize: pointer to the dynamic output array size.
|
||||
*/
|
||||
void ZopfliZlibCompress(const ZopfliOptions* options,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* ZOPFLI_ZLIB_H_ */
|
||||
94
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli.h
generated
vendored
Normal file
94
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli.h
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#ifndef ZOPFLI_ZOPFLI_H_
|
||||
#define ZOPFLI_ZOPFLI_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Options used throughout the program.
|
||||
*/
|
||||
typedef struct ZopfliOptions {
|
||||
/* Whether to print output */
|
||||
int verbose;
|
||||
|
||||
/* Whether to print more detailed output */
|
||||
int verbose_more;
|
||||
|
||||
/*
|
||||
Maximum amount of times to rerun forward and backward pass to optimize LZ77
|
||||
compression cost. Good values: 10, 15 for small files, 5 for files over
|
||||
several MB in size or it will be too slow.
|
||||
*/
|
||||
int numiterations;
|
||||
|
||||
/*
|
||||
If true, splits the data in multiple deflate blocks with optimal choice
|
||||
for the block boundaries. Block splitting gives better compression. Default:
|
||||
true (1).
|
||||
*/
|
||||
int blocksplitting;
|
||||
|
||||
/*
|
||||
No longer used, left for compatibility.
|
||||
*/
|
||||
int blocksplittinglast;
|
||||
|
||||
/*
|
||||
Maximum amount of blocks to split into (0 for unlimited, but this can give
|
||||
extreme results that hurt compression on some files). Default value: 15.
|
||||
*/
|
||||
int blocksplittingmax;
|
||||
} ZopfliOptions;
|
||||
|
||||
/* Initializes options with default values. */
|
||||
void ZopfliInitOptions(ZopfliOptions* options);
|
||||
|
||||
/* Output format */
|
||||
typedef enum {
|
||||
ZOPFLI_FORMAT_GZIP,
|
||||
ZOPFLI_FORMAT_ZLIB,
|
||||
ZOPFLI_FORMAT_DEFLATE
|
||||
} ZopfliFormat;
|
||||
|
||||
/*
|
||||
Compresses according to the given output format and appends the result to the
|
||||
output.
|
||||
|
||||
options: global program options
|
||||
output_type: the output format to use
|
||||
out: pointer to the dynamic output array to which the result is appended. Must
|
||||
be freed after use
|
||||
outsize: pointer to the dynamic output array size
|
||||
*/
|
||||
void ZopfliCompress(const ZopfliOptions* options, ZopfliFormat output_type,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* ZOPFLI_ZOPFLI_H_ */
|
||||
222
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli_bin.c
generated
vendored
Normal file
222
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli_bin.c
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
/*
|
||||
Zopfli compressor program. It can output gzip-, zlib- or deflate-compatible
|
||||
data. By default it creates a .gz file. This tool can only compress, not
|
||||
decompress. Decompression can be done by any standard gzip, zlib or deflate
|
||||
decompressor.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "deflate.h"
|
||||
#include "gzip_container.h"
|
||||
#include "zlib_container.h"
|
||||
|
||||
/* Windows workaround for stdout output. */
|
||||
#if _WIN32
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Loads a file into a memory array. Returns 1 on success, 0 if file doesn't exist
|
||||
or couldn't be opened.
|
||||
*/
|
||||
static int LoadFile(const char* filename,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
FILE* file;
|
||||
|
||||
*out = 0;
|
||||
*outsize = 0;
|
||||
file = fopen(filename, "rb");
|
||||
if (!file) return 0;
|
||||
|
||||
fseek(file , 0 , SEEK_END);
|
||||
*outsize = ftell(file);
|
||||
if(*outsize > 2147483647) {
|
||||
fprintf(stderr,"Files larger than 2GB are not supported.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
rewind(file);
|
||||
|
||||
*out = (unsigned char*)malloc(*outsize);
|
||||
|
||||
if (*outsize && (*out)) {
|
||||
size_t testsize = fread(*out, 1, *outsize, file);
|
||||
if (testsize != *outsize) {
|
||||
/* It could be a directory */
|
||||
free(*out);
|
||||
*out = 0;
|
||||
*outsize = 0;
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
assert(!(*outsize) || out); /* If size is not zero, out must be allocated. */
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Saves a file from a memory array, overwriting the file if it existed.
|
||||
*/
|
||||
static void SaveFile(const char* filename,
|
||||
const unsigned char* in, size_t insize) {
|
||||
FILE* file = fopen(filename, "wb" );
|
||||
if (file == NULL) {
|
||||
fprintf(stderr,"Error: Cannot write to output file, terminating.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
assert(file);
|
||||
fwrite((char*)in, 1, insize, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
/*
|
||||
outfilename: filename to write output to, or 0 to write to stdout instead
|
||||
*/
|
||||
static void CompressFile(const ZopfliOptions* options,
|
||||
ZopfliFormat output_type,
|
||||
const char* infilename,
|
||||
const char* outfilename) {
|
||||
unsigned char* in;
|
||||
size_t insize;
|
||||
unsigned char* out = 0;
|
||||
size_t outsize = 0;
|
||||
if (!LoadFile(infilename, &in, &insize)) {
|
||||
fprintf(stderr, "Invalid filename: %s\n", infilename);
|
||||
return;
|
||||
}
|
||||
|
||||
ZopfliCompress(options, output_type, in, insize, &out, &outsize);
|
||||
|
||||
if (outfilename) {
|
||||
SaveFile(outfilename, out, outsize);
|
||||
} else {
|
||||
size_t i;
|
||||
#if _WIN32
|
||||
/* Windows workaround for stdout output. */
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#endif
|
||||
for (i = 0; i < outsize; i++) {
|
||||
printf("%c", out[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(out);
|
||||
free(in);
|
||||
}
|
||||
|
||||
/*
|
||||
Add two strings together. Size does not matter. Result must be freed.
|
||||
*/
|
||||
static char* AddStrings(const char* str1, const char* str2) {
|
||||
size_t len = strlen(str1) + strlen(str2);
|
||||
char* result = (char*)malloc(len + 1);
|
||||
if (!result) exit(-1); /* Allocation failed. */
|
||||
strcpy(result, str1);
|
||||
strcat(result, str2);
|
||||
return result;
|
||||
}
|
||||
|
||||
static char StringsEqual(const char* str1, const char* str2) {
|
||||
return strcmp(str1, str2) == 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
ZopfliOptions options;
|
||||
ZopfliFormat output_type = ZOPFLI_FORMAT_GZIP;
|
||||
const char* filename = 0;
|
||||
int output_to_stdout = 0;
|
||||
int i;
|
||||
|
||||
ZopfliInitOptions(&options);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char* arg = argv[i];
|
||||
if (StringsEqual(arg, "-v")) options.verbose = 1;
|
||||
else if (StringsEqual(arg, "-c")) output_to_stdout = 1;
|
||||
else if (StringsEqual(arg, "--deflate")) {
|
||||
output_type = ZOPFLI_FORMAT_DEFLATE;
|
||||
}
|
||||
else if (StringsEqual(arg, "--zlib")) output_type = ZOPFLI_FORMAT_ZLIB;
|
||||
else if (StringsEqual(arg, "--gzip")) output_type = ZOPFLI_FORMAT_GZIP;
|
||||
else if (StringsEqual(arg, "--splitlast")) /* Ignore */;
|
||||
else if (arg[0] == '-' && arg[1] == '-' && arg[2] == 'i'
|
||||
&& arg[3] >= '0' && arg[3] <= '9') {
|
||||
options.numiterations = atoi(arg + 3);
|
||||
}
|
||||
else if (StringsEqual(arg, "-h")) {
|
||||
fprintf(stderr,
|
||||
"Usage: zopfli [OPTION]... FILE...\n"
|
||||
" -h gives this help\n"
|
||||
" -c write the result on standard output, instead of disk"
|
||||
" filename + '.gz'\n"
|
||||
" -v verbose mode\n"
|
||||
" --i# perform # iterations (default 15). More gives"
|
||||
" more compression but is slower."
|
||||
" Examples: --i10, --i50, --i1000\n");
|
||||
fprintf(stderr,
|
||||
" --gzip output to gzip format (default)\n"
|
||||
" --zlib output to zlib format instead of gzip\n"
|
||||
" --deflate output to deflate format instead of gzip\n"
|
||||
" --splitlast ignored, left for backwards compatibility\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.numiterations < 1) {
|
||||
fprintf(stderr, "Error: must have 1 or more iterations\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] != '-') {
|
||||
char* outfilename;
|
||||
filename = argv[i];
|
||||
if (output_to_stdout) {
|
||||
outfilename = 0;
|
||||
} else if (output_type == ZOPFLI_FORMAT_GZIP) {
|
||||
outfilename = AddStrings(filename, ".gz");
|
||||
} else if (output_type == ZOPFLI_FORMAT_ZLIB) {
|
||||
outfilename = AddStrings(filename, ".zlib");
|
||||
} else {
|
||||
assert(output_type == ZOPFLI_FORMAT_DEFLATE);
|
||||
outfilename = AddStrings(filename, ".deflate");
|
||||
}
|
||||
if (options.verbose && outfilename) {
|
||||
fprintf(stderr, "Saving to: %s\n", outfilename);
|
||||
}
|
||||
CompressFile(&options, output_type, filename, outfilename);
|
||||
free(outfilename);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
fprintf(stderr,
|
||||
"Please provide filename\nFor help, type: %s -h\n", argv[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
42
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli_lib.c
generated
vendored
Normal file
42
build/node_modules/node-zopfli/zopfli/src/zopfli/zopfli_lib.c
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
*/
|
||||
|
||||
#include "zopfli.h"
|
||||
|
||||
#include "deflate.h"
|
||||
#include "gzip_container.h"
|
||||
#include "zlib_container.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
void ZopfliCompress(const ZopfliOptions* options, ZopfliFormat output_type,
|
||||
const unsigned char* in, size_t insize,
|
||||
unsigned char** out, size_t* outsize) {
|
||||
if (output_type == ZOPFLI_FORMAT_GZIP) {
|
||||
ZopfliGzipCompress(options, in, insize, out, outsize);
|
||||
} else if (output_type == ZOPFLI_FORMAT_ZLIB) {
|
||||
ZopfliZlibCompress(options, in, insize, out, outsize);
|
||||
} else if (output_type == ZOPFLI_FORMAT_DEFLATE) {
|
||||
unsigned char bp = 0;
|
||||
ZopfliDeflate(options, 2 /* Dynamic block */, 1,
|
||||
in, insize, &bp, out, outsize);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
6206
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng.cpp
generated
vendored
Normal file
6206
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng.cpp
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1758
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng.h
generated
vendored
Normal file
1758
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
671
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.cpp
generated
vendored
Normal file
671
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.cpp
generated
vendored
Normal file
@@ -0,0 +1,671 @@
|
||||
/*
|
||||
LodePNG Utils
|
||||
|
||||
Copyright (c) 2005-2014 Lode Vandevenne
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#include "lodepng_util.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace lodepng
|
||||
{
|
||||
|
||||
LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png)
|
||||
{
|
||||
unsigned w, h;
|
||||
lodepng::State state;
|
||||
lodepng_inspect(&w, &h, &state, &png[0], png.size());
|
||||
return state.info_png;
|
||||
}
|
||||
|
||||
unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
|
||||
const std::vector<unsigned char>& png)
|
||||
{
|
||||
// Listing chunks is based on the original file, not the decoded png info.
|
||||
const unsigned char *chunk, *begin, *end, *next;
|
||||
end = &png.back() + 1;
|
||||
begin = chunk = &png.front() + 8;
|
||||
|
||||
while(chunk + 8 < end && chunk >= begin)
|
||||
{
|
||||
char type[5];
|
||||
lodepng_chunk_type(type, chunk);
|
||||
if(std::string(type).size() != 4) return 1;
|
||||
|
||||
unsigned length = lodepng_chunk_length(chunk);
|
||||
if(chunk + length + 12 > end) return 1;
|
||||
names.push_back(type);
|
||||
sizes.push_back(length);
|
||||
|
||||
next = lodepng_chunk_next_const(chunk);
|
||||
if (next <= chunk) return 1; // integer overflow
|
||||
chunk = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned getChunks(std::vector<std::string> names[3],
|
||||
std::vector<std::vector<unsigned char> > chunks[3],
|
||||
const std::vector<unsigned char>& png)
|
||||
{
|
||||
const unsigned char *chunk, *next, *begin, *end;
|
||||
end = &png.back() + 1;
|
||||
begin = chunk = &png.front() + 8;
|
||||
|
||||
int location = 0;
|
||||
|
||||
while(chunk + 8 < end && chunk >= begin)
|
||||
{
|
||||
char type[5];
|
||||
lodepng_chunk_type(type, chunk);
|
||||
std::string name(type);
|
||||
if(name.size() != 4) return 1;
|
||||
|
||||
next = lodepng_chunk_next_const(chunk);
|
||||
if (next <= chunk) return 1; // integer overflow
|
||||
|
||||
if(name == "IHDR")
|
||||
{
|
||||
location = 0;
|
||||
}
|
||||
else if(name == "PLTE")
|
||||
{
|
||||
location = 1;
|
||||
}
|
||||
else if(name == "IDAT")
|
||||
{
|
||||
location = 2;
|
||||
}
|
||||
else if(name == "IEND")
|
||||
{
|
||||
break; // anything after IEND is not part of the PNG or the 3 groups here.
|
||||
}
|
||||
else
|
||||
{
|
||||
if(next > end) return 1; // invalid chunk, content too far
|
||||
names[location].push_back(name);
|
||||
chunks[location].push_back(std::vector<unsigned char>(chunk, next));
|
||||
}
|
||||
|
||||
chunk = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned insertChunks(std::vector<unsigned char>& png,
|
||||
const std::vector<std::vector<unsigned char> > chunks[3])
|
||||
{
|
||||
const unsigned char *chunk, *next, *begin, *end;
|
||||
end = &png.back() + 1;
|
||||
begin = chunk = &png.front() + 8;
|
||||
|
||||
long l0 = 0; //location 0: IHDR-l0-PLTE (or IHDR-l0-l1-IDAT)
|
||||
long l1 = 0; //location 1: PLTE-l1-IDAT (or IHDR-l0-l1-IDAT)
|
||||
long l2 = 0; //location 2: IDAT-l2-IEND
|
||||
|
||||
while(chunk + 8 < end && chunk >= begin)
|
||||
{
|
||||
char type[5];
|
||||
lodepng_chunk_type(type, chunk);
|
||||
std::string name(type);
|
||||
if(name.size() != 4) return 1;
|
||||
|
||||
next = lodepng_chunk_next_const(chunk);
|
||||
if (next <= chunk) return 1; // integer overflow
|
||||
|
||||
if(name == "PLTE")
|
||||
{
|
||||
if(l0 == 0) l0 = chunk - begin + 8;
|
||||
}
|
||||
else if(name == "IDAT")
|
||||
{
|
||||
if(l0 == 0) l0 = chunk - begin + 8;
|
||||
if(l1 == 0) l1 = chunk - begin + 8;
|
||||
}
|
||||
else if(name == "IEND")
|
||||
{
|
||||
if(l2 == 0) l2 = chunk - begin + 8;
|
||||
}
|
||||
|
||||
chunk = next;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> result;
|
||||
result.insert(result.end(), png.begin(), png.begin() + l0);
|
||||
for(size_t i = 0; i < chunks[0].size(); i++) result.insert(result.end(), chunks[0][i].begin(), chunks[0][i].end());
|
||||
result.insert(result.end(), png.begin() + l0, png.begin() + l1);
|
||||
for(size_t i = 0; i < chunks[1].size(); i++) result.insert(result.end(), chunks[1][i].begin(), chunks[1][i].end());
|
||||
result.insert(result.end(), png.begin() + l1, png.begin() + l2);
|
||||
for(size_t i = 0; i < chunks[2].size(); i++) result.insert(result.end(), chunks[2][i].begin(), chunks[2][i].end());
|
||||
result.insert(result.end(), png.begin() + l2, png.end());
|
||||
|
||||
png = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes,
|
||||
const std::vector<unsigned char>& png)
|
||||
{
|
||||
//Get color type and interlace type
|
||||
lodepng::State state;
|
||||
unsigned w, h;
|
||||
unsigned error;
|
||||
error = lodepng_inspect(&w, &h, &state, &png[0], png.size());
|
||||
|
||||
if(error) return 1;
|
||||
|
||||
//Read literal data from all IDAT chunks
|
||||
const unsigned char *chunk, *begin, *end, *next;
|
||||
end = &png.back() + 1;
|
||||
begin = chunk = &png.front() + 8;
|
||||
|
||||
std::vector<unsigned char> zdata;
|
||||
|
||||
while(chunk + 8 < end && chunk >= begin)
|
||||
{
|
||||
char type[5];
|
||||
lodepng_chunk_type(type, chunk);
|
||||
if(std::string(type).size() != 4) return 1; //Probably not a PNG file
|
||||
|
||||
if(std::string(type) == "IDAT")
|
||||
{
|
||||
const unsigned char* cdata = lodepng_chunk_data_const(chunk);
|
||||
unsigned clength = lodepng_chunk_length(chunk);
|
||||
if(chunk + clength + 12 > end || clength > png.size() || chunk + clength + 12 < begin) {
|
||||
// corrupt chunk length
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < clength; i++)
|
||||
{
|
||||
zdata.push_back(cdata[i]);
|
||||
}
|
||||
}
|
||||
|
||||
next = lodepng_chunk_next_const(chunk);
|
||||
if (next <= chunk) return 1; // integer overflow
|
||||
chunk = next;
|
||||
}
|
||||
|
||||
//Decompress all IDAT data
|
||||
std::vector<unsigned char> data;
|
||||
error = lodepng::decompress(data, &zdata[0], zdata.size());
|
||||
|
||||
if(error) return 1;
|
||||
|
||||
if(state.info_png.interlace_method == 0)
|
||||
{
|
||||
filterTypes.resize(1);
|
||||
|
||||
//A line is 1 filter byte + all pixels
|
||||
size_t linebytes = 1 + lodepng_get_raw_size(w, 1, &state.info_png.color);
|
||||
|
||||
for(size_t i = 0; i < data.size(); i += linebytes)
|
||||
{
|
||||
filterTypes[0].push_back(data[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Interlaced
|
||||
filterTypes.resize(7);
|
||||
static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
|
||||
static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
|
||||
static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
|
||||
static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
|
||||
size_t pos = 0;
|
||||
for(size_t j = 0; j < 7; j++)
|
||||
{
|
||||
unsigned w2 = (w - ADAM7_IX[j] + ADAM7_DX[j] - 1) / ADAM7_DX[j];
|
||||
unsigned h2 = (h - ADAM7_IY[j] + ADAM7_DY[j] - 1) / ADAM7_DY[j];
|
||||
if(ADAM7_IX[j] >= w) w2 = 0;
|
||||
if(ADAM7_IY[j] >= h) h2 = 0;
|
||||
size_t linebytes = 1 + lodepng_get_raw_size(w2, 1, &state.info_png.color);
|
||||
for(size_t i = 0; i < h2; i++)
|
||||
{
|
||||
filterTypes[j].push_back(data[pos]);
|
||||
pos += linebytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
|
||||
unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png)
|
||||
{
|
||||
std::vector<std::vector<unsigned char> > passes;
|
||||
unsigned error = getFilterTypesInterlaced(passes, png);
|
||||
if(error) return error;
|
||||
|
||||
if(passes.size() == 1)
|
||||
{
|
||||
filterTypes.swap(passes[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
lodepng::State state;
|
||||
unsigned w, h;
|
||||
lodepng_inspect(&w, &h, &state, &png[0], png.size());
|
||||
/*
|
||||
Interlaced. Simplify it: put pass 6 and 7 alternating in the one vector so
|
||||
that one filter per scanline of the uninterlaced image is given, with that
|
||||
filter corresponding the closest to what it would be for non-interlaced
|
||||
image.
|
||||
*/
|
||||
for(size_t i = 0; i < h; i++)
|
||||
{
|
||||
filterTypes.push_back(i % 2 == 0 ? passes[5][i / 2] : passes[6][i / 2]);
|
||||
}
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
int getPaletteValue(const unsigned char* data, size_t i, int bits)
|
||||
{
|
||||
if(bits == 8) return data[i];
|
||||
else if(bits == 4) return (data[i / 2] >> ((i % 2) * 4)) & 15;
|
||||
else if(bits == 2) return (data[i / 4] >> ((i % 4) * 2)) & 3;
|
||||
else if(bits == 1) return (data[i / 8] >> (i % 8)) & 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
//This uses a stripped down version of picoPNG to extract detailed zlib information while decompressing.
|
||||
static const unsigned long LENBASE[29] =
|
||||
{3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
|
||||
static const unsigned long LENEXTRA[29] =
|
||||
{0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
static const unsigned long DISTBASE[30] =
|
||||
{1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
|
||||
static const unsigned long DISTEXTRA[30] =
|
||||
{0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
|
||||
static const unsigned long CLCL[19] =
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; //code length code lengths
|
||||
|
||||
struct ExtractZlib // Zlib decompression and information extraction
|
||||
{
|
||||
std::vector<ZlibBlockInfo>* zlibinfo;
|
||||
ExtractZlib(std::vector<ZlibBlockInfo>* info) : zlibinfo(info) {};
|
||||
int error;
|
||||
|
||||
unsigned long readBitFromStream(size_t& bitp, const unsigned char* bits)
|
||||
{
|
||||
unsigned long result = (bits[bitp >> 3] >> (bitp & 0x7)) & 1;
|
||||
bitp++;
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long readBitsFromStream(size_t& bitp, const unsigned char* bits, size_t nbits)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
for(size_t i = 0; i < nbits; i++) result += (readBitFromStream(bitp, bits)) << i;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct HuffmanTree
|
||||
{
|
||||
int makeFromLengths(const std::vector<unsigned long>& bitlen, unsigned long maxbitlen)
|
||||
{ //make tree given the lengths
|
||||
unsigned long numcodes = (unsigned long)(bitlen.size()), treepos = 0, nodefilled = 0;
|
||||
std::vector<unsigned long> tree1d(numcodes), blcount(maxbitlen + 1, 0), nextcode(maxbitlen + 1, 0);
|
||||
//count number of instances of each code length
|
||||
for(unsigned long bits = 0; bits < numcodes; bits++) blcount[bitlen[bits]]++;
|
||||
for(unsigned long bits = 1; bits <= maxbitlen; bits++)
|
||||
{
|
||||
nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1;
|
||||
}
|
||||
//generate all the codes
|
||||
for(unsigned long n = 0; n < numcodes; n++) if(bitlen[n] != 0) tree1d[n] = nextcode[bitlen[n]]++;
|
||||
tree2d.clear(); tree2d.resize(numcodes * 2, 32767); //32767 here means the tree2d isn't filled there yet
|
||||
for(unsigned long n = 0; n < numcodes; n++) //the codes
|
||||
for(unsigned long i = 0; i < bitlen[n]; i++) //the bits for this code
|
||||
{
|
||||
unsigned long bit = (tree1d[n] >> (bitlen[n] - i - 1)) & 1;
|
||||
if(treepos > numcodes - 2) return 55;
|
||||
if(tree2d[2 * treepos + bit] == 32767) //not yet filled in
|
||||
{
|
||||
if(i + 1 == bitlen[n])
|
||||
{
|
||||
//last bit
|
||||
tree2d[2 * treepos + bit] = n;
|
||||
treepos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//addresses are encoded as values > numcodes
|
||||
tree2d[2 * treepos + bit] = ++nodefilled + numcodes;
|
||||
treepos = nodefilled;
|
||||
}
|
||||
}
|
||||
else treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int decode(bool& decoded, unsigned long& result, size_t& treepos, unsigned long bit) const
|
||||
{ //Decodes a symbol from the tree
|
||||
unsigned long numcodes = (unsigned long)tree2d.size() / 2;
|
||||
if(treepos >= numcodes) return 11; //error: you appeared outside the codetree
|
||||
result = tree2d[2 * treepos + bit];
|
||||
decoded = (result < numcodes);
|
||||
treepos = decoded ? 0 : result - numcodes;
|
||||
return 0;
|
||||
}
|
||||
//2D representation of a huffman tree: one dimension is "0" or "1", the other contains all nodes and leaves.
|
||||
std::vector<unsigned long> tree2d;
|
||||
};
|
||||
|
||||
void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, size_t inpos = 0)
|
||||
{
|
||||
size_t bp = 0, pos = 0; //bit pointer and byte pointer
|
||||
error = 0;
|
||||
unsigned long BFINAL = 0;
|
||||
while(!BFINAL && !error)
|
||||
{
|
||||
size_t uncomprblockstart = pos;
|
||||
size_t bpstart = bp;
|
||||
if(bp >> 3 >= in.size()) { error = 52; return; } //error, bit pointer will jump past memory
|
||||
BFINAL = readBitFromStream(bp, &in[inpos]);
|
||||
unsigned long BTYPE = readBitFromStream(bp, &in[inpos]); BTYPE += 2 * readBitFromStream(bp, &in[inpos]);
|
||||
zlibinfo->resize(zlibinfo->size() + 1);
|
||||
zlibinfo->back().btype = BTYPE;
|
||||
if(BTYPE == 3) { error = 20; return; } //error: invalid BTYPE
|
||||
else if(BTYPE == 0) inflateNoCompression(out, &in[inpos], bp, pos, in.size());
|
||||
else inflateHuffmanBlock(out, &in[inpos], bp, pos, in.size(), BTYPE);
|
||||
size_t uncomprblocksize = pos - uncomprblockstart;
|
||||
zlibinfo->back().compressedbits = bp - bpstart;
|
||||
zlibinfo->back().uncompressedbytes = uncomprblocksize;
|
||||
}
|
||||
}
|
||||
|
||||
void generateFixedTrees(HuffmanTree& tree, HuffmanTree& treeD) //get the tree of a deflated block with fixed tree
|
||||
{
|
||||
std::vector<unsigned long> bitlen(288, 8), bitlenD(32, 5);;
|
||||
for(size_t i = 144; i <= 255; i++) bitlen[i] = 9;
|
||||
for(size_t i = 256; i <= 279; i++) bitlen[i] = 7;
|
||||
tree.makeFromLengths(bitlen, 15);
|
||||
treeD.makeFromLengths(bitlenD, 15);
|
||||
}
|
||||
|
||||
//the code tree for Huffman codes, dist codes, and code length codes
|
||||
HuffmanTree codetree, codetreeD, codelengthcodetree;
|
||||
unsigned long huffmanDecodeSymbol(const unsigned char* in, size_t& bp, const HuffmanTree& tree, size_t inlength)
|
||||
{
|
||||
//decode a single symbol from given list of bits with given code tree. return value is the symbol
|
||||
bool decoded; unsigned long ct;
|
||||
for(size_t treepos = 0;;)
|
||||
{
|
||||
if((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10; return 0; } //error: end reached without endcode
|
||||
error = tree.decode(decoded, ct, treepos, readBitFromStream(bp, in));
|
||||
if(error) return 0; //stop, an error happened
|
||||
if(decoded) return ct;
|
||||
}
|
||||
}
|
||||
|
||||
void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD,
|
||||
const unsigned char* in, size_t& bp, size_t inlength)
|
||||
{
|
||||
size_t bpstart = bp;
|
||||
//get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree
|
||||
std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
|
||||
if(bp >> 3 >= inlength - 2) { error = 49; return; } //the bit pointer is or will go past the memory
|
||||
size_t HLIT = readBitsFromStream(bp, in, 5) + 257; //number of literal/length codes + 257
|
||||
size_t HDIST = readBitsFromStream(bp, in, 5) + 1; //number of dist codes + 1
|
||||
size_t HCLEN = readBitsFromStream(bp, in, 4) + 4; //number of code length codes + 4
|
||||
zlibinfo->back().hlit = HLIT - 257;
|
||||
zlibinfo->back().hdist = HDIST - 1;
|
||||
zlibinfo->back().hclen = HCLEN - 4;
|
||||
std::vector<unsigned long> codelengthcode(19); //lengths of tree to decode the lengths of the dynamic tree
|
||||
for(size_t i = 0; i < 19; i++) codelengthcode[CLCL[i]] = (i < HCLEN) ? readBitsFromStream(bp, in, 3) : 0;
|
||||
//code length code lengths
|
||||
for(size_t i = 0; i < codelengthcode.size(); i++) zlibinfo->back().clcl.push_back(codelengthcode[i]);
|
||||
error = codelengthcodetree.makeFromLengths(codelengthcode, 7); if(error) return;
|
||||
size_t i = 0, replength;
|
||||
while(i < HLIT + HDIST)
|
||||
{
|
||||
unsigned long code = huffmanDecodeSymbol(in, bp, codelengthcodetree, inlength); if(error) return;
|
||||
zlibinfo->back().treecodes.push_back(code); //tree symbol code
|
||||
if(code <= 15) { if(i < HLIT) bitlen[i++] = code; else bitlenD[i++ - HLIT] = code; } //a length code
|
||||
else if(code == 16) //repeat previous
|
||||
{
|
||||
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
|
||||
replength = 3 + readBitsFromStream(bp, in, 2);
|
||||
unsigned long value; //set value to the previous code
|
||||
if((i - 1) < HLIT) value = bitlen[i - 1];
|
||||
else value = bitlenD[i - HLIT - 1];
|
||||
for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
|
||||
{
|
||||
if(i >= HLIT + HDIST) { error = 13; return; } //error: i is larger than the amount of codes
|
||||
if(i < HLIT) bitlen[i++] = value; else bitlenD[i++ - HLIT] = value;
|
||||
}
|
||||
}
|
||||
else if(code == 17) //repeat "0" 3-10 times
|
||||
{
|
||||
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
|
||||
replength = 3 + readBitsFromStream(bp, in, 3);
|
||||
zlibinfo->back().treecodes.push_back(replength); //tree symbol code repetitions
|
||||
for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
|
||||
{
|
||||
if(i >= HLIT + HDIST) { error = 14; return; } //error: i is larger than the amount of codes
|
||||
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
|
||||
}
|
||||
}
|
||||
else if(code == 18) //repeat "0" 11-138 times
|
||||
{
|
||||
if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
|
||||
replength = 11 + readBitsFromStream(bp, in, 7);
|
||||
zlibinfo->back().treecodes.push_back(replength); //tree symbol code repetitions
|
||||
for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
|
||||
{
|
||||
if(i >= HLIT + HDIST) { error = 15; return; } //error: i is larger than the amount of codes
|
||||
if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
|
||||
}
|
||||
}
|
||||
else { error = 16; return; } //error: somehow an unexisting code appeared. This can never happen.
|
||||
}
|
||||
if(bitlen[256] == 0) { error = 64; return; } //the length of the end code 256 must be larger than 0
|
||||
error = tree.makeFromLengths(bitlen, 15);
|
||||
if(error) return; //now we've finally got HLIT and HDIST, so generate the code trees, and the function is done
|
||||
error = treeD.makeFromLengths(bitlenD, 15);
|
||||
if(error) return;
|
||||
zlibinfo->back().treebits = bp - bpstart;
|
||||
//lit/len/end symbol lengths
|
||||
for(size_t j = 0; j < bitlen.size(); j++) zlibinfo->back().litlenlengths.push_back(bitlen[j]);
|
||||
//dist lengths
|
||||
for(size_t j = 0; j < bitlenD.size(); j++) zlibinfo->back().distlengths.push_back(bitlenD[j]);
|
||||
}
|
||||
|
||||
void inflateHuffmanBlock(std::vector<unsigned char>& out,
|
||||
const unsigned char* in, size_t& bp, size_t& pos, size_t inlength, unsigned long btype)
|
||||
{
|
||||
size_t numcodes = 0, numlit = 0, numlen = 0; //for logging
|
||||
if(btype == 1) { generateFixedTrees(codetree, codetreeD); }
|
||||
else if(btype == 2) { getTreeInflateDynamic(codetree, codetreeD, in, bp, inlength); if(error) return; }
|
||||
for(;;)
|
||||
{
|
||||
unsigned long code = huffmanDecodeSymbol(in, bp, codetree, inlength); if(error) return;
|
||||
numcodes++;
|
||||
zlibinfo->back().lz77_lcode.push_back(code); //output code
|
||||
zlibinfo->back().lz77_dcode.push_back(0);
|
||||
zlibinfo->back().lz77_lbits.push_back(0);
|
||||
zlibinfo->back().lz77_dbits.push_back(0);
|
||||
zlibinfo->back().lz77_lvalue.push_back(0);
|
||||
zlibinfo->back().lz77_dvalue.push_back(0);
|
||||
|
||||
if(code == 256) break; //end code
|
||||
else if(code <= 255) //literal symbol
|
||||
{
|
||||
out.push_back((unsigned char)(code));
|
||||
pos++;
|
||||
numlit++;
|
||||
}
|
||||
else if(code >= 257 && code <= 285) //length code
|
||||
{
|
||||
size_t length = LENBASE[code - 257], numextrabits = LENEXTRA[code - 257];
|
||||
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
|
||||
length += readBitsFromStream(bp, in, numextrabits);
|
||||
unsigned long codeD = huffmanDecodeSymbol(in, bp, codetreeD, inlength); if(error) return;
|
||||
if(codeD > 29) { error = 18; return; } //error: invalid dist code (30-31 are never used)
|
||||
unsigned long dist = DISTBASE[codeD], numextrabitsD = DISTEXTRA[codeD];
|
||||
if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
|
||||
dist += readBitsFromStream(bp, in, numextrabitsD);
|
||||
size_t start = pos, back = start - dist; //backwards
|
||||
for(size_t i = 0; i < length; i++)
|
||||
{
|
||||
out.push_back(out[back++]);
|
||||
pos++;
|
||||
if(back >= start) back = start - dist;
|
||||
}
|
||||
numlen++;
|
||||
zlibinfo->back().lz77_dcode.back() = codeD; //output distance code
|
||||
zlibinfo->back().lz77_lbits.back() = numextrabits; //output length extra bits
|
||||
zlibinfo->back().lz77_dbits.back() = numextrabitsD; //output dist extra bits
|
||||
zlibinfo->back().lz77_lvalue.back() = length; //output length
|
||||
zlibinfo->back().lz77_dvalue.back() = dist; //output dist
|
||||
}
|
||||
}
|
||||
zlibinfo->back().numlit = numlit; //output number of literal symbols
|
||||
zlibinfo->back().numlen = numlen; //output number of length symbols
|
||||
}
|
||||
|
||||
void inflateNoCompression(std::vector<unsigned char>& out,
|
||||
const unsigned char* in, size_t& bp, size_t& pos, size_t inlength)
|
||||
{
|
||||
while((bp & 0x7) != 0) bp++; //go to first boundary of byte
|
||||
size_t p = bp / 8;
|
||||
if(p >= inlength - 4) { error = 52; return; } //error, bit pointer will jump past memory
|
||||
unsigned long LEN = in[p] + 256u * in[p + 1], NLEN = in[p + 2] + 256u * in[p + 3]; p += 4;
|
||||
if(LEN + NLEN != 65535) { error = 21; return; } //error: NLEN is not one's complement of LEN
|
||||
if(p + LEN > inlength) { error = 23; return; } //error: reading outside of in buffer
|
||||
for(unsigned long n = 0; n < LEN; n++)
|
||||
{
|
||||
out.push_back(in[p++]); //read LEN bytes of literal data
|
||||
pos++;
|
||||
}
|
||||
bp = p * 8;
|
||||
}
|
||||
|
||||
int decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in) //returns error value
|
||||
{
|
||||
if(in.size() < 2) { return 53; } //error, size of zlib data too small
|
||||
//error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way
|
||||
if((in[0] * 256 + in[1]) % 31 != 0) { return 24; }
|
||||
unsigned long CM = in[0] & 15, CINFO = (in[0] >> 4) & 15, FDICT = (in[1] >> 5) & 1;
|
||||
//error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec
|
||||
if(CM != 8 || CINFO > 7) { return 25; }
|
||||
//error: the PNG spec says about the zlib stream: "The additional flags shall not specify a preset dictionary."
|
||||
if(FDICT != 0) { return 26; }
|
||||
inflate(out, in, 2);
|
||||
return error; //note: adler32 checksum was skipped and ignored
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtractPNG //PNG decoding and information extraction
|
||||
{
|
||||
std::vector<ZlibBlockInfo>* zlibinfo;
|
||||
ExtractPNG(std::vector<ZlibBlockInfo>* info) : zlibinfo(info) {};
|
||||
int error;
|
||||
void decode(const unsigned char* in, size_t size)
|
||||
{
|
||||
error = 0;
|
||||
if(size == 0 || in == 0) { error = 48; return; } //the given data is empty
|
||||
readPngHeader(&in[0], size); if(error) return;
|
||||
size_t pos = 33; //first byte of the first chunk after the header
|
||||
std::vector<unsigned char> idat; //the data from idat chunks
|
||||
bool IEND = false;
|
||||
//loop through the chunks, ignoring unknown chunks and stopping at IEND chunk.
|
||||
//IDAT data is put at the start of the in buffer
|
||||
while(!IEND)
|
||||
{
|
||||
//error: size of the in buffer too small to contain next chunk
|
||||
if(pos + 8 >= size) { error = 30; return; }
|
||||
size_t chunkLength = read32bitInt(&in[pos]); pos += 4;
|
||||
if(chunkLength > 2147483647) { error = 63; return; }
|
||||
//error: size of the in buffer too small to contain next chunk
|
||||
if(pos + chunkLength >= size) { error = 35; return; }
|
||||
//IDAT chunk, containing compressed image data
|
||||
if(in[pos + 0] == 'I' && in[pos + 1] == 'D' && in[pos + 2] == 'A' && in[pos + 3] == 'T')
|
||||
{
|
||||
idat.insert(idat.end(), &in[pos + 4], &in[pos + 4 + chunkLength]);
|
||||
pos += (4 + chunkLength);
|
||||
}
|
||||
else if(in[pos + 0] == 'I' && in[pos + 1] == 'E' && in[pos + 2] == 'N' && in[pos + 3] == 'D')
|
||||
{
|
||||
pos += 4;
|
||||
IEND = true;
|
||||
}
|
||||
else //it's not an implemented chunk type, so ignore it: skip over the data
|
||||
{
|
||||
pos += (chunkLength + 4); //skip 4 letters and uninterpreted data of unimplemented chunk
|
||||
}
|
||||
pos += 4; //step over CRC (which is ignored)
|
||||
}
|
||||
std::vector<unsigned char> out; //now the out buffer will be filled
|
||||
ExtractZlib zlib(zlibinfo); //decompress with the Zlib decompressor
|
||||
error = zlib.decompress(out, idat);
|
||||
if(error) return; //stop if the zlib decompressor returned an error
|
||||
}
|
||||
|
||||
//read the information from the header and store it in the Info
|
||||
void readPngHeader(const unsigned char* in, size_t inlength)
|
||||
{
|
||||
if(inlength < 29) { error = 27; return; } //error: the data length is smaller than the length of the header
|
||||
if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
|
||||
|| in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { error = 28; return; } //no PNG signature
|
||||
//error: it doesn't start with a IHDR chunk!
|
||||
if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { error = 29; return; }
|
||||
}
|
||||
|
||||
unsigned long readBitFromReversedStream(size_t& bitp, const unsigned char* bits)
|
||||
{
|
||||
unsigned long result = (bits[bitp >> 3] >> (7 - (bitp & 0x7))) & 1;
|
||||
bitp++;
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long readBitsFromReversedStream(size_t& bitp, const unsigned char* bits, unsigned long nbits)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
for(size_t i = nbits - 1; i < nbits; i--) result += ((readBitFromReversedStream(bitp, bits)) << i);
|
||||
return result;
|
||||
}
|
||||
|
||||
void setBitOfReversedStream(size_t& bitp, unsigned char* bits, unsigned long bit)
|
||||
{
|
||||
bits[bitp >> 3] |= (bit << (7 - (bitp & 0x7))); bitp++;
|
||||
}
|
||||
|
||||
unsigned long read32bitInt(const unsigned char* buffer)
|
||||
{
|
||||
return (unsigned int)((buffer[0] << 24u) | (buffer[1] << 16u) | (buffer[2] << 8u) | buffer[3]);
|
||||
}
|
||||
};
|
||||
|
||||
void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in)
|
||||
{
|
||||
ExtractPNG decoder(&zlibinfo);
|
||||
decoder.decode(&in[0], in.size());
|
||||
|
||||
if(decoder.error) std::cout << "extract error: " << decoder.error << std::endl;
|
||||
}
|
||||
|
||||
} // namespace lodepng
|
||||
151
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.h
generated
vendored
Normal file
151
build/node_modules/node-zopfli/zopfli/src/zopflipng/lodepng/lodepng_util.h
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
LodePNG Utils
|
||||
|
||||
Copyright (c) 2005-2014 Lode Vandevenne
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
Extra C++ utilities for LodePNG, for convenience.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "lodepng.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace lodepng
|
||||
{
|
||||
|
||||
/*
|
||||
Returns info from the header of the PNG by value, purely for convenience.
|
||||
Does NOT check for errors. Returns bogus info if the PNG has an error.
|
||||
Does not require cleanup of allocated memory because no palette or text chunk
|
||||
info is in the LodePNGInfo object after checking only the header of the PNG.
|
||||
*/
|
||||
LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png);
|
||||
|
||||
/*
|
||||
Get the names and sizes of all chunks in the PNG file.
|
||||
Returns 0 if ok, non-0 if error happened.
|
||||
*/
|
||||
unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
|
||||
const std::vector<unsigned char>& png);
|
||||
|
||||
/*
|
||||
Returns the names and full chunks (including the name and everything else that
|
||||
makes up the chunk) for all chunks except IHDR, PLTE, IDAT and IEND.
|
||||
It separates the chunks into 3 separate lists, representing the chunks between
|
||||
certain critical chunks: 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
|
||||
Returns 0 if ok, non-0 if error happened.
|
||||
*/
|
||||
unsigned getChunks(std::vector<std::string> names[3],
|
||||
std::vector<std::vector<unsigned char> > chunks[3],
|
||||
const std::vector<unsigned char>& png);
|
||||
|
||||
/*
|
||||
Inserts chunks into the given png file. The chunks must be fully encoded,
|
||||
including length, type, content and CRC.
|
||||
The array index determines where it goes:
|
||||
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
|
||||
They're appended at the end of those locations within the PNG.
|
||||
Returns 0 if ok, non-0 if error happened.
|
||||
*/
|
||||
unsigned insertChunks(std::vector<unsigned char>& png,
|
||||
const std::vector<std::vector<unsigned char> > chunks[3]);
|
||||
|
||||
/*
|
||||
Get the filtertypes of each scanline in this PNG file.
|
||||
Returns 0 if ok, 1 if PNG decoding error happened.
|
||||
|
||||
For a non-interlaced PNG, it returns one filtertype per scanline, in order.
|
||||
|
||||
For interlaced PNGs, it returns a result as if it's not interlaced. It returns
|
||||
one filtertype per scanline, in order. The values match pass 6 and 7 of the
|
||||
Adam7 interlacing, alternating between the two, so that the values correspond
|
||||
the most to their scanlines.
|
||||
*/
|
||||
unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png);
|
||||
|
||||
/*
|
||||
Get the filtertypes of each scanline in every interlace pass this PNG file.
|
||||
Returns 0 if ok, 1 if PNG decoding error happened.
|
||||
|
||||
For a non-interlaced PNG, it returns one filtertype per scanline, in order, in
|
||||
a single std::vector in filterTypes.
|
||||
|
||||
For an interlaced PNG, it returns 7 std::vectors in filterTypes, one for each
|
||||
Adam7 pass. The amount of values per pass can be calculated as follows, where
|
||||
w and h are the size of the image and all divisions are integer divisions:
|
||||
pass 1: (h + 7) / 8
|
||||
pass 2: w <= 4 ? 0 : (h + 7) / 8
|
||||
pass 3: h <= 4 ? 0 : (h + 7) / 8
|
||||
pass 4: w <= 2 ? 0 : (h + 3) / 4
|
||||
pass 5: h <= 2 ? 0 : (h + 3) / 4
|
||||
pass 6: w <= 1 ? 0 : (h + 1) / 2
|
||||
pass 7: h <= 1 ? 0 : (h + 1) / 2
|
||||
*/
|
||||
unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes,
|
||||
const std::vector<unsigned char>& png);
|
||||
|
||||
/*
|
||||
Returns the value of the i-th pixel in an image with 1, 2, 4 or 8-bit color.
|
||||
E.g. if bits is 4 and i is 5, it returns the 5th nibble (4-bit group), which
|
||||
is the second half of the 3th byte, in big endian (PNG's endian order).
|
||||
*/
|
||||
int getPaletteValue(const unsigned char* data, size_t i, int bits);
|
||||
|
||||
/*
|
||||
The information for extractZlibInfo.
|
||||
*/
|
||||
struct ZlibBlockInfo
|
||||
{
|
||||
int btype; //block type (0-2)
|
||||
size_t compressedbits; //size of compressed block in bits
|
||||
size_t uncompressedbytes; //size of uncompressed block in bytes
|
||||
|
||||
// only filled in for block type 2
|
||||
size_t treebits; //encoded tree size in bits
|
||||
int hlit; //the HLIT value that was filled in for this tree
|
||||
int hdist; //the HDIST value that was filled in for this tree
|
||||
int hclen; //the HCLEN value that was filled in for this tree
|
||||
std::vector<int> clcl; //19 code length code lengths (compressed tree's tree)
|
||||
std::vector<int> treecodes; //N tree codes, with values 0-18. Values 17 or 18 are followed by the repetition value.
|
||||
std::vector<int> litlenlengths; //288 code lengths for lit/len symbols
|
||||
std::vector<int> distlengths; //32 code lengths for dist symbols
|
||||
|
||||
// only filled in for block types 1 or 2
|
||||
std::vector<int> lz77_lcode; //LZ77 codes. 0-255: literals. 256: end symbol. 257-285: length code of length/dist pairs
|
||||
// the next vectors have the same size as lz77_lcode, but an element only has meaningful value if lz77_lcode contains a length code.
|
||||
std::vector<int> lz77_dcode;
|
||||
std::vector<int> lz77_lbits;
|
||||
std::vector<int> lz77_dbits;
|
||||
std::vector<int> lz77_lvalue;
|
||||
std::vector<int> lz77_dvalue;
|
||||
size_t numlit; //number of lit codes in this block
|
||||
size_t numlen; //number of len codes in this block
|
||||
};
|
||||
|
||||
//Extracts all info needed from a PNG file to reconstruct the zlib compression exactly.
|
||||
void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in);
|
||||
|
||||
} // namespace lodepng
|
||||
471
build/node_modules/node-zopfli/zopfli/src/zopflipng/zopflipng_bin.cc
generated
vendored
Normal file
471
build/node_modules/node-zopfli/zopfli/src/zopflipng/zopflipng_bin.cc
generated
vendored
Normal file
@@ -0,0 +1,471 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
||||
// Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
||||
|
||||
// Command line tool to recompress and optimize PNG images, using zopflipng_lib.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lodepng/lodepng.h"
|
||||
#include "lodepng/lodepng_util.h"
|
||||
#include "zopflipng_lib.h"
|
||||
|
||||
// Returns directory path (including last slash) in dir, filename without
|
||||
// extension in file, extension (including the dot) in ext
|
||||
void GetFileNameParts(const std::string& filename,
|
||||
std::string* dir, std::string* file, std::string* ext) {
|
||||
size_t npos = (size_t)(-1);
|
||||
size_t slashpos = filename.find_last_of("/\\");
|
||||
std::string nodir;
|
||||
if (slashpos == npos) {
|
||||
*dir = "";
|
||||
nodir = filename;
|
||||
} else {
|
||||
*dir = filename.substr(0, slashpos + 1);
|
||||
nodir = filename.substr(slashpos + 1);
|
||||
}
|
||||
size_t dotpos = nodir.find_last_of('.');
|
||||
if (dotpos == (size_t)(-1)) {
|
||||
*file = nodir;
|
||||
*ext = "";
|
||||
} else {
|
||||
*file = nodir.substr(0, dotpos);
|
||||
*ext = nodir.substr(dotpos);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns whether the file exists and we have read permissions.
|
||||
bool FileExists(const std::string& filename) {
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
if (file) {
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the size of the file, if it exists and we have read permissions.
|
||||
size_t GetFileSize(const std::string& filename) {
|
||||
size_t size;
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
if (!file) return 0;
|
||||
fseek(file , 0 , SEEK_END);
|
||||
size = static_cast<size_t>(ftell(file));
|
||||
fclose(file);
|
||||
return size;
|
||||
}
|
||||
|
||||
void ShowHelp() {
|
||||
printf("ZopfliPNG, a Portable Network Graphics (PNG) image optimizer.\n"
|
||||
"\n"
|
||||
"Usage: zopflipng [options]... infile.png outfile.png\n"
|
||||
" zopflipng [options]... --prefix=[fileprefix] [files.png]...\n"
|
||||
"\n"
|
||||
"If the output file exists, it is considered a result from a"
|
||||
" previous run and not overwritten if its filesize is smaller.\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"-m: compress more: use more iterations (depending on file size)\n"
|
||||
"--prefix=[fileprefix]: Adds a prefix to output filenames. May also"
|
||||
" contain a directory path. When using a prefix, multiple input files"
|
||||
" can be given and the output filenames are generated with the"
|
||||
" prefix\n"
|
||||
" If --prefix is specified without value, 'zopfli_' is used.\n"
|
||||
" If input file names contain the prefix, they are not processed but"
|
||||
" considered as output from previous runs. This is handy when using"
|
||||
" *.png wildcard expansion with multiple runs.\n"
|
||||
"-y: do not ask about overwriting files.\n"
|
||||
"--lossy_transparent: remove colors behind alpha channel 0. No visual"
|
||||
" difference, removes hidden information.\n"
|
||||
"--lossy_8bit: convert 16-bit per channel image to 8-bit per"
|
||||
" channel.\n"
|
||||
"-d: dry run: don't save any files, just see the console output"
|
||||
" (e.g. for benchmarking)\n"
|
||||
"--always_zopflify: always output the image encoded by Zopfli, even if"
|
||||
" it's bigger than the original, for benchmarking the algorithm. Not"
|
||||
" good for real optimization.\n"
|
||||
"-q: use quick, but not very good, compression"
|
||||
" (e.g. for only trying the PNG filter and color types)\n"
|
||||
"--iterations=[number]: number of iterations, more iterations makes it"
|
||||
" slower but provides slightly better compression. Default: 15 for"
|
||||
" small files, 5 for large files.\n"
|
||||
"--splitting=[0-3]: ignored, left for backwards compatibility\n"
|
||||
"--filters=[types]: filter strategies to try:\n"
|
||||
" 0-4: give all scanlines PNG filter type 0-4\n"
|
||||
" m: minimum sum\n"
|
||||
" e: entropy\n"
|
||||
" p: predefined (keep from input, this likely overlaps another"
|
||||
" strategy)\n"
|
||||
" b: brute force (experimental)\n"
|
||||
" By default, if this argument is not given, one that is most likely"
|
||||
" the best for this image is chosen by trying faster compression with"
|
||||
" each type.\n"
|
||||
" If this argument is used, all given filter types"
|
||||
" are tried with slow compression and the best result retained. A good"
|
||||
" set of filters to try is --filters=0me.\n"
|
||||
"--keepchunks=nAME,nAME,...: keep metadata chunks with these names"
|
||||
" that would normally be removed, e.g. tEXt,zTXt,iTXt,gAMA, ... \n"
|
||||
" Due to adding extra data, this increases the result size. Keeping"
|
||||
" bKGD or sBIT chunks may cause additional worse compression due to"
|
||||
" forcing a certain color type, it is advised to not keep these for"
|
||||
" web images because web browsers do not use these chunks. By default"
|
||||
" ZopfliPNG only keeps (and losslessly modifies) the following chunks"
|
||||
" because they are essential: IHDR, PLTE, tRNS, IDAT and IEND.\n"
|
||||
"\n"
|
||||
"Usage examples:\n"
|
||||
"Optimize a file and overwrite if smaller: zopflipng infile.png"
|
||||
" outfile.png\n"
|
||||
"Compress more: zopflipng -m infile.png outfile.png\n"
|
||||
"Optimize multiple files: zopflipng --prefix a.png b.png c.png\n"
|
||||
"Compress really good and trying all filter strategies: zopflipng"
|
||||
" --iterations=500 --filters=01234mepb --lossy_8bit"
|
||||
" --lossy_transparent infile.png outfile.png\n");
|
||||
}
|
||||
|
||||
void PrintSize(const char* label, size_t size) {
|
||||
printf("%s: %d (%dK)\n", label, (int) size, (int) size / 1024);
|
||||
}
|
||||
|
||||
void PrintResultSize(const char* label, size_t oldsize, size_t newsize) {
|
||||
printf("%s: %d (%dK). Percentage of original: %.3f%%\n",
|
||||
label, (int) newsize, (int) newsize / 1024, newsize * 100.0 / oldsize);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
ShowHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZopfliPNGOptions png_options;
|
||||
|
||||
// cmd line options
|
||||
bool always_zopflify = false; // overwrite file even if we have bigger result
|
||||
bool yes = false; // do not ask to overwrite files
|
||||
bool dryrun = false; // never save anything
|
||||
|
||||
std::string user_out_filename; // output filename if no prefix is used
|
||||
bool use_prefix = false;
|
||||
std::string prefix = "zopfli_"; // prefix for output filenames
|
||||
|
||||
std::vector<std::string> files;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg = argv[i];
|
||||
if (arg[0] == '-' && arg.size() > 1 && arg[1] != '-') {
|
||||
for (size_t pos = 1; pos < arg.size(); pos++) {
|
||||
char c = arg[pos];
|
||||
if (c == 'y') {
|
||||
yes = true;
|
||||
} else if (c == 'd') {
|
||||
dryrun = true;
|
||||
} else if (c == 'm') {
|
||||
png_options.num_iterations *= 4;
|
||||
png_options.num_iterations_large *= 4;
|
||||
} else if (c == 'q') {
|
||||
png_options.use_zopfli = false;
|
||||
} else if (c == 'h') {
|
||||
ShowHelp();
|
||||
return 0;
|
||||
} else {
|
||||
printf("Unknown flag: %c\n", c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (arg[0] == '-' && arg.size() > 1 && arg[1] == '-') {
|
||||
size_t eq = arg.find('=');
|
||||
std::string name = arg.substr(0, eq);
|
||||
std::string value = eq >= arg.size() - 1 ? "" : arg.substr(eq + 1);
|
||||
int num = atoi(value.c_str());
|
||||
if (name == "--always_zopflify") {
|
||||
always_zopflify = true;
|
||||
} else if (name == "--verbose") {
|
||||
png_options.verbose = true;
|
||||
} else if (name == "--lossy_transparent") {
|
||||
png_options.lossy_transparent = true;
|
||||
} else if (name == "--lossy_8bit") {
|
||||
png_options.lossy_8bit = true;
|
||||
} else if (name == "--iterations") {
|
||||
if (num < 1) num = 1;
|
||||
png_options.num_iterations = num;
|
||||
png_options.num_iterations_large = num;
|
||||
} else if (name == "--splitting") {
|
||||
// ignored
|
||||
} else if (name == "--filters") {
|
||||
for (size_t j = 0; j < value.size(); j++) {
|
||||
ZopfliPNGFilterStrategy strategy = kStrategyZero;
|
||||
char f = value[j];
|
||||
switch (f) {
|
||||
case '0': strategy = kStrategyZero; break;
|
||||
case '1': strategy = kStrategyOne; break;
|
||||
case '2': strategy = kStrategyTwo; break;
|
||||
case '3': strategy = kStrategyThree; break;
|
||||
case '4': strategy = kStrategyFour; break;
|
||||
case 'm': strategy = kStrategyMinSum; break;
|
||||
case 'e': strategy = kStrategyEntropy; break;
|
||||
case 'p': strategy = kStrategyPredefined; break;
|
||||
case 'b': strategy = kStrategyBruteForce; break;
|
||||
default:
|
||||
printf("Unknown filter strategy: %c\n", f);
|
||||
return 1;
|
||||
}
|
||||
png_options.filter_strategies.push_back(strategy);
|
||||
// Enable auto filter strategy only if no user-specified filter is
|
||||
// given.
|
||||
png_options.auto_filter_strategy = false;
|
||||
}
|
||||
} else if (name == "--keepchunks") {
|
||||
bool correct = true;
|
||||
if ((value.size() + 1) % 5 != 0) correct = false;
|
||||
for (size_t i = 0; i + 4 <= value.size() && correct; i += 5) {
|
||||
png_options.keepchunks.push_back(value.substr(i, 4));
|
||||
if (i > 4 && value[i - 1] != ',') correct = false;
|
||||
}
|
||||
if (!correct) {
|
||||
printf("Error: keepchunks format must be like for example:\n"
|
||||
" --keepchunks=gAMA,cHRM,sRGB,iCCP\n");
|
||||
return 0;
|
||||
}
|
||||
} else if (name == "--prefix") {
|
||||
use_prefix = true;
|
||||
if (!value.empty()) prefix = value;
|
||||
} else if (name == "--help") {
|
||||
ShowHelp();
|
||||
return 0;
|
||||
} else {
|
||||
printf("Unknown flag: %s\n", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
files.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_prefix) {
|
||||
if (files.size() == 2) {
|
||||
// The second filename is the output instead of an input if no prefix is
|
||||
// given.
|
||||
user_out_filename = files[1];
|
||||
files.resize(1);
|
||||
} else {
|
||||
printf("Please provide one input and output filename\n\n");
|
||||
ShowHelp();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t total_in_size = 0;
|
||||
// Total output size, taking input size if the input file was smaller
|
||||
size_t total_out_size = 0;
|
||||
// Total output size that zopfli produced, even if input was smaller, for
|
||||
// benchmark information
|
||||
size_t total_out_size_zopfli = 0;
|
||||
size_t total_errors = 0;
|
||||
size_t total_files = 0;
|
||||
size_t total_files_smaller = 0;
|
||||
size_t total_files_saved = 0;
|
||||
size_t total_files_equal = 0;
|
||||
|
||||
for (size_t i = 0; i < files.size(); i++) {
|
||||
if (use_prefix && files.size() > 1) {
|
||||
std::string dir, file, ext;
|
||||
GetFileNameParts(files[i], &dir, &file, &ext);
|
||||
// avoid doing filenames which were already output by this so that you
|
||||
// don't get zopfli_zopfli_zopfli_... files after multiple runs.
|
||||
if (file.find(prefix) == 0) continue;
|
||||
}
|
||||
|
||||
total_files++;
|
||||
|
||||
printf("Optimizing %s\n", files[i].c_str());
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
std::vector<unsigned char> origpng;
|
||||
unsigned error;
|
||||
lodepng::State inputstate;
|
||||
std::vector<unsigned char> resultpng;
|
||||
|
||||
error = lodepng::load_file(origpng, files[i]);
|
||||
if (!error) {
|
||||
error = ZopfliPNGOptimize(origpng, png_options,
|
||||
png_options.verbose, &resultpng);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (error == 1) {
|
||||
printf("Decoding error\n");
|
||||
} else {
|
||||
printf("Decoding error %u: %s\n", error, lodepng_error_text(error));
|
||||
}
|
||||
}
|
||||
|
||||
// Verify result, check that the result causes no decoding errors
|
||||
if (!error) {
|
||||
error = lodepng::decode(image, w, h, resultpng);
|
||||
if (!error) {
|
||||
std::vector<unsigned char> origimage;
|
||||
unsigned origw, origh;
|
||||
lodepng::decode(origimage, origw, origh, origpng);
|
||||
if (origw != w || origh != h || origimage.size() != image.size()) {
|
||||
error = 1;
|
||||
} else {
|
||||
for (size_t i = 0; i < image.size(); i += 4) {
|
||||
bool same_alpha = image[i + 3] == origimage[i + 3];
|
||||
bool same_rgb =
|
||||
(png_options.lossy_transparent && image[i + 3] == 0) ||
|
||||
(image[i + 0] == origimage[i + 0] &&
|
||||
image[i + 1] == origimage[i + 1] &&
|
||||
image[i + 2] == origimage[i + 2]);
|
||||
if (!same_alpha || !same_rgb) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
printf("Error: verification of result failed, keeping original."
|
||||
" Error: %u.\n", error);
|
||||
// Reset the error to 0, instead set output back to the original. The
|
||||
// input PNG is valid, zopfli failed on it so treat as if it could not
|
||||
// make it smaller.
|
||||
error = 0;
|
||||
resultpng = origpng;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
total_errors++;
|
||||
} else {
|
||||
size_t origsize = origpng.size();
|
||||
size_t resultsize = resultpng.size();
|
||||
|
||||
if (!png_options.keepchunks.empty()) {
|
||||
std::vector<std::string> names;
|
||||
std::vector<size_t> sizes;
|
||||
lodepng::getChunkInfo(names, sizes, resultpng);
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
if (names[i] == "bKGD" || names[i] == "sBIT") {
|
||||
printf("Forced to keep original color type due to keeping bKGD or"
|
||||
" sBIT chunk. Try without --keepchunks for better"
|
||||
" compression.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintSize("Input size", origsize);
|
||||
PrintResultSize("Result size", origsize, resultsize);
|
||||
if (resultsize < origsize) {
|
||||
printf("Result is smaller\n");
|
||||
} else if (resultsize == origsize) {
|
||||
printf("Result has exact same size\n");
|
||||
} else {
|
||||
printf(always_zopflify
|
||||
? "Original was smaller\n"
|
||||
: "Preserving original PNG since it was smaller\n");
|
||||
}
|
||||
|
||||
std::string out_filename = user_out_filename;
|
||||
if (use_prefix) {
|
||||
std::string dir, file, ext;
|
||||
GetFileNameParts(files[i], &dir, &file, &ext);
|
||||
out_filename = dir + prefix + file + ext;
|
||||
}
|
||||
bool different_output_name = out_filename != files[i];
|
||||
|
||||
total_in_size += origsize;
|
||||
total_out_size_zopfli += resultpng.size();
|
||||
if (resultpng.size() < origsize) total_files_smaller++;
|
||||
else if (resultpng.size() == origsize) total_files_equal++;
|
||||
|
||||
if (!always_zopflify && resultpng.size() >= origsize) {
|
||||
// Set output file to input since zopfli didn't improve it.
|
||||
resultpng = origpng;
|
||||
}
|
||||
|
||||
bool already_exists = FileExists(out_filename);
|
||||
size_t origoutfilesize = GetFileSize(out_filename);
|
||||
|
||||
// When using a prefix, and the output file already exist, assume it's
|
||||
// from a previous run. If that file is smaller, it may represent a
|
||||
// previous run with different parameters that gave a smaller PNG image.
|
||||
// This also applies when not using prefix but same input as output file.
|
||||
// In that case, do not overwrite it. This behaviour can be removed by
|
||||
// adding the always_zopflify flag.
|
||||
bool keep_earlier_output_file = already_exists &&
|
||||
resultpng.size() >= origoutfilesize && !always_zopflify &&
|
||||
(use_prefix || !different_output_name);
|
||||
|
||||
if (keep_earlier_output_file) {
|
||||
// An output file from a previous run is kept, add that files' size
|
||||
// to the output size statistics.
|
||||
total_out_size += origoutfilesize;
|
||||
if (use_prefix) {
|
||||
printf(resultpng.size() == origoutfilesize
|
||||
? "File not written because a previous run was as good.\n"
|
||||
: "File not written because a previous run was better.\n");
|
||||
}
|
||||
} else {
|
||||
bool confirmed = true;
|
||||
if (!yes && !dryrun && already_exists) {
|
||||
printf("File %s exists, overwrite? (y/N) ", out_filename.c_str());
|
||||
char answer = 0;
|
||||
// Read the first character, the others and enter with getchar.
|
||||
while (int input = getchar()) {
|
||||
if (input == '\n' || input == EOF) break;
|
||||
else if (!answer) answer = input;
|
||||
}
|
||||
confirmed = answer == 'y' || answer == 'Y';
|
||||
}
|
||||
if (confirmed) {
|
||||
if (!dryrun) {
|
||||
if (lodepng::save_file(resultpng, out_filename) != 0) {
|
||||
printf("Failed to write to file %s\n", out_filename.c_str());
|
||||
} else {
|
||||
total_files_saved++;
|
||||
}
|
||||
}
|
||||
total_out_size += resultpng.size();
|
||||
} else {
|
||||
// An output file from a previous run is kept, add that files' size
|
||||
// to the output size statistics.
|
||||
total_out_size += origoutfilesize;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (total_files > 1) {
|
||||
printf("Summary for all files:\n");
|
||||
printf("Files tried: %d\n", (int) total_files);
|
||||
printf("Files smaller: %d\n", (int) total_files_smaller);
|
||||
if (total_files_equal) {
|
||||
printf("Files equal: %d\n", (int) total_files_equal);
|
||||
}
|
||||
printf("Files saved: %d\n", (int) total_files_saved);
|
||||
if (total_errors) printf("Errors: %d\n", (int) total_errors);
|
||||
PrintSize("Total input size", total_in_size);
|
||||
PrintResultSize("Total output size", total_in_size, total_out_size);
|
||||
PrintResultSize("Benchmark result size",
|
||||
total_in_size, total_out_size_zopfli);
|
||||
}
|
||||
|
||||
if (dryrun) printf("No files were written because dry run was specified\n");
|
||||
|
||||
return total_errors;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user