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.