forked from external-repos/squoosh
Mozjpeg opts (#140)
* Switching to embind * Adding options to mozjpeg wasm * Updating packages * Ditching enum - causing more problems than it's worth * Adding mozjpeg options UI * Forgot about this enum * Bools just work
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<script src='mozjpeg_enc.js'></script>
|
<script src='mozjpeg_enc.js'></script>
|
||||||
<script>
|
<script>
|
||||||
const Module = mozjpeg_enc();
|
const module = mozjpeg_enc();
|
||||||
|
|
||||||
async function loadImage(src) {
|
async function loadImage(src) {
|
||||||
// Load image
|
// Load image
|
||||||
@@ -17,27 +17,32 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
module.onRuntimeInitialized = async _ => {
|
||||||
const api = {
|
console.log('Version:', module.version().toString(16));
|
||||||
version: Module.cwrap('version', 'number', []),
|
|
||||||
create_buffer: Module.cwrap('create_buffer', 'number', ['number', 'number']),
|
|
||||||
destroy_buffer: Module.cwrap('destroy_buffer', '', ['number']),
|
|
||||||
encode: Module.cwrap('encode', '', ['number', 'number', 'number', 'number']),
|
|
||||||
free_result: Module.cwrap('free_result', '', ['number']),
|
|
||||||
get_result_pointer: Module.cwrap('get_result_pointer', 'number', []),
|
|
||||||
get_result_size: Module.cwrap('get_result_size', 'number', []),
|
|
||||||
};
|
|
||||||
console.log('Version:', api.version().toString(16));
|
|
||||||
const image = await loadImage('../example.png');
|
const image = await loadImage('../example.png');
|
||||||
const p = api.create_buffer(image.width, image.height);
|
const p = module.create_buffer(image.width, image.height);
|
||||||
Module.HEAP8.set(image.data, p);
|
module.HEAP8.set(image.data, p);
|
||||||
api.encode(p, image.width, image.height, 2);
|
module.encode(p, image.width, image.height, {
|
||||||
const resultPointer = api.get_result_pointer();
|
quality: 40,
|
||||||
const resultSize = api.get_result_size();
|
baseline: false,
|
||||||
const resultView = new Uint8Array(Module.HEAP8.buffer, resultPointer, resultSize);
|
arithmetic: false,
|
||||||
|
progressive: true,
|
||||||
|
optimize_coding: true,
|
||||||
|
smoothing: 0,
|
||||||
|
color_space: 3,
|
||||||
|
quant_table: 3,
|
||||||
|
trellis_multipass: true,
|
||||||
|
trellis_opt_zero: true,
|
||||||
|
trellis_opt_table: true,
|
||||||
|
trellis_loops: 1,
|
||||||
|
});
|
||||||
|
const resultPointer = module.get_result_pointer();
|
||||||
|
const resultSize = module.get_result_size();
|
||||||
|
console.log('size', resultSize);
|
||||||
|
const resultView = new Uint8Array(module.HEAP8.buffer, resultPointer, resultSize);
|
||||||
const result = new Uint8Array(resultView);
|
const result = new Uint8Array(resultView);
|
||||||
api.free_result(resultPointer);
|
module.free_result();
|
||||||
api.destroy_buffer(p);
|
module.destroy_buffer(p);
|
||||||
|
|
||||||
const blob = new Blob([result], {type: 'image/jpeg'});
|
const blob = new Blob([result], {type: 'image/jpeg'});
|
||||||
const blobURL = URL.createObjectURL(blob);
|
const blobURL = URL.createObjectURL(blob);
|
||||||
|
|||||||
@@ -4,14 +4,33 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "jpeglib.h"
|
#include <emscripten/bind.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "jpeglib.h"
|
||||||
|
#include "cdjpeg.h"
|
||||||
|
|
||||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro hackery to turn it into a string. More details here: https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
using namespace emscripten;
|
||||||
|
|
||||||
|
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro hackery to turn it
|
||||||
|
// into a string. More details here: https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) str(s)
|
||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
struct MozJpegOptions {
|
||||||
|
int quality;
|
||||||
|
bool baseline;
|
||||||
|
bool arithmetic;
|
||||||
|
bool progressive;
|
||||||
|
bool optimize_coding;
|
||||||
|
int smoothing;
|
||||||
|
int color_space;
|
||||||
|
int quant_table;
|
||||||
|
bool trellis_multipass;
|
||||||
|
bool trellis_opt_zero;
|
||||||
|
bool trellis_opt_table;
|
||||||
|
int trellis_loops;
|
||||||
|
};
|
||||||
|
|
||||||
int version() {
|
int version() {
|
||||||
char buffer[] = xstr(MOZJPEG_VERSION);
|
char buffer[] = xstr(MOZJPEG_VERSION);
|
||||||
int version = 0;
|
int version = 0;
|
||||||
@@ -28,27 +47,17 @@ int version() {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
int create_buffer(int width, int height) {
|
||||||
uint8_t* create_buffer(int width, int height) {
|
return (int) malloc(width * height * 4 * sizeof(uint8_t));
|
||||||
return malloc(width * height * 4 * sizeof(uint8_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
void destroy_buffer(int p) {
|
||||||
void destroy_buffer(uint8_t* p) {
|
free((uint8_t*) p);
|
||||||
free(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int result[2];
|
int result[2];
|
||||||
EMSCRIPTEN_KEEPALIVE
|
void encode(int image_in, int image_width, int image_height, MozJpegOptions opts) {
|
||||||
void encode(uint8_t* image_buffer, int image_width, int image_height, int quality) {
|
uint8_t* image_buffer = (uint8_t*) image_in;
|
||||||
// Manually convert RGBA data into RGB
|
|
||||||
for(int y = 0; y < image_height; y++) {
|
|
||||||
for(int x = 0; x < image_width; x++) {
|
|
||||||
image_buffer[(y*image_width + x)*3 + 0] = image_buffer[(y*image_width + x)*4 + 0];
|
|
||||||
image_buffer[(y*image_width + x)*3 + 1] = image_buffer[(y*image_width + x)*4 + 1];
|
|
||||||
image_buffer[(y*image_width + x)*3 + 2] = image_buffer[(y*image_width + x)*4 + 2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The code below is basically the `write_JPEG_file` function from
|
// The code below is basically the `write_JPEG_file` function from
|
||||||
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
||||||
@@ -109,18 +118,48 @@ void encode(uint8_t* image_buffer, int image_width, int image_height, int qualit
|
|||||||
*/
|
*/
|
||||||
cinfo.image_width = image_width; /* image width and height, in pixels */
|
cinfo.image_width = image_width; /* image width and height, in pixels */
|
||||||
cinfo.image_height = image_height;
|
cinfo.image_height = image_height;
|
||||||
cinfo.input_components = 3; /* # of color components per pixel */
|
cinfo.input_components = 4; /* # of color components per pixel */
|
||||||
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
||||||
/* Now use the library's routine to set default compression parameters.
|
/* Now use the library's routine to set default compression parameters.
|
||||||
* (You must set at least cinfo.in_color_space before calling this,
|
* (You must set at least cinfo.in_color_space before calling this,
|
||||||
* since the defaults depend on the source color space.)
|
* since the defaults depend on the source color space.)
|
||||||
*/
|
*/
|
||||||
jpeg_set_defaults(&cinfo);
|
jpeg_set_defaults(&cinfo);
|
||||||
|
|
||||||
/* Now you can set any non-default parameters you wish to.
|
/* Now you can set any non-default parameters you wish to.
|
||||||
* Here we just illustrate the use of quality (quantization table) scaling:
|
* Here we just illustrate the use of quality (quantization table) scaling:
|
||||||
*/
|
*/
|
||||||
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
|
jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE) opts.color_space);
|
||||||
|
|
||||||
|
if (opts.quant_table != -1) {
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.optimize_coding = opts.optimize_coding;
|
||||||
|
|
||||||
|
if (opts.arithmetic) {
|
||||||
|
cinfo.arith_code = TRUE;
|
||||||
|
cinfo.optimize_coding = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.smoothing_factor = opts.smoothing;
|
||||||
|
|
||||||
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_SCANS_IN_TRELLIS, opts.trellis_multipass);
|
||||||
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
||||||
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
||||||
|
|
||||||
|
std::string quality_str = std::to_string(opts.quality);
|
||||||
|
char const *pqual = quality_str.c_str();
|
||||||
|
|
||||||
|
set_quality_ratings(&cinfo, (char*) pqual, opts.baseline);
|
||||||
|
|
||||||
|
if (!opts.baseline && opts.progressive) {
|
||||||
|
jpeg_simple_progression(&cinfo);
|
||||||
|
} else {
|
||||||
|
cinfo.num_scans = 0;
|
||||||
|
cinfo.scan_info = NULL;
|
||||||
|
}
|
||||||
/* Step 4: Start compressor */
|
/* Step 4: Start compressor */
|
||||||
|
|
||||||
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
||||||
@@ -136,7 +175,7 @@ void encode(uint8_t* image_buffer, int image_width, int image_height, int qualit
|
|||||||
* To keep things simple, we pass one scanline per call; you can pass
|
* To keep things simple, we pass one scanline per call; you can pass
|
||||||
* more if you wish, though.
|
* more if you wish, though.
|
||||||
*/
|
*/
|
||||||
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
|
row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
|
||||||
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||||
@@ -161,18 +200,39 @@ void encode(uint8_t* image_buffer, int image_width, int image_height, int qualit
|
|||||||
/* And we're done! */
|
/* And we're done! */
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
|
||||||
void free_result() {
|
void free_result() {
|
||||||
free(result[0]); // not sure if this is right with mozjpeg
|
free((void*)result[0]); // not sure if this is right with mozjpeg
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
|
||||||
int get_result_pointer() {
|
int get_result_pointer() {
|
||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE
|
|
||||||
int get_result_size() {
|
int get_result_size() {
|
||||||
return result[1];
|
return result[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
value_object<MozJpegOptions>("MozJpegOptions")
|
||||||
|
.field("quality", &MozJpegOptions::quality)
|
||||||
|
.field("baseline", &MozJpegOptions::baseline)
|
||||||
|
.field("arithmetic", &MozJpegOptions::arithmetic)
|
||||||
|
.field("progressive", &MozJpegOptions::progressive)
|
||||||
|
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
||||||
|
.field("smoothing", &MozJpegOptions::smoothing)
|
||||||
|
.field("color_space", &MozJpegOptions::color_space)
|
||||||
|
.field("quant_table", &MozJpegOptions::quant_table)
|
||||||
|
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
||||||
|
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
||||||
|
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
||||||
|
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
||||||
|
;
|
||||||
|
|
||||||
|
function("version", &version);
|
||||||
|
function("create_buffer", &create_buffer, allow_raw_pointers());
|
||||||
|
function("destroy_buffer", &destroy_buffer, allow_raw_pointers());
|
||||||
|
function("encode", &encode, allow_raw_pointers());
|
||||||
|
function("free_result", &free_result);
|
||||||
|
function("get_result_pointer", &get_result_pointer, allow_raw_pointers());
|
||||||
|
function("get_result_size", &get_result_size, allow_raw_pointers());
|
||||||
|
}
|
||||||
14
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
14
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
@@ -1 +1,13 @@
|
|||||||
export default function(opts: EmscriptenWasm.ModuleOpts): EmscriptenWasm.Module;
|
import { EncodeOptions } from '../../src/codecs/mozjpeg/encoder';
|
||||||
|
|
||||||
|
interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||||
|
create_buffer(width: number, height: number): number;
|
||||||
|
encode(pointer: number, width: number, height: number, options: EncodeOptions): void;
|
||||||
|
get_result_pointer(): number;
|
||||||
|
get_result_size(): number;
|
||||||
|
free_result(): void;
|
||||||
|
destroy_buffer(pointer: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function(opts: EmscriptenWasm.ModuleOpts): MozJPEGModule;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -4,7 +4,7 @@
|
|||||||
"install": "napa",
|
"install": "napa",
|
||||||
"build": "npm run build:library && npm run build:wasm",
|
"build": "npm run build:library && npm run build:wasm",
|
||||||
"build:library": "cd node_modules/mozjpeg && autoreconf -fiv && docker run --rm -v $(pwd):/src trzeci/emscripten emconfigure ./configure --without-simd && docker run --rm -v $(pwd):/src trzeci/emscripten emmake make libjpeg.la",
|
"build:library": "cd node_modules/mozjpeg && autoreconf -fiv && docker run --rm -v $(pwd):/src trzeci/emscripten emconfigure ./configure --without-simd && docker run --rm -v $(pwd):/src trzeci/emscripten emmake make libjpeg.la",
|
||||||
"build:wasm": "docker run --rm -v $(pwd):/src trzeci/emscripten emcc -O3 -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]' -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME=\"mozjpeg_enc\"' -I node_modules/mozjpeg -o ./mozjpeg_enc.js mozjpeg_enc.c node_modules/mozjpeg/.libs/libjpeg.a"
|
"build:wasm": "docker run --rm -v $(pwd):/src trzeci/emscripten emcc --bind -O3 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME=\"mozjpeg_enc\"' -I node_modules/mozjpeg -o ./mozjpeg_enc.js -Wno-deprecated-register -Wno-writable-strings node_modules/mozjpeg/rdswitch.c -x c++ -std=c++11 mozjpeg_enc.cpp node_modules/mozjpeg/.libs/libjpeg.a"
|
||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"mozjpeg": "mozilla/mozjpeg#v3.3.1"
|
"mozjpeg": "mozilla/mozjpeg#v3.3.1"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "webp_enc",
|
"name": "webp_enc",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "napa",
|
"install": "napa",
|
||||||
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten emcc --bind -O3 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME=\"webp_enc\"' -I node_modules/libwebp -o ./webp_enc.js -x c node_modules/libwebp/src/{dec,dsp,demux,enc,mux,utils}/*.c -x c++ -std=c++11 webp_enc.cpp "
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten emcc --bind -O3 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME=\"webp_enc\"' -I node_modules/libwebp -o ./webp_enc.js -x c node_modules/libwebp/src/{dec,dsp,demux,enc,mux,utils}/*.c -x c++ -std=c++11 webp_enc.cpp"
|
||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"libwebp": "webmproject/libwebp#v1.0.0"
|
"libwebp": "webmproject/libwebp#v1.0.0"
|
||||||
|
|||||||
368
package-lock.json
generated
368
package-lock.json
generated
@@ -1243,13 +1243,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "4.11.8",
|
"version": "5.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
||||||
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
|
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"co": "^4.6.0",
|
"co": "^4.6.0",
|
||||||
"json-stable-stringify": "^1.0.1"
|
"fast-deep-equal": "^1.0.0",
|
||||||
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
|
"json-schema-traverse": "^0.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ajv-keywords": {
|
"ajv-keywords": {
|
||||||
@@ -1426,10 +1428,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"asn1": {
|
"asn1": {
|
||||||
"version": "0.2.3",
|
"version": "0.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||||
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
|
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safer-buffer": "~2.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"asn1.js": {
|
"asn1.js": {
|
||||||
"version": "4.10.1",
|
"version": "4.10.1",
|
||||||
@@ -1469,9 +1474,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"assert-plus": {
|
"assert-plus": {
|
||||||
"version": "0.2.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
|
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"assign-symbols": {
|
"assign-symbols": {
|
||||||
@@ -1552,15 +1557,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"aws-sign2": {
|
"aws-sign2": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||||
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
|
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aws4": {
|
"aws4": {
|
||||||
"version": "1.7.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||||
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
|
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"babel-code-frame": {
|
"babel-code-frame": {
|
||||||
@@ -2306,9 +2311,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"babel-plugin-transform-react-remove-prop-types": {
|
"babel-plugin-transform-react-remove-prop-types": {
|
||||||
"version": "0.4.13",
|
"version": "0.4.14",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.13.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.14.tgz",
|
||||||
"integrity": "sha1-Mxz8BQmagII4MR14MZwnRg1IEYk=",
|
"integrity": "sha512-fMlqvLZPX9v7k0Sl4SVzHofQOKTDXvQbpKx+glCm5Ar5L5KQZ8VxjCsYslQwP+KrYXCG6BY7hOp+O1tUVATTDA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"babel-plugin-transform-regenerator": {
|
"babel-plugin-transform-regenerator": {
|
||||||
@@ -2765,15 +2770,6 @@
|
|||||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
|
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"boom": {
|
|
||||||
"version": "2.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
|
||||||
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"hoek": "2.x.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -3462,12 +3458,6 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"for-in": "^1.0.1"
|
"for-in": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"kind-of": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
|
||||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3902,15 +3892,6 @@
|
|||||||
"which": "^1.2.9"
|
"which": "^1.2.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cryptiles": {
|
|
||||||
"version": "2.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
|
||||||
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"boom": "2.x.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"crypto-browserify": {
|
"crypto-browserify": {
|
||||||
"version": "3.12.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
|
||||||
@@ -4093,14 +4074,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"date-fns": {
|
"date-fns": {
|
||||||
@@ -4490,13 +4463,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ecc-jsbn": {
|
"ecc-jsbn": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||||
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
|
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"jsbn": "~0.1.0"
|
"jsbn": "~0.1.0",
|
||||||
|
"safer-buffer": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editions": {
|
"editions": {
|
||||||
@@ -4530,9 +4504,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"elliptic": {
|
"elliptic": {
|
||||||
"version": "6.4.0",
|
"version": "6.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
|
||||||
"integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
|
"integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bn.js": "^4.4.0",
|
"bn.js": "^4.4.0",
|
||||||
@@ -5287,13 +5261,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"form-data": {
|
"form-data": {
|
||||||
"version": "2.1.4",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
|
||||||
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
|
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.5",
|
"combined-stream": "1.0.6",
|
||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5986,14 +5960,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gh-got": {
|
"gh-got": {
|
||||||
@@ -6305,19 +6271,19 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"har-schema": {
|
"har-schema": {
|
||||||
"version": "1.0.5",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||||
"integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
|
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"har-validator": {
|
"har-validator": {
|
||||||
"version": "4.2.1",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
|
||||||
"integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
|
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^4.9.1",
|
"ajv": "^5.1.0",
|
||||||
"har-schema": "^1.0.5"
|
"har-schema": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"has": {
|
"has": {
|
||||||
@@ -6429,18 +6395,6 @@
|
|||||||
"minimalistic-assert": "^1.0.1"
|
"minimalistic-assert": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hawk": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
|
||||||
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"boom": "2.x.x",
|
|
||||||
"cryptiles": "2.x.x",
|
|
||||||
"hoek": "2.x.x",
|
|
||||||
"sntp": "1.x.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"he": {
|
"he": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||||
@@ -6458,12 +6412,6 @@
|
|||||||
"minimalistic-crypto-utils": "^1.0.1"
|
"minimalistic-crypto-utils": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hoek": {
|
|
||||||
"version": "2.16.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
|
||||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"home-or-tmp": {
|
"home-or-tmp": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
||||||
@@ -6658,12 +6606,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"http-signature": {
|
"http-signature": {
|
||||||
"version": "1.1.1",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||||
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
|
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"assert-plus": "^0.2.0",
|
"assert-plus": "^1.0.0",
|
||||||
"jsprim": "^1.2.2",
|
"jsprim": "^1.2.2",
|
||||||
"sshpk": "^1.7.0"
|
"sshpk": "^1.7.0"
|
||||||
}
|
}
|
||||||
@@ -7619,15 +7567,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
|
||||||
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
|
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
|
||||||
},
|
},
|
||||||
"json-stable-stringify": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"jsonify": "~0.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"json-stringify-safe": {
|
"json-stringify-safe": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||||
@@ -7661,14 +7600,6 @@
|
|||||||
"extsprintf": "1.3.0",
|
"extsprintf": "1.3.0",
|
||||||
"json-schema": "0.2.3",
|
"json-schema": "0.2.3",
|
||||||
"verror": "1.10.0"
|
"verror": "1.10.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyv": {
|
"keyv": {
|
||||||
@@ -8848,8 +8779,7 @@
|
|||||||
"version": "2.10.0",
|
"version": "2.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"nanomatch": {
|
"nanomatch": {
|
||||||
"version": "1.2.13",
|
"version": "1.2.13",
|
||||||
@@ -8916,9 +8846,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-gyp": {
|
"node-gyp": {
|
||||||
"version": "3.7.0",
|
"version": "3.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
||||||
"integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==",
|
"integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fstream": "^1.0.0",
|
"fstream": "^1.0.0",
|
||||||
@@ -8928,49 +8858,13 @@
|
|||||||
"nopt": "2 || 3",
|
"nopt": "2 || 3",
|
||||||
"npmlog": "0 || 1 || 2 || 3 || 4",
|
"npmlog": "0 || 1 || 2 || 3 || 4",
|
||||||
"osenv": "0",
|
"osenv": "0",
|
||||||
"request": ">=2.9.0 <2.82.0",
|
"request": "^2.87.0",
|
||||||
"rimraf": "2",
|
"rimraf": "2",
|
||||||
"semver": "~5.3.0",
|
"semver": "~5.3.0",
|
||||||
"tar": "^2.0.0",
|
"tar": "^2.0.0",
|
||||||
"which": "1"
|
"which": "1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"qs": {
|
|
||||||
"version": "6.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
|
|
||||||
"integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"version": "2.81.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
|
|
||||||
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"aws-sign2": "~0.6.0",
|
|
||||||
"aws4": "^1.2.1",
|
|
||||||
"caseless": "~0.12.0",
|
|
||||||
"combined-stream": "~1.0.5",
|
|
||||||
"extend": "~3.0.0",
|
|
||||||
"forever-agent": "~0.6.1",
|
|
||||||
"form-data": "~2.1.1",
|
|
||||||
"har-validator": "~4.2.1",
|
|
||||||
"hawk": "~3.1.3",
|
|
||||||
"http-signature": "~1.1.0",
|
|
||||||
"is-typedarray": "~1.0.0",
|
|
||||||
"isstream": "~0.1.2",
|
|
||||||
"json-stringify-safe": "~5.0.1",
|
|
||||||
"mime-types": "~2.1.7",
|
|
||||||
"oauth-sign": "~0.8.1",
|
|
||||||
"performance-now": "^0.2.0",
|
|
||||||
"qs": "~6.4.0",
|
|
||||||
"safe-buffer": "^5.0.1",
|
|
||||||
"stringstream": "~0.0.4",
|
|
||||||
"tough-cookie": "~2.3.0",
|
|
||||||
"tunnel-agent": "^0.6.0",
|
|
||||||
"uuid": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||||
@@ -9011,9 +8905,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-sass": {
|
"node-sass": {
|
||||||
"version": "4.9.2",
|
"version": "4.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.3.tgz",
|
||||||
"integrity": "sha512-LdxoJLZutx0aQXHtWIYwJKMj+9pTjneTcLWJgzf2XbGu0q5pRNqW5QvFCEdm3mc5rJOdru/mzln5d0EZLacf6g==",
|
"integrity": "sha512-XzXyGjO+84wxyH7fV6IwBOTrEBe2f0a6SBze9QWWYR/cL74AcQUks2AsqcCZenl/Fp/JVbuEaLpgrLtocwBUww==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"async-foreach": "^0.1.3",
|
"async-foreach": "^0.1.3",
|
||||||
@@ -9029,7 +8923,7 @@
|
|||||||
"meow": "^3.7.0",
|
"meow": "^3.7.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"nan": "^2.10.0",
|
"nan": "^2.10.0",
|
||||||
"node-gyp": "^3.3.1",
|
"node-gyp": "^3.8.0",
|
||||||
"npmlog": "^4.0.0",
|
"npmlog": "^4.0.0",
|
||||||
"request": "2.87.0",
|
"request": "2.87.0",
|
||||||
"sass-graph": "^2.2.4",
|
"sass-graph": "^2.2.4",
|
||||||
@@ -9060,12 +8954,6 @@
|
|||||||
"which": "^1.2.9"
|
"which": "^1.2.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nan": {
|
|
||||||
"version": "2.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
|
||||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
@@ -9748,9 +9636,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"performance-now": {
|
"performance-now": {
|
||||||
"version": "0.2.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
"integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
|
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"pify": {
|
"pify": {
|
||||||
@@ -10413,9 +10301,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"preact": {
|
"preact": {
|
||||||
"version": "8.2.9",
|
"version": "8.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/preact/-/preact-8.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/preact/-/preact-8.3.1.tgz",
|
||||||
"integrity": "sha512-ThuGXBmJS3VsT+jIP+eQufD3L8pRw/PY3FoCys6O9Pu6aF12Pn9zAJDX99TfwRAFOCEKm/P0lwiPTbqKMJp0fA=="
|
"integrity": "sha512-s8H1Y8O9e+mOBo3UP1jvWqArPmjCba2lrrGLlq/0kN1XuIINUbYtf97iiXKxCuG3eYwmppPKnyW2DBrNj/TuTg=="
|
||||||
},
|
},
|
||||||
"preact-i18n": {
|
"preact-i18n": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
@@ -11362,76 +11250,6 @@
|
|||||||
"tough-cookie": "~2.3.3",
|
"tough-cookie": "~2.3.3",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.1.0"
|
"uuid": "^3.1.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ajv": {
|
|
||||||
"version": "5.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
|
||||||
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"co": "^4.6.0",
|
|
||||||
"fast-deep-equal": "^1.0.0",
|
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
|
||||||
"json-schema-traverse": "^0.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"aws-sign2": {
|
|
||||||
"version": "0.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
|
||||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"form-data": {
|
|
||||||
"version": "2.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
|
|
||||||
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"asynckit": "^0.4.0",
|
|
||||||
"combined-stream": "1.0.6",
|
|
||||||
"mime-types": "^2.1.12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"har-schema": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"har-validator": {
|
|
||||||
"version": "5.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
|
|
||||||
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ajv": "^5.1.0",
|
|
||||||
"har-schema": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"http-signature": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
|
||||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"assert-plus": "^1.0.0",
|
|
||||||
"jsprim": "^1.2.2",
|
|
||||||
"sshpk": "^1.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"performance-now": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
|
||||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require-directory": {
|
"require-directory": {
|
||||||
@@ -11691,16 +11509,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sass-loader": {
|
"sass-loader": {
|
||||||
"version": "6.0.7",
|
"version": "7.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz",
|
||||||
"integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==",
|
"integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"clone-deep": "^2.0.1",
|
"clone-deep": "^2.0.1",
|
||||||
"loader-utils": "^1.0.1",
|
"loader-utils": "^1.0.1",
|
||||||
"lodash.tail": "^4.1.1",
|
"lodash.tail": "^4.1.1",
|
||||||
"neo-async": "^2.5.0",
|
"neo-async": "^2.5.0",
|
||||||
"pify": "^3.0.0"
|
"pify": "^3.0.0",
|
||||||
|
"semver": "^5.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pify": {
|
"pify": {
|
||||||
@@ -12131,15 +11950,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sntp": {
|
|
||||||
"version": "1.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
|
||||||
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"hoek": "2.x.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sockjs": {
|
"sockjs": {
|
||||||
"version": "0.3.19",
|
"version": "0.3.19",
|
||||||
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
|
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
|
||||||
@@ -12377,14 +12187,6 @@
|
|||||||
"jsbn": "~0.1.0",
|
"jsbn": "~0.1.0",
|
||||||
"safer-buffer": "^2.0.2",
|
"safer-buffer": "^2.0.2",
|
||||||
"tweetnacl": "~0.14.0"
|
"tweetnacl": "~0.14.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ssri": {
|
"ssri": {
|
||||||
@@ -12537,12 +12339,6 @@
|
|||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stringstream": {
|
|
||||||
"version": "0.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
|
|
||||||
"integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||||
@@ -12595,9 +12391,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"style-loader": {
|
"style-loader": {
|
||||||
"version": "0.20.3",
|
"version": "0.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.22.1.tgz",
|
||||||
"integrity": "sha512-2I7AVP73MvK33U7B9TKlYZAqdROyMXDYSMvHLX43qy3GCOaJNiV6i0v/sv9idWIaQ42Yn2dNv79Q5mKXbKhAZg==",
|
"integrity": "sha512-WXUrLeinPIR1Oat3PfCDro7qTniwNTJqGqv1KcQiL3JR5PzrVLTyNsd9wTsPXG/qNCJ7lzR2NY/QDjFsP7nuSQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"loader-utils": "^1.1.0",
|
"loader-utils": "^1.1.0",
|
||||||
@@ -13157,9 +12953,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"uglifyjs-webpack-plugin": {
|
"uglifyjs-webpack-plugin": {
|
||||||
"version": "1.2.7",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz",
|
||||||
"integrity": "sha512-1VicfKhCYHLS8m1DCApqBhoulnASsEoJ/BvpUpP4zoNAPpKzdH+ghk0olGJMmwX2/jprK2j3hAHdUbczBSy2FA==",
|
"integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cacache": "^10.0.4",
|
"cacache": "^10.0.4",
|
||||||
@@ -13506,14 +13302,6 @@
|
|||||||
"assert-plus": "^1.0.0",
|
"assert-plus": "^1.0.0",
|
||||||
"core-util-is": "1.0.2",
|
"core-util-is": "1.0.2",
|
||||||
"extsprintf": "^1.2.0"
|
"extsprintf": "^1.2.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"assert-plus": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vinyl": {
|
"vinyl": {
|
||||||
@@ -13571,9 +13359,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"version": "4.16.2",
|
"version": "4.16.5",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.5.tgz",
|
||||||
"integrity": "sha512-Fw+RtyJD9ekQ6Mh6e/hYeoafIKK6bP6qS7EVnZ3hejt+1Ah3JCJZTGE0e5S6Eq4ijIVht6ktWOEqJfm92+5MLw==",
|
"integrity": "sha512-i5cHYHonzSc1zBuwB5MSzW4v9cScZFbprkHK8ZgzPDCRkQXGGpYzPmJhbus5bOrZ0tXTcQp+xyImRSvKb0b+Kw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@webassemblyjs/ast": "1.5.13",
|
"@webassemblyjs/ast": "1.5.13",
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -27,7 +27,7 @@
|
|||||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||||
"babel-plugin-transform-react-constant-elements": "^6.23.0",
|
"babel-plugin-transform-react-constant-elements": "^6.23.0",
|
||||||
"babel-plugin-transform-react-jsx": "^6.24.1",
|
"babel-plugin-transform-react-jsx": "^6.24.1",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.13",
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.14",
|
||||||
"babel-preset-env": "^1.7.0",
|
"babel-preset-env": "^1.7.0",
|
||||||
"babel-register": "^6.26.0",
|
"babel-register": "^6.26.0",
|
||||||
"clean-webpack-plugin": "^0.1.19",
|
"clean-webpack-plugin": "^0.1.19",
|
||||||
@@ -40,14 +40,14 @@
|
|||||||
"if-env": "^1.0.4",
|
"if-env": "^1.0.4",
|
||||||
"loader-utils": "^1.1.0",
|
"loader-utils": "^1.1.0",
|
||||||
"mini-css-extract-plugin": "^0.3.0",
|
"mini-css-extract-plugin": "^0.3.0",
|
||||||
"node-sass": "^4.9.2",
|
"node-sass": "^4.9.3",
|
||||||
"optimize-css-assets-webpack-plugin": "^4.0.3",
|
"optimize-css-assets-webpack-plugin": "^4.0.3",
|
||||||
"progress-bar-webpack-plugin": "^1.11.0",
|
"progress-bar-webpack-plugin": "^1.11.0",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"sass-loader": "^6.0.7",
|
"sass-loader": "^7.1.0",
|
||||||
"script-ext-html-webpack-plugin": "^2.0.1",
|
"script-ext-html-webpack-plugin": "^2.0.1",
|
||||||
"source-map-loader": "^0.2.3",
|
"source-map-loader": "^0.2.3",
|
||||||
"style-loader": "^0.20.3",
|
"style-loader": "^0.22.1",
|
||||||
"ts-loader": "^4.4.2",
|
"ts-loader": "^4.4.2",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.11.0",
|
||||||
"tslint-config-airbnb": "^5.9.2",
|
"tslint-config-airbnb": "^5.9.2",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"tslint-react": "^3.6.0",
|
"tslint-react": "^3.6.0",
|
||||||
"typescript": "^2.9.2",
|
"typescript": "^2.9.2",
|
||||||
"typings-for-css-modules-loader": "^1.7.0",
|
"typings-for-css-modules-loader": "^1.7.0",
|
||||||
"webpack": "^4.16.2",
|
"webpack": "^4.16.5",
|
||||||
"webpack-bundle-analyzer": "^2.13.1",
|
"webpack-bundle-analyzer": "^2.13.1",
|
||||||
"webpack-cli": "^2.1.5",
|
"webpack-cli": "^2.1.5",
|
||||||
"webpack-dev-server": "^3.1.5",
|
"webpack-dev-server": "^3.1.5",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
"comlink-loader": "^1.0.0",
|
"comlink-loader": "^1.0.0",
|
||||||
"filesize": "^3.6.1",
|
"filesize": "^3.6.1",
|
||||||
"material-components-web": "^0.32.0",
|
"material-components-web": "^0.32.0",
|
||||||
"preact": "^8.2.9",
|
"preact": "^8.3.1",
|
||||||
"preact-i18n": "^1.2.2",
|
"preact-i18n": "^1.2.2",
|
||||||
"preact-material-components": "^1.4.7",
|
"preact-material-components": "^1.4.7",
|
||||||
"preact-router": "^2.6.1"
|
"preact-router": "^2.6.1"
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
import mozjpeg_enc from '../../../codecs/mozjpeg_enc/mozjpeg_enc';
|
import mozjpeg_enc, { MozJPEGModule } from '../../../codecs/mozjpeg_enc/mozjpeg_enc';
|
||||||
// Using require() so TypeScript doesn’t complain about this not being a module.
|
// Using require() so TypeScript doesn’t complain about this not being a module.
|
||||||
import { EncodeOptions } from './encoder';
|
import { EncodeOptions } from './encoder';
|
||||||
const wasmBinaryUrl = require('../../../codecs/mozjpeg_enc/mozjpeg_enc.wasm');
|
const wasmBinaryUrl = require('../../../codecs/mozjpeg_enc/mozjpeg_enc.wasm');
|
||||||
|
|
||||||
// API exposed by wasm module. Details in the codec’s README.
|
|
||||||
interface ModuleAPI {
|
|
||||||
version(): number;
|
|
||||||
create_buffer(width: number, height: number): number;
|
|
||||||
destroy_buffer(pointer: number): void;
|
|
||||||
encode(buffer: number, width: number, height: number, quality: number): void;
|
|
||||||
free_result(): void;
|
|
||||||
get_result_pointer(): number;
|
|
||||||
get_result_size(): number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class MozJpegEncoder {
|
export default class MozJpegEncoder {
|
||||||
private emscriptenModule: Promise<EmscriptenWasm.Module>;
|
private emscriptenModule: Promise<MozJPEGModule>;
|
||||||
private api: Promise<ModuleAPI>;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.emscriptenModule = new Promise((resolve) => {
|
this.emscriptenModule = new Promise((resolve) => {
|
||||||
@@ -41,37 +29,20 @@ export default class MozJpegEncoder {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.api = (async () => {
|
|
||||||
// Not sure why, but TypeScript complains that I am using
|
|
||||||
// `emscriptenModule` before it’s getting assigned, which is clearly not
|
|
||||||
// true :shrug: Using `any`
|
|
||||||
const m = await (this as any).emscriptenModule;
|
|
||||||
return {
|
|
||||||
version: m.cwrap('version', 'number', []),
|
|
||||||
create_buffer: m.cwrap('create_buffer', 'number', ['number', 'number']),
|
|
||||||
destroy_buffer: m.cwrap('destroy_buffer', '', ['number']),
|
|
||||||
encode: m.cwrap('encode', '', ['number', 'number', 'number', 'number']),
|
|
||||||
free_result: m.cwrap('free_result', '', []),
|
|
||||||
get_result_pointer: m.cwrap('get_result_pointer', 'number', []),
|
|
||||||
get_result_size: m.cwrap('get_result_size', 'number', []),
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async encode(data: ImageData, options: EncodeOptions): Promise<ArrayBuffer> {
|
async encode(data: ImageData, options: EncodeOptions): Promise<ArrayBuffer> {
|
||||||
const m = await this.emscriptenModule;
|
const module = await this.emscriptenModule;
|
||||||
const api = await this.api;
|
|
||||||
|
|
||||||
const p = api.create_buffer(data.width, data.height);
|
const p = module.create_buffer(data.width, data.height);
|
||||||
m.HEAP8.set(data.data, p);
|
module.HEAP8.set(data.data, p);
|
||||||
api.encode(p, data.width, data.height, options.quality);
|
module.encode(p, data.width, data.height, options);
|
||||||
const resultPointer = api.get_result_pointer();
|
const resultPointer = module.get_result_pointer();
|
||||||
const resultSize = api.get_result_size();
|
const resultSize = module.get_result_size();
|
||||||
const resultView = new Uint8Array(m.HEAP8.buffer, resultPointer, resultSize);
|
const resultView = new Uint8Array(module.HEAP8.buffer, resultPointer, resultSize);
|
||||||
const result = new Uint8Array(resultView);
|
const result = new Uint8Array(resultView);
|
||||||
api.free_result();
|
module.free_result();
|
||||||
api.destroy_buffer(p);
|
module.destroy_buffer(p);
|
||||||
|
|
||||||
// wasm can’t run on SharedArrayBuffers, so we hard-cast to ArrayBuffer.
|
// wasm can’t run on SharedArrayBuffers, so we hard-cast to ArrayBuffer.
|
||||||
return result.buffer as ArrayBuffer;
|
return result.buffer as ArrayBuffer;
|
||||||
|
|||||||
@@ -1,13 +1,46 @@
|
|||||||
import EncoderWorker from './Encoder.worker';
|
import EncoderWorker from './Encoder.worker';
|
||||||
|
|
||||||
export interface EncodeOptions { quality: number; }
|
export enum MozJpegColorSpace {
|
||||||
|
GRAYSCALE = 1,
|
||||||
|
RGB,
|
||||||
|
YCbCr,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EncodeOptions {
|
||||||
|
quality: number;
|
||||||
|
baseline: boolean;
|
||||||
|
arithmetic: boolean;
|
||||||
|
progressive: boolean;
|
||||||
|
optimize_coding: boolean;
|
||||||
|
smoothing: number;
|
||||||
|
color_space: MozJpegColorSpace;
|
||||||
|
quant_table: number;
|
||||||
|
trellis_multipass: boolean;
|
||||||
|
trellis_opt_zero: boolean;
|
||||||
|
trellis_opt_table: boolean;
|
||||||
|
trellis_loops: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EncoderState { type: typeof type; options: EncodeOptions; }
|
export interface EncoderState { type: typeof type; options: EncodeOptions; }
|
||||||
|
|
||||||
export const type = 'mozjpeg';
|
export const type = 'mozjpeg';
|
||||||
export const label = 'MozJPEG';
|
export const label = 'MozJPEG';
|
||||||
export const mimeType = 'image/jpeg';
|
export const mimeType = 'image/jpeg';
|
||||||
export const extension = 'jpg';
|
export const extension = 'jpg';
|
||||||
export const defaultOptions: EncodeOptions = { quality: 7 };
|
export const defaultOptions: EncodeOptions = {
|
||||||
|
quality: 75,
|
||||||
|
baseline: false,
|
||||||
|
arithmetic: false,
|
||||||
|
progressive: true,
|
||||||
|
optimize_coding: true,
|
||||||
|
smoothing: 0,
|
||||||
|
color_space: MozJpegColorSpace.YCbCr,
|
||||||
|
quant_table: 3,
|
||||||
|
trellis_multipass: false,
|
||||||
|
trellis_opt_zero: false,
|
||||||
|
trellis_opt_table: false,
|
||||||
|
trellis_loops: 1,
|
||||||
|
};
|
||||||
|
|
||||||
export async function encode(data: ImageData, options: EncodeOptions) {
|
export async function encode(data: ImageData, options: EncodeOptions) {
|
||||||
// We need to await this because it's been comlinked.
|
// We need to await this because it's been comlinked.
|
||||||
|
|||||||
@@ -1,3 +1,161 @@
|
|||||||
import qualityOption from '../generic/quality-option';
|
import { h, Component } from 'preact';
|
||||||
|
import { bind, inputFieldChecked, inputFieldValueAsNumber } from '../../lib/util';
|
||||||
|
import { EncodeOptions, MozJpegColorSpace } from './encoder';
|
||||||
|
|
||||||
export default qualityOption();
|
type Props = {
|
||||||
|
options: EncodeOptions,
|
||||||
|
onChange(newOptions: EncodeOptions): void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class MozJPEGEncoderOptions extends Component<Props, {}> {
|
||||||
|
@bind
|
||||||
|
onChange(event: Event) {
|
||||||
|
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
|
||||||
|
|
||||||
|
const options: EncodeOptions = {
|
||||||
|
// Copy over options the form doesn't currently care about, eg arithmetic
|
||||||
|
...this.props.options,
|
||||||
|
// And now stuff from the form:
|
||||||
|
// .checked
|
||||||
|
baseline: inputFieldChecked(form.baseline),
|
||||||
|
progressive: inputFieldChecked(form.progressive),
|
||||||
|
optimize_coding: inputFieldChecked(form.optimize_coding),
|
||||||
|
trellis_multipass: inputFieldChecked(form.trellis_multipass),
|
||||||
|
trellis_opt_zero: inputFieldChecked(form.trellis_opt_zero),
|
||||||
|
trellis_opt_table: inputFieldChecked(form.trellis_opt_table),
|
||||||
|
// .value
|
||||||
|
quality: inputFieldValueAsNumber(form.quality),
|
||||||
|
smoothing: inputFieldValueAsNumber(form.smoothing),
|
||||||
|
color_space: inputFieldValueAsNumber(form.color_space),
|
||||||
|
quant_table: inputFieldValueAsNumber(form.quant_table),
|
||||||
|
trellis_loops: inputFieldValueAsNumber(form.trellis_loops),
|
||||||
|
};
|
||||||
|
this.props.onChange(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
render({ options }: Props) {
|
||||||
|
// I'm rendering both lossy and lossless forms, as it becomes much easier when
|
||||||
|
// gathering the data.
|
||||||
|
return (
|
||||||
|
<form>
|
||||||
|
<label>
|
||||||
|
Quality:
|
||||||
|
<input
|
||||||
|
name="quality"
|
||||||
|
type="range"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
value={'' + options.quality}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
name="baseline"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.baseline}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Baseline (worse but legacy-compatible)
|
||||||
|
</label>
|
||||||
|
<label style={{ display: options.baseline ? 'none' : '' }}>
|
||||||
|
<input
|
||||||
|
name="progressive"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.progressive}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Progressive multi-pass rendering
|
||||||
|
</label>
|
||||||
|
<label style={{ display: options.baseline ? '' : 'none' }}>
|
||||||
|
<input
|
||||||
|
name="optimize_coding"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.optimize_coding}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Optimize Huffman table
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Smoothing:
|
||||||
|
<input
|
||||||
|
name="smoothing"
|
||||||
|
type="range"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
value={'' + options.smoothing}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Output color space:
|
||||||
|
<select
|
||||||
|
name="color_space"
|
||||||
|
value={'' + options.color_space}
|
||||||
|
onChange={this.onChange}
|
||||||
|
>
|
||||||
|
<option value={MozJpegColorSpace.GRAYSCALE}>Grayscale</option>
|
||||||
|
<option value={MozJpegColorSpace.RGB}>RGB (sub-optimal)</option>
|
||||||
|
<option value={MozJpegColorSpace.YCbCr}>YCbCr (optimized for color)</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Quantization table:
|
||||||
|
<select
|
||||||
|
name="quant_table"
|
||||||
|
value={'' + options.quant_table}
|
||||||
|
onChange={this.onChange}
|
||||||
|
>
|
||||||
|
<option value="0">JPEG Annex K</option>
|
||||||
|
<option value="1">Flat</option>
|
||||||
|
<option value="2">MSSIM-tuned Kodak</option>
|
||||||
|
<option value="3">ImageMagick</option>
|
||||||
|
<option value="4">PSNR-HVS-M-tuned Kodak</option>
|
||||||
|
<option value="5">Klein et al</option>
|
||||||
|
<option value="6">Watson et al</option>
|
||||||
|
<option value="7">Ahumada et al</option>
|
||||||
|
<option value="8">Peterson et al</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
name="trellis_multipass"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.trellis_multipass}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Consider multiple scans during trellis quantization
|
||||||
|
</label>
|
||||||
|
<label style={{ display: options.trellis_multipass ? '' : 'none' }}>
|
||||||
|
<input
|
||||||
|
name="trellis_opt_zero"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.trellis_opt_zero}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Optimize runs of zero blocks
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
name="trellis_opt_table"
|
||||||
|
type="checkbox"
|
||||||
|
checked={options.trellis_opt_table}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
Optimize after trellis quantization
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Trellis quantization passes:
|
||||||
|
<input
|
||||||
|
name="trellis_loops"
|
||||||
|
type="range"
|
||||||
|
min="1"
|
||||||
|
max="50"
|
||||||
|
value={'' + options.trellis_loops}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -157,7 +157,14 @@ export function inputFieldValueAsNumber(field: any): number {
|
|||||||
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
|
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
|
||||||
*/
|
*/
|
||||||
export function inputFieldCheckedAsNumber(field: any): number {
|
export function inputFieldCheckedAsNumber(field: any): number {
|
||||||
return Number((field as HTMLInputElement).checked);
|
return Number(inputFieldChecked(field));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param field An HTMLInputElement, but the casting is done here to tidy up onChange.
|
||||||
|
*/
|
||||||
|
export function inputFieldChecked(field: any): boolean {
|
||||||
|
return (field as HTMLInputElement).checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user