11cb0ef41Sopenharmony_ci/* NOLINT(build/header_guard) */ 21cb0ef41Sopenharmony_ci/* Copyright 2013 Google Inc. All Rights Reserved. 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci Distributed under MIT license. 51cb0ef41Sopenharmony_ci See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 61cb0ef41Sopenharmony_ci*/ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci/* template parameters: FN */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#define HistogramType FN(Histogram) 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cidouble FN(BrotliPopulationCost)(const HistogramType* histogram) { 131cb0ef41Sopenharmony_ci static const double kOneSymbolHistogramCost = 12; 141cb0ef41Sopenharmony_ci static const double kTwoSymbolHistogramCost = 20; 151cb0ef41Sopenharmony_ci static const double kThreeSymbolHistogramCost = 28; 161cb0ef41Sopenharmony_ci static const double kFourSymbolHistogramCost = 37; 171cb0ef41Sopenharmony_ci const size_t data_size = FN(HistogramDataSize)(); 181cb0ef41Sopenharmony_ci int count = 0; 191cb0ef41Sopenharmony_ci size_t s[5]; 201cb0ef41Sopenharmony_ci double bits = 0.0; 211cb0ef41Sopenharmony_ci size_t i; 221cb0ef41Sopenharmony_ci if (histogram->total_count_ == 0) { 231cb0ef41Sopenharmony_ci return kOneSymbolHistogramCost; 241cb0ef41Sopenharmony_ci } 251cb0ef41Sopenharmony_ci for (i = 0; i < data_size; ++i) { 261cb0ef41Sopenharmony_ci if (histogram->data_[i] > 0) { 271cb0ef41Sopenharmony_ci s[count] = i; 281cb0ef41Sopenharmony_ci ++count; 291cb0ef41Sopenharmony_ci if (count > 4) break; 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci if (count == 1) { 331cb0ef41Sopenharmony_ci return kOneSymbolHistogramCost; 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci if (count == 2) { 361cb0ef41Sopenharmony_ci return (kTwoSymbolHistogramCost + (double)histogram->total_count_); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci if (count == 3) { 391cb0ef41Sopenharmony_ci const uint32_t histo0 = histogram->data_[s[0]]; 401cb0ef41Sopenharmony_ci const uint32_t histo1 = histogram->data_[s[1]]; 411cb0ef41Sopenharmony_ci const uint32_t histo2 = histogram->data_[s[2]]; 421cb0ef41Sopenharmony_ci const uint32_t histomax = 431cb0ef41Sopenharmony_ci BROTLI_MAX(uint32_t, histo0, BROTLI_MAX(uint32_t, histo1, histo2)); 441cb0ef41Sopenharmony_ci return (kThreeSymbolHistogramCost + 451cb0ef41Sopenharmony_ci 2 * (histo0 + histo1 + histo2) - histomax); 461cb0ef41Sopenharmony_ci } 471cb0ef41Sopenharmony_ci if (count == 4) { 481cb0ef41Sopenharmony_ci uint32_t histo[4]; 491cb0ef41Sopenharmony_ci uint32_t h23; 501cb0ef41Sopenharmony_ci uint32_t histomax; 511cb0ef41Sopenharmony_ci for (i = 0; i < 4; ++i) { 521cb0ef41Sopenharmony_ci histo[i] = histogram->data_[s[i]]; 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci /* Sort */ 551cb0ef41Sopenharmony_ci for (i = 0; i < 4; ++i) { 561cb0ef41Sopenharmony_ci size_t j; 571cb0ef41Sopenharmony_ci for (j = i + 1; j < 4; ++j) { 581cb0ef41Sopenharmony_ci if (histo[j] > histo[i]) { 591cb0ef41Sopenharmony_ci BROTLI_SWAP(uint32_t, histo, j, i); 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci h23 = histo[2] + histo[3]; 641cb0ef41Sopenharmony_ci histomax = BROTLI_MAX(uint32_t, h23, histo[0]); 651cb0ef41Sopenharmony_ci return (kFourSymbolHistogramCost + 661cb0ef41Sopenharmony_ci 3 * h23 + 2 * (histo[0] + histo[1]) - histomax); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci { 701cb0ef41Sopenharmony_ci /* In this loop we compute the entropy of the histogram and simultaneously 711cb0ef41Sopenharmony_ci build a simplified histogram of the code length codes where we use the 721cb0ef41Sopenharmony_ci zero repeat code 17, but we don't use the non-zero repeat code 16. */ 731cb0ef41Sopenharmony_ci size_t max_depth = 1; 741cb0ef41Sopenharmony_ci uint32_t depth_histo[BROTLI_CODE_LENGTH_CODES] = { 0 }; 751cb0ef41Sopenharmony_ci const double log2total = FastLog2(histogram->total_count_); 761cb0ef41Sopenharmony_ci for (i = 0; i < data_size;) { 771cb0ef41Sopenharmony_ci if (histogram->data_[i] > 0) { 781cb0ef41Sopenharmony_ci /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = 791cb0ef41Sopenharmony_ci = log2(total_count) - log2(count(symbol)) */ 801cb0ef41Sopenharmony_ci double log2p = log2total - FastLog2(histogram->data_[i]); 811cb0ef41Sopenharmony_ci /* Approximate the bit depth by round(-log2(P(symbol))) */ 821cb0ef41Sopenharmony_ci size_t depth = (size_t)(log2p + 0.5); 831cb0ef41Sopenharmony_ci bits += histogram->data_[i] * log2p; 841cb0ef41Sopenharmony_ci if (depth > 15) { 851cb0ef41Sopenharmony_ci depth = 15; 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci if (depth > max_depth) { 881cb0ef41Sopenharmony_ci max_depth = depth; 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci ++depth_histo[depth]; 911cb0ef41Sopenharmony_ci ++i; 921cb0ef41Sopenharmony_ci } else { 931cb0ef41Sopenharmony_ci /* Compute the run length of zeros and add the appropriate number of 0 941cb0ef41Sopenharmony_ci and 17 code length codes to the code length code histogram. */ 951cb0ef41Sopenharmony_ci uint32_t reps = 1; 961cb0ef41Sopenharmony_ci size_t k; 971cb0ef41Sopenharmony_ci for (k = i + 1; k < data_size && histogram->data_[k] == 0; ++k) { 981cb0ef41Sopenharmony_ci ++reps; 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci i += reps; 1011cb0ef41Sopenharmony_ci if (i == data_size) { 1021cb0ef41Sopenharmony_ci /* Don't add any cost for the last zero run, since these are encoded 1031cb0ef41Sopenharmony_ci only implicitly. */ 1041cb0ef41Sopenharmony_ci break; 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci if (reps < 3) { 1071cb0ef41Sopenharmony_ci depth_histo[0] += reps; 1081cb0ef41Sopenharmony_ci } else { 1091cb0ef41Sopenharmony_ci reps -= 2; 1101cb0ef41Sopenharmony_ci while (reps > 0) { 1111cb0ef41Sopenharmony_ci ++depth_histo[BROTLI_REPEAT_ZERO_CODE_LENGTH]; 1121cb0ef41Sopenharmony_ci /* Add the 3 extra bits for the 17 code length code. */ 1131cb0ef41Sopenharmony_ci bits += 3; 1141cb0ef41Sopenharmony_ci reps >>= 3; 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci /* Add the estimated encoding cost of the code length code histogram. */ 1201cb0ef41Sopenharmony_ci bits += (double)(18 + 2 * max_depth); 1211cb0ef41Sopenharmony_ci /* Add the entropy of the code length code histogram. */ 1221cb0ef41Sopenharmony_ci bits += BitsEntropy(depth_histo, BROTLI_CODE_LENGTH_CODES); 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci return bits; 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci#undef HistogramType 128