From 323dc4d9b9d5fdbab554671f89de4f140d328cc3 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Wed, 1 Aug 2012 18:22:06 -0700 Subject: [PATCH] remove use of log2(). Use VP8LFastLog2() instead. Order-by-cost mostly unchanged (up to a scaling constant 1/log(2)) (except for few minor diff in < 2% of cases) + remove unused field cost_mode->cache_bits_ Change-Id: I714f8ab12f49a23f5d499a64c741382c9b489a3e --- src/dsp/lossless.c | 272 ++++++++++++++++++++-------------- src/dsp/lossless.h | 6 +- src/enc/backward_references.c | 70 +++++---- src/enc/histogram.c | 55 +------ src/enc/histogram.h | 3 - 5 files changed, 214 insertions(+), 192 deletions(-) diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c index cb8ad0bc..9b446cf9 100644 --- a/src/dsp/lossless.c +++ b/src/dsp/lossless.c @@ -23,113 +23,156 @@ extern "C" { #include "../dsp/dsp.h" #include "../enc/histogram.h" -// A lookup table for small values of log(int) to be used in entropy -// computation. -// -// ", ".join(["%.16ff" % x for x in [0.0]+[log(x) for x in range(1, 256)]]) +#define MAX_DIFF_COST (1e30f) + +// lookup table for small values of log2(int) +#define APPROX_LOG_MAX 4096 +#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086 #define LOG_LOOKUP_IDX_MAX 256 -static const float kLogTable[LOG_LOOKUP_IDX_MAX] = { - 0.0000000000000000f, 0.0000000000000000f, 0.6931471805599453f, - 1.0986122886681098f, 1.3862943611198906f, 1.6094379124341003f, - 1.7917594692280550f, 1.9459101490553132f, 2.0794415416798357f, - 2.1972245773362196f, 2.3025850929940459f, 2.3978952727983707f, - 2.4849066497880004f, 2.5649493574615367f, 2.6390573296152584f, - 2.7080502011022101f, 2.7725887222397811f, 2.8332133440562162f, - 2.8903717578961645f, 2.9444389791664403f, 2.9957322735539909f, - 3.0445224377234230f, 3.0910424533583161f, 3.1354942159291497f, - 3.1780538303479458f, 3.2188758248682006f, 3.2580965380214821f, - 3.2958368660043291f, 3.3322045101752038f, 3.3672958299864741f, - 3.4011973816621555f, 3.4339872044851463f, 3.4657359027997265f, - 3.4965075614664802f, 3.5263605246161616f, 3.5553480614894135f, - 3.5835189384561099f, 3.6109179126442243f, 3.6375861597263857f, - 3.6635616461296463f, 3.6888794541139363f, 3.7135720667043080f, - 3.7376696182833684f, 3.7612001156935624f, 3.7841896339182610f, - 3.8066624897703196f, 3.8286413964890951f, 3.8501476017100584f, - 3.8712010109078911f, 3.8918202981106265f, 3.9120230054281460f, - 3.9318256327243257f, 3.9512437185814275f, 3.9702919135521220f, - 3.9889840465642745f, 4.0073331852324712f, 4.0253516907351496f, - 4.0430512678345503f, 4.0604430105464191f, 4.0775374439057197f, - 4.0943445622221004f, 4.1108738641733114f, 4.1271343850450917f, - 4.1431347263915326f, 4.1588830833596715f, 4.1743872698956368f, - 4.1896547420264252f, 4.2046926193909657f, 4.2195077051761070f, - 4.2341065045972597f, 4.2484952420493594f, 4.2626798770413155f, - 4.2766661190160553f, 4.2904594411483910f, 4.3040650932041702f, - 4.3174881135363101f, 4.3307333402863311f, 4.3438054218536841f, - 4.3567088266895917f, 4.3694478524670215f, 4.3820266346738812f, - 4.3944491546724391f, 4.4067192472642533f, 4.4188406077965983f, - 4.4308167988433134f, 4.4426512564903167f, 4.4543472962535073f, - 4.4659081186545837f, 4.4773368144782069f, 4.4886363697321396f, - 4.4998096703302650f, 4.5108595065168497f, 4.5217885770490405f, - 4.5325994931532563f, 4.5432947822700038f, 4.5538768916005408f, - 4.5643481914678361f, 4.5747109785033828f, 4.5849674786705723f, - 4.5951198501345898f, 4.6051701859880918f, 4.6151205168412597f, - 4.6249728132842707f, 4.6347289882296359f, 4.6443908991413725f, - 4.6539603501575231f, 4.6634390941120669f, 4.6728288344619058f, - 4.6821312271242199f, 4.6913478822291435f, 4.7004803657924166f, - 4.7095302013123339f, 4.7184988712950942f, 4.7273878187123408f, - 4.7361984483944957f, 4.7449321283632502f, 4.7535901911063645f, - 4.7621739347977563f, 4.7706846244656651f, 4.7791234931115296f, - 4.7874917427820458f, 4.7957905455967413f, 4.8040210447332568f, - 4.8121843553724171f, 4.8202815656050371f, 4.8283137373023015f, - 4.8362819069514780f, 4.8441870864585912f, 4.8520302639196169f, - 4.8598124043616719f, 4.8675344504555822f, 4.8751973232011512f, - 4.8828019225863706f, 4.8903491282217537f, 4.8978397999509111f, - 4.9052747784384296f, 4.9126548857360524f, 4.9199809258281251f, - 4.9272536851572051f, 4.9344739331306915f, 4.9416424226093039f, - 4.9487598903781684f, 4.9558270576012609f, 4.9628446302599070f, - 4.9698132995760007f, 4.9767337424205742f, 4.9836066217083363f, - 4.9904325867787360f, 4.9972122737641147f, 5.0039463059454592f, - 5.0106352940962555f, 5.0172798368149243f, 5.0238805208462765f, - 5.0304379213924353f, 5.0369526024136295f, 5.0434251169192468f, - 5.0498560072495371f, 5.0562458053483077f, 5.0625950330269669f, - 5.0689042022202315f, 5.0751738152338266f, 5.0814043649844631f, - 5.0875963352323836f, 5.0937502008067623f, 5.0998664278241987f, - 5.1059454739005803f, 5.1119877883565437f, 5.1179938124167554f, - 5.1239639794032588f, 5.1298987149230735f, 5.1357984370502621f, - 5.1416635565026603f, 5.1474944768134527f, 5.1532915944977793f, - 5.1590552992145291f, 5.1647859739235145f, 5.1704839950381514f, - 5.1761497325738288f, 5.1817835502920850f, 5.1873858058407549f, - 5.1929568508902104f, 5.1984970312658261f, 5.2040066870767951f, - 5.2094861528414214f, 5.2149357576089859f, 5.2203558250783244f, - 5.2257466737132017f, 5.2311086168545868f, 5.2364419628299492f, - 5.2417470150596426f, 5.2470240721604862f, 5.2522734280466299f, - 5.2574953720277815f, 5.2626901889048856f, 5.2678581590633282f, - 5.2729995585637468f, 5.2781146592305168f, 5.2832037287379885f, - 5.2882670306945352f, 5.2933048247244923f, 5.2983173665480363f, - 5.3033049080590757f, 5.3082676974012051f, 5.3132059790417872f, - 5.3181199938442161f, 5.3230099791384085f, 5.3278761687895813f, - 5.3327187932653688f, 5.3375380797013179f, 5.3423342519648109f, - 5.3471075307174685f, 5.3518581334760666f, 5.3565862746720123f, - 5.3612921657094255f, 5.3659760150218512f, 5.3706380281276624f, - 5.3752784076841653f, 5.3798973535404597f, 5.3844950627890888f, - 5.3890717298165010f, 5.3936275463523620f, 5.3981627015177525f, - 5.4026773818722793f, 5.4071717714601188f, 5.4116460518550396f, - 5.4161004022044201f, 5.4205349992722862f, 5.4249500174814029f, - 5.4293456289544411f, 5.4337220035542400f, 5.4380793089231956f, - 5.4424177105217932f, 5.4467373716663099f, 5.4510384535657002f, - 5.4553211153577017f, 5.4595855141441589f, 5.4638318050256105f, - 5.4680601411351315f, 5.4722706736714750f, 5.4764635519315110f, - 5.4806389233419912f, 5.4847969334906548f, 5.4889377261566867f, - 5.4930614433405482f, 5.4971682252932021f, 5.5012582105447274f, - 5.5053315359323625f, 5.5093883366279774f, 5.5134287461649825f, - 5.5174528964647074f, 5.5214609178622460f, 5.5254529391317835f, - 5.5294290875114234f, 5.5333894887275203f, 5.5373342670185366f, - 5.5412635451584258f +static const float kLog2Table[LOG_LOOKUP_IDX_MAX] = { + 0.0000000000000000f, 0.0000000000000000f, + 1.0000000000000000f, 1.5849625007211560f, + 2.0000000000000000f, 2.3219280948873621f, + 2.5849625007211560f, 2.8073549220576041f, + 3.0000000000000000f, 3.1699250014423121f, + 3.3219280948873621f, 3.4594316186372973f, + 3.5849625007211560f, 3.7004397181410921f, + 3.8073549220576041f, 3.9068905956085187f, + 4.0000000000000000f, 4.0874628412503390f, + 4.1699250014423121f, 4.2479275134435852f, + 4.3219280948873626f, 4.3923174227787606f, + 4.4594316186372973f, 4.5235619560570130f, + 4.5849625007211560f, 4.6438561897747243f, + 4.7004397181410917f, 4.7548875021634682f, + 4.8073549220576037f, 4.8579809951275718f, + 4.9068905956085187f, 4.9541963103868749f, + 5.0000000000000000f, 5.0443941193584533f, + 5.0874628412503390f, 5.1292830169449663f, + 5.1699250014423121f, 5.2094533656289501f, + 5.2479275134435852f, 5.2854022188622487f, + 5.3219280948873626f, 5.3575520046180837f, + 5.3923174227787606f, 5.4262647547020979f, + 5.4594316186372973f, 5.4918530963296747f, + 5.5235619560570130f, 5.5545888516776376f, + 5.5849625007211560f, 5.6147098441152083f, + 5.6438561897747243f, 5.6724253419714951f, + 5.7004397181410917f, 5.7279204545631987f, + 5.7548875021634682f, 5.7813597135246599f, + 5.8073549220576037f, 5.8328900141647412f, + 5.8579809951275718f, 5.8826430493618415f, + 5.9068905956085187f, 5.9307373375628866f, + 5.9541963103868749f, 5.9772799234999167f, + 6.0000000000000000f, 6.0223678130284543f, + 6.0443941193584533f, 6.0660891904577720f, + 6.0874628412503390f, 6.1085244567781691f, + 6.1292830169449663f, 6.1497471195046822f, + 6.1699250014423121f, 6.1898245588800175f, + 6.2094533656289501f, 6.2288186904958804f, + 6.2479275134435852f, 6.2667865406949010f, + 6.2854022188622487f, 6.3037807481771030f, + 6.3219280948873626f, 6.3398500028846243f, + 6.3575520046180837f, 6.3750394313469245f, + 6.3923174227787606f, 6.4093909361377017f, + 6.4262647547020979f, 6.4429434958487279f, + 6.4594316186372973f, 6.4757334309663976f, + 6.4918530963296747f, 6.5077946401986963f, + 6.5235619560570130f, 6.5391588111080309f, + 6.5545888516776376f, 6.5698556083309478f, + 6.5849625007211560f, 6.5999128421871278f, + 6.6147098441152083f, 6.6293566200796094f, + 6.6438561897747243f, 6.6582114827517946f, + 6.6724253419714951f, 6.6865005271832185f, + 6.7004397181410917f, 6.7142455176661224f, + 6.7279204545631987f, 6.7414669864011464f, + 6.7548875021634682f, 6.7681843247769259f, + 6.7813597135246599f, 6.7944158663501061f, + 6.8073549220576037f, 6.8201789624151878f, + 6.8328900141647412f, 6.8454900509443747f, + 6.8579809951275718f, 6.8703647195834047f, + 6.8826430493618415f, 6.8948177633079437f, + 6.9068905956085187f, 6.9188632372745946f, + 6.9307373375628866f, 6.9425145053392398f, + 6.9541963103868749f, 6.9657842846620869f, + 6.9772799234999167f, 6.9886846867721654f, + 7.0000000000000000f, 7.0112272554232539f, + 7.0223678130284543f, 7.0334230015374501f, + 7.0443941193584533f, 7.0552824355011898f, + 7.0660891904577720f, 7.0768155970508308f, + 7.0874628412503390f, 7.0980320829605263f, + 7.1085244567781691f, 7.1189410727235076f, + 7.1292830169449663f, 7.1395513523987936f, + 7.1497471195046822f, 7.1598713367783890f, + 7.1699250014423121f, 7.1799090900149344f, + 7.1898245588800175f, 7.1996723448363644f, + 7.2094533656289501f, 7.2191685204621611f, + 7.2288186904958804f, 7.2384047393250785f, + 7.2479275134435852f, 7.2573878426926521f, + 7.2667865406949010f, 7.2761244052742375f, + 7.2854022188622487f, 7.2946207488916270f, + 7.3037807481771030f, 7.3128829552843557f, + 7.3219280948873626f, 7.3309168781146167f, + 7.3398500028846243f, 7.3487281542310771f, + 7.3575520046180837f, 7.3663222142458160f, + 7.3750394313469245f, 7.3837042924740519f, + 7.3923174227787606f, 7.4008794362821843f, + 7.4093909361377017f, 7.4178525148858982f, + 7.4262647547020979f, 7.4346282276367245f, + 7.4429434958487279f, 7.4512111118323289f, + 7.4594316186372973f, 7.4676055500829976f, + 7.4757334309663976f, 7.4838157772642563f, + 7.4918530963296747f, 7.4998458870832056f, + 7.5077946401986963f, 7.5156998382840427f, + 7.5235619560570130f, 7.5313814605163118f, + 7.5391588111080309f, 7.5468944598876364f, + 7.5545888516776376f, 7.5622424242210728f, + 7.5698556083309478f, 7.5774288280357486f, + 7.5849625007211560f, 7.5924570372680806f, + 7.5999128421871278f, 7.6073303137496104f, + 7.6147098441152083f, 7.6220518194563764f, + 7.6293566200796094f, 7.6366246205436487f, + 7.6438561897747243f, 7.6510516911789281f, + 7.6582114827517946f, 7.6653359171851764f, + 7.6724253419714951f, 7.6794800995054464f, + 7.6865005271832185f, 7.6934869574993252f, + 7.7004397181410917f, 7.7073591320808825f, + 7.7142455176661224f, 7.7210991887071855f, + 7.7279204545631987f, 7.7347096202258383f, + 7.7414669864011464f, 7.7481928495894605f, + 7.7548875021634682f, 7.7615512324444795f, + 7.7681843247769259f, 7.7747870596011736f, + 7.7813597135246599f, 7.7879025593914317f, + 7.7944158663501061f, 7.8008998999203047f, + 7.8073549220576037f, 7.8137811912170374f, + 7.8201789624151878f, 7.8265484872909150f, + 7.8328900141647412f, 7.8392037880969436f, + 7.8454900509443747f, 7.8517490414160571f, + 7.8579809951275718f, 7.8641861446542797f, + 7.8703647195834047f, 7.8765169465649993f, + 7.8826430493618415f, 7.8887432488982591f, + 7.8948177633079437f, 7.9008668079807486f, + 7.9068905956085187f, 7.9128893362299619f, + 7.9188632372745946f, 7.9248125036057812f, + 7.9307373375628866f, 7.9366379390025709f, + 7.9425145053392398f, 7.9483672315846778f, + 7.9541963103868749f, 7.9600019320680805f, + 7.9657842846620869f, 7.9715435539507719f, + 7.9772799234999167f, 7.9829935746943103f, + 7.9886846867721654f, 7.9943534368588577f }; -#define APPROX_LOG_MAX 4096 -#define LOG_2_BASE_E 0.6931471805599453f - -float VP8LFastLog(int v) { - if (v < APPROX_LOG_MAX) { +float VP8LFastLog2(int v) { + if (v < LOG_LOOKUP_IDX_MAX) { + return kLog2Table[v]; + } else if (v < APPROX_LOG_MAX) { int log_cnt = 0; while (v >= LOG_LOOKUP_IDX_MAX) { ++log_cnt; v = v >> 1; } - return kLogTable[v] + (log_cnt * LOG_2_BASE_E); + return kLog2Table[v] + (float)log_cnt; + } else { + return (float)(LOG_2_RECIPROCAL * log((double)v)); } - return (float)log(v); } //------------------------------------------------------------------------------ @@ -284,7 +327,7 @@ static const PredictorFunc kPredictors[16] = { }; // TODO(vikasa): Replace 256 etc with defines. -static double PredictionCostSpatial(const int* counts, +static float PredictionCostSpatial(const int* counts, int weight_0, double exp_val) { const int significant_symbols = 16; const double exp_decay_factor = 0.6; @@ -294,27 +337,26 @@ static double PredictionCostSpatial(const int* counts, bits += exp_val * (counts[i] + counts[256 - i]); exp_val *= exp_decay_factor; } - return -0.1 * bits; + return (float)(-0.1 * bits); } // Compute the Shanon's entropy: Sum(p*log2(p)) -static double ShannonEntropy(const int* const array, int n) { +static float ShannonEntropy(const int* const array, int n) { int i; - double retval = 0; + float retval = 0.f; int sum = 0; for (i = 0; i < n; ++i) { if (array[i] != 0) { sum += array[i]; - retval += array[i] * VP8LFastLog(array[i]); + retval -= VP8LFastSLog2(array[i]); } } - retval -= sum * VP8LFastLog(sum); - retval *= -1.4426950408889634; // 1.0 / -FastLog(2); + retval += VP8LFastSLog2(sum); return retval; } -static double PredictionCostSpatialHistogram(int accumulated[4][256], - int tile[4][256]) { +static float PredictionCostSpatialHistogram(int accumulated[4][256], + int tile[4][256]) { int i; int k; int combo[256]; @@ -328,7 +370,7 @@ static double PredictionCostSpatialHistogram(int accumulated[4][256], } retval += ShannonEntropy(&combo[0], 256); } - return retval; + return (float)retval; } static int GetBestPredictorForTile(int width, int height, @@ -344,14 +386,14 @@ static int GetBestPredictorForTile(int width, int height, const int xmax = (tile_size <= width - col_start) ? tile_size : width - col_start; int histo[4][256]; - double best_diff = 1e99; + float best_diff = MAX_DIFF_COST; int best_mode = 0; int mode; for (mode = 0; mode < kNumPredModes; ++mode) { const uint32_t* current_row = argb_scratch; const PredictorFunc pred_func = kPredictors[mode]; - double cur_diff; + float cur_diff; int y; memset(&histo[0][0], 0, sizeof(histo)); for (y = 0; y < ymax; ++y) { @@ -630,8 +672,8 @@ static WEBP_INLINE int SkipRepeatedPixels(const uint32_t* const argb, return 0; } -static double PredictionCostCrossColor(const int accumulated[256], - const int counts[256]) { +static float PredictionCostCrossColor(const int accumulated[256], + const int counts[256]) { // Favor low entropy, locally and globally. int i; int combo[256]; @@ -651,8 +693,8 @@ static Multipliers GetBestColorTransformForTile( int* accumulated_red_histo, int* accumulated_blue_histo, const uint32_t* const argb) { - double best_diff = 1e99; - double cur_diff; + float best_diff = MAX_DIFF_COST; + float cur_diff; const int halfstep = step / 2; const int max_tile_size = 1 << bits; const int tile_y_offset = tile_y * max_tile_size; @@ -704,7 +746,7 @@ static Multipliers GetBestColorTransformForTile( best_tx = tx; } } - best_diff = 1e99; + best_diff = MAX_DIFF_COST; green_to_red = best_tx.green_to_red_; for (green_to_blue = -32; green_to_blue <= 32; green_to_blue += step) { for (red_to_blue = -32; red_to_blue <= 32; red_to_blue += step) { diff --git a/src/dsp/lossless.h b/src/dsp/lossless.h index f00e90e0..992516fc 100644 --- a/src/dsp/lossless.h +++ b/src/dsp/lossless.h @@ -59,8 +59,10 @@ static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size, return (size + (1 << sampling_bits) - 1) >> sampling_bits; } -// Faster logarithm for small integers, with the property of log(0) == 0. -float VP8LFastLog(int v); +// Faster logarithm for integers, with the property of log2(0) == 0. +float VP8LFastLog2(int v); +// Fast calculation of v * log2(v) for integer input. +static WEBP_INLINE float VP8LFastSLog2(int v) { return VP8LFastLog2(v) * v; } // In-place difference of each component with mod 256. static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) { diff --git a/src/enc/backward_references.c b/src/enc/backward_references.c index b20a1fcf..b8c8ece8 100644 --- a/src/enc/backward_references.c +++ b/src/enc/backward_references.c @@ -14,6 +14,7 @@ #include "./backward_references.h" #include "./histogram.h" +#include "../dsp/lossless.h" #include "../utils/color_cache.h" #include "../utils/utils.h" @@ -357,46 +358,65 @@ typedef struct { double literal_[PIX_OR_COPY_CODES_MAX]; double blue_[VALUES_IN_BYTE]; double distance_[NUM_DISTANCE_CODES]; - int cache_bits_; } CostModel; static int BackwardReferencesTraceBackwards( int xsize, int ysize, int recursive_cost_model, const uint32_t* const argb, int cache_bits, VP8LBackwardRefs* const refs); -static int CostModelBuild(CostModel* const p, int xsize, int ysize, +static void ConvertPopulationCountTableToBitEstimates( + int num_symbols, const int population_counts[], double output[]) { + int sum = 0; + int nonzeros = 0; + int i; + for (i = 0; i < num_symbols; ++i) { + sum += population_counts[i]; + if (population_counts[i] > 0) { + ++nonzeros; + } + } + if (nonzeros <= 1) { + memset(output, 0, num_symbols * sizeof(*output)); + } else { + const double logsum = VP8LFastLog2(sum); + for (i = 0; i < num_symbols; ++i) { + output[i] = logsum - VP8LFastLog2(population_counts[i]); + } + } +} + +static int CostModelBuild(CostModel* const m, int xsize, int ysize, int recursion_level, const uint32_t* const argb, int cache_bits) { int ok = 0; VP8LHistogram histo; VP8LBackwardRefs refs; + const int quality = 100; if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize)) goto Error; - p->cache_bits_ = cache_bits; if (recursion_level > 0) { if (!BackwardReferencesTraceBackwards(xsize, ysize, recursion_level - 1, argb, cache_bits, &refs)) { goto Error; } } else { - const int quality = 100; if (!BackwardReferencesHashChain(xsize, ysize, argb, cache_bits, quality, &refs)) { goto Error; } } VP8LHistogramCreate(&histo, &refs, cache_bits); - VP8LConvertPopulationCountTableToBitEstimates( - VP8LHistogramNumCodes(&histo), histo.literal_, p->literal_); - VP8LConvertPopulationCountTableToBitEstimates( - VALUES_IN_BYTE, histo.red_, p->red_); - VP8LConvertPopulationCountTableToBitEstimates( - VALUES_IN_BYTE, histo.blue_, p->blue_); - VP8LConvertPopulationCountTableToBitEstimates( - VALUES_IN_BYTE, histo.alpha_, p->alpha_); - VP8LConvertPopulationCountTableToBitEstimates( - NUM_DISTANCE_CODES, histo.distance_, p->distance_); + ConvertPopulationCountTableToBitEstimates( + VP8LHistogramNumCodes(&histo), histo.literal_, m->literal_); + ConvertPopulationCountTableToBitEstimates( + VALUES_IN_BYTE, histo.red_, m->red_); + ConvertPopulationCountTableToBitEstimates( + VALUES_IN_BYTE, histo.blue_, m->blue_); + ConvertPopulationCountTableToBitEstimates( + VALUES_IN_BYTE, histo.alpha_, m->alpha_); + ConvertPopulationCountTableToBitEstimates( + NUM_DISTANCE_CODES, histo.distance_, m->distance_); ok = 1; Error: @@ -404,30 +424,30 @@ static int CostModelBuild(CostModel* const p, int xsize, int ysize, return ok; } -static WEBP_INLINE double GetLiteralCost(const CostModel* const p, uint32_t v) { - return p->alpha_[v >> 24] + - p->red_[(v >> 16) & 0xff] + - p->literal_[(v >> 8) & 0xff] + - p->blue_[v & 0xff]; +static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) { + return m->alpha_[v >> 24] + + m->red_[(v >> 16) & 0xff] + + m->literal_[(v >> 8) & 0xff] + + m->blue_[v & 0xff]; } -static WEBP_INLINE double GetCacheCost(const CostModel* const p, uint32_t idx) { +static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) { const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx; - return p->literal_[literal_idx]; + return m->literal_[literal_idx]; } -static WEBP_INLINE double GetLengthCost(const CostModel* const p, +static WEBP_INLINE double GetLengthCost(const CostModel* const m, uint32_t length) { int code, extra_bits_count, extra_bits_value; PrefixEncode(length, &code, &extra_bits_count, &extra_bits_value); - return p->literal_[VALUES_IN_BYTE + code] + extra_bits_count; + return m->literal_[VALUES_IN_BYTE + code] + extra_bits_count; } -static WEBP_INLINE double GetDistanceCost(const CostModel* const p, +static WEBP_INLINE double GetDistanceCost(const CostModel* const m, uint32_t distance) { int code, extra_bits_count, extra_bits_value; PrefixEncode(distance, &code, &extra_bits_count, &extra_bits_value); - return p->distance_[code] + extra_bits_count; + return m->distance_[code] + extra_bits_count; } static int BackwardReferencesHashChainDistanceOnly( diff --git a/src/enc/histogram.c b/src/enc/histogram.c index da3b3d74..ca838e06 100644 --- a/src/enc/histogram.c +++ b/src/enc/histogram.c @@ -19,17 +19,6 @@ #include "../dsp/lossless.h" #include "../utils/utils.h" -#if defined(_MSC_VER) && !defined(NOT_HAVE_LOG2) -# define NOT_HAVE_LOG2 1 -#endif - -#ifdef NOT_HAVE_LOG2 -static WEBP_INLINE double log2(double d) { - const double kLog2Reciprocal = 1.442695040888963; - return log(d) * kLog2Reciprocal; -} -#endif - static void HistogramClear(VP8LHistogram* const p) { memset(p->literal_, 0, sizeof(p->literal_)); memset(p->red_, 0, sizeof(p->red_)); @@ -88,33 +77,6 @@ VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) { // ----------------------------------------------------------------------------- -void VP8LConvertPopulationCountTableToBitEstimates( - int num_symbols, const int population_counts[], double output[]) { - int sum = 0; - int nonzeros = 0; - int i; - for (i = 0; i < num_symbols; ++i) { - sum += population_counts[i]; - if (population_counts[i] > 0) { - ++nonzeros; - } - } - if (nonzeros <= 1) { - memset(output, 0, num_symbols * sizeof(*output)); - return; - } - { - const double log2sum = log2(sum); - for (i = 0; i < num_symbols; ++i) { - if (population_counts[i] == 0) { - output[i] = log2sum; - } else { - output[i] = log2sum - log2(population_counts[i]); - } - } - } -} - void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo, const PixOrCopy* const v) { if (PixOrCopyIsLiteral(v)) { @@ -139,7 +101,7 @@ void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo, static double BitsEntropy(const int* const array, int n) { - double retval = 0; + double retval = 0.; int sum = 0; int nonzeros = 0; int max_val = 0; @@ -149,15 +111,14 @@ static double BitsEntropy(const int* const array, int n) { if (array[i] != 0) { sum += array[i]; ++nonzeros; - retval += array[i] * VP8LFastLog(array[i]); + retval -= VP8LFastSLog2(array[i]); if (max_val < array[i]) { max_val = array[i]; } } } - retval -= sum * VP8LFastLog(sum); - retval *= -1.4426950408889634; // 1.0 / -Log(2); - mix = 0.627; + retval += VP8LFastSLog2(sum); + if (nonzeros < 5) { if (nonzeros <= 1) { return 0; @@ -177,15 +138,15 @@ static double BitsEntropy(const int* const array, int n) { } else { mix = 0.7; // nonzeros == 4. } + } else { + mix = 0.627; } + { double min_limit = 2 * sum - max_val; min_limit = mix * min_limit + (1.0 - mix) * retval; - if (retval < min_limit) { - return min_limit; - } + return (retval < min_limit) ? min_limit : retval; } - return retval; } double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) { diff --git a/src/enc/histogram.h b/src/enc/histogram.h index 480aba81..ec573c5c 100644 --- a/src/enc/histogram.h +++ b/src/enc/histogram.h @@ -101,9 +101,6 @@ static WEBP_INLINE int VP8LHistogramNumCodes(const VP8LHistogram* const p) { ((p->palette_code_bits_ > 0) ? (1 << p->palette_code_bits_) : 0); } -void VP8LConvertPopulationCountTableToBitEstimates( - int num_symbols, const int population_counts[], double output[]); - // Builds the histogram image. int VP8LGetHistoImageSymbols(int xsize, int ysize, const VP8LBackwardRefs* const refs,