Home | History | Annotate | Download | only in enc
      1 // Copyright 2015 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 // Author: Mislav Bradac (mislavm (at) google.com)
     11 //
     12 
     13 #include "./delta_palettization_enc.h"
     14 
     15 #ifdef WEBP_EXPERIMENTAL_FEATURES
     16 #include "../webp/types.h"
     17 #include "../dsp/lossless.h"
     18 
     19 #define MK_COL(r, g, b) (((r) << 16) + ((g) << 8) + (b))
     20 
     21 // Format allows palette up to 256 entries, but more palette entries produce
     22 // bigger entropy. In the future it will probably be useful to add more entries
     23 // that are far from the origin of the palette or choose remaining entries
     24 // dynamically.
     25 #define DELTA_PALETTE_SIZE 226
     26 
     27 // Palette used for delta_palettization. Entries are roughly sorted by distance
     28 // of their signed equivalents from the origin.
     29 static const uint32_t kDeltaPalette[DELTA_PALETTE_SIZE] = {
     30   MK_COL(0u, 0u, 0u),
     31   MK_COL(255u, 255u, 255u),
     32   MK_COL(1u, 1u, 1u),
     33   MK_COL(254u, 254u, 254u),
     34   MK_COL(2u, 2u, 2u),
     35   MK_COL(4u, 4u, 4u),
     36   MK_COL(252u, 252u, 252u),
     37   MK_COL(250u, 0u, 0u),
     38   MK_COL(0u, 250u, 0u),
     39   MK_COL(0u, 0u, 250u),
     40   MK_COL(6u, 0u, 0u),
     41   MK_COL(0u, 6u, 0u),
     42   MK_COL(0u, 0u, 6u),
     43   MK_COL(0u, 0u, 248u),
     44   MK_COL(0u, 0u, 8u),
     45   MK_COL(0u, 248u, 0u),
     46   MK_COL(0u, 248u, 248u),
     47   MK_COL(0u, 248u, 8u),
     48   MK_COL(0u, 8u, 0u),
     49   MK_COL(0u, 8u, 248u),
     50   MK_COL(0u, 8u, 8u),
     51   MK_COL(8u, 8u, 8u),
     52   MK_COL(248u, 0u, 0u),
     53   MK_COL(248u, 0u, 248u),
     54   MK_COL(248u, 0u, 8u),
     55   MK_COL(248u, 248u, 0u),
     56   MK_COL(248u, 8u, 0u),
     57   MK_COL(8u, 0u, 0u),
     58   MK_COL(8u, 0u, 248u),
     59   MK_COL(8u, 0u, 8u),
     60   MK_COL(8u, 248u, 0u),
     61   MK_COL(8u, 8u, 0u),
     62   MK_COL(23u, 23u, 23u),
     63   MK_COL(13u, 13u, 13u),
     64   MK_COL(232u, 232u, 232u),
     65   MK_COL(244u, 244u, 244u),
     66   MK_COL(245u, 245u, 250u),
     67   MK_COL(50u, 50u, 50u),
     68   MK_COL(204u, 204u, 204u),
     69   MK_COL(236u, 236u, 236u),
     70   MK_COL(16u, 16u, 16u),
     71   MK_COL(240u, 16u, 16u),
     72   MK_COL(16u, 240u, 16u),
     73   MK_COL(240u, 240u, 16u),
     74   MK_COL(16u, 16u, 240u),
     75   MK_COL(240u, 16u, 240u),
     76   MK_COL(16u, 240u, 240u),
     77   MK_COL(240u, 240u, 240u),
     78   MK_COL(0u, 0u, 232u),
     79   MK_COL(0u, 232u, 0u),
     80   MK_COL(232u, 0u, 0u),
     81   MK_COL(0u, 0u, 24u),
     82   MK_COL(0u, 24u, 0u),
     83   MK_COL(24u, 0u, 0u),
     84   MK_COL(32u, 32u, 32u),
     85   MK_COL(224u, 32u, 32u),
     86   MK_COL(32u, 224u, 32u),
     87   MK_COL(224u, 224u, 32u),
     88   MK_COL(32u, 32u, 224u),
     89   MK_COL(224u, 32u, 224u),
     90   MK_COL(32u, 224u, 224u),
     91   MK_COL(224u, 224u, 224u),
     92   MK_COL(0u, 0u, 176u),
     93   MK_COL(0u, 0u, 80u),
     94   MK_COL(0u, 176u, 0u),
     95   MK_COL(0u, 176u, 176u),
     96   MK_COL(0u, 176u, 80u),
     97   MK_COL(0u, 80u, 0u),
     98   MK_COL(0u, 80u, 176u),
     99   MK_COL(0u, 80u, 80u),
    100   MK_COL(176u, 0u, 0u),
    101   MK_COL(176u, 0u, 176u),
    102   MK_COL(176u, 0u, 80u),
    103   MK_COL(176u, 176u, 0u),
    104   MK_COL(176u, 80u, 0u),
    105   MK_COL(80u, 0u, 0u),
    106   MK_COL(80u, 0u, 176u),
    107   MK_COL(80u, 0u, 80u),
    108   MK_COL(80u, 176u, 0u),
    109   MK_COL(80u, 80u, 0u),
    110   MK_COL(0u, 0u, 152u),
    111   MK_COL(0u, 0u, 104u),
    112   MK_COL(0u, 152u, 0u),
    113   MK_COL(0u, 152u, 152u),
    114   MK_COL(0u, 152u, 104u),
    115   MK_COL(0u, 104u, 0u),
    116   MK_COL(0u, 104u, 152u),
    117   MK_COL(0u, 104u, 104u),
    118   MK_COL(152u, 0u, 0u),
    119   MK_COL(152u, 0u, 152u),
    120   MK_COL(152u, 0u, 104u),
    121   MK_COL(152u, 152u, 0u),
    122   MK_COL(152u, 104u, 0u),
    123   MK_COL(104u, 0u, 0u),
    124   MK_COL(104u, 0u, 152u),
    125   MK_COL(104u, 0u, 104u),
    126   MK_COL(104u, 152u, 0u),
    127   MK_COL(104u, 104u, 0u),
    128   MK_COL(216u, 216u, 216u),
    129   MK_COL(216u, 216u, 40u),
    130   MK_COL(216u, 216u, 176u),
    131   MK_COL(216u, 216u, 80u),
    132   MK_COL(216u, 40u, 216u),
    133   MK_COL(216u, 40u, 40u),
    134   MK_COL(216u, 40u, 176u),
    135   MK_COL(216u, 40u, 80u),
    136   MK_COL(216u, 176u, 216u),
    137   MK_COL(216u, 176u, 40u),
    138   MK_COL(216u, 176u, 176u),
    139   MK_COL(216u, 176u, 80u),
    140   MK_COL(216u, 80u, 216u),
    141   MK_COL(216u, 80u, 40u),
    142   MK_COL(216u, 80u, 176u),
    143   MK_COL(216u, 80u, 80u),
    144   MK_COL(40u, 216u, 216u),
    145   MK_COL(40u, 216u, 40u),
    146   MK_COL(40u, 216u, 176u),
    147   MK_COL(40u, 216u, 80u),
    148   MK_COL(40u, 40u, 216u),
    149   MK_COL(40u, 40u, 40u),
    150   MK_COL(40u, 40u, 176u),
    151   MK_COL(40u, 40u, 80u),
    152   MK_COL(40u, 176u, 216u),
    153   MK_COL(40u, 176u, 40u),
    154   MK_COL(40u, 176u, 176u),
    155   MK_COL(40u, 176u, 80u),
    156   MK_COL(40u, 80u, 216u),
    157   MK_COL(40u, 80u, 40u),
    158   MK_COL(40u, 80u, 176u),
    159   MK_COL(40u, 80u, 80u),
    160   MK_COL(80u, 216u, 216u),
    161   MK_COL(80u, 216u, 40u),
    162   MK_COL(80u, 216u, 176u),
    163   MK_COL(80u, 216u, 80u),
    164   MK_COL(80u, 40u, 216u),
    165   MK_COL(80u, 40u, 40u),
    166   MK_COL(80u, 40u, 176u),
    167   MK_COL(80u, 40u, 80u),
    168   MK_COL(80u, 176u, 216u),
    169   MK_COL(80u, 176u, 40u),
    170   MK_COL(80u, 176u, 176u),
    171   MK_COL(80u, 176u, 80u),
    172   MK_COL(80u, 80u, 216u),
    173   MK_COL(80u, 80u, 40u),
    174   MK_COL(80u, 80u, 176u),
    175   MK_COL(80u, 80u, 80u),
    176   MK_COL(0u, 0u, 192u),
    177   MK_COL(0u, 0u, 64u),
    178   MK_COL(0u, 0u, 128u),
    179   MK_COL(0u, 192u, 0u),
    180   MK_COL(0u, 192u, 192u),
    181   MK_COL(0u, 192u, 64u),
    182   MK_COL(0u, 192u, 128u),
    183   MK_COL(0u, 64u, 0u),
    184   MK_COL(0u, 64u, 192u),
    185   MK_COL(0u, 64u, 64u),
    186   MK_COL(0u, 64u, 128u),
    187   MK_COL(0u, 128u, 0u),
    188   MK_COL(0u, 128u, 192u),
    189   MK_COL(0u, 128u, 64u),
    190   MK_COL(0u, 128u, 128u),
    191   MK_COL(176u, 216u, 216u),
    192   MK_COL(176u, 216u, 40u),
    193   MK_COL(176u, 216u, 176u),
    194   MK_COL(176u, 216u, 80u),
    195   MK_COL(176u, 40u, 216u),
    196   MK_COL(176u, 40u, 40u),
    197   MK_COL(176u, 40u, 176u),
    198   MK_COL(176u, 40u, 80u),
    199   MK_COL(176u, 176u, 216u),
    200   MK_COL(176u, 176u, 40u),
    201   MK_COL(176u, 176u, 176u),
    202   MK_COL(176u, 176u, 80u),
    203   MK_COL(176u, 80u, 216u),
    204   MK_COL(176u, 80u, 40u),
    205   MK_COL(176u, 80u, 176u),
    206   MK_COL(176u, 80u, 80u),
    207   MK_COL(192u, 0u, 0u),
    208   MK_COL(192u, 0u, 192u),
    209   MK_COL(192u, 0u, 64u),
    210   MK_COL(192u, 0u, 128u),
    211   MK_COL(192u, 192u, 0u),
    212   MK_COL(192u, 192u, 192u),
    213   MK_COL(192u, 192u, 64u),
    214   MK_COL(192u, 192u, 128u),
    215   MK_COL(192u, 64u, 0u),
    216   MK_COL(192u, 64u, 192u),
    217   MK_COL(192u, 64u, 64u),
    218   MK_COL(192u, 64u, 128u),
    219   MK_COL(192u, 128u, 0u),
    220   MK_COL(192u, 128u, 192u),
    221   MK_COL(192u, 128u, 64u),
    222   MK_COL(192u, 128u, 128u),
    223   MK_COL(64u, 0u, 0u),
    224   MK_COL(64u, 0u, 192u),
    225   MK_COL(64u, 0u, 64u),
    226   MK_COL(64u, 0u, 128u),
    227   MK_COL(64u, 192u, 0u),
    228   MK_COL(64u, 192u, 192u),
    229   MK_COL(64u, 192u, 64u),
    230   MK_COL(64u, 192u, 128u),
    231   MK_COL(64u, 64u, 0u),
    232   MK_COL(64u, 64u, 192u),
    233   MK_COL(64u, 64u, 64u),
    234   MK_COL(64u, 64u, 128u),
    235   MK_COL(64u, 128u, 0u),
    236   MK_COL(64u, 128u, 192u),
    237   MK_COL(64u, 128u, 64u),
    238   MK_COL(64u, 128u, 128u),
    239   MK_COL(128u, 0u, 0u),
    240   MK_COL(128u, 0u, 192u),
    241   MK_COL(128u, 0u, 64u),
    242   MK_COL(128u, 0u, 128u),
    243   MK_COL(128u, 192u, 0u),
    244   MK_COL(128u, 192u, 192u),
    245   MK_COL(128u, 192u, 64u),
    246   MK_COL(128u, 192u, 128u),
    247   MK_COL(128u, 64u, 0u),
    248   MK_COL(128u, 64u, 192u),
    249   MK_COL(128u, 64u, 64u),
    250   MK_COL(128u, 64u, 128u),
    251   MK_COL(128u, 128u, 0u),
    252   MK_COL(128u, 128u, 192u),
    253   MK_COL(128u, 128u, 64u),
    254   MK_COL(128u, 128u, 128u),
    255 };
    256 
    257 #undef MK_COL
    258 
    259 //------------------------------------------------------------------------------
    260 // TODO(skal): move the functions to dsp/lossless.c when the correct
    261 // granularity is found. For now, we'll just copy-paste some useful bits
    262 // here instead.
    263 
    264 // In-place sum of each component with mod 256.
    265 static WEBP_INLINE void AddPixelsEq(uint32_t* a, uint32_t b) {
    266   const uint32_t alpha_and_green = (*a & 0xff00ff00u) + (b & 0xff00ff00u);
    267   const uint32_t red_and_blue = (*a & 0x00ff00ffu) + (b & 0x00ff00ffu);
    268   *a = (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
    269 }
    270 
    271 static WEBP_INLINE uint32_t Clip255(uint32_t a) {
    272   if (a < 256) {
    273     return a;
    274   }
    275   // return 0, when a is a negative integer.
    276   // return 255, when a is positive.
    277   return ~a >> 24;
    278 }
    279 
    280 // Delta palettization functions.
    281 static WEBP_INLINE int Square(int x) {
    282   return x * x;
    283 }
    284 
    285 static WEBP_INLINE uint32_t Intensity(uint32_t a) {
    286   return
    287       30 * ((a >> 16) & 0xff) +
    288       59 * ((a >>  8) & 0xff) +
    289       11 * ((a >>  0) & 0xff);
    290 }
    291 
    292 static uint32_t CalcDist(uint32_t predicted_value, uint32_t actual_value,
    293                          uint32_t palette_entry) {
    294   int i;
    295   uint32_t distance = 0;
    296   AddPixelsEq(&predicted_value, palette_entry);
    297   for (i = 0; i < 32; i += 8) {
    298     const int32_t av = (actual_value >> i) & 0xff;
    299     const int32_t pv = (predicted_value >> i) & 0xff;
    300     distance += Square(pv - av);
    301   }
    302   // We sum square of intensity difference with factor 10, but because Intensity
    303   // returns 100 times real intensity we need to multiply differences of colors
    304   // by 1000.
    305   distance *= 1000u;
    306   distance += Square(Intensity(predicted_value)
    307                      - Intensity(actual_value));
    308   return distance;
    309 }
    310 
    311 static uint32_t Predict(int x, int y, uint32_t* image) {
    312   const uint32_t t = (y == 0) ? ARGB_BLACK : image[x];
    313   const uint32_t l = (x == 0) ? ARGB_BLACK : image[x - 1];
    314   const uint32_t p =
    315       (((((t >> 24) & 0xff) + ((l >> 24) & 0xff)) / 2) << 24) +
    316       (((((t >> 16) & 0xff) + ((l >> 16) & 0xff)) / 2) << 16) +
    317       (((((t >>  8) & 0xff) + ((l >>  8) & 0xff)) / 2) <<  8) +
    318       (((((t >>  0) & 0xff) + ((l >>  0) & 0xff)) / 2) <<  0);
    319   if (x == 0 && y == 0) return ARGB_BLACK;
    320   if (x == 0) return t;
    321   if (y == 0) return l;
    322   return p;
    323 }
    324 
    325 static WEBP_INLINE int AddSubtractComponentFullWithCoefficient(
    326     int a, int b, int c) {
    327   return Clip255(a + ((b - c) >> 2));
    328 }
    329 
    330 static WEBP_INLINE uint32_t ClampedAddSubtractFullWithCoefficient(
    331     uint32_t c0, uint32_t c1, uint32_t c2) {
    332   const int a = AddSubtractComponentFullWithCoefficient(
    333       c0 >> 24, c1 >> 24, c2 >> 24);
    334   const int r = AddSubtractComponentFullWithCoefficient((c0 >> 16) & 0xff,
    335                                                        (c1 >> 16) & 0xff,
    336                                                        (c2 >> 16) & 0xff);
    337   const int g = AddSubtractComponentFullWithCoefficient((c0 >> 8) & 0xff,
    338                                                        (c1 >> 8) & 0xff,
    339                                                        (c2 >> 8) & 0xff);
    340   const int b = AddSubtractComponentFullWithCoefficient(
    341       c0 & 0xff, c1 & 0xff, c2 & 0xff);
    342   return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
    343 }
    344 
    345 //------------------------------------------------------------------------------
    346 
    347 // Find palette entry with minimum error from difference of actual pixel value
    348 // and predicted pixel value. Propagate error of pixel to its top and left pixel
    349 // in src array. Write predicted_value + palette_entry to new_image. Return
    350 // index of best palette entry.
    351 static int FindBestPaletteEntry(uint32_t src, uint32_t predicted_value,
    352                                 const uint32_t palette[], int palette_size) {
    353   int i;
    354   int idx = 0;
    355   uint32_t best_distance = CalcDist(predicted_value, src, palette[0]);
    356   for (i = 1; i < palette_size; ++i) {
    357     const uint32_t distance = CalcDist(predicted_value, src, palette[i]);
    358     if (distance < best_distance) {
    359       best_distance = distance;
    360       idx = i;
    361     }
    362   }
    363   return idx;
    364 }
    365 
    366 static void ApplyBestPaletteEntry(int x, int y,
    367                                   uint32_t new_value, uint32_t palette_value,
    368                                   uint32_t* src, int src_stride,
    369                                   uint32_t* new_image) {
    370   AddPixelsEq(&new_value, palette_value);
    371   if (x > 0) {
    372     src[x - 1] = ClampedAddSubtractFullWithCoefficient(src[x - 1],
    373                                                        new_value, src[x]);
    374   }
    375   if (y > 0) {
    376     src[x - src_stride] =
    377         ClampedAddSubtractFullWithCoefficient(src[x - src_stride],
    378                                               new_value, src[x]);
    379   }
    380   new_image[x] = new_value;
    381 }
    382 
    383 //------------------------------------------------------------------------------
    384 // Main entry point
    385 
    386 static WebPEncodingError ApplyDeltaPalette(uint32_t* src, uint32_t* dst,
    387                                            uint32_t src_stride,
    388                                            uint32_t dst_stride,
    389                                            const uint32_t* palette,
    390                                            int palette_size,
    391                                            int width, int height,
    392                                            int num_passes) {
    393   int x, y;
    394   WebPEncodingError err = VP8_ENC_OK;
    395   uint32_t* new_image = (uint32_t*)WebPSafeMalloc(width, sizeof(*new_image));
    396   uint8_t* const tmp_row = (uint8_t*)WebPSafeMalloc(width, sizeof(*tmp_row));
    397   if (new_image == NULL || tmp_row == NULL) {
    398     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    399     goto Error;
    400   }
    401 
    402   while (num_passes--) {
    403     uint32_t* cur_src = src;
    404     uint32_t* cur_dst = dst;
    405     for (y = 0; y < height; ++y) {
    406       for (x = 0; x < width; ++x) {
    407         const uint32_t predicted_value = Predict(x, y, new_image);
    408         tmp_row[x] = FindBestPaletteEntry(cur_src[x], predicted_value,
    409                                           palette, palette_size);
    410         ApplyBestPaletteEntry(x, y, predicted_value, palette[tmp_row[x]],
    411                               cur_src, src_stride, new_image);
    412       }
    413       for (x = 0; x < width; ++x) {
    414         cur_dst[x] = palette[tmp_row[x]];
    415       }
    416       cur_src += src_stride;
    417       cur_dst += dst_stride;
    418     }
    419   }
    420  Error:
    421   WebPSafeFree(new_image);
    422   WebPSafeFree(tmp_row);
    423   return err;
    424 }
    425 
    426 // replaces enc->argb_ by a palettizable approximation of it,
    427 // and generates optimal enc->palette_[]
    428 WebPEncodingError WebPSearchOptimalDeltaPalette(VP8LEncoder* const enc) {
    429   const WebPPicture* const pic = enc->pic_;
    430   uint32_t* src = pic->argb;
    431   uint32_t* dst = enc->argb_;
    432   const int width = pic->width;
    433   const int height = pic->height;
    434 
    435   WebPEncodingError err = VP8_ENC_OK;
    436   memcpy(enc->palette_, kDeltaPalette, sizeof(kDeltaPalette));
    437   enc->palette_[DELTA_PALETTE_SIZE - 1] = src[0] - 0xff000000u;
    438   enc->palette_size_ = DELTA_PALETTE_SIZE;
    439   err = ApplyDeltaPalette(src, dst, pic->argb_stride, enc->current_width_,
    440                           enc->palette_, enc->palette_size_,
    441                           width, height, 2);
    442   if (err != VP8_ENC_OK) goto Error;
    443 
    444  Error:
    445   return err;
    446 }
    447 
    448 #else  // !WEBP_EXPERIMENTAL_FEATURES
    449 
    450 WebPEncodingError WebPSearchOptimalDeltaPalette(VP8LEncoder* const enc) {
    451   (void)enc;
    452   return VP8_ENC_ERROR_INVALID_CONFIGURATION;
    453 }
    454 
    455 #endif  // WEBP_EXPERIMENTAL_FEATURES
    456