mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 14:34:33 +02:00
Enc: add a qmin / qmax range for quality factor
This is particularly useful for multi-pass search (but not only), to prevent the search from going over or below a reasonable threshold. E.g.: 'cwebp -qrange 50 80 ...' will prevent any unreasonable degradation. new cwebp option: -qrange min max Change-Id: I59f394533535fc20b6996bc0895f4301476d5eff
This commit is contained in:
@ -39,6 +39,8 @@ int WebPConfigInitInternal(WebPConfig* config,
|
||||
config->partitions = 0;
|
||||
config->segments = 4;
|
||||
config->pass = 1;
|
||||
config->qmin = 0;
|
||||
config->qmax = 100;
|
||||
config->show_compressed = 0;
|
||||
config->preprocessing = 0;
|
||||
config->autofilter = 0;
|
||||
@ -106,6 +108,9 @@ int WebPValidateConfig(const WebPConfig* config) {
|
||||
if (config->filter_type < 0 || config->filter_type > 1) return 0;
|
||||
if (config->autofilter < 0 || config->autofilter > 1) return 0;
|
||||
if (config->pass < 1 || config->pass > 10) return 0;
|
||||
if (config->qmin < 0 || config->qmax > 100 || config->qmin > config->qmax) {
|
||||
return 0;
|
||||
}
|
||||
if (config->show_compressed < 0 || config->show_compressed > 1) return 0;
|
||||
if (config->preprocessing < 0 || config->preprocessing > 7) return 0;
|
||||
if (config->partitions < 0 || config->partitions > 3) return 0;
|
||||
|
@ -31,10 +31,15 @@
|
||||
// we allow 2k of extra head-room in PARTITION0 limit.
|
||||
#define PARTITION0_SIZE_LIMIT ((VP8_MAX_PARTITION0_SIZE - 2048ULL) << 11)
|
||||
|
||||
static float Clamp(float v, float min, float max) {
|
||||
return (v < min) ? min : (v > max) ? max : v;
|
||||
}
|
||||
|
||||
typedef struct { // struct for organizing convergence in either size or PSNR
|
||||
int is_first;
|
||||
float dq;
|
||||
float q, last_q;
|
||||
float qmin, qmax;
|
||||
double value, last_value; // PSNR or size
|
||||
double target;
|
||||
int do_size_search;
|
||||
@ -47,7 +52,9 @@ static int InitPassStats(const VP8Encoder* const enc, PassStats* const s) {
|
||||
|
||||
s->is_first = 1;
|
||||
s->dq = 10.f;
|
||||
s->q = s->last_q = enc->config_->quality;
|
||||
s->qmin = enc->config_->qmin;
|
||||
s->qmax = enc->config_->qmax;
|
||||
s->q = s->last_q = Clamp(enc->config_->quality, s->qmin, s->qmax);
|
||||
s->target = do_size_search ? (double)target_size
|
||||
: (target_PSNR > 0.) ? target_PSNR
|
||||
: 40.; // default, just in case
|
||||
@ -56,10 +63,6 @@ static int InitPassStats(const VP8Encoder* const enc, PassStats* const s) {
|
||||
return do_size_search;
|
||||
}
|
||||
|
||||
static float Clamp(float v, float min, float max) {
|
||||
return (v < min) ? min : (v > max) ? max : v;
|
||||
}
|
||||
|
||||
static float ComputeNextQ(PassStats* const s) {
|
||||
float dq;
|
||||
if (s->is_first) {
|
||||
@ -75,7 +78,7 @@ static float ComputeNextQ(PassStats* const s) {
|
||||
s->dq = Clamp(dq, -30.f, 30.f);
|
||||
s->last_q = s->q;
|
||||
s->last_value = s->value;
|
||||
s->q = Clamp(s->q + s->dq, 0.f, 100.f);
|
||||
s->q = Clamp(s->q + s->dq, s->qmin, s->qmax);
|
||||
return s->q;
|
||||
}
|
||||
|
||||
@ -848,9 +851,10 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
||||
}
|
||||
|
||||
#if (DEBUG_SEARCH > 0)
|
||||
printf("#%2d metric:%.1lf -> %.1lf last_q=%.2lf q=%.2lf dq=%.2lf\n",
|
||||
printf("#%2d metric:%.1lf -> %.1lf last_q=%.2lf q=%.2lf dq=%.2lf "
|
||||
" range:[%.1f, %.1f]\n",
|
||||
num_pass_left, stats.last_value, stats.value,
|
||||
stats.last_q, stats.q, stats.dq);
|
||||
stats.last_q, stats.q, stats.dq, stats.qmin, stats.qmax);
|
||||
#endif
|
||||
if (enc->max_i4_header_bits_ > 0 && size_p0 > PARTITION0_SIZE_LIMIT) {
|
||||
++num_pass_left;
|
||||
|
@ -20,7 +20,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b)
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x0210 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
|
||||
// the types are left here for reference.
|
||||
@ -121,6 +121,8 @@ struct WebPConfig {
|
||||
int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
|
||||
// Default is 100.
|
||||
int pass; // number of entropy-analysis passes (in [1..10]).
|
||||
int qmin; // minimum permissible quality factor
|
||||
int qmax; // maximum permissible quality factor
|
||||
|
||||
int show_compressed; // if true, export the compressed picture back.
|
||||
// In-loop filtering is not applied.
|
||||
|
Reference in New Issue
Block a user