Merge ".gitignore: add img2webp"
diff --git a/README b/README
index 400d23a..0caab28 100644
--- a/README
+++ b/README
@@ -241,6 +241,7 @@
-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
-strong ................ use strong filter instead of simple (default)
-nostrong .............. use simple filter instead of strong
+ -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
-partition_limit <int> . limit quality to fit the 512k limit on
the first partition (0=no degradation ... 100=full)
-pass <int> ............ analysis pass number (1..10)
diff --git a/examples/cwebp.c b/examples/cwebp.c
index 98f3681..27e5138 100644
--- a/examples/cwebp.c
+++ b/examples/cwebp.c
@@ -549,6 +549,8 @@
printf(" -strong ................ use strong filter instead "
"of simple (default)\n");
printf(" -nostrong .............. use simple filter instead of strong\n");
+ printf(" -sharp_yuv ............. use sharper (and slower) RGB->YUV "
+ "conversion\n");
printf(" -partition_limit <int> . limit quality to fit the 512k limit on\n");
printf(" "
"the first partition (0=no degradation ... 100=full)\n");
@@ -577,8 +579,8 @@
printf(" -near_lossless <int> ... use near-lossless image\n"
" preprocessing (0..100=off), "
"default=100\n");
-#ifdef WEBP_EXPERIMENTAL_FEATURES
- printf(" -delta_palettization ... use delta palettization\n");
+#ifdef WEBP_EXPERIMENTAL_FEATURES /* not documented yet */
+ printf(" -delta_palette ......... use delta palettization\n");
#endif // WEBP_EXPERIMENTAL_FEATURES
printf(" -hint <string> ......... specify image characteristics hint,\n");
printf(" one of: photo, picture or graph\n");
@@ -749,9 +751,9 @@
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
config.lossless = 1; // use near-lossless only with lossless
#ifdef WEBP_EXPERIMENTAL_FEATURES
- } else if (!strcmp(argv[c], "-delta_palettization")) {
- config.delta_palettization = 1;
- config.lossless = 1; // use delta-palettization only with lossless
+ } else if (!strcmp(argv[c], "-delta_palette")) {
+ config.use_delta_palette = 1;
+ config.lossless = 1; // delta-palette is for lossless only
#endif // WEBP_EXPERIMENTAL_FEATURES
} else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
++c;
@@ -787,6 +789,8 @@
config.filter_type = 0;
} else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error);
+ } else if (!strcmp(argv[c], "-sharp_yuv")) {
+ config.use_sharp_yuv = 1;
} else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
config.pass = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
@@ -945,7 +949,8 @@
// Read the input. We need to decide if we prefer ARGB or YUVA
// samples, depending on the expected compression mode (this saves
// some conversion steps).
- picture.use_argb = (config.lossless || config.preprocessing > 0 ||
+ picture.use_argb = (config.lossless || config.use_sharp_yuv ||
+ config.preprocessing > 0 ||
crop || (resize_w | resize_h) > 0);
if (verbose) {
StopwatchReset(&stop_watch);
diff --git a/man/cwebp.1 b/man/cwebp.1
index 12fb472..81cbaa9 100644
--- a/man/cwebp.1
+++ b/man/cwebp.1
@@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
-.TH CWEBP 1 "September 02, 2016"
+.TH CWEBP 1 "January 20, 2017"
.SH NAME
cwebp \- compress an image file to a WebP file
.SH SYNOPSIS
@@ -166,6 +166,10 @@
Disable strong filtering (if filtering is being used thanks to the
\fB\-f\fP option) and use simple filtering instead.
.TP
+.B \-sharp_yuv
+Use more accurate and sharper RGB->YUV conversion if needed. Note that this
+process is slower than the default 'fast' RGB->YUV conversion.
+.TP
.BI \-sns " int
Specify the amplitude of the spatial noise shaping. Spatial noise shaping
(or \fBsns\fP for short) refers to a general collection of built\-in algorithms
diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h
index 7ce5885..813fed4 100644
--- a/src/dsp/dsp.h
+++ b/src/dsp/dsp.h
@@ -429,11 +429,11 @@
uint8_t* u, uint8_t* v, int width);
// utilities for accurate RGB->YUV conversion
-extern uint64_t (*WebPSmartYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
+extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
uint16_t* dst, int len);
-extern void (*WebPSmartYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
+extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
int16_t* dst, int len);
-extern void (*WebPSmartYUVFilterRow)(const int16_t* A, const int16_t* B,
+extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B,
int len,
const uint16_t* best_y, uint16_t* out);
diff --git a/src/dsp/yuv.c b/src/dsp/yuv.c
index 797cc0f..dd7d9de 100644
--- a/src/dsp/yuv.c
+++ b/src/dsp/yuv.c
@@ -251,7 +251,7 @@
return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
}
-static uint64_t SmartYUVUpdateY_C(const uint16_t* ref, const uint16_t* src,
+static uint64_t SharpYUVUpdateY_C(const uint16_t* ref, const uint16_t* src,
uint16_t* dst, int len) {
uint64_t diff = 0;
int i;
@@ -264,7 +264,7 @@
return diff;
}
-static void SmartYUVUpdateRGB_C(const int16_t* ref, const int16_t* src,
+static void SharpYUVUpdateRGB_C(const int16_t* ref, const int16_t* src,
int16_t* dst, int len) {
int i;
for (i = 0; i < len; ++i) {
@@ -273,7 +273,7 @@
}
}
-static void SmartYUVFilterRow_C(const int16_t* A, const int16_t* B, int len,
+static void SharpYUVFilterRow_C(const int16_t* A, const int16_t* B, int len,
const uint16_t* best_y, uint16_t* out) {
int i;
for (i = 0; i < len; ++i, ++A, ++B) {
@@ -297,18 +297,18 @@
void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
int src_width, int do_store);
-uint64_t (*WebPSmartYUVUpdateY)(const uint16_t* ref, const uint16_t* src,
+uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* ref, const uint16_t* src,
uint16_t* dst, int len);
-void (*WebPSmartYUVUpdateRGB)(const int16_t* ref, const int16_t* src,
+void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src,
int16_t* dst, int len);
-void (*WebPSmartYUVFilterRow)(const int16_t* A, const int16_t* B, int len,
+void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len,
const uint16_t* best_y, uint16_t* out);
static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used =
(VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used;
extern void WebPInitConvertARGBToYUVSSE2(void);
-extern void WebPInitSmartYUVSSE2(void);
+extern void WebPInitSharpYUVSSE2(void);
WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
@@ -321,15 +321,15 @@
WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C;
- WebPSmartYUVUpdateY = SmartYUVUpdateY_C;
- WebPSmartYUVUpdateRGB = SmartYUVUpdateRGB_C;
- WebPSmartYUVFilterRow = SmartYUVFilterRow_C;
+ WebPSharpYUVUpdateY = SharpYUVUpdateY_C;
+ WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_C;
+ WebPSharpYUVFilterRow = SharpYUVFilterRow_C;
if (VP8GetCPUInfo != NULL) {
#if defined(WEBP_USE_SSE2)
if (VP8GetCPUInfo(kSSE2)) {
WebPInitConvertARGBToYUVSSE2();
- WebPInitSmartYUVSSE2();
+ WebPInitSharpYUVSSE2();
}
#endif // WEBP_USE_SSE2
}
diff --git a/src/dsp/yuv_sse2.c b/src/dsp/yuv_sse2.c
index 1f610d6..e33c2bb 100644
--- a/src/dsp/yuv_sse2.c
+++ b/src/dsp/yuv_sse2.c
@@ -743,7 +743,7 @@
return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v;
}
-static uint64_t SmartYUVUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
+static uint64_t SharpYUVUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
uint16_t* dst, int len) {
uint64_t diff = 0;
uint32_t tmp[4];
@@ -777,7 +777,7 @@
return diff;
}
-static void SmartYUVUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
+static void SharpYUVUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
int16_t* dst, int len) {
int i = 0;
for (i = 0; i + 8 <= len; i += 8) {
@@ -794,7 +794,7 @@
}
}
-static void SmartYUVFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
+static void SharpYUVFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
const uint16_t* best_y, uint16_t* out) {
int i;
const __m128i kCst8 = _mm_set1_epi16(8);
@@ -846,18 +846,18 @@
//------------------------------------------------------------------------------
-extern void WebPInitSmartYUVSSE2(void);
+extern void WebPInitSharpYUVSSE2(void);
-WEBP_TSAN_IGNORE_FUNCTION void WebPInitSmartYUVSSE2(void) {
- WebPSmartYUVUpdateY = SmartYUVUpdateY_SSE2;
- WebPSmartYUVUpdateRGB = SmartYUVUpdateRGB_SSE2;
- WebPSmartYUVFilterRow = SmartYUVFilterRow_SSE2;
+WEBP_TSAN_IGNORE_FUNCTION void WebPInitSharpYUVSSE2(void) {
+ WebPSharpYUVUpdateY = SharpYUVUpdateY_SSE2;
+ WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_SSE2;
+ WebPSharpYUVFilterRow = SharpYUVFilterRow_SSE2;
}
#else // !WEBP_USE_SSE2
WEBP_DSP_INIT_STUB(WebPInitSamplersSSE2)
WEBP_DSP_INIT_STUB(WebPInitConvertARGBToYUVSSE2)
-WEBP_DSP_INIT_STUB(WebPInitSmartYUVSSE2)
+WEBP_DSP_INIT_STUB(WebPInitSharpYUVSSE2)
#endif // WEBP_USE_SSE2
diff --git a/src/enc/config_enc.c b/src/enc/config_enc.c
index f7975ff..4589dc0 100644
--- a/src/enc/config_enc.c
+++ b/src/enc/config_enc.c
@@ -53,9 +53,8 @@
config->thread_level = 0;
config->low_memory = 0;
config->near_lossless = 100;
-#ifdef WEBP_EXPERIMENTAL_FEATURES
- config->delta_palettization = 0;
-#endif // WEBP_EXPERIMENTAL_FEATURES
+ config->use_delta_palette = 0;
+ config->use_sharp_yuv = 0;
// TODO(skal): tune.
switch (preset) {
@@ -121,11 +120,11 @@
if (config->thread_level < 0 || config->thread_level > 1) return 0;
if (config->low_memory < 0 || config->low_memory > 1) return 0;
if (config->exact < 0 || config->exact > 1) return 0;
-#ifdef WEBP_EXPERIMENTAL_FEATURES
- if (config->delta_palettization < 0 || config->delta_palettization > 1) {
+ if (config->use_delta_palette < 0 || config->use_delta_palette > 1) {
return 0;
}
-#endif // WEBP_EXPERIMENTAL_FEATURES
+ if (config->use_sharp_yuv < 0 || config->use_sharp_yuv > 1) return 0;
+
return 1;
}
diff --git a/src/enc/picture_csp_enc.c b/src/enc/picture_csp_enc.c
index d030302..e5d1c75 100644
--- a/src/enc/picture_csp_enc.c
+++ b/src/enc/picture_csp_enc.c
@@ -153,7 +153,7 @@
}
//------------------------------------------------------------------------------
-// Smart RGB->YUV conversion
+// Sharp RGB->YUV conversion
static const int kNumIterations = 4;
static const int kMinDimensionIterativeConversion = 4;
@@ -353,8 +353,8 @@
out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0]);
out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w]);
- WebPSmartYUVFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1);
- WebPSmartYUVFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1);
+ WebPSharpYUVFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1);
+ WebPSharpYUVFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1);
// special boundary case for i == w - 1 when w is even
if (!(w & 1)) {
@@ -527,8 +527,8 @@
UpdateChroma(src1, src2, best_rgb_uv, uv_w);
// update two rows of Y and one row of RGB
- diff_y_sum += WebPSmartYUVUpdateY(target_y, best_rgb_y, best_y, 2 * w);
- WebPSmartYUVUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
+ diff_y_sum += WebPSharpYUVUpdateY(target_y, best_rgb_y, best_y, 2 * w);
+ WebPSharpYUVUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
best_y += 2 * w;
best_uv += 3 * uv_w;
@@ -1011,9 +1011,13 @@
return PictureARGBToYUVA(picture, colorspace, 0.f, 0);
}
-int WebPPictureSmartARGBToYUVA(WebPPicture* picture) {
+int WebPPictureSharpARGBToYUVA(WebPPicture* picture) {
return PictureARGBToYUVA(picture, WEBP_YUV420, 0.f, 1);
}
+// for backward compatibility
+int WebPPictureSmartARGBToYUVA(WebPPicture* picture) {
+ return WebPPictureSharpARGBToYUVA(picture);
+}
//------------------------------------------------------------------------------
// call for YUVA -> ARGB conversion
diff --git a/src/enc/vp8l_enc.c b/src/enc/vp8l_enc.c
index a7e88af..b1a793d 100644
--- a/src/enc/vp8l_enc.c
+++ b/src/enc/vp8l_enc.c
@@ -1454,7 +1454,7 @@
int use_near_lossless = 0;
int hdr_size = 0;
int data_size = 0;
- int use_delta_palettization = 0;
+ int use_delta_palette = 0;
if (enc == NULL) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
@@ -1481,7 +1481,7 @@
}
#ifdef WEBP_EXPERIMENTAL_FEATURES
- if (config->delta_palettization) {
+ if (config->use_delta_palette) {
enc->use_predict_ = 1;
enc->use_cross_color_ = 0;
enc->use_subtract_green_ = 0;
@@ -1495,7 +1495,7 @@
if (err != VP8_ENC_OK) goto Error;
err = EncodeDeltaPalettePredictorImage(bw, enc, quality, low_effort);
if (err != VP8_ENC_OK) goto Error;
- use_delta_palettization = 1;
+ use_delta_palette = 1;
}
}
#endif // WEBP_EXPERIMENTAL_FEATURES
@@ -1504,14 +1504,14 @@
if (enc->use_palette_) {
err = EncodePalette(bw, low_effort, enc);
if (err != VP8_ENC_OK) goto Error;
- err = MapImageFromPalette(enc, use_delta_palettization);
+ err = MapImageFromPalette(enc, use_delta_palette);
if (err != VP8_ENC_OK) goto Error;
// If using a color cache, do not have it bigger than the number of colors.
if (use_cache && enc->palette_size_ < (1 << MAX_COLOR_CACHE_BITS)) {
enc->cache_bits_ = BitsLog2Floor(enc->palette_size_) + 1;
}
}
- if (!use_delta_palettization) {
+ if (!use_delta_palette) {
// In case image is not packed.
if (enc->argb_ == NULL) {
err = MakeInputImageCopy(enc);
diff --git a/src/enc/webp_enc.c b/src/enc/webp_enc.c
index 71e7c2a..f18461e 100644
--- a/src/enc/webp_enc.c
+++ b/src/enc/webp_enc.c
@@ -342,8 +342,8 @@
if (pic->use_argb || pic->y == NULL || pic->u == NULL || pic->v == NULL) {
// Make sure we have YUVA samples.
- if (config->preprocessing & 4) {
- if (!WebPPictureSmartARGBToYUVA(pic)) {
+ if (config->use_sharp_yuv || (config->preprocessing & 4)) {
+ if (!WebPPictureSharpARGBToYUVA(pic)) {
return 0;
}
} else {
diff --git a/src/webp/encode.h b/src/webp/encode.h
index fe21ded..35fde1d 100644
--- a/src/webp/encode.h
+++ b/src/webp/encode.h
@@ -20,7 +20,7 @@
extern "C" {
#endif
-#define WEBP_ENCODER_ABI_VERSION 0x020b // MAJOR(8b) + MINOR(8b)
+#define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
@@ -141,12 +141,10 @@
// RGB information for better compression. The default
// value is 0.
-#ifdef WEBP_EXPERIMENTAL_FEATURES
- int delta_palettization;
+ int use_delta_palette; // reserved for future lossless feature
+ int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
+
uint32_t pad[2]; // padding for later use
-#else
- uint32_t pad[3]; // padding for later use
-#endif // WEBP_EXPERIMENTAL_FEATURES
};
// Enumerate some predefined settings for WebPConfig, depending on the type
@@ -488,11 +486,13 @@
WEBP_EXTERN(int) WebPPictureARGBToYUVADithered(
WebPPicture* picture, WebPEncCSP colorspace, float dithering);
-// Performs 'smart' RGBA->YUVA420 downsampling and colorspace conversion.
+// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
// Downsampling is handled with extra care in case of color clipping. This
// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
-// YUV representation.
+// and sharper YUV representation.
// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureSharpARGBToYUVA(WebPPicture* picture);
+// kept for backward compatibility:
WEBP_EXTERN(int) WebPPictureSmartARGBToYUVA(WebPPicture* picture);
// Converts picture->yuv to picture->argb and sets picture->use_argb to true.