diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..b0522bad --- /dev/null +++ b/.clang-format @@ -0,0 +1,2 @@ +BasedOnStyle: Chromium +ColumnLimit: 120 diff --git a/codecs/imagequant/imagequant.cpp b/codecs/imagequant/imagequant.cpp index 7684f6ea..9fa9defe 100644 --- a/codecs/imagequant/imagequant.cpp +++ b/codecs/imagequant/imagequant.cpp @@ -1,36 +1,37 @@ -#include "emscripten/bind.h" -#include "emscripten/val.h" -#include +#include +#include #include #include #include +#include #include "libimagequant.h" using namespace emscripten; int version() { - return (((LIQ_VERSION/10000) % 100) << 16) | - (((LIQ_VERSION/100 ) % 100) << 8) | - (((LIQ_VERSION/1 ) % 100) << 0); + return (((LIQ_VERSION / 10000) % 100) << 16) | (((LIQ_VERSION / 100) % 100) << 8) | + (((LIQ_VERSION / 1) % 100) << 0); } class RawImage { -public: + public: val buffer; int width; int height; - RawImage(val b, int w, int h) - : buffer(b), width(w), height(h) {} + RawImage(val b, int w, int h) : buffer(b), width(w), height(h) {} }; - -liq_attr *attr; -liq_image *image; -liq_result *res; +liq_attr* attr; +liq_image* image; +liq_result* res; uint8_t* result; -RawImage quantize(std::string rawimage, int image_width, int image_height, int num_colors, float dithering) { +RawImage quantize(std::string rawimage, + int image_width, + int image_height, + int num_colors, + float dithering) { const uint8_t* image_buffer = (uint8_t*)rawimage.c_str(); int size = image_width * image_height; attr = liq_attr_create(); @@ -38,12 +39,12 @@ RawImage quantize(std::string rawimage, int image_width, int image_height, int n liq_set_max_colors(attr, num_colors); liq_image_quantize(image, attr, &res); liq_set_dithering_level(res, dithering); - uint8_t* image8bit = (uint8_t*) malloc(size); - result = (uint8_t*) malloc(size * 4); + uint8_t* image8bit = (uint8_t*)malloc(size); + result = (uint8_t*)malloc(size * 4); liq_write_remapped_image(res, image, image8bit, size); - const liq_palette *pal = liq_get_palette(res); + const liq_palette* pal = liq_get_palette(res); // Turn palletted image back into an RGBA image - for(int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { result[i * 4 + 0] = pal->entries[image8bit[i]].r; result[i * 4 + 1] = pal->entries[image8bit[i]].g; result[i * 4 + 2] = pal->entries[image8bit[i]].b; @@ -53,43 +54,41 @@ RawImage quantize(std::string rawimage, int image_width, int image_height, int n liq_result_destroy(res); liq_image_destroy(image); liq_attr_destroy(attr); - return { - val(typed_memory_view(image_width*image_height*4, result)), - image_width, - image_height - }; + return {val(typed_memory_view(image_width * image_height * 4, result)), image_width, + image_height}; } const liq_color zx_colors[] = { - {.r = 0, .g = 0, .b = 0, .a = 255}, // regular black - {.r = 0, .g = 0, .b = 215, .a = 255}, // regular blue - {.r = 215, .g = 0, .b = 0, .a = 255}, // regular red - {.r = 215, .g = 0, .b = 215, .a = 255}, // regular magenta - {.r = 0, .g = 215, .b = 0, .a = 255}, // regular green - {.r = 0, .g = 215, .b = 215, .a = 255}, // regular cyan - {.r = 215, .g = 215, .b = 0, .a = 255}, // regular yellow - {.r = 215, .g = 215, .b = 215, .a = 255}, // regular white - {.r = 0, .g = 0, .b = 255, .a = 255}, // bright blue - {.r = 255, .g = 0, .b = 0, .a = 255}, // bright red - {.r = 255, .g = 0, .b = 255, .a = 255}, // bright magenta - {.r = 0, .g = 255, .b = 0, .a = 255}, // bright green - {.r = 0, .g = 255, .b = 255, .a = 255}, // bright cyan - {.r = 255, .g = 255, .b = 0, .a = 255}, // bright yellow - {.r = 255, .g = 255, .b = 255, .a = 255} // bright white + {.r = 0, .g = 0, .b = 0, .a = 255}, // regular black + {.r = 0, .g = 0, .b = 215, .a = 255}, // regular blue + {.r = 215, .g = 0, .b = 0, .a = 255}, // regular red + {.r = 215, .g = 0, .b = 215, .a = 255}, // regular magenta + {.r = 0, .g = 215, .b = 0, .a = 255}, // regular green + {.r = 0, .g = 215, .b = 215, .a = 255}, // regular cyan + {.r = 215, .g = 215, .b = 0, .a = 255}, // regular yellow + {.r = 215, .g = 215, .b = 215, .a = 255}, // regular white + {.r = 0, .g = 0, .b = 255, .a = 255}, // bright blue + {.r = 255, .g = 0, .b = 0, .a = 255}, // bright red + {.r = 255, .g = 0, .b = 255, .a = 255}, // bright magenta + {.r = 0, .g = 255, .b = 0, .a = 255}, // bright green + {.r = 0, .g = 255, .b = 255, .a = 255}, // bright cyan + {.r = 255, .g = 255, .b = 0, .a = 255}, // bright yellow + {.r = 255, .g = 255, .b = 255, .a = 255} // bright white }; uint8_t block[8 * 8 * 4]; /** - * The ZX has one bit per pixel, but can assign two colours to an 8x8 block. The two colours must - * both be 'regular' or 'bright'. Black exists as both regular and bright. + * The ZX has one bit per pixel, but can assign two colours to an 8x8 block. The + * two colours must both be 'regular' or 'bright'. Black exists as both regular + * and bright. */ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, float dithering) { - const uint8_t* image_buffer = (uint8_t*) rawimage.c_str(); + const uint8_t* image_buffer = (uint8_t*)rawimage.c_str(); int size = image_width * image_height; int bytes_per_pixel = 4; - result = (uint8_t*) malloc(size * bytes_per_pixel); - uint8_t* image8bit = (uint8_t*) malloc(8 * 8); + result = (uint8_t*)malloc(size * bytes_per_pixel); + uint8_t* image8bit = (uint8_t*)malloc(8 * 8); // For each 8x8 grid for (int block_start_y = 0; block_start_y < image_height; block_start_y += 8) { @@ -99,7 +98,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl int block_width = 8; int block_height = 8; - // If the block hangs off the right/bottom of the image dimensions, make it smaller to fit. + // If the block hangs off the right/bottom of the image dimensions, make + // it smaller to fit. if (block_start_y + block_height > image_height) { block_height = image_height - block_start_y; } @@ -125,12 +125,11 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl for (int color_index = 0; color_index < 15; color_index++) { liq_color color = zx_colors[color_index]; - // Using Euclidean distance. LibQuant has better methods, but it requires conversion to - // LAB, so I don't think it's worth it. - int distance = - pow(color.r - image_buffer[pixel_start + 0], 2) + - pow(color.g - image_buffer[pixel_start + 1], 2) + - pow(color.b - image_buffer[pixel_start + 2], 2); + // Using Euclidean distance. LibQuant has better methods, but it + // requires conversion to LAB, so I don't think it's worth it. + int distance = pow(color.r - image_buffer[pixel_start + 0], 2) + + pow(color.g - image_buffer[pixel_start + 1], 2) + + pow(color.b - image_buffer[pixel_start + 2], 2); if (distance < smallest_distance) { winning_index = color_index; @@ -151,7 +150,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl for (int color_index = 0; color_index < 15; color_index++) { if (color_popularity[color_index] > highest_popularity) { - // Store this as the most popular pixel, and demote the current values: + // Store this as the most popular pixel, and demote the current + // values: third_color_index = second_color_index; third_highest_popularity = second_highest_popularity; second_color_index = first_color_index; @@ -169,8 +169,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl } } - // ZX images can't mix bright and regular colours, except black which appears in both. - // Resolve any conflict: + // ZX images can't mix bright and regular colours, except black which + // appears in both. Resolve any conflict: while (1) { // If either colour is black, there's no conflict to resolve. if (first_color_index != 0 && second_color_index != 0) { @@ -183,12 +183,13 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl } } - // If, during conflict resolving, we now have two of the same colour (because we initially - // selected the bright & regular version of the same colour), retry again with the third - // most popular colour. + // If, during conflict resolving, we now have two of the same colour + // (because we initially selected the bright & regular version of the + // same colour), retry again with the third most popular colour. if (first_color_index == second_color_index) { second_color_index = third_color_index; - } else break; + } else + break; } // Quantize @@ -200,13 +201,15 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl liq_image_quantize(image, attr, &res); liq_set_dithering_level(res, dithering); liq_write_remapped_image(res, image, image8bit, size); - const liq_palette *pal = liq_get_palette(res); + const liq_palette* pal = liq_get_palette(res); - // Turn palletted image back into an RGBA image, and write it into the full size result image. - for(int y = 0; y < block_height; y++) { - for(int x = 0; x < block_width; x++) { + // Turn palletted image back into an RGBA image, and write it into the + // full size result image. + for (int y = 0; y < block_height; y++) { + for (int x = 0; x < block_width; x++) { int image8BitPos = y * block_width + x; - int resultStartPos = ((block_start_y + y) * bytes_per_pixel * image_width) + ((block_start_x + x) * bytes_per_pixel); + int resultStartPos = ((block_start_y + y) * bytes_per_pixel * image_width) + + ((block_start_x + x) * bytes_per_pixel); result[resultStartPos + 0] = pal->entries[image8bit[image8BitPos]].r; result[resultStartPos + 1] = pal->entries[image8bit[image8BitPos]].g; result[resultStartPos + 2] = pal->entries[image8bit[image8BitPos]].b; @@ -221,11 +224,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl } free(image8bit); - return { - val(typed_memory_view(image_width*image_height*4, result)), - image_width, - image_height - }; + return {val(typed_memory_view(image_width * image_height * 4, result)), image_width, + image_height}; } void free_result() { @@ -234,9 +234,9 @@ void free_result() { EMSCRIPTEN_BINDINGS(my_module) { class_("RawImage") - .property("buffer", &RawImage::buffer) - .property("width", &RawImage::width) - .property("height", &RawImage::height); + .property("buffer", &RawImage::buffer) + .property("width", &RawImage::width) + .property("height", &RawImage::height); function("quantize", &quantize); function("zx_quantize", &zx_quantize); diff --git a/codecs/mozjpeg_enc/mozjpeg_enc.cpp b/codecs/mozjpeg_enc/mozjpeg_enc.cpp index 19615252..ae368c15 100644 --- a/codecs/mozjpeg_enc/mozjpeg_enc.cpp +++ b/codecs/mozjpeg_enc/mozjpeg_enc.cpp @@ -1,9 +1,9 @@ #include #include -#include #include -#include #include +#include +#include #include #include "config.h" #include "jpeglib.h" @@ -14,8 +14,9 @@ extern "C" { 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 +// 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 str(s) #s @@ -42,8 +43,8 @@ int version() { char buffer[] = xstr(MOZJPEG_VERSION); int version = 0; int last_index = 0; - for(int i = 0; i < strlen(buffer); i++) { - if(buffer[i] == '.') { + for (int i = 0; i < strlen(buffer); i++) { + if (buffer[i] == '.') { buffer[i] = '\0'; version = version << 8 | atoi(&buffer[last_index]); buffer[i] = '.'; @@ -58,13 +59,12 @@ uint8_t* last_result; struct jpeg_compress_struct cinfo; val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) { - uint8_t* image_buffer = (uint8_t*) image_in.c_str(); + uint8_t* image_buffer = (uint8_t*)image_in.c_str(); // The code below is basically the `write_JPEG_file` function from // https://github.com/mozilla/mozjpeg/blob/master/example.c // I just write to memory instead of a file. - /* This struct contains the JPEG compression parameters and pointers to * working space (which is allocated as needed by the JPEG library). * It is possible to have several such structures, representing multiple @@ -81,8 +81,8 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio */ struct jpeg_error_mgr jerr; /* More stuff */ - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - int row_stride; /* physical row width in image buffer */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ uint8_t* output; unsigned long size; @@ -116,17 +116,17 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio /* First we supply a description of the input image. * Four fields of the cinfo struct must be filled in: */ - 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.input_components = 4; /* # of color components per pixel */ - cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */ + cinfo.input_components = 4; /* # of color components per pixel */ + cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */ /* Now use the library's routine to set default compression parameters. * (You must set at least cinfo.in_color_space before calling this, * since the defaults depend on the source color space.) */ jpeg_set_defaults(&cinfo); - jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE) opts.color_space); + 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); @@ -146,17 +146,17 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio 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); - // A little hacky to build a string for this, but it means we can use set_quality_ratings which - // does some useful heuristic stuff. + // A little hacky to build a string for this, but it means we can use + // set_quality_ratings which does some useful heuristic stuff. std::string quality_str = std::to_string(opts.quality); if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) { quality_str += "," + std::to_string(opts.chroma_quality); } - char const *pqual = quality_str.c_str(); + char const* pqual = quality_str.c_str(); - set_quality_ratings(&cinfo, (char*) pqual, opts.baseline); + set_quality_ratings(&cinfo, (char*)pqual, opts.baseline); if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) { cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample; @@ -191,8 +191,8 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio * Here the array is only one element long, but you could pass * more than one scanline at a time if that's more convenient. */ - row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride]; + (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); } /* Step 6: Finish compression */ @@ -213,23 +213,22 @@ void free_result() { EMSCRIPTEN_BINDINGS(my_module) { value_object("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) - .field("chroma_subsample", &MozJpegOptions::chroma_subsample) - .field("auto_subsample", &MozJpegOptions::auto_subsample) - .field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality) - .field("chroma_quality", &MozJpegOptions::chroma_quality) - ; + .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) + .field("chroma_subsample", &MozJpegOptions::chroma_subsample) + .field("auto_subsample", &MozJpegOptions::auto_subsample) + .field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality) + .field("chroma_quality", &MozJpegOptions::chroma_quality); function("version", &version); function("encode", &encode); diff --git a/codecs/webp/dec/webp_dec.cpp b/codecs/webp/dec/webp_dec.cpp index 1edff9ac..969338d5 100644 --- a/codecs/webp/dec/webp_dec.cpp +++ b/codecs/webp/dec/webp_dec.cpp @@ -1,8 +1,8 @@ +#include #include "emscripten/bind.h" #include "emscripten/val.h" #include "src/webp/decode.h" #include "src/webp/demux.h" -#include using namespace emscripten; @@ -11,24 +11,19 @@ int version() { } class RawImage { -public: + public: val buffer; int width; int height; - RawImage(val b, int w, int h) - : buffer(b), width(w), height(h) {} + RawImage(val b, int w, int h) : buffer(b), width(w), height(h) {} }; uint8_t* last_result; RawImage decode(std::string buffer) { int width, height; last_result = WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height); - return RawImage( - val(typed_memory_view(width*height*4, last_result)), - width, - height - ); + return RawImage(val(typed_memory_view(width * height * 4, last_result)), width, height); } void free_result() { @@ -37,9 +32,9 @@ void free_result() { EMSCRIPTEN_BINDINGS(my_module) { class_("RawImage") - .property("buffer", &RawImage::buffer) - .property("width", &RawImage::width) - .property("height", &RawImage::height); + .property("buffer", &RawImage::buffer) + .property("width", &RawImage::width) + .property("height", &RawImage::height); function("decode", &decode); function("version", &version); diff --git a/codecs/webp/enc/webp_enc.cpp b/codecs/webp/enc/webp_enc.cpp index 3f22badc..0cc4afef 100644 --- a/codecs/webp/enc/webp_enc.cpp +++ b/codecs/webp/enc/webp_enc.cpp @@ -1,9 +1,9 @@ #include #include -#include "src/webp/encode.h" #include #include #include +#include "src/webp/encode.h" using namespace emscripten; @@ -14,7 +14,7 @@ int version() { uint8_t* last_result; val encode(std::string img, int width, int height, WebPConfig config) { - uint8_t* img_in = (uint8_t*) img.c_str(); + uint8_t* img_in = (uint8_t*)img.c_str(); // A lot of this is duplicated from Encode in picture_enc.c WebPPicture pic; @@ -35,7 +35,7 @@ val encode(std::string img, int width, int height, WebPConfig config) { WebPMemoryWriterInit(&wrt); - ok = WebPPictureImportRGBA(&pic, (uint8_t*) img_in, width * 4) && WebPEncode(&config, &pic); + ok = WebPPictureImportRGBA(&pic, (uint8_t*)img_in, width * 4) && WebPEncode(&config, &pic); WebPPictureFree(&pic); if (!ok) { WebPMemoryWriterClear(&wrt); @@ -51,44 +51,41 @@ void free_result() { WebPFree(last_result); } - EMSCRIPTEN_BINDINGS(my_module) { enum_("WebPImageHint") - .value("WEBP_HINT_DEFAULT", WebPImageHint::WEBP_HINT_DEFAULT) - .value("WEBP_HINT_PICTURE", WebPImageHint::WEBP_HINT_PICTURE) - .value("WEBP_HINT_PHOTO", WebPImageHint::WEBP_HINT_PHOTO) - .value("WEBP_HINT_GRAPH", WebPImageHint::WEBP_HINT_GRAPH) - ; + .value("WEBP_HINT_DEFAULT", WebPImageHint::WEBP_HINT_DEFAULT) + .value("WEBP_HINT_PICTURE", WebPImageHint::WEBP_HINT_PICTURE) + .value("WEBP_HINT_PHOTO", WebPImageHint::WEBP_HINT_PHOTO) + .value("WEBP_HINT_GRAPH", WebPImageHint::WEBP_HINT_GRAPH); value_object("WebPConfig") - .field("lossless", &WebPConfig::lossless) - .field("quality", &WebPConfig::quality) - .field("method", &WebPConfig::method) - .field("image_hint", &WebPConfig::image_hint) - .field("target_size", &WebPConfig::target_size) - .field("target_PSNR", &WebPConfig::target_PSNR) - .field("segments", &WebPConfig::segments) - .field("sns_strength", &WebPConfig::sns_strength) - .field("filter_strength", &WebPConfig::filter_strength) - .field("filter_sharpness", &WebPConfig::filter_sharpness) - .field("filter_type", &WebPConfig::filter_type) - .field("autofilter", &WebPConfig::autofilter) - .field("alpha_compression", &WebPConfig::alpha_compression) - .field("alpha_filtering", &WebPConfig::alpha_filtering) - .field("alpha_quality", &WebPConfig::alpha_quality) - .field("pass", &WebPConfig::pass) - .field("show_compressed", &WebPConfig::show_compressed) - .field("preprocessing", &WebPConfig::preprocessing) - .field("partitions", &WebPConfig::partitions) - .field("partition_limit", &WebPConfig::partition_limit) - .field("emulate_jpeg_size", &WebPConfig::emulate_jpeg_size) - .field("thread_level", &WebPConfig::thread_level) - .field("low_memory", &WebPConfig::low_memory) - .field("near_lossless", &WebPConfig::near_lossless) - .field("exact", &WebPConfig::exact) - .field("use_delta_palette", &WebPConfig::use_delta_palette) - .field("use_sharp_yuv", &WebPConfig::use_sharp_yuv) - ; + .field("lossless", &WebPConfig::lossless) + .field("quality", &WebPConfig::quality) + .field("method", &WebPConfig::method) + .field("image_hint", &WebPConfig::image_hint) + .field("target_size", &WebPConfig::target_size) + .field("target_PSNR", &WebPConfig::target_PSNR) + .field("segments", &WebPConfig::segments) + .field("sns_strength", &WebPConfig::sns_strength) + .field("filter_strength", &WebPConfig::filter_strength) + .field("filter_sharpness", &WebPConfig::filter_sharpness) + .field("filter_type", &WebPConfig::filter_type) + .field("autofilter", &WebPConfig::autofilter) + .field("alpha_compression", &WebPConfig::alpha_compression) + .field("alpha_filtering", &WebPConfig::alpha_filtering) + .field("alpha_quality", &WebPConfig::alpha_quality) + .field("pass", &WebPConfig::pass) + .field("show_compressed", &WebPConfig::show_compressed) + .field("preprocessing", &WebPConfig::preprocessing) + .field("partitions", &WebPConfig::partitions) + .field("partition_limit", &WebPConfig::partition_limit) + .field("emulate_jpeg_size", &WebPConfig::emulate_jpeg_size) + .field("thread_level", &WebPConfig::thread_level) + .field("low_memory", &WebPConfig::low_memory) + .field("near_lossless", &WebPConfig::near_lossless) + .field("exact", &WebPConfig::exact) + .field("use_delta_palette", &WebPConfig::use_delta_palette) + .field("use_sharp_yuv", &WebPConfig::use_sharp_yuv); function("version", &version); function("encode", &encode);