diff --git a/src/webpenc.c b/src/webpenc.c index 0e66adb..80f7fd4 100644 --- a/src/webpenc.c +++ b/src/webpenc.c @@ -64,6 +64,40 @@ EMSCRIPTEN_KEEPALIVE void *new_webpwrapper_config() { return config; } +#define WEBP_PRESET_DEFAULT_TYPE 1 +#define WEBP_PRESET_PICTURE_TYPE 2 +#define WEBP_PRESET_PHOTO_TYPE 3 +#define WEBP_PRESET_DRAWING_TYPE 4 +#define WEBP_PRESET_ICON_TYPE 5 +#define WEBP_PRESET_TEXT_TYPE 6 + +void load_webp_config_preset(WebPConfig * config, int value, float quality_factor) { + WebPPreset preset = WEBP_PRESET_DEFAULT; + switch (value) { + case WEBP_PRESET_DEFAULT_TYPE: + preset = WEBP_PRESET_DEFAULT; + break; + case WEBP_PRESET_PICTURE_TYPE: + preset = WEBP_PRESET_PICTURE; + break; + case WEBP_PRESET_PHOTO_TYPE: + preset = WEBP_PRESET_PHOTO; + break; + case WEBP_PRESET_DRAWING_TYPE: + preset = WEBP_PRESET_DRAWING; + break; + case WEBP_PRESET_ICON_TYPE: + preset = WEBP_PRESET_ICON; + break; + case WEBP_PRESET_TEXT_TYPE: + preset = WEBP_PRESET_TEXT; + break; + default: + break; + } + WebPConfigPreset(config, preset, quality_factor); +} + #define SET_WEBP_CONFIG_PARAM_INT(parameter_name) \ void set_webp_config_##parameter_name (WebPConfig * config, int value) {\ config->parameter_name = value;\ @@ -74,6 +108,16 @@ void set_webp_config_##parameter_name(WebPConfig * config, float value) {\ config->parameter_name = value;\ } +#define GET_WEBP_CONFIG_PARAM_INT(parameter_name) \ +int get_webp_config_##parameter_name (WebPConfig * config) {\ + return config->parameter_name;\ +} + +#define GET_WEBP_CONFIG_PARAM_FLOAT(parameter_name) \ +float get_webp_config_##parameter_name(WebPConfig * config) {\ + return config->parameter_name;\ +} + SET_WEBP_CONFIG_PARAM_INT(lossless) SET_WEBP_CONFIG_PARAM_FLOAT(quality) SET_WEBP_CONFIG_PARAM_INT(method) @@ -100,6 +144,32 @@ SET_WEBP_CONFIG_PARAM_INT(exact) SET_WEBP_CONFIG_PARAM_INT(use_delta_palette) SET_WEBP_CONFIG_PARAM_INT(use_sharp_yuv) +GET_WEBP_CONFIG_PARAM_INT(lossless) +GET_WEBP_CONFIG_PARAM_FLOAT(quality) +GET_WEBP_CONFIG_PARAM_INT(method) +GET_WEBP_CONFIG_PARAM_INT(target_size) +GET_WEBP_CONFIG_PARAM_FLOAT(target_PSNR) +GET_WEBP_CONFIG_PARAM_INT(segments) +GET_WEBP_CONFIG_PARAM_INT(sns_strength) +GET_WEBP_CONFIG_PARAM_INT(filter_strength) +GET_WEBP_CONFIG_PARAM_INT(filter_sharpness) +GET_WEBP_CONFIG_PARAM_INT(filter_type) +GET_WEBP_CONFIG_PARAM_INT(autofilter) +GET_WEBP_CONFIG_PARAM_INT(alpha_compression) +GET_WEBP_CONFIG_PARAM_INT(alpha_filtering) +GET_WEBP_CONFIG_PARAM_INT(alpha_quality) +GET_WEBP_CONFIG_PARAM_INT(pass) +GET_WEBP_CONFIG_PARAM_INT(preprocessing) +GET_WEBP_CONFIG_PARAM_INT(partitions) +GET_WEBP_CONFIG_PARAM_INT(partition_limit) +GET_WEBP_CONFIG_PARAM_INT(emulate_jpeg_size) +GET_WEBP_CONFIG_PARAM_INT(thread_level) +GET_WEBP_CONFIG_PARAM_INT(low_memory) +GET_WEBP_CONFIG_PARAM_INT(near_lossless) +GET_WEBP_CONFIG_PARAM_INT(exact) +GET_WEBP_CONFIG_PARAM_INT(use_delta_palette) +GET_WEBP_CONFIG_PARAM_INT(use_sharp_yuv) + #define WEBP_HINT_DEFAULT_TYPE 1 #define WEBP_HINT_PICTURE_TYPE 2 #define WEBP_HINT_PHOTO_TYPE 3 @@ -294,3 +364,4 @@ EMSCRIPTEN_KEEPALIVE void *encodeWebPWithConfig(uint32_t *bs, WebPConfig * confi } return encoded; } + diff --git a/src/webpxmux.ts b/src/webpxmux.ts index dd0f393..d5731a3 100644 --- a/src/webpxmux.ts +++ b/src/webpxmux.ts @@ -37,6 +37,7 @@ interface WebPXMuxModule extends EmscriptenModule { encodeWebPWithConfig: (ptr: Ptr, config: Ptr) => Ptr; newWebPConfig: () => Ptr; + loadWebPConfigPreset: (ptr: Ptr, presetIndex: number; quality: number) => Ptr; setWebPConfigLossless: (ptr: Ptr, value: number) => void; setWebPConfigQuality: (ptr: Ptr, value: number) => void; setWebPConfigMethod: (ptr: Ptr, value: number) => void; @@ -62,6 +63,32 @@ interface WebPXMuxModule extends EmscriptenModule { setWebPConfigExact: (ptr: Ptr, value: number) => void; setWebPConfigUseDeltaPalette: (ptr: Ptr, value: number) => void; setWebPConfigUseSharpYUV: (ptr: Ptr, value: number) => void; + + getWebPConfigLossless: (ptr: Ptr) => number; + getWebPConfigQuality: (ptr: Ptr) => number; + getWebPConfigMethod: (ptr: Ptr) => number; + getWebPConfigTargetSize: (ptr: Ptr) => number; + getWebPConfigTargetPSNR: (ptr: Ptr) => number; + getWebPConfigSegments: (ptr: Ptr) => number; + getWebPConfigSNSStrength: (ptr: Ptr) => number; + getWebPConfigFilterStrength: (ptr: Ptr) => number; + getWebPConfigFilterSharpness: (ptr: Ptr) => number; + getWebPConfigFilterType: (ptr: Ptr) => number; + getWebPConfigAutoFilter: (ptr: Ptr) => number; + getWebPConfigAlphaCompression: (ptr: Ptr) => number; + getWebPConfigAlphaFiltering: (ptr: Ptr) => number; + getWebPConfigAlphaQuality: (ptr: Ptr) => number; + getWebPConfigPass: (ptr: Ptr) => number; + getWebPConfigPreprocessing: (ptr: Ptr) => number; + getWebPConfigPartitions: (ptr: Ptr) => number; + getWebPConfigPartitionsLimit: (ptr: Ptr) => number; + getWebPConfigEmulateJPEGSize: (ptr: Ptr) => number; + getWebPConfigThreadLevel: (ptr: Ptr) => number; + getWebPConfigLowMemory: (ptr: Ptr) => number; + getWebPConfigNearLossless: (ptr: Ptr) => number; + getWebPConfigExact: (ptr: Ptr) => number; + getWebPConfigUseDeltaPalette: (ptr: Ptr) => number; + getWebPConfigUseSharpYUV: (ptr: Ptr) => number; } const toUnsigned = (n: number) => n >>> 0; @@ -170,6 +197,11 @@ class WebPXMux { "number", ["number", "number"] ); + this.Module!.loadWebPConfigPreset = this.Module!.cwrap( + "load_webp_config_preset", + "number", + ["number", "number", "number"] + ); this.Module!.setWebPConfigLossless = this.Module!.cwrap( "set_webp_config_lossless", "number", @@ -295,6 +327,133 @@ class WebPXMux { "number", ["number", "number"] ); + + this.Module!.getWebPConfigLossless = this.Module!.cwrap( + "get_webp_config_lossless", + "number", + ["number"] + ); + this.Module!.getWebPConfigQuality = this.Module!.cwrap( + "get_webp_config_quality", + "number", + ["number"] + ); + this.Module!.getWebPConfigMethod = this.Module!.cwrap( + "get_webp_config_method", + "number", + ["number"] + ); + this.Module!.getWebPConfigTargetSize = this.Module!.cwrap( + "get_webp_config_target_size", + "number", + ["number"] + ); + this.Module!.getWebPConfigTargetPSNR = this.Module!.cwrap( + "get_webp_config_target_PSNR", + "number", + ["number"] + ); + this.Module!.getWebPConfigSegments = this.Module!.cwrap( + "get_webp_config_segments", + "number", + ["number"] + ); + this.Module!.getWebPConfigSNSStrength = this.Module!.cwrap( + "get_webp_config_sns_strength", + "number", + ["number"] + ); + this.Module!.getWebPConfigFilterStrength = this.Module!.cwrap( + "get_webp_config_filter_strength", + "number", + ["number"] + ); + this.Module!.getWebPConfigFilterSharpness = this.Module!.cwrap( + "get_webp_config_filter_sharpness", + "number", + ["number"] + ); + this.Module!.getWebPConfigFilterType = this.Module!.cwrap( + "get_webp_config_filter_type", + "number", + ["number"] + ); + this.Module!.getWebPConfigAutoFilter = this.Module!.cwrap( + "get_webp_config_autofilter", + "number", + ["number"] + ); + this.Module!.getWebPConfigAlphaCompression = this.Module!.cwrap( + "get_webp_config_alpha_compression", + "number", + ["number"] + ); + this.Module!.getWebPConfigAlphaFiltering = this.Module!.cwrap( + "get_webp_config_alpha_filtering", + "number", + ["number"] + ); + this.Module!.getWebPConfigAlphaQuality = this.Module!.cwrap( + "get_webp_config_alpha_quality", + "number", + ["number"] + ); + this.Module!.getWebPConfigPass = this.Module!.cwrap( + "get_webp_config_pass", + "number", + ["number"] + ); + this.Module!.getWebPConfigPreprocessing = this.Module!.cwrap( + "get_webp_config_preprocessing", + "number", + ["number"] + ); + this.Module!.getWebPConfigPartitions = this.Module!.cwrap( + "get_webp_config_partitions", + "number", + ["number"] + ); + this.Module!.getWebPConfigPartitionsLimit = this.Module!.cwrap( + "get_webp_config_partition_limit", + "number", + ["number"] + ); + this.Module!.getWebPConfigEmulateJPEGSize = this.Module!.cwrap( + "get_webp_config_emulate_jpeg_size", + "number", + ["number"] + ); + this.Module!.getWebPConfigThreadLevel = this.Module!.cwrap( + "get_webp_config_thread_level", + "number", + ["number"] + ); + this.Module!.getWebPConfigLowMemory = this.Module!.cwrap( + "get_webp_config_low_memory", + "number", + ["number"] + ); + this.Module!.getWebPConfigNearLossless = this.Module!.cwrap( + "get_webp_config_near_lossless", + "number", + ["number"] + ); + this.Module!.getWebPConfigExact = this.Module!.cwrap( + "get_webp_config_exact", + "number", + ["number"] + ); + this.Module!.getWebPConfigUseDeltaPalette = this.Module!.cwrap( + "get_webp_config_use_delta_palette", + "number", + ["number"] + ); + this.Module!.getWebPConfigUseSharpYUV = this.Module!.cwrap( + "get_webp_config_use_sharp_yuv", + "number", + ["number"] + ); + this.SIZE_SIZE_T = toUnsigned( this.Module!.cwrap("sizeof_size_t", "number", [])() ) as AlignedByteSize; @@ -398,6 +557,96 @@ class WebPXMux { return ptr; } + newEmptyWebPConfig(): WebPConfig { + var config: WebPConfig = { + lossless: 0, + quality: 0, + method: 0, + target_size: 0, + target_PSNR: 0, + segments: 0, + sns_strength: 0, + filter_strength: 0, + filter_sharpness: 0, + filter_type: 0, + autofilter: 0, + alpha_compression: 0, + alpha_filtering: 0, + alpha_quality: 0, + pass: 0, + preprocessing: 0, + partitions: 0, + partition_limit: 0, + emulate_jpeg_size: 0, + thread_level: 0, + low_memory: 0, + near_lossless: 0, + exact: 0, + use_delta_palette: 0, + use_sharp_yuv: 0 + } + return config + } + + loadWebPPreset(presetName: string, qualityFactor: number): WebPConfig { + var config = this.newEmptyWebPConfig(); + const configPtr = this.Module!.newWebPConfig(); + var preset = 1; + switch (presetName) { + case "picture": { + preset = 2; + break; + } + case "photo": { + preset = 3; + break; + } + case "drawing": { + preset = 4; + break; + } + case "icon": { + preset = 5; + break; + } + case "text": { + preset = 6; + break; + } + default: { + break; + } + } + this.Module!.loadWebPConfigPreset(configPtr, preset, qualityFactor); + config.lossless = this.Module!.getWebPConfigLossless(configPtr); + config.quality = this.Module!.getWebPConfigQuality(configPtr); + config.method = this.Module!.getWebPConfigMethod(configPtr); + config.target_size = this.Module!.getWebPConfigTargetSize(configPtr); + config.target_PSNR = this.Module!.getWebPConfigTargetPSNR(configPtr); + config.segments = this.Module!.getWebPConfigSegments(configPtr); + config.sns_strength = this.Module!.getWebPConfigSNSStrength(configPtr); + config.filter_strength = this.Module!.getWebPConfigFilterStrength(configPtr); + config.filter_sharpness = this.Module!.getWebPConfigFilterSharpness(configPtr); + config.filter_type = this.Module!.getWebPConfigFilterType(configPtr); + config.autofilter = this.Module!.getWebPConfigAutoFilter(configPtr); + config.alpha_compression = this.Module!.getWebPConfigAlphaCompression(configPtr); + config.alpha_filtering = this.Module!.getWebPConfigAlphaFiltering(configPtr); + config.alpha_quality = this.Module!.getWebPConfigAlphaQuality(configPtr); + config.pass = this.Module!.getWebPConfigPass(configPtr); + config.preprocessing = this.Module!.getWebPConfigPreprocessing(configPtr); + config.partitions = this.Module!.getWebPConfigPartitions(configPtr); + config.partition_limit = this.Module!.getWebPConfigPartitionsLimit(configPtr); + config.emulate_jpeg_size = this.Module!.getWebPConfigEmulateJPEGSize(configPtr); + config.thread_level = this.Module!.getWebPConfigThreadLevel(configPtr); + config.low_memory = this.Module!.getWebPConfigLowMemory(configPtr); + config.near_lossless = this.Module!.getWebPConfigNearLossless(configPtr); + config.exact = this.Module!.getWebPConfigExact(configPtr); + config.use_delta_palette = this.Module!.getWebPConfigUseDeltaPalette(configPtr); + config.use_sharp_yuv = this.Module!.getWebPConfigUseSharpYUV(configPtr); + this.Module!._free(configPtr); + return config; + } + async decodeFrames(webPData: Uint8Array) { const size = webPData.length * webPData.BYTES_PER_ELEMENT; const ptr = this.Module!._malloc(size);