mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-19 12:08:57 +00:00
Optipng (#156)
* omg it’s compiling * example actually works * Expose compression level options * Disable crypto and path module emulation in webpack * Update README * Remove small image * Use -O3 on optipng * Free memory after copy * Handle unexpected file reader return types * Rename level label to effort
This commit is contained in:
BIN
codecs/example_palette.png
Normal file
BIN
codecs/example_palette.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 239 KiB |
2
codecs/optipng/.gitignore
vendored
Normal file
2
codecs/optipng/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build/
|
||||
*.o
|
||||
26
codecs/optipng/README.md
Normal file
26
codecs/optipng/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# OptiPNG
|
||||
|
||||
- Source: <https://sourceforge.net/project/optipng>
|
||||
- Version: v0.7.7
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Docker
|
||||
|
||||
## Example
|
||||
|
||||
See `example.html`
|
||||
|
||||
## API
|
||||
|
||||
### `int version()`
|
||||
|
||||
Returns the version of optipng as a number. va.b.c is encoded as 0x0a0b0c
|
||||
|
||||
### `ArrayBuffer compress(std::string buffer, {level})`;
|
||||
|
||||
`compress` will re-compress the given PNG image via `buffer`. `level` is a number between 0 and 7.
|
||||
|
||||
### `void free_result()`
|
||||
|
||||
Frees the result created by `compress()`.
|
||||
80
codecs/optipng/build.sh
Executable file
80
codecs/optipng/build.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export PREFIX="/src/build"
|
||||
export CFLAGS="-I${PREFIX}/include/"
|
||||
export CPPFLAGS="-I${PREFIX}/include/"
|
||||
export LDFLAGS="-L${PREFIX}/lib/"
|
||||
|
||||
apt-get update
|
||||
apt-get install -qqy autoconf libtool
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling zlib"
|
||||
echo "============================================="
|
||||
test -n "$SKIP_ZLIB" || (
|
||||
cd node_modules/zlib
|
||||
emconfigure ./configure --prefix=${PREFIX}/
|
||||
emmake make
|
||||
emmake make install
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling zlib done"
|
||||
echo "============================================="
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling libpng"
|
||||
echo "============================================="
|
||||
test -n "$SKIP_LIBPNG" || (
|
||||
cd node_modules/libpng
|
||||
autoreconf -i
|
||||
emconfigure ./configure --with-zlib-prefix=${PREFIX}/ --prefix=${PREFIX}/
|
||||
emmake make
|
||||
emmake make install
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling libpng done"
|
||||
echo "============================================="
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling optipng"
|
||||
echo "============================================="
|
||||
(
|
||||
emcc \
|
||||
-O3 \
|
||||
-Wno-implicit-function-declaration \
|
||||
-I ${PREFIX}/include \
|
||||
-I node_modules/optipng/src/opngreduc \
|
||||
-I node_modules/optipng/src/pngxtern \
|
||||
-I node_modules/optipng/src/cexcept \
|
||||
-I node_modules/optipng/src/gifread \
|
||||
-I node_modules/optipng/src/pnmio \
|
||||
-I node_modules/optipng/src/minitiff \
|
||||
--std=c99 -c \
|
||||
node_modules/optipng/src/opngreduc/*.c \
|
||||
node_modules/optipng/src/pngxtern/*.c \
|
||||
node_modules/optipng/src/gifread/*.c \
|
||||
node_modules/optipng/src/minitiff/*.c \
|
||||
node_modules/optipng/src/pnmio/*.c \
|
||||
node_modules/optipng/src/optipng/*.c
|
||||
|
||||
emcc \
|
||||
--bind -O3 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME="optipng"' \
|
||||
-I ${PREFIX}/include \
|
||||
-I node_modules/optipng/src/opngreduc \
|
||||
-I node_modules/optipng/src/pngxtern \
|
||||
-I node_modules/optipng/src/cexcept \
|
||||
-I node_modules/optipng/src/gifread \
|
||||
-I node_modules/optipng/src/pnmio \
|
||||
-I node_modules/optipng/src/minitiff \
|
||||
-o "optipng.js" \
|
||||
--std=c++11 \
|
||||
optipng.cpp \
|
||||
*.o \
|
||||
${PREFIX}/lib/libz.so ${PREFIX}/lib/libpng.a
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling optipng done"
|
||||
echo "============================================="
|
||||
19
codecs/optipng/example.html
Normal file
19
codecs/optipng/example.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<script src='optipng.js'></script>
|
||||
<script>
|
||||
const Module = optipng();
|
||||
|
||||
Module.onRuntimeInitialized = async _ => {
|
||||
console.log('Version:', Module.version().toString(16));
|
||||
const image = await fetch('../example_palette.png').then(r => r.arrayBuffer());
|
||||
const newImage = Module.compress(image, {level: 3});
|
||||
console.log('done');
|
||||
Module.free_result();
|
||||
|
||||
console.log(`Old size: ${image.byteLength}, new size: ${newImage.byteLength} (${newImage.byteLength/image.byteLength*100}%)`);
|
||||
const blobURL = URL.createObjectURL(new Blob([newImage], {type: 'image/png'}));
|
||||
const img = document.createElement('img');
|
||||
img.src = blobURL;
|
||||
document.body.appendChild(img);
|
||||
};
|
||||
</script>
|
||||
51
codecs/optipng/optipng.cpp
Normal file
51
codecs/optipng/optipng.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "emscripten/bind.h"
|
||||
#include "emscripten/val.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
extern "C" int main(int argc, char *argv[]);
|
||||
|
||||
int version() {
|
||||
// FIXME (@surma): Haven’t found a version in optipng :(
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct OptiPngOpts {
|
||||
int level;
|
||||
};
|
||||
|
||||
uint8_t* result;
|
||||
val compress(std::string png, OptiPngOpts opts) {
|
||||
FILE* infile = fopen("input.png", "wb");
|
||||
fwrite(png.c_str(), png.length(), 1, infile);
|
||||
fflush(infile);
|
||||
fclose(infile);
|
||||
|
||||
char optlevel[8];
|
||||
sprintf(&optlevel[0], "-o%d", opts.level);
|
||||
char* args[] = {"optipng", optlevel, "-out", "output.png", "input.png"};
|
||||
main(5, args);
|
||||
|
||||
FILE *outfile = fopen("output.png", "rb");
|
||||
fseek(outfile, 0, SEEK_END);
|
||||
int fsize = ftell(outfile);
|
||||
result = (uint8_t*) malloc(fsize);
|
||||
fseek(outfile, 0, SEEK_SET);
|
||||
fread(result, fsize, 1, outfile);
|
||||
return val(typed_memory_view(fsize, result));
|
||||
}
|
||||
|
||||
void free_result() {
|
||||
free(result);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<OptiPngOpts>("OptiPngOpts")
|
||||
.field("level", &OptiPngOpts::level);
|
||||
|
||||
function("version", &version);
|
||||
function("compress", &compress);
|
||||
function("free_result", &free_result);
|
||||
}
|
||||
10
codecs/optipng/optipng.d.ts
vendored
Normal file
10
codecs/optipng/optipng.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import {EncodeOptions} from "src/codecs/optipng/encoder";
|
||||
|
||||
export interface OptiPngModule extends EmscriptenWasm.Module {
|
||||
compress(data: BufferSource, opts: EncodeOptions): Uint8Array;
|
||||
free_result(): void;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): OptiPngModule;
|
||||
|
||||
|
||||
24
codecs/optipng/optipng.js
Normal file
24
codecs/optipng/optipng.js
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/optipng/optipng.wasm
Normal file
BIN
codecs/optipng/optipng.wasm
Normal file
Binary file not shown.
1457
codecs/optipng/package-lock.json
generated
Normal file
1457
codecs/optipng/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
codecs/optipng/package.json
Normal file
22
codecs/optipng/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "optipng",
|
||||
"scripts": {
|
||||
"install": "tar-dependency install && napa",
|
||||
"build": "npm run build:wasm",
|
||||
"build:wasm": "docker run --rm -v $(pwd):/src -e SKIP_ZLIB=\"${SKIP_ZLIB}\" -e SKIP_LIBPNG=\"${SKIP_LIBPNG}\" trzeci/emscripten ./build.sh"
|
||||
},
|
||||
"tarDependencies": {
|
||||
"node_modules/optipng": {
|
||||
"url": "https://netcologne.dl.sourceforge.net/project/optipng/OptiPNG/optipng-0.7.7/optipng-0.7.7.tar.gz",
|
||||
"strip": 1
|
||||
}
|
||||
},
|
||||
"napa": {
|
||||
"libpng": "emscripten-ports/libpng",
|
||||
"zlib": "emscripten-ports/zlib"
|
||||
},
|
||||
"dependencies": {
|
||||
"napa": "^3.0.0",
|
||||
"tar-dependency": "0.0.3"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user